diff mbox series

[meta-oe,kirkstone,2/4] nodejs: fix CVE-2024-21892

Message ID 20240223083620.182565-2-archana.polampalli@windriver.com
State New
Headers show
Series [meta-oe,kirkstone,1/4] nodejs: fix CVE-2024-22019 | expand

Commit Message

Polampalli, Archana Feb. 23, 2024, 8:36 a.m. UTC
From: Archana Polampalli <archana.polampalli@windriver.com>

On Linux, Node.js ignores certain environment variables if those may have been
set by an unprivileged user while the process is running with elevated privileges
with the only exception of CAP_NET_BIND_SERVICE. Due to a bug in the
implementation of this exception, Node.js incorrectly applies this exception
even when certain other capabilities have been set. This allows unprivileged
users to inject code that inherits the process's elevated privileges.

Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
---
 .../nodejs/nodejs/CVE-2024-21892-0001.patch   | 97 +++++++++++++++++++
 .../nodejs/nodejs/CVE-2024-21892-0002.patch   | 58 +++++++++++
 .../recipes-devtools/nodejs/nodejs_16.20.2.bb |  2 +
 3 files changed, 157 insertions(+)
 create mode 100644 meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0001.patch
 create mode 100644 meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0002.patch
diff mbox series

Patch

diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0001.patch b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0001.patch
new file mode 100644
index 000000000..0eb988fac
--- /dev/null
+++ b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0001.patch
@@ -0,0 +1,97 @@ 
+From 3f619407fe1e597657b598383d0b5003a064311b Mon Sep 17 00:00:00 2001
+From: Daniel Bevenius <daniel.bevenius@gmail.com>
+Date: Wed, 17 Mar 2021 13:48:51 +0100
+Subject: [PATCH 2/5] 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: https://github.com/nodejs/node/pull/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>
+
+CVE: CVE-2024-21892
+
+Upstream-Status: Backport [https://github.com/nodejs/node/commit/3f619407fe1e5976]
+
+Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
+---
+ src/node_credentials.cc | 38 +++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 37 insertions(+), 1 deletion(-)
+
+diff --git a/src/node_credentials.cc b/src/node_credentials.cc
+index 4c098c9..7688af8 100644
+--- a/src/node_credentials.cc
++++ b/src/node_credentials.cc
+@@ -12,6 +12,11 @@
+ #include <unistd.h>  // setuid, getuid
+ #endif
+
++#ifdef __linux__
++#include <linux/capability.h>
++#include <sys/syscall.h>
++#endif  // __linux__
++
+ namespace node {
+
+ using v8::Array;
+@@ -33,14 +38,45 @@ bool linux_at_secure = false;
+
+ namespace credentials {
+
+-// Look up environment variable unless running as setuid root.
++#if defined(__linux__)
++// Returns true if the current process only has the passed-in capability.
++bool HasOnly(int capability) {
++  DCHECK(cap_valid(capability));
++
++  struct __user_cap_data_struct cap_data[2];
++  struct __user_cap_header_struct cap_header_data = {
++    _LINUX_CAPABILITY_VERSION_3,
++    getpid()};
++
++
++  if (syscall(SYS_capget, &cap_header_data, &cap_data) != 0) {
++    return false;
++  }
++  if (capability < 32) {
++    return cap_data[0].permitted ==
++        static_cast<unsigned int>(CAP_TO_MASK(capability));
++  }
++  return cap_data[1].permitted ==
++      static_cast<unsigned int>(CAP_TO_MASK(capability));
++}
++#endif
++
++// Look up the environment variable and allow the lookup if the current
++// process only has the capability CAP_NET_BIND_SERVICE set. If the current
++// process does not have any capabilities set and the process is running as
++// setuid root then lookup will not be allowed.
+ bool SafeGetenv(const char* key,
+                 std::string* text,
+                 std::shared_ptr<KVStore> env_vars,
+                 v8::Isolate* isolate) {
+ #if !defined(__CloudABI__) && !defined(_WIN32)
++#if defined(__linux__)
++  if ((!HasOnly(CAP_NET_BIND_SERVICE) && per_process::linux_at_secure) ||
++      getuid() != geteuid() || getgid() != getegid())
++#else
+   if (per_process::linux_at_secure || getuid() != geteuid() ||
+       getgid() != getegid())
++#endif
+     goto fail;
+ #endif
+
+--
+2.40.0
diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0002.patch b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0002.patch
new file mode 100644
index 000000000..efb64db7d
--- /dev/null
+++ b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2024-21892-0002.patch
@@ -0,0 +1,58 @@ 
+From 10ecf400679e04eddab940721cad3f6c1d603b61 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= <tniessen@tnie.de>
+Date: Sat, 4 Nov 2023 00:39:57 +0000
+Subject: [PATCH 3/5] 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: https://github.com/nodejs-private/node-private/pull/505
+Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
+
+CVE-ID: CVE-2024-21892
+
+Upstream-Status: Backport [https://github.com/nodejs/node/commit/10ecf400679e04ed]
+
+Signed-off-by: Archana Polampalli <archana.polampalli@windriver.com>
+---
+ src/node_credentials.cc | 12 +++++-------
+ 1 file changed, 5 insertions(+), 7 deletions(-)
+
+diff --git a/src/node_credentials.cc b/src/node_credentials.cc
+index 7688af8..3dcbc8a 100644
+--- a/src/node_credentials.cc
++++ b/src/node_credentials.cc
+@@ -43,7 +43,7 @@ namespace credentials {
+ bool HasOnly(int capability) {
+   DCHECK(cap_valid(capability));
+
+-  struct __user_cap_data_struct cap_data[2];
++  struct __user_cap_data_struct cap_data[_LINUX_CAPABILITY_U32S_3];
+   struct __user_cap_header_struct cap_header_data = {
+     _LINUX_CAPABILITY_VERSION_3,
+     getpid()};
+@@ -52,12 +52,10 @@ bool HasOnly(int capability) {
+   if (syscall(SYS_capget, &cap_header_data, &cap_data) != 0) {
+     return false;
+   }
+-  if (capability < 32) {
+-    return cap_data[0].permitted ==
+-        static_cast<unsigned int>(CAP_TO_MASK(capability));
+-  }
+-  return cap_data[1].permitted ==
+-      static_cast<unsigned int>(CAP_TO_MASK(capability));
++  static_assert(arraysize(cap_data) == 2);
++  return cap_data[CAP_TO_INDEX(capability)].permitted ==
++             static_cast<unsigned int>(CAP_TO_MASK(capability)) &&
++         cap_data[1 - CAP_TO_INDEX(capability)].permitted == 0;
+ }
+ #endif
+
+--
+2.40.0
diff --git a/meta-oe/recipes-devtools/nodejs/nodejs_16.20.2.bb b/meta-oe/recipes-devtools/nodejs/nodejs_16.20.2.bb
index b786c0273..9540ed44e 100644
--- a/meta-oe/recipes-devtools/nodejs/nodejs_16.20.2.bb
+++ b/meta-oe/recipes-devtools/nodejs/nodejs_16.20.2.bb
@@ -28,6 +28,8 @@  SRC_URI = "http://nodejs.org/dist/v${PV}/node-v${PV}.tar.xz \
            file://0001-Nodejs-Fixed-pipes-DeprecationWarning.patch \
            file://CVE-2022-25883.patch \
            file://CVE-2024-22019.patch \
+           file://CVE-2024-21892-0001.patch \
+           file://CVE-2024-21892-0002.patch \
            "
 SRC_URI:append:class-target = " \
            file://0001-Using-native-binaries.patch \