diff options
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fork.c | 7 | ||||
-rw-r--r-- | kernel/sys.c | 30 |
2 files changed, 24 insertions, 13 deletions
diff --git a/kernel/fork.c b/kernel/fork.c index 56d85fd81411..dd5a371c392a 100644 --- a/kernel/fork.c +++ b/kernel/fork.c | |||
@@ -1681,9 +1681,12 @@ static __latent_entropy struct task_struct *copy_process( | |||
1681 | goto bad_fork_cleanup_perf; | 1681 | goto bad_fork_cleanup_perf; |
1682 | /* copy all the process information */ | 1682 | /* copy all the process information */ |
1683 | shm_init_task(p); | 1683 | shm_init_task(p); |
1684 | retval = copy_semundo(clone_flags, p); | 1684 | retval = security_task_alloc(p, clone_flags); |
1685 | if (retval) | 1685 | if (retval) |
1686 | goto bad_fork_cleanup_audit; | 1686 | goto bad_fork_cleanup_audit; |
1687 | retval = copy_semundo(clone_flags, p); | ||
1688 | if (retval) | ||
1689 | goto bad_fork_cleanup_security; | ||
1687 | retval = copy_files(clone_flags, p); | 1690 | retval = copy_files(clone_flags, p); |
1688 | if (retval) | 1691 | if (retval) |
1689 | goto bad_fork_cleanup_semundo; | 1692 | goto bad_fork_cleanup_semundo; |
@@ -1907,6 +1910,8 @@ bad_fork_cleanup_files: | |||
1907 | exit_files(p); /* blocking */ | 1910 | exit_files(p); /* blocking */ |
1908 | bad_fork_cleanup_semundo: | 1911 | bad_fork_cleanup_semundo: |
1909 | exit_sem(p); | 1912 | exit_sem(p); |
1913 | bad_fork_cleanup_security: | ||
1914 | security_task_free(p); | ||
1910 | bad_fork_cleanup_audit: | 1915 | bad_fork_cleanup_audit: |
1911 | audit_free(p); | 1916 | audit_free(p); |
1912 | bad_fork_cleanup_perf: | 1917 | bad_fork_cleanup_perf: |
diff --git a/kernel/sys.c b/kernel/sys.c index 7ff6d1b10cec..196c7134bee6 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1432,25 +1432,26 @@ out: | |||
1432 | } | 1432 | } |
1433 | 1433 | ||
1434 | /* rcu lock must be held */ | 1434 | /* rcu lock must be held */ |
1435 | static int check_prlimit_permission(struct task_struct *task) | 1435 | static int check_prlimit_permission(struct task_struct *task, |
1436 | unsigned int flags) | ||
1436 | { | 1437 | { |
1437 | const struct cred *cred = current_cred(), *tcred; | 1438 | const struct cred *cred = current_cred(), *tcred; |
1439 | bool id_match; | ||
1438 | 1440 | ||
1439 | if (current == task) | 1441 | if (current == task) |
1440 | return 0; | 1442 | return 0; |
1441 | 1443 | ||
1442 | tcred = __task_cred(task); | 1444 | tcred = __task_cred(task); |
1443 | if (uid_eq(cred->uid, tcred->euid) && | 1445 | id_match = (uid_eq(cred->uid, tcred->euid) && |
1444 | uid_eq(cred->uid, tcred->suid) && | 1446 | uid_eq(cred->uid, tcred->suid) && |
1445 | uid_eq(cred->uid, tcred->uid) && | 1447 | uid_eq(cred->uid, tcred->uid) && |
1446 | gid_eq(cred->gid, tcred->egid) && | 1448 | gid_eq(cred->gid, tcred->egid) && |
1447 | gid_eq(cred->gid, tcred->sgid) && | 1449 | gid_eq(cred->gid, tcred->sgid) && |
1448 | gid_eq(cred->gid, tcred->gid)) | 1450 | gid_eq(cred->gid, tcred->gid)); |
1449 | return 0; | 1451 | if (!id_match && !ns_capable(tcred->user_ns, CAP_SYS_RESOURCE)) |
1450 | if (ns_capable(tcred->user_ns, CAP_SYS_RESOURCE)) | 1452 | return -EPERM; |
1451 | return 0; | ||
1452 | 1453 | ||
1453 | return -EPERM; | 1454 | return security_task_prlimit(cred, tcred, flags); |
1454 | } | 1455 | } |
1455 | 1456 | ||
1456 | SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, | 1457 | SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, |
@@ -1460,12 +1461,17 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, | |||
1460 | struct rlimit64 old64, new64; | 1461 | struct rlimit64 old64, new64; |
1461 | struct rlimit old, new; | 1462 | struct rlimit old, new; |
1462 | struct task_struct *tsk; | 1463 | struct task_struct *tsk; |
1464 | unsigned int checkflags = 0; | ||
1463 | int ret; | 1465 | int ret; |
1464 | 1466 | ||
1467 | if (old_rlim) | ||
1468 | checkflags |= LSM_PRLIMIT_READ; | ||
1469 | |||
1465 | if (new_rlim) { | 1470 | if (new_rlim) { |
1466 | if (copy_from_user(&new64, new_rlim, sizeof(new64))) | 1471 | if (copy_from_user(&new64, new_rlim, sizeof(new64))) |
1467 | return -EFAULT; | 1472 | return -EFAULT; |
1468 | rlim64_to_rlim(&new64, &new); | 1473 | rlim64_to_rlim(&new64, &new); |
1474 | checkflags |= LSM_PRLIMIT_WRITE; | ||
1469 | } | 1475 | } |
1470 | 1476 | ||
1471 | rcu_read_lock(); | 1477 | rcu_read_lock(); |
@@ -1474,7 +1480,7 @@ SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource, | |||
1474 | rcu_read_unlock(); | 1480 | rcu_read_unlock(); |
1475 | return -ESRCH; | 1481 | return -ESRCH; |
1476 | } | 1482 | } |
1477 | ret = check_prlimit_permission(tsk); | 1483 | ret = check_prlimit_permission(tsk, checkflags); |
1478 | if (ret) { | 1484 | if (ret) { |
1479 | rcu_read_unlock(); | 1485 | rcu_read_unlock(); |
1480 | return ret; | 1486 | return ret; |