diff options
Diffstat (limited to 'kernel/sys.c')
| -rw-r--r-- | kernel/sys.c | 18 |
1 files changed, 15 insertions, 3 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index 4c3f48c93148..0bd0c5a399a6 100644 --- a/kernel/sys.c +++ b/kernel/sys.c @@ -601,6 +601,14 @@ static int set_user(uid_t new_ruid, int dumpclear) new_user = alloc_uid(new_ruid); if (!new_user) return -EAGAIN; + + if (atomic_read(&new_user->processes) >= + current->rlim[RLIMIT_NPROC].rlim_cur && + new_user != &root_user) { + free_uid(new_user); + return -EAGAIN; + } + switch_uid(new_user); if(dumpclear) @@ -1159,6 +1167,7 @@ asmlinkage long sys_newuname(struct new_utsname __user * name) asmlinkage long sys_sethostname(char __user *name, int len) { int errno; + char tmp[__NEW_UTS_LEN]; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1166,7 +1175,8 @@ asmlinkage long sys_sethostname(char __user *name, int len) return -EINVAL; down_write(&uts_sem); errno = -EFAULT; - if (!copy_from_user(system_utsname.nodename, name, len)) { + if (!copy_from_user(tmp, name, len)) { + memcpy(system_utsname.nodename, tmp, len); system_utsname.nodename[len] = 0; errno = 0; } @@ -1198,6 +1208,7 @@ asmlinkage long sys_gethostname(char __user *name, int len) asmlinkage long sys_setdomainname(char __user *name, int len) { int errno; + char tmp[__NEW_UTS_LEN]; if (!capable(CAP_SYS_ADMIN)) return -EPERM; @@ -1206,9 +1217,10 @@ asmlinkage long sys_setdomainname(char __user *name, int len) down_write(&uts_sem); errno = -EFAULT; - if (!copy_from_user(system_utsname.domainname, name, len)) { - errno = 0; + if (!copy_from_user(tmp, name, len)) { + memcpy(system_utsname.domainname, tmp, len); system_utsname.domainname[len] = 0; + errno = 0; } up_write(&uts_sem); return errno; |
