Skip to content

Commit 42a1166

Browse 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.
1 parent da4b233 commit 42a1166

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

src/node_credentials.cc

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010

1111
#if !defined(_MSC_VER)
1212
#include <unistd.h> // setuid, getuid
13+
#include <sys/capability.h>
1314
#endif
1415

1516
namespace node {
@@ -33,11 +34,32 @@ bool linux_at_secure = false;
3334

3435
namespace credentials {
3536

36-
// Look up environment variable unless running as setuid root.
37+
#if !defined(__CloudABI__) && !defined(_WIN32)
38+
// Returns true if the current process has effective capabilities and the
39+
// passed-in capability is in that set.
40+
bool HasCapability(int capability) {
41+
DCHECK(cap_valid(capability));
42+
struct __user_cap_header_struct cap_header_data = {
43+
_LINUX_CAPABILITY_VERSION_3, getpid()
44+
};
45+
struct __user_cap_data_struct cap_data;
46+
47+
if (capget(&cap_header_data, &cap_data) == -1) {
48+
return false;
49+
}
50+
51+
return cap_data.effective & CAP_TO_MASK(capability);
52+
}
53+
#endif
54+
55+
// Look up the environment variable and allow the lookup if the current
56+
// process has the capability CAP_NET_BIND_SERVICE set. If the current process
57+
// does not have any capabilities set and the process is running as setuid root
58+
// then lookup will not be allowed.
3759
bool SafeGetenv(const char* key, std::string* text, Environment* env) {
3860
#if !defined(__CloudABI__) && !defined(_WIN32)
39-
if (per_process::linux_at_secure || getuid() != geteuid() ||
40-
getgid() != getegid())
61+
if (!HasCapability(CAP_NET_BIND_SERVICE) && per_process::linux_at_secure ||
62+
getuid() != geteuid() || getgid() != getegid())
4163
goto fail;
4264
#endif
4365

0 commit comments

Comments
 (0)