1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-04 13:51:24 +03:00

Merge pull request #11919 from poettering/login-simplify

various fixes to $HOME and $SHELL validation
This commit is contained in:
Lennart Poettering 2019-03-12 18:33:14 +01:00 committed by GitHub
commit fbaefc3ff9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 58 additions and 49 deletions

3
TODO
View File

@ -23,6 +23,9 @@ Janitorial Clean-ups:
Features:
* maybe add a seccomp-based high-level filter that blocks creation of suid/sgid
files.
* make MAINPID= message reception checks even stricter: if service uses User=,
then check sending UID and ignore message if it doesn't match the user or
root.

View File

@ -1103,48 +1103,40 @@ int path_simplify_and_warn(
unsigned line,
const char *lvalue) {
bool absolute, fatal = flag & PATH_CHECK_FATAL;
bool fatal = flag & PATH_CHECK_FATAL;
assert(!FLAGS_SET(flag, PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE));
if (!utf8_is_valid(path)) {
log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
return -EINVAL;
}
if (!utf8_is_valid(path))
return log_syntax_invalid_utf8(unit, LOG_ERR, filename, line, path);
if (flag & (PATH_CHECK_ABSOLUTE | PATH_CHECK_RELATIVE)) {
bool absolute;
absolute = path_is_absolute(path);
if (!absolute && (flag & PATH_CHECK_ABSOLUTE)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"%s= path is not absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
return -EINVAL;
}
if (!absolute && (flag & PATH_CHECK_ABSOLUTE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
if (absolute && (flag & PATH_CHECK_RELATIVE)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"%s= path is absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
return -EINVAL;
}
if (absolute && (flag & PATH_CHECK_RELATIVE))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is absolute%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
}
path_simplify(path, true);
if (!path_is_normalized(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"%s= path is not normalized%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
return -EINVAL;
}
if (!path_is_valid(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path has invalid length (%zu bytes)%s.",
lvalue, strlen(path), fatal ? "" : ", ignoring");
if (!path_is_valid(path)) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"%s= path has invalid length (%zu bytes)%s.",
lvalue, strlen(path), fatal ? "" : ", ignoring");
return -EINVAL;
}
if (!path_is_normalized(path))
return log_syntax(unit, LOG_ERR, filename, line, SYNTHETIC_ERRNO(EINVAL),
"%s= path is not normalized%s: %s",
lvalue, fatal ? "" : ", ignoring", path);
return 0;
}

View File

@ -80,7 +80,7 @@ char* getlogname_malloc(void) {
char *getusername_malloc(void) {
const char *e;
e = getenv("USER");
e = secure_getenv("USER");
if (e)
return strdup(e);
@ -238,14 +238,21 @@ int get_user_creds(
}
if (home) {
if (FLAGS_SET(flags, USER_CREDS_CLEAN) && empty_or_root(p->pw_dir))
*home = NULL;
if (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
(empty_or_root(p->pw_dir) ||
!path_is_valid(p->pw_dir) ||
!path_is_absolute(p->pw_dir)))
*home = NULL; /* Note: we don't insist on normalized paths, since there are setups that have /./ in the path */
else
*home = p->pw_dir;
}
if (shell) {
if (FLAGS_SET(flags, USER_CREDS_CLEAN) && (isempty(p->pw_shell) || is_nologin_shell(p->pw_shell)))
if (FLAGS_SET(flags, USER_CREDS_CLEAN) &&
(isempty(p->pw_shell) ||
!path_is_valid(p->pw_dir) ||
!path_is_absolute(p->pw_shell) ||
is_nologin_shell(p->pw_shell)))
*shell = NULL;
else
*shell = p->pw_shell;
@ -343,6 +350,9 @@ char* uid_to_name(uid_t uid) {
if (r != ERANGE)
break;
if (bufsize > LONG_MAX/2) /* overflow check */
return NULL;
bufsize *= 2;
}
}
@ -384,6 +394,9 @@ char* gid_to_name(gid_t gid) {
if (r != ERANGE)
break;
if (bufsize > LONG_MAX/2) /* overflow check */
return NULL;
bufsize *= 2;
}
}
@ -445,12 +458,12 @@ int get_home_dir(char **_h) {
/* Take the user specified one */
e = secure_getenv("HOME");
if (e && path_is_absolute(e)) {
if (e && path_is_valid(e) && path_is_absolute(e)) {
h = strdup(e);
if (!h)
return -ENOMEM;
*_h = h;
*_h = path_simplify(h, true);
return 0;
}
@ -480,14 +493,15 @@ int get_home_dir(char **_h) {
if (!p)
return errno > 0 ? -errno : -ESRCH;
if (!path_is_absolute(p->pw_dir))
if (!path_is_valid(p->pw_dir) ||
!path_is_absolute(p->pw_dir))
return -EINVAL;
h = strdup(p->pw_dir);
if (!h)
return -ENOMEM;
*_h = h;
*_h = path_simplify(h, true);
return 0;
}
@ -500,13 +514,13 @@ int get_shell(char **_s) {
assert(_s);
/* Take the user specified one */
e = getenv("SHELL");
if (e) {
e = secure_getenv("SHELL");
if (e && path_is_valid(e) && path_is_absolute(e)) {
s = strdup(e);
if (!s)
return -ENOMEM;
*_s = s;
*_s = path_simplify(s, true);
return 0;
}
@ -536,14 +550,15 @@ int get_shell(char **_s) {
if (!p)
return errno > 0 ? -errno : -ESRCH;
if (!path_is_absolute(p->pw_shell))
if (!path_is_valid(p->pw_shell) ||
!path_is_absolute(p->pw_shell))
return -EINVAL;
s = strdup(p->pw_shell);
if (!s)
return -ENOMEM;
*_s = s;
*_s = path_simplify(s, true);
return 0;
}

View File

@ -1697,6 +1697,8 @@ static int build_environment(
x = strappend("HOME=", home);
if (!x)
return -ENOMEM;
path_simplify(x + 5, true);
our_env[n_env++] = x;
}
@ -1716,6 +1718,8 @@ static int build_environment(
x = strappend("SHELL=", shell);
if (!x)
return -ENOMEM;
path_simplify(x + 6, true);
our_env[n_env++] = x;
}
@ -2738,12 +2742,6 @@ static int acquire_home(const ExecContext *c, uid_t uid, const char** home, char
if (!c->working_directory_home)
return 0;
if (uid == 0) {
/* Hardcode /root as home directory for UID 0 */
*home = "/root";
return 1;
}
r = get_home_dir(buf);
if (r < 0)
return r;

View File

@ -2711,7 +2711,6 @@ static int method_can_reboot_to_boot_loader_menu(
Manager *m = userdata;
int r;
assert(message);
assert(m);

View File

@ -68,6 +68,8 @@ int user_new(User **ret,
if (!u->home)
return -ENOMEM;
path_simplify(u->home, true);
if (asprintf(&u->state_file, "/run/systemd/users/"UID_FMT, uid) < 0)
return -ENOMEM;