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 e93dd4d

Browse filesBrowse files
joyeecheungaddaleax
authored andcommitted
process: move POSIX credential accessors into node_credentials.cc
Expose the POSIX credential accessors through `internalBinding('credentials')` instead of setting them on the process or bootstrapper object from C++ directly. Also moves `SafeGetEnv` from `internalBinding('util')` to `internalBinding('credentials')` since it's closely related to the credentials. In the JS land, instead of wrapping the bindings then writing to the process object directly in main_thread_only.js, return the wrapped functions back to bootstrap/node.js where they get written to the process object conditionally for clarity. Refs: #24961 PR-URL: #25066 Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: James M Snell <jasnell@gmail.com>
1 parent 37ba201 commit e93dd4d
Copy full SHA for e93dd4d

File tree

Expand file treeCollapse file tree

17 files changed

+498
-474
lines changed
Open diff view settings
Filter options
Expand file treeCollapse file tree

17 files changed

+498
-474
lines changed
Open diff view settings
Collapse file

‎lib/internal/bootstrap/node.js‎

Copy file name to clipboardExpand all lines: lib/internal/bootstrap/node.js
+20-6Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ const {
2323
_setupPromises, _chdir, _cpuUsage,
2424
_hrtime, _hrtimeBigInt,
2525
_memoryUsage, _rawDebug,
26-
_umask, _initgroups, _setegid, _seteuid,
27-
_setgid, _setuid, _setgroups,
26+
_umask,
2827
_shouldAbortOnUncaughtToggle
2928
} = bootstrappers;
3029
const { internalBinding, NativeModule } = loaderExports;
@@ -73,13 +72,28 @@ function startup() {
7372
NativeModule.require('internal/process/warning').setup();
7473
NativeModule.require('internal/process/next_tick').setup(_setupNextTick,
7574
_setupPromises);
75+
const credentials = internalBinding('credentials');
76+
if (credentials.implementsPosixCredentials) {
77+
process.getuid = credentials.getuid;
78+
process.geteuid = credentials.geteuid;
79+
process.getgid = credentials.getgid;
80+
process.getegid = credentials.getegid;
81+
process.getgroups = credentials.getgroups;
82+
83+
if (isMainThread) {
84+
const wrapped = mainThreadSetup.wrapPosixCredentialSetters(credentials);
85+
process.initgroups = wrapped.initgroups;
86+
process.setgroups = wrapped.setgroups;
87+
process.setegid = wrapped.setegid;
88+
process.seteuid = wrapped.seteuid;
89+
process.setgid = wrapped.setgid;
90+
process.setuid = wrapped.setuid;
91+
}
92+
}
7693

7794
if (isMainThread) {
7895
mainThreadSetup.setupStdio();
79-
mainThreadSetup.setupProcessMethods(
80-
_chdir, _umask, _initgroups, _setegid, _seteuid,
81-
_setgid, _setuid, _setgroups
82-
);
96+
mainThreadSetup.setupProcessMethods(_chdir, _umask);
8397
} else {
8498
workerThreadSetup.setupStdio();
8599
}
Collapse file

‎lib/internal/modules/cjs/loader.js‎

Copy file name to clipboardExpand all lines: lib/internal/modules/cjs/loader.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const {
3434
internalModuleReadJSON,
3535
internalModuleStat
3636
} = internalBinding('fs');
37-
const { safeGetenv } = internalBinding('util');
37+
const { safeGetenv } = internalBinding('credentials');
3838
const {
3939
makeRequireFunction,
4040
requireDepth,
Collapse file

‎lib/internal/process/main_thread_only.js‎

Copy file name to clipboardExpand all lines: lib/internal/process/main_thread_only.js
+35-38Lines changed: 35 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,7 @@ function setupStdio() {
2929

3030
// Non-POSIX platforms like Windows don't have certain methods.
3131
// Workers also lack these methods since they change process-global state.
32-
function setupProcessMethods(_chdir, _umask, _initgroups, _setegid,
33-
_seteuid, _setgid, _setuid, _setgroups) {
34-
if (_setgid !== undefined) {
35-
setupPosixMethods(_initgroups, _setegid, _seteuid,
36-
_setgid, _setuid, _setgroups);
37-
}
38-
32+
function setupProcessMethods(_chdir, _umask) {
3933
process.chdir = function chdir(directory) {
4034
validateString(directory, 'directory');
4135
return _chdir(directory);
@@ -51,10 +45,17 @@ function setupProcessMethods(_chdir, _umask, _initgroups, _setegid,
5145
};
5246
}
5347

54-
function setupPosixMethods(_initgroups, _setegid, _seteuid,
55-
_setgid, _setuid, _setgroups) {
56-
57-
process.initgroups = function initgroups(user, extraGroup) {
48+
function wrapPosixCredentialSetters(credentials) {
49+
const {
50+
initgroups: _initgroups,
51+
setgroups: _setgroups,
52+
setegid: _setegid,
53+
seteuid: _seteuid,
54+
setgid: _setgid,
55+
setuid: _setuid
56+
} = credentials;
57+
58+
function initgroups(user, extraGroup) {
5859
validateId(user, 'user');
5960
validateId(extraGroup, 'extraGroup');
6061
// Result is 0 on success, 1 if user is unknown, 2 if group is unknown.
@@ -64,25 +65,9 @@ function setupPosixMethods(_initgroups, _setegid, _seteuid,
6465
} else if (result === 2) {
6566
throw new ERR_UNKNOWN_CREDENTIAL('Group', extraGroup);
6667
}
67-
};
68-
69-
process.setegid = function setegid(id) {
70-
return execId(id, 'Group', _setegid);
71-
};
72-
73-
process.seteuid = function seteuid(id) {
74-
return execId(id, 'User', _seteuid);
75-
};
76-
77-
process.setgid = function setgid(id) {
78-
return execId(id, 'Group', _setgid);
79-
};
80-
81-
process.setuid = function setuid(id) {
82-
return execId(id, 'User', _setuid);
83-
};
68+
}
8469

85-
process.setgroups = function setgroups(groups) {
70+
function setgroups(groups) {
8671
if (!Array.isArray(groups)) {
8772
throw new ERR_INVALID_ARG_TYPE('groups', 'Array', groups);
8873
}
@@ -95,15 +80,17 @@ function setupPosixMethods(_initgroups, _setegid, _seteuid,
9580
if (result > 0) {
9681
throw new ERR_UNKNOWN_CREDENTIAL('Group', groups[result - 1]);
9782
}
98-
};
83+
}
9984

100-
function execId(id, type, method) {
101-
validateId(id, 'id');
102-
// Result is 0 on success, 1 if credential is unknown.
103-
const result = method(id);
104-
if (result === 1) {
105-
throw new ERR_UNKNOWN_CREDENTIAL(type, id);
106-
}
85+
function wrapIdSetter(type, method) {
86+
return function(id) {
87+
validateId(id, 'id');
88+
// Result is 0 on success, 1 if credential is unknown.
89+
const result = method(id);
90+
if (result === 1) {
91+
throw new ERR_UNKNOWN_CREDENTIAL(type, id);
92+
}
93+
};
10794
}
10895

10996
function validateId(id, name) {
@@ -113,6 +100,15 @@ function setupPosixMethods(_initgroups, _setegid, _seteuid,
113100
throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id);
114101
}
115102
}
103+
104+
return {
105+
initgroups,
106+
setgroups,
107+
setegid: wrapIdSetter('Group', _setegid),
108+
seteuid: wrapIdSetter('User', _seteuid),
109+
setgid: wrapIdSetter('Group', _setgid),
110+
setuid: wrapIdSetter('User', _setuid)
111+
};
116112
}
117113

118114
// Worker threads don't receive signals.
@@ -181,5 +177,6 @@ module.exports = {
181177
setupStdio,
182178
setupProcessMethods,
183179
setupSignalHandlers,
184-
setupChildProcessIpcChannel
180+
setupChildProcessIpcChannel,
181+
wrapPosixCredentialSetters
185182
};
Collapse file

‎lib/os.js‎

Copy file name to clipboardExpand all lines: lib/os.js
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
'use strict';
2323

24-
const { safeGetenv } = internalBinding('util');
24+
const { safeGetenv } = internalBinding('credentials');
2525
const constants = internalBinding('constants').os;
2626
const { deprecate } = require('internal/util');
2727
const isWindows = process.platform === 'win32';
Collapse file

‎node.gyp‎

Copy file name to clipboardExpand all lines: node.gyp
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -352,6 +352,7 @@
352352
'src/node_config.cc',
353353
'src/node_constants.cc',
354354
'src/node_contextify.cc',
355+
'src/node_credentials.cc',
355356
'src/node_domain.cc',
356357
'src/node_encoding.cc',
357358
'src/node_env_var.cc',
Collapse file

‎src/bootstrapper.cc‎

Copy file name to clipboardExpand all lines: src/bootstrapper.cc
-11Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -147,17 +147,6 @@ void SetupBootstrapObject(Environment* env,
147147
BOOTSTRAP_METHOD(_rawDebug, RawDebug);
148148
BOOTSTRAP_METHOD(_umask, Umask);
149149

150-
#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
151-
if (env->is_main_thread()) {
152-
BOOTSTRAP_METHOD(_initgroups, InitGroups);
153-
BOOTSTRAP_METHOD(_setegid, SetEGid);
154-
BOOTSTRAP_METHOD(_seteuid, SetEUid);
155-
BOOTSTRAP_METHOD(_setgid, SetGid);
156-
BOOTSTRAP_METHOD(_setuid, SetUid);
157-
BOOTSTRAP_METHOD(_setgroups, SetGroups);
158-
}
159-
#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
160-
161150
Local<String> should_abort_on_uncaught_toggle =
162151
FIXED_ONE_BYTE_STRING(env->isolate(), "_shouldAbortOnUncaughtToggle");
163152
CHECK(bootstrapper->Set(env->context(),
Collapse file

‎src/env.cc‎

Copy file name to clipboardExpand all lines: src/env.cc
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -227,7 +227,7 @@ Environment::Environment(IsolateData* isolate_data,
227227
should_abort_on_uncaught_toggle_[0] = 1;
228228

229229
std::string debug_cats;
230-
SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats);
230+
credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats);
231231
set_debug_categories(debug_cats, true);
232232

233233
isolate()->GetHeapProfiler()->AddBuildEmbedderGraphCallback(
Collapse file

‎src/node.cc‎

Copy file name to clipboardExpand all lines: src/node.cc
+13-46Lines changed: 13 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -100,12 +100,7 @@ typedef int mode_t;
100100
#else
101101
#include <pthread.h>
102102
#include <sys/resource.h> // getrlimit, setrlimit
103-
#include <unistd.h> // setuid, getuid
104-
#endif
105-
106-
#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
107-
#include <pwd.h> // getpwnam()
108-
#include <grp.h> // getgrnam()
103+
#include <unistd.h> // STDIN_FILENO, STDERR_FILENO
109104
#endif
110105

111106
namespace node {
@@ -153,8 +148,6 @@ unsigned int reverted = 0;
153148

154149
bool v8_initialized = false;
155150

156-
bool linux_at_secure = false;
157-
158151
// process-relative uptime base, initialized at start-up
159152
double prog_start_time;
160153

@@ -504,27 +497,6 @@ const char* signo_string(int signo) {
504497
}
505498
}
506499

507-
// Look up environment variable unless running as setuid root.
508-
bool SafeGetenv(const char* key, std::string* text) {
509-
#if !defined(__CloudABI__) && !defined(_WIN32)
510-
if (linux_at_secure || getuid() != geteuid() || getgid() != getegid())
511-
goto fail;
512-
#endif
513-
514-
{
515-
Mutex::ScopedLock lock(environ_mutex);
516-
if (const char* value = getenv(key)) {
517-
*text = value;
518-
return true;
519-
}
520-
}
521-
522-
fail:
523-
text->clear();
524-
return false;
525-
}
526-
527-
528500
void* ArrayBufferAllocator::Allocate(size_t size) {
529501
if (zero_fill_field_ || per_process_opts->zero_fill_all_buffers)
530502
return UncheckedCalloc(size);
@@ -1165,14 +1137,6 @@ void SetupProcessObject(Environment* env,
11651137
env->SetMethod(process, "dlopen", binding::DLOpen);
11661138
env->SetMethod(process, "reallyExit", Exit);
11671139
env->SetMethodNoSideEffect(process, "uptime", Uptime);
1168-
1169-
#if defined(__POSIX__) && !defined(__ANDROID__) && !defined(__CloudABI__)
1170-
env->SetMethodNoSideEffect(process, "getuid", GetUid);
1171-
env->SetMethodNoSideEffect(process, "geteuid", GetEUid);
1172-
env->SetMethodNoSideEffect(process, "getgid", GetGid);
1173-
env->SetMethodNoSideEffect(process, "getegid", GetEGid);
1174-
env->SetMethodNoSideEffect(process, "getgroups", GetGroups);
1175-
#endif // __POSIX__ && !defined(__ANDROID__) && !defined(__CloudABI__)
11761140
}
11771141

11781142

@@ -1633,37 +1597,40 @@ void Init(std::vector<std::string>* argv,
16331597
{
16341598
std::string text;
16351599
default_env_options->pending_deprecation =
1636-
SafeGetenv("NODE_PENDING_DEPRECATION", &text) && text[0] == '1';
1600+
credentials::SafeGetenv("NODE_PENDING_DEPRECATION", &text) &&
1601+
text[0] == '1';
16371602
}
16381603

16391604
// Allow for environment set preserving symlinks.
16401605
{
16411606
std::string text;
16421607
default_env_options->preserve_symlinks =
1643-
SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) && text[0] == '1';
1608+
credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS", &text) &&
1609+
text[0] == '1';
16441610
}
16451611

16461612
{
16471613
std::string text;
16481614
default_env_options->preserve_symlinks_main =
1649-
SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) && text[0] == '1';
1615+
credentials::SafeGetenv("NODE_PRESERVE_SYMLINKS_MAIN", &text) &&
1616+
text[0] == '1';
16501617
}
16511618

16521619
if (default_env_options->redirect_warnings.empty()) {
1653-
SafeGetenv("NODE_REDIRECT_WARNINGS",
1654-
&default_env_options->redirect_warnings);
1620+
credentials::SafeGetenv("NODE_REDIRECT_WARNINGS",
1621+
&default_env_options->redirect_warnings);
16551622
}
16561623

16571624
#if HAVE_OPENSSL
16581625
std::string* openssl_config = &per_process_opts->openssl_config;
16591626
if (openssl_config->empty()) {
1660-
SafeGetenv("OPENSSL_CONF", openssl_config);
1627+
credentials::SafeGetenv("OPENSSL_CONF", openssl_config);
16611628
}
16621629
#endif
16631630

16641631
#if !defined(NODE_WITHOUT_NODE_OPTIONS)
16651632
std::string node_options;
1666-
if (SafeGetenv("NODE_OPTIONS", &node_options)) {
1633+
if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
16671634
std::vector<std::string> env_argv;
16681635
// [0] is expected to be the program name, fill it in from the real argv.
16691636
env_argv.push_back(argv->at(0));
@@ -1695,7 +1662,7 @@ void Init(std::vector<std::string>* argv,
16951662
#if defined(NODE_HAVE_I18N_SUPPORT)
16961663
// If the parameter isn't given, use the env variable.
16971664
if (per_process_opts->icu_data_dir.empty())
1698-
SafeGetenv("NODE_ICU_DATA", &per_process_opts->icu_data_dir);
1665+
credentials::SafeGetenv("NODE_ICU_DATA", &per_process_opts->icu_data_dir);
16991666
// Initialize ICU.
17001667
// If icu_data_dir is empty here, it will load the 'minimal' data.
17011668
if (!i18n::InitializeICUDirectory(per_process_opts->icu_data_dir)) {
@@ -2103,7 +2070,7 @@ int Start(int argc, char** argv) {
21032070
#if HAVE_OPENSSL
21042071
{
21052072
std::string extra_ca_certs;
2106-
if (SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
2073+
if (credentials::SafeGetenv("NODE_EXTRA_CA_CERTS", &extra_ca_certs))
21072074
crypto::UseExtraCaCerts(extra_ca_certs);
21082075
}
21092076
#ifdef NODE_FIPS_MODE
Collapse file

‎src/node_binding.cc‎

Copy file name to clipboardExpand all lines: src/node_binding.cc
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
V(cares_wrap) \
2727
V(config) \
2828
V(contextify) \
29+
V(credentials) \
2930
V(domain) \
3031
V(fs) \
3132
V(fs_event_wrap) \

0 commit comments

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