-
Notifications
You must be signed in to change notification settings - Fork 29.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: call linux getauxval(AT_SECURE) in SafeGetenv #12548
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM if the CI is happy... but it appears not to be so far.
I'm afraid you can't use plain getauxval() because it is a fairly recent addition to glibc (>=2.16) and we support (much) older versions. You can get the value of AT_SECURE by rooting through the auxiliary vector that the kernel puts after the programs arguments and the environment but that is complicated by the relocating of Perhaps the best option is to do it as early as possible, in main() in src/node_main.cc. Doing it in Start() won't work because it could be an embedder-provided argv vector. EDIT: I owe you an apology for the comment. I was using "call getauxval(AT_SECURE)" as a shorthand for "call our lovingly handcrafted homegrown getauxval(AT_SECURE) reimplementation that libc does not provide" but there is no way you could have guessed that from looking at it. |
Maybe we can use this if node is compiled with a version that supports it? idk what our guidelines would be for |
I'll try this and see if I can get that right and have it pass the CI tests. Let me know if this is what you hade in mind. |
Just trying to see if I understand what should happen here. We need to retrieve the auxiliary vector information in node_main, and store the key value pairs so that when the node version of getauxval is called the value can be returned? |
Not allowed, but dynamic detection with dlsym() is. Rationale: a binary compiled on a system with getauxval() would be unusable on a system without.
Correct. You don't need to copy out the aux vector (libuv doesn't touch it) but neither would it hurt. |
f4e6fa2
to
b356a19
Compare
Thanks for the verifying. I've made an attempt at this now. It lacks any form of tests but if this looks like I'm on the right path I'll take a look at adding something. I've just manually tested using the following steps for now: $ setcap cap_net_raw+ep out/Release/node
$ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation"
true
$ useradd test
$ su test
$ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation"
undefined |
b356a19
to
914d196
Compare
c3842c2
to
f7636a5
Compare
Rebased CI: https://ci.nodejs.org/job/node-test-pull-request/8117/ |
e5bbee7
to
848294b
Compare
test/arm seems to have completed successfullyhttps://ci.nodejs.org/job/node-test-commit-arm/nodes=armv7-ubuntu1404/9741/console: Run condition [Always] enabling perform for step [[Execute a set of scripts, Execute a set of scripts]]
TAP Reports Processing: START
Looking for TAP results report in workspace using pattern: *.tap
Saving reports...
Processing '/var/lib/jenkins/jobs/node-test-commit-arm/configurations/axis-nodes/armv7-ubuntu1404/builds/9741/tap-master-files/cctest.tap'
Parsing TAP test result [/var/lib/jenkins/jobs/node-test-commit-arm/configurations/axis-nodes/armv7-ubuntu1404/builds/9741/tap-master-files/cctest.tap].
Processing '/var/lib/jenkins/jobs/node-test-commit-arm/configurations/axis-nodes/armv7-ubuntu1404/builds/9741/tap-master-files/test.tap'
Parsing TAP test result [/var/lib/jenkins/jobs/node-test-commit-arm/configurations/axis-nodes/armv7-ubuntu1404/builds/9741/tap-master-files/test.tap].
TAP Reports Processing: FINISH
Checking ^not ok
Notifying upstream projects of job completion
Finished: SUCCESS |
@bnoordhuis Could you take another look at this when you get a chance? |
src/node.cc
Outdated
#if defined(__linux__) | ||
AuxVector::AuxVector() { | ||
char** envp = environ; | ||
while (*envp++ != NULL) {} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nullptr
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix this.
src/node.cc
Outdated
Elf_auxv_t* auxv = reinterpret_cast<Elf_auxv_t*>(envp); | ||
for (; auxv->a_type != AT_NULL; auxv++) { | ||
auxv_map_[auxv->a_type] = auxv->a_un.a_val; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should skip AT_IGNORE entries here. That said, I'd make this the simplest possible implementation and not bother with a map since we're only interested in AT_SECURE. E.g. bool linux_at_secure;
in node.cc in and set it in node_main.cc if AT_SECURE is present (with an extern bool linux_at_secure;
declaration to make it link.)
I'd be okay with unconditionally defining the bool to save on #ifdef __linux__
ugliness.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That sounds much better. I'll give that a go and see what you think.
src/node.h
Outdated
void operator=(AuxVector const&); | ||
std::map<std::size_t, std::size_t> auxv_map_; | ||
}; | ||
#endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should not go into node.h, it's a public header. node_internals.h is okay, though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll move it. Thanks
This commit attempts to fix the following TODO: // TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE) is non-zero on Linux. This can be manually tested at the moment using the following steps: $ setcap cap_net_raw+ep out/Release/node $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" true $ useradd test $ su test $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" undefined
848294b
to
a7c7bea
Compare
@bnoordhuis I've made another attempt on this and tried to follow your suggestions. Could you take another look and see if this was what you had in mind? Thanks |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM modulo nit and question. Nice work.
src/node_main.cc
Outdated
#else | ||
#define Elf_auxv_t Elf32_auxv_t | ||
#endif // __LP64__ | ||
extern char **environ; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Style nit: extern char** environ;
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll fix this.
src/node_main.cc
Outdated
@@ -71,7 +71,33 @@ int wmain(int argc, wchar_t *wargv[]) { | |||
} | |||
#else | |||
// UNIX | |||
#ifdef __linux__ | |||
#include <elf.h> | |||
#include <inttypes.h> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you need inttypes.h for?
This commit attempts to fix the following TODO: // TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE) is non-zero on Linux. This can be manually tested at the moment using the following steps: $ setcap cap_net_raw+ep out/Release/node $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" true $ useradd test $ su test $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" undefined PR-URL: nodejs#12548 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
Landed in 6caf1b0 |
This commit attempts to fix the following TODO: // TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE) is non-zero on Linux. This can be manually tested at the moment using the following steps: $ setcap cap_net_raw+ep out/Release/node $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" true $ useradd test $ su test $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" undefined PR-URL: #12548 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
This commit attempts to fix the following TODO: // TODO(bnoordhuis) Should perhaps also check whether getauxval(AT_SECURE) is non-zero on Linux. This can be manually tested at the moment using the following steps: $ setcap cap_net_raw+ep out/Release/node $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" true $ useradd test $ su test $ NODE_PENDING_DEPRECATION="1" out/Release/node -p "process.binding('config').pendingDeprecation" undefined PR-URL: #12548 Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: Ben Noordhuis <[email protected]>
This does not land cleanly in LTS. Please feel free to manually backport. Please also feel free to replace the backport request label with do-not-land if it shouldn't land |
This commit suggests using getauxval in node_main.cc. The motivation for this is that getauxval was introduced in glibc 2.16 and looking at BUILDING.md, in the 'Platform list' section, it looks like we now support glibc >= 2.17 and perhaps this change would be alright now. Refs: nodejs#12548
This commit suggests using getauxval in node_main.cc. The motivation for this is that getauxval was introduced in glibc 2.16 and looking at BUILDING.md, in the 'Platform list' section, it looks like we now support glibc >= 2.17 and perhaps this change would be alright now. PR-URL: #33693 Refs: #12548 Reviewed-By: Ben Noordhuis <[email protected]> Reviewed-By: David Carlier <[email protected]> Reviewed-By: Anna Henningsen <[email protected]> Reviewed-By: Colin Ihrig <[email protected]> Reviewed-By: James M Snell <[email protected]>
This commit attempts to fix the following TODO:
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passesAffected core subsystem(s)
src