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;
+}
#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"
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;
}
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;
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;
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;
}