GeezerVison is showing github.com — process: move POSIX credential accessors into node_credentials.cc · nodejs/node@e93dd4d
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: lib/internal/bootstrap/node.js +20-6Lines changed: 20 additions & 6 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -23,8 +23,7 @@ const { | 23 | 23 | _setupPromises, _chdir, _cpuUsage, | 24 | 24 | _hrtime, _hrtimeBigInt, | 25 | 25 | _memoryUsage, _rawDebug, | 26 | | - _umask, _initgroups, _setegid, _seteuid, | 27 | | - _setgid, _setuid, _setgroups, | | 26 | + _umask, | 28 | 27 | _shouldAbortOnUncaughtToggle | 29 | 28 | } = bootstrappers; | 30 | 29 | const { internalBinding, NativeModule } = loaderExports; | @@ -73,13 +72,28 @@ function startup() { | 73 | 72 | NativeModule.require('internal/process/warning').setup(); | 74 | 73 | NativeModule.require('internal/process/next_tick').setup(_setupNextTick, | 75 | 74 | _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 | + } | 76 | 93 |
| 77 | 94 | if (isMainThread) { | 78 | 95 | mainThreadSetup.setupStdio(); | 79 | | - mainThreadSetup.setupProcessMethods( | 80 | | - _chdir, _umask, _initgroups, _setegid, _seteuid, | 81 | | - _setgid, _setuid, _setgroups | 82 | | - ); | | 96 | + mainThreadSetup.setupProcessMethods(_chdir, _umask); | 83 | 97 | } else { | 84 | 98 | workerThreadSetup.setupStdio(); | 85 | 99 | } | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/modules/cjs/loader.js +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -34,7 +34,7 @@ const { | 34 | 34 | internalModuleReadJSON, | 35 | 35 | internalModuleStat | 36 | 36 | } = internalBinding('fs'); | 37 | | -const { safeGetenv } = internalBinding('util'); | | 37 | +const { safeGetenv } = internalBinding('credentials'); | 38 | 38 | const { | 39 | 39 | makeRequireFunction, | 40 | 40 | requireDepth, | |
Collapse file Copy file name to clipboardExpand all lines: lib/internal/process/main_thread_only.js +35-38Lines changed: 35 additions & 38 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -29,13 +29,7 @@ function setupStdio() { | 29 | 29 |
| 30 | 30 | // Non-POSIX platforms like Windows don't have certain methods. | 31 | 31 | // 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) { | 39 | 33 | process.chdir = function chdir(directory) { | 40 | 34 | validateString(directory, 'directory'); | 41 | 35 | return _chdir(directory); | @@ -51,10 +45,17 @@ function setupProcessMethods(_chdir, _umask, _initgroups, _setegid, | 51 | 45 | }; | 52 | 46 | } | 53 | 47 |
| 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) { | 58 | 59 | validateId(user, 'user'); | 59 | 60 | validateId(extraGroup, 'extraGroup'); | 60 | 61 | // Result is 0 on success, 1 if user is unknown, 2 if group is unknown. | @@ -64,25 +65,9 @@ function setupPosixMethods(_initgroups, _setegid, _seteuid, | 64 | 65 | } else if (result === 2) { | 65 | 66 | throw new ERR_UNKNOWN_CREDENTIAL('Group', extraGroup); | 66 | 67 | } | 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 | + } | 84 | 69 |
| 85 | | - process.setgroups = function setgroups(groups) { | | 70 | + function setgroups(groups) { | 86 | 71 | if (!Array.isArray(groups)) { | 87 | 72 | throw new ERR_INVALID_ARG_TYPE('groups', 'Array', groups); | 88 | 73 | } | @@ -95,15 +80,17 @@ function setupPosixMethods(_initgroups, _setegid, _seteuid, | 95 | 80 | if (result > 0) { | 96 | 81 | throw new ERR_UNKNOWN_CREDENTIAL('Group', groups[result - 1]); | 97 | 82 | } | 98 | | - }; | | 83 | + } | 99 | 84 |
| 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 | + }; | 107 | 94 | } | 108 | 95 |
| 109 | 96 | function validateId(id, name) { | @@ -113,6 +100,15 @@ function setupPosixMethods(_initgroups, _setegid, _seteuid, | 113 | 100 | throw new ERR_INVALID_ARG_TYPE(name, ['number', 'string'], id); | 114 | 101 | } | 115 | 102 | } | | 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 | + }; | 116 | 112 | } | 117 | 113 |
| 118 | 114 | // Worker threads don't receive signals. | @@ -181,5 +177,6 @@ module.exports = { | 181 | 177 | setupStdio, | 182 | 178 | setupProcessMethods, | 183 | 179 | setupSignalHandlers, | 184 | | - setupChildProcessIpcChannel | | 180 | + setupChildProcessIpcChannel, | | 181 | + wrapPosixCredentialSetters | 185 | 182 | }; |
Collapse file Copy file name to clipboardExpand all lines: lib/os.js +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
| 21 | 21 |
| 22 | 22 | 'use strict'; | 23 | 23 |
| 24 | | -const { safeGetenv } = internalBinding('util'); | | 24 | +const { safeGetenv } = internalBinding('credentials'); | 25 | 25 | const constants = internalBinding('constants').os; | 26 | 26 | const { deprecate } = require('internal/util'); | 27 | 27 | const isWindows = process.platform === 'win32'; | |
Collapse file Copy file name to clipboardExpand all lines: node.gyp +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 352 | 352 | 'src/node_config.cc', | 353 | 353 | 'src/node_constants.cc', | 354 | 354 | 'src/node_contextify.cc', | | 355 | + 'src/node_credentials.cc', | 355 | 356 | 'src/node_domain.cc', | 356 | 357 | 'src/node_encoding.cc', | 357 | 358 | 'src/node_env_var.cc', | |
Collapse file Copy file name to clipboardExpand all lines: src/bootstrapper.cc -11Lines changed: 0 additions & 11 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -147,17 +147,6 @@ void SetupBootstrapObject(Environment* env, | 147 | 147 | BOOTSTRAP_METHOD(_rawDebug, RawDebug); | 148 | 148 | BOOTSTRAP_METHOD(_umask, Umask); | 149 | 149 |
| 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 | | - | 161 | 150 | Local<String> should_abort_on_uncaught_toggle = | 162 | 151 | FIXED_ONE_BYTE_STRING(env->isolate(), "_shouldAbortOnUncaughtToggle"); | 163 | 152 | CHECK(bootstrapper->Set(env->context(), | |
Collapse file Copy file name to clipboardExpand all lines: src/env.cc +1-1Lines changed: 1 addition & 1 deletion | Original file line number | Diff line number | Diff line change |
|---|
@@ -227,7 +227,7 @@ Environment::Environment(IsolateData* isolate_data, | 227 | 227 | should_abort_on_uncaught_toggle_[0] = 1; | 228 | 228 |
| 229 | 229 | std::string debug_cats; | 230 | | - SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats); | | 230 | + credentials::SafeGetenv("NODE_DEBUG_NATIVE", &debug_cats); | 231 | 231 | set_debug_categories(debug_cats, true); | 232 | 232 |
| 233 | 233 | isolate()->GetHeapProfiler()->AddBuildEmbedderGraphCallback( | |
Collapse file Copy file name to clipboardExpand all lines: src/node.cc +13-46Lines changed: 13 additions & 46 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -100,12 +100,7 @@ typedef int mode_t; | 100 | 100 | #else | 101 | 101 | #include <pthread.h> | 102 | 102 | #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 | 109 | 104 | #endif | 110 | 105 |
| 111 | 106 | namespace node { | @@ -153,8 +148,6 @@ unsigned int reverted = 0; | 153 | 148 |
| 154 | 149 | bool v8_initialized = false; | 155 | 150 |
| 156 | | -bool linux_at_secure = false; | 157 | | - | 158 | 151 | // process-relative uptime base, initialized at start-up | 159 | 152 | double prog_start_time; | 160 | 153 |
| @@ -504,27 +497,6 @@ const char* signo_string(int signo) { | 504 | 497 | } | 505 | 498 | } | 506 | 499 |
| 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 | | - | 528 | 500 | void* ArrayBufferAllocator::Allocate(size_t size) { | 529 | 501 | if (zero_fill_field_ || per_process_opts->zero_fill_all_buffers) | 530 | 502 | return UncheckedCalloc(size); | @@ -1165,14 +1137,6 @@ void SetupProcessObject(Environment* env, | 1165 | 1137 | env->SetMethod(process, "dlopen", binding::DLOpen); | 1166 | 1138 | env->SetMethod(process, "reallyExit", Exit); | 1167 | 1139 | 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__) | 1176 | 1140 | } | 1177 | 1141 |
| 1178 | 1142 |
| @@ -1633,37 +1597,40 @@ void Init(std::vector<std::string>* argv, | 1633 | 1597 | { | 1634 | 1598 | std::string text; | 1635 | 1599 | 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'; | 1637 | 1602 | } | 1638 | 1603 |
| 1639 | 1604 | // Allow for environment set preserving symlinks. | 1640 | 1605 | { | 1641 | 1606 | std::string text; | 1642 | 1607 | 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'; | 1644 | 1610 | } | 1645 | 1611 |
| 1646 | 1612 | { | 1647 | 1613 | std::string text; | 1648 | 1614 | 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'; | 1650 | 1617 | } | 1651 | 1618 |
| 1652 | 1619 | 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); | 1655 | 1622 | } | 1656 | 1623 |
| 1657 | 1624 | #if HAVE_OPENSSL | 1658 | 1625 | std::string* openssl_config = &per_process_opts->openssl_config; | 1659 | 1626 | if (openssl_config->empty()) { | 1660 | | - SafeGetenv("OPENSSL_CONF", openssl_config); | | 1627 | + credentials::SafeGetenv("OPENSSL_CONF", openssl_config); | 1661 | 1628 | } | 1662 | 1629 | #endif | 1663 | 1630 |
| 1664 | 1631 | #if !defined(NODE_WITHOUT_NODE_OPTIONS) | 1665 | 1632 | std::string node_options; | 1666 | | - if (SafeGetenv("NODE_OPTIONS", &node_options)) { | | 1633 | + if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) { | 1667 | 1634 | std::vector<std::string> env_argv; | 1668 | 1635 | // [0] is expected to be the program name, fill it in from the real argv. | 1669 | 1636 | env_argv.push_back(argv->at(0)); | @@ -1695,7 +1662,7 @@ void Init(std::vector<std::string>* argv, | 1695 | 1662 | #if defined(NODE_HAVE_I18N_SUPPORT) | 1696 | 1663 | // If the parameter isn't given, use the env variable. | 1697 | 1664 | 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); | 1699 | 1666 | // Initialize ICU. | 1700 | 1667 | // If icu_data_dir is empty here, it will load the 'minimal' data. | 1701 | 1668 | if (!i18n::InitializeICUDirectory(per_process_opts->icu_data_dir)) { | @@ -2103,7 +2070,7 @@ int Start(int argc, char** argv) { | 2103 | 2070 | #if HAVE_OPENSSL | 2104 | 2071 | { | 2105 | 2072 | 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)) | 2107 | 2074 | crypto::UseExtraCaCerts(extra_ca_certs); | 2108 | 2075 | } | 2109 | 2076 | #ifdef NODE_FIPS_MODE | |
Collapse file Copy file name to clipboardExpand all lines: src/node_binding.cc +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| 26 | 26 | V(cares_wrap) \ | 27 | 27 | V(config) \ | 28 | 28 | V(contextify) \ | | 29 | + V(credentials) \ | 29 | 30 | V(domain) \ | 30 | 31 | V(fs) \ | 31 | 32 | V(fs_event_wrap) \ | |
|