Skip to content

Commit

Permalink
Rework file ownership checks based on parent dir owner
Browse files Browse the repository at this point in the history
  • Loading branch information
62832 committed Apr 5, 2024
1 parent 03bcc2f commit 00b4e37
Showing 1 changed file with 34 additions and 22 deletions.
56 changes: 34 additions & 22 deletions session.c
Original file line number Diff line number Diff line change
Expand Up @@ -832,33 +832,45 @@ check_quietlogin(Session *s, const char *command)
return 0;
}

/*
* Check that any custom user environment/rc file is "safe" to run, i.e.
* - it belongs to either the superuser or to the logged in user, of which
* the latter must also own the parent directory
* - if it belongs to the logged in user, either the file or its parent dir
* is only accessible to the user
*/
static int
safe_user_file(const char *filename, struct passwd *pw)
safe_user_file(const char *filename, uid_t uid)
{
struct stat st;
char *path;
char *lastsep;
uid_t dirowner;
mode_t dirmode;

/* Gather parent dir owner and mode first */
lastsep = strrchr(filename, '/');
*lastsep = '\0';
if (stat(filename, &st) == -1)
return 0;

path = realpath(filename, NULL);
if (strncmp(path, pw->pw_dir, strlen(pw->pw_dir)) == 0) {
if (st.st_uid != pw->pw_uid) {
fprintf(stderr, "Bad owner on %s, ignoring.\n",
path);
return 0;
}
if ((st.st_mode & 077) != 0) {
fprintf(stderr,
"Permissions too open (%3o) on %s, ignoring.\n",
st.st_mode & 0777u, path);
return 0;
}
return 1;
}
if (st.st_uid != 0) {
fprintf(stderr, "%s not root-owned, ignoring.\n", path);
dirowner = st.st_uid;
dirmode = st.st_mode;
/* Then gather actual file info */
*lastsep = '/';
if (stat(filename, &st) == -1)
return 0;

if (st.st_uid != 0 && st.st_uid != uid && st.st_uid != dirowner) {
fprintf(stderr, "Bad owner on %s, ignoring.\n",
filename);
return 0;
}

if (st.st_uid == uid &&
(st.st_mode & 077) != 0 && (dirmode & 077) != 0) {
fprintf(stderr,
"Permissions too open on %s or its parent dir, ignoring.\n",
filename);
return 0;
}
return 1;
}
Expand Down Expand Up @@ -1152,7 +1164,7 @@ do_setup_env(struct ssh *ssh, Session *s, const char *shell)
for (i = 0; i < options.num_user_env_files; i++) {
userenv = expand_user_file(options.user_env_files[i], pw,
"UserEnvironment");
if (safe_user_file(userenv, pw))
if (safe_user_file(userenv, pw->pw_uid))
read_environment_file(&env, &envsize, userenv,
options.permit_user_env_allowlist);
}
Expand Down Expand Up @@ -1250,7 +1262,7 @@ do_rc_files(struct ssh *ssh, Session *s, const char *shell)
for (i = 0; i < options.num_user_rc_files; i++) {
user_rc = expand_user_file(options.user_rc_files[i],
s->pw, "UserRC");
if (safe_user_file(user_rc, s->pw)) {
if (safe_user_file(user_rc, s->pw->pw_uid)) {
if (xasprintf(&cmd, "%s -c '%s %s'", shell,
_PATH_BSHELL, user_rc) == -1)
fatal_f("xasprintf: %s", strerror(errno));
Expand Down

0 comments on commit 00b4e37

Please sign in to comment.