mirror of
https://github.com/systemd/systemd.git
synced 2025-08-25 13:49:55 +03:00
nspawn: tighten userns UID shift/range checks
Let's add a helper that ensures the UID shift/range parameters actually fit together.
This commit is contained in:
@ -9,3 +9,18 @@ int namespace_enter(int pidns_fd, int mntns_fd, int netns_fd, int userns_fd, int
|
||||
int fd_is_ns(int fd, unsigned long nsflag);
|
||||
|
||||
int detach_mount_namespace(void);
|
||||
|
||||
static inline bool userns_shift_range_valid(uid_t shift, uid_t range) {
|
||||
/* Checks that the specified userns range makes sense, i.e. contains at least one UID, and the end
|
||||
* doesn't overflow uid_t. */
|
||||
|
||||
assert_cc((uid_t) -1 > 0); /* verify that uid_t is unsigned */
|
||||
|
||||
if (range <= 0)
|
||||
return false;
|
||||
|
||||
if (shift > (uid_t) -1 - range)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "conf-parser.h"
|
||||
#include "cpu-set-util.h"
|
||||
#include "hostname-util.h"
|
||||
#include "namespace-util.h"
|
||||
#include "nspawn-network.h"
|
||||
#include "nspawn-settings.h"
|
||||
#include "parse-util.h"
|
||||
@ -611,7 +612,7 @@ int config_parse_private_users(
|
||||
range++;
|
||||
|
||||
r = safe_atou32(range, &rn);
|
||||
if (r < 0 || rn <= 0) {
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "UID/GID range invalid, ignoring: %s", range);
|
||||
return 0;
|
||||
}
|
||||
@ -626,6 +627,11 @@ int config_parse_private_users(
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!userns_shift_range_valid(sh, rn)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0, "UID/GID shift and range combination invalid, ignoring: %s", range);
|
||||
return 0;
|
||||
}
|
||||
|
||||
settings->userns_mode = USER_NAMESPACE_FIXED;
|
||||
settings->uid_shift = sh;
|
||||
settings->uid_range = rn;
|
||||
|
@ -1259,11 +1259,10 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
return log_error_errno(r, "Failed to parse UID \"%s\": %m", optarg);
|
||||
|
||||
arg_userns_mode = USER_NAMESPACE_FIXED;
|
||||
}
|
||||
|
||||
if (arg_uid_range <= 0)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"UID range cannot be 0.");
|
||||
if (!userns_shift_range_valid(arg_uid_shift, arg_uid_range))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "UID range cannot be empty or go beyond " UID_FMT ".", UID_INVALID);
|
||||
}
|
||||
|
||||
arg_settings_mask |= SETTING_USERNS;
|
||||
break;
|
||||
@ -3068,9 +3067,8 @@ static int determine_uid_shift(const char *directory) {
|
||||
arg_uid_range = UINT32_C(0x10000);
|
||||
}
|
||||
|
||||
if (arg_uid_shift > UID_INVALID - arg_uid_range)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"UID base too high for UID range.");
|
||||
if (!userns_shift_range_valid(arg_uid_shift, arg_uid_range))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "UID base too high for UID range.");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Reference in New Issue
Block a user