Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 3f61940

Browse filesBrowse files
committed
src: allow CAP_NET_BIND_SERVICE in SafeGetenv
This commit updates SafeGetenv to check if the current process has the effective capability cap_net_bind_service set, and if so allows environment variables to be read. The motivation for this change is a use-case where Node is run in a container, and the is a requirement to be able to listen to ports below 1024. This is done by setting the capability of cap_net_bind_service. In addition there is a need to set the environment variable `NODE_EXTRA_CA_CERTS`. But currently this environment variable will not be read when the capability has been set on the executable. PR-URL: #37727 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Michael Dawson <midawson@redhat.com>
1 parent 8e84d56 commit 3f61940
Copy full SHA for 3f61940

File tree

Expand file treeCollapse file tree

1 file changed

+36
-1
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

1 file changed

+36
-1
lines changed
Open diff view settings
Collapse file

‎src/node_credentials.cc‎

Copy file name to clipboardExpand all lines: src/node_credentials.cc
+36-1Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@
1111
#if !defined(_MSC_VER)
1212
#include <unistd.h> // setuid, getuid
1313
#endif
14+
#ifdef __linux__
15+
#include <linux/capability.h>
16+
#include <sys/syscall.h>
17+
#endif // __linux__
1418

1519
namespace node {
1620

@@ -33,11 +37,42 @@ bool linux_at_secure = false;
3337

3438
namespace credentials {
3539

36-
// Look up environment variable unless running as setuid root.
40+
#if defined(__linux__)
41+
// Returns true if the current process only has the passed-in capability.
42+
bool HasOnly(int capability) {
43+
DCHECK(cap_valid(capability));
44+
45+
struct __user_cap_data_struct cap_data[2];
46+
struct __user_cap_header_struct cap_header_data = {
47+
_LINUX_CAPABILITY_VERSION_3,
48+
getpid()};
49+
50+
51+
if (syscall(SYS_capget, &cap_header_data, &cap_data) != 0) {
52+
return false;
53+
}
54+
if (capability < 32) {
55+
return cap_data[0].permitted ==
56+
static_cast<unsigned int>(CAP_TO_MASK(capability));
57+
}
58+
return cap_data[1].permitted ==
59+
static_cast<unsigned int>(CAP_TO_MASK(capability));
60+
}
61+
#endif
62+
63+
// Look up the environment variable and allow the lookup if the current
64+
// process only has the capability CAP_NET_BIND_SERVICE set. If the current
65+
// process does not have any capabilities set and the process is running as
66+
// setuid root then lookup will not be allowed.
3767
bool SafeGetenv(const char* key, std::string* text, Environment* env) {
3868
#if !defined(__CloudABI__) && !defined(_WIN32)
69+
#if defined(__linux__)
70+
if ((!HasOnly(CAP_NET_BIND_SERVICE) && per_process::linux_at_secure) ||
71+
getuid() != geteuid() || getgid() != getegid())
72+
#else
3973
if (per_process::linux_at_secure || getuid() != geteuid() ||
4074
getgid() != getegid())
75+
#endif
4176
goto fail;
4277
#endif
4378

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.