Skip to content

Commit e6b4c10

Browse files
tniessenmarco-ippolito
authored andcommittedFeb 7, 2024
src: fix HasOnly(capability) in node::credentials
SYS_capget with _LINUX_CAPABILITY_VERSION_3 returns the process's permitted capabilities as two 32-bit values. To determine if the only permitted capability is indeed CAP_NET_BIND_SERVICE, it is necessary to check both of those values. Not doing so creates a vulnerability that potentially allows unprivileged users to inject code into a privileged Node.js process through environment variables such as NODE_OPTIONS. PR-URL: nodejs-private/node-private#505 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com> CVE-ID: CVE-2024-21892
1 parent 7fa1551 commit e6b4c10

File tree

1 file changed

+6
-7
lines changed

1 file changed

+6
-7
lines changed
 

‎src/node_credentials.cc

+6-7
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ namespace credentials {
5252
bool HasOnly(int capability) {
5353
DCHECK(cap_valid(capability));
5454

55-
struct __user_cap_data_struct cap_data[2];
55+
struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_3];
5656
struct __user_cap_header_struct cap_header_data = {
5757
_LINUX_CAPABILITY_VERSION_3,
5858
getpid()};
@@ -61,12 +61,11 @@ bool HasOnly(int capability) {
6161
if (syscall(SYS_capget, &cap_header_data, &cap_data) != 0) {
6262
return false;
6363
}
64-
if (capability < 32) {
65-
return cap_data[0].permitted ==
66-
static_cast<unsigned int>(CAP_TO_MASK(capability));
67-
}
68-
return cap_data[1].permitted ==
69-
static_cast<unsigned int>(CAP_TO_MASK(capability));
64+
65+
static_assert(arraysize(cap_data) == 2);
66+
return cap_data[CAP_TO_INDEX(capability)].permitted ==
67+
static_cast<unsigned int>(CAP_TO_MASK(capability)) &&
68+
cap_data[1 - CAP_TO_INDEX(capability)].permitted == 0;
7069
}
7170
#endif
7271

0 commit comments

Comments
 (0)
Please sign in to comment.