diff options
-rw-r--r-- | fs/exec.c | 4 | ||||
-rw-r--r-- | include/linux/sched.h | 18 | ||||
-rw-r--r-- | kernel/seccomp.c | 2 | ||||
-rw-r--r-- | kernel/sys.c | 4 | ||||
-rw-r--r-- | security/apparmor/domain.c | 4 |
5 files changed, 22 insertions, 10 deletions
@@ -1234,7 +1234,7 @@ static void check_unsafe_exec(struct linux_binprm *bprm) | |||
1234 | * This isn't strictly necessary, but it makes it harder for LSMs to | 1234 | * This isn't strictly necessary, but it makes it harder for LSMs to |
1235 | * mess up. | 1235 | * mess up. |
1236 | */ | 1236 | */ |
1237 | if (current->no_new_privs) | 1237 | if (task_no_new_privs(current)) |
1238 | bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS; | 1238 | bprm->unsafe |= LSM_UNSAFE_NO_NEW_PRIVS; |
1239 | 1239 | ||
1240 | t = p; | 1240 | t = p; |
@@ -1272,7 +1272,7 @@ int prepare_binprm(struct linux_binprm *bprm) | |||
1272 | bprm->cred->egid = current_egid(); | 1272 | bprm->cred->egid = current_egid(); |
1273 | 1273 | ||
1274 | if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && | 1274 | if (!(bprm->file->f_path.mnt->mnt_flags & MNT_NOSUID) && |
1275 | !current->no_new_privs && | 1275 | !task_no_new_privs(current) && |
1276 | kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && | 1276 | kuid_has_mapping(bprm->cred->user_ns, inode->i_uid) && |
1277 | kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { | 1277 | kgid_has_mapping(bprm->cred->user_ns, inode->i_gid)) { |
1278 | /* Set-uid? */ | 1278 | /* Set-uid? */ |
diff --git a/include/linux/sched.h b/include/linux/sched.h index 306f4f0c987a..0fd19055bb64 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h | |||
@@ -1307,13 +1307,12 @@ struct task_struct { | |||
1307 | * execve */ | 1307 | * execve */ |
1308 | unsigned in_iowait:1; | 1308 | unsigned in_iowait:1; |
1309 | 1309 | ||
1310 | /* task may not gain privileges */ | ||
1311 | unsigned no_new_privs:1; | ||
1312 | |||
1313 | /* Revert to default priority/policy when forking */ | 1310 | /* Revert to default priority/policy when forking */ |
1314 | unsigned sched_reset_on_fork:1; | 1311 | unsigned sched_reset_on_fork:1; |
1315 | unsigned sched_contributes_to_load:1; | 1312 | unsigned sched_contributes_to_load:1; |
1316 | 1313 | ||
1314 | unsigned long atomic_flags; /* Flags needing atomic access. */ | ||
1315 | |||
1317 | pid_t pid; | 1316 | pid_t pid; |
1318 | pid_t tgid; | 1317 | pid_t tgid; |
1319 | 1318 | ||
@@ -1967,6 +1966,19 @@ static inline void memalloc_noio_restore(unsigned int flags) | |||
1967 | current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags; | 1966 | current->flags = (current->flags & ~PF_MEMALLOC_NOIO) | flags; |
1968 | } | 1967 | } |
1969 | 1968 | ||
1969 | /* Per-process atomic flags. */ | ||
1970 | #define PFA_NO_NEW_PRIVS 0x00000001 /* May not gain new privileges. */ | ||
1971 | |||
1972 | static inline bool task_no_new_privs(struct task_struct *p) | ||
1973 | { | ||
1974 | return test_bit(PFA_NO_NEW_PRIVS, &p->atomic_flags); | ||
1975 | } | ||
1976 | |||
1977 | static inline void task_set_no_new_privs(struct task_struct *p) | ||
1978 | { | ||
1979 | set_bit(PFA_NO_NEW_PRIVS, &p->atomic_flags); | ||
1980 | } | ||
1981 | |||
1970 | /* | 1982 | /* |
1971 | * task->jobctl flags | 1983 | * task->jobctl flags |
1972 | */ | 1984 | */ |
diff --git a/kernel/seccomp.c b/kernel/seccomp.c index f0652578af75..d2596136b0d1 100644 --- a/kernel/seccomp.c +++ b/kernel/seccomp.c | |||
@@ -241,7 +241,7 @@ static long seccomp_attach_filter(struct sock_fprog *fprog) | |||
241 | * This avoids scenarios where unprivileged tasks can affect the | 241 | * This avoids scenarios where unprivileged tasks can affect the |
242 | * behavior of privileged children. | 242 | * behavior of privileged children. |
243 | */ | 243 | */ |
244 | if (!current->no_new_privs && | 244 | if (!task_no_new_privs(current) && |
245 | security_capable_noaudit(current_cred(), current_user_ns(), | 245 | security_capable_noaudit(current_cred(), current_user_ns(), |
246 | CAP_SYS_ADMIN) != 0) | 246 | CAP_SYS_ADMIN) != 0) |
247 | return -EACCES; | 247 | return -EACCES; |
diff --git a/kernel/sys.c b/kernel/sys.c index 66a751ebf9d9..ce8129192a26 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1990,12 +1990,12 @@ SYSCALL_DEFINE5(prctl, int, option, unsigned long, arg2, unsigned long, arg3, | |||
1990 | if (arg2 != 1 || arg3 || arg4 || arg5) | 1990 | if (arg2 != 1 || arg3 || arg4 || arg5) |
1991 | return -EINVAL; | 1991 | return -EINVAL; |
1992 | 1992 | ||
1993 | current->no_new_privs = 1; | 1993 | task_set_no_new_privs(current); |
1994 | break; | 1994 | break; |
1995 | case PR_GET_NO_NEW_PRIVS: | 1995 | case PR_GET_NO_NEW_PRIVS: |
1996 | if (arg2 || arg3 || arg4 || arg5) | 1996 | if (arg2 || arg3 || arg4 || arg5) |
1997 | return -EINVAL; | 1997 | return -EINVAL; |
1998 | return current->no_new_privs ? 1 : 0; | 1998 | return task_no_new_privs(current) ? 1 : 0; |
1999 | case PR_GET_THP_DISABLE: | 1999 | case PR_GET_THP_DISABLE: |
2000 | if (arg2 || arg3 || arg4 || arg5) | 2000 | if (arg2 || arg3 || arg4 || arg5) |
2001 | return -EINVAL; | 2001 | return -EINVAL; |
diff --git a/security/apparmor/domain.c b/security/apparmor/domain.c index 452567d3a08e..d97cba3e3849 100644 --- a/security/apparmor/domain.c +++ b/security/apparmor/domain.c | |||
@@ -621,7 +621,7 @@ int aa_change_hat(const char *hats[], int count, u64 token, bool permtest) | |||
621 | * There is no exception for unconfined as change_hat is not | 621 | * There is no exception for unconfined as change_hat is not |
622 | * available. | 622 | * available. |
623 | */ | 623 | */ |
624 | if (current->no_new_privs) | 624 | if (task_no_new_privs(current)) |
625 | return -EPERM; | 625 | return -EPERM; |
626 | 626 | ||
627 | /* released below */ | 627 | /* released below */ |
@@ -776,7 +776,7 @@ int aa_change_profile(const char *ns_name, const char *hname, bool onexec, | |||
776 | * no_new_privs is set because this aways results in a reduction | 776 | * no_new_privs is set because this aways results in a reduction |
777 | * of permissions. | 777 | * of permissions. |
778 | */ | 778 | */ |
779 | if (current->no_new_privs && !unconfined(profile)) { | 779 | if (task_no_new_privs(current) && !unconfined(profile)) { |
780 | put_cred(cred); | 780 | put_cred(cred); |
781 | return -EPERM; | 781 | return -EPERM; |
782 | } | 782 | } |