diff options
Diffstat (limited to 'kernel/sys.c')
-rw-r--r-- | kernel/sys.c | 38 |
1 files changed, 25 insertions, 13 deletions
diff --git a/kernel/sys.c b/kernel/sys.c index d046a7a055c2..53879cdae483 100644 --- a/kernel/sys.c +++ b/kernel/sys.c | |||
@@ -1050,9 +1050,7 @@ asmlinkage long sys_setsid(void) | |||
1050 | group_leader->signal->leader = 1; | 1050 | group_leader->signal->leader = 1; |
1051 | __set_special_pids(sid); | 1051 | __set_special_pids(sid); |
1052 | 1052 | ||
1053 | spin_lock(&group_leader->sighand->siglock); | 1053 | proc_clear_tty(group_leader); |
1054 | group_leader->signal->tty = NULL; | ||
1055 | spin_unlock(&group_leader->sighand->siglock); | ||
1056 | 1054 | ||
1057 | err = session; | 1055 | err = session; |
1058 | out: | 1056 | out: |
@@ -1341,8 +1339,10 @@ asmlinkage long sys_sethostname(char __user *name, int len) | |||
1341 | down_write(&uts_sem); | 1339 | down_write(&uts_sem); |
1342 | errno = -EFAULT; | 1340 | errno = -EFAULT; |
1343 | if (!copy_from_user(tmp, name, len)) { | 1341 | if (!copy_from_user(tmp, name, len)) { |
1344 | memcpy(utsname()->nodename, tmp, len); | 1342 | struct new_utsname *u = utsname(); |
1345 | utsname()->nodename[len] = 0; | 1343 | |
1344 | memcpy(u->nodename, tmp, len); | ||
1345 | memset(u->nodename + len, 0, sizeof(u->nodename) - len); | ||
1346 | errno = 0; | 1346 | errno = 0; |
1347 | } | 1347 | } |
1348 | up_write(&uts_sem); | 1348 | up_write(&uts_sem); |
@@ -1354,15 +1354,17 @@ asmlinkage long sys_sethostname(char __user *name, int len) | |||
1354 | asmlinkage long sys_gethostname(char __user *name, int len) | 1354 | asmlinkage long sys_gethostname(char __user *name, int len) |
1355 | { | 1355 | { |
1356 | int i, errno; | 1356 | int i, errno; |
1357 | struct new_utsname *u; | ||
1357 | 1358 | ||
1358 | if (len < 0) | 1359 | if (len < 0) |
1359 | return -EINVAL; | 1360 | return -EINVAL; |
1360 | down_read(&uts_sem); | 1361 | down_read(&uts_sem); |
1361 | i = 1 + strlen(utsname()->nodename); | 1362 | u = utsname(); |
1363 | i = 1 + strlen(u->nodename); | ||
1362 | if (i > len) | 1364 | if (i > len) |
1363 | i = len; | 1365 | i = len; |
1364 | errno = 0; | 1366 | errno = 0; |
1365 | if (copy_to_user(name, utsname()->nodename, i)) | 1367 | if (copy_to_user(name, u->nodename, i)) |
1366 | errno = -EFAULT; | 1368 | errno = -EFAULT; |
1367 | up_read(&uts_sem); | 1369 | up_read(&uts_sem); |
1368 | return errno; | 1370 | return errno; |
@@ -1387,8 +1389,10 @@ asmlinkage long sys_setdomainname(char __user *name, int len) | |||
1387 | down_write(&uts_sem); | 1389 | down_write(&uts_sem); |
1388 | errno = -EFAULT; | 1390 | errno = -EFAULT; |
1389 | if (!copy_from_user(tmp, name, len)) { | 1391 | if (!copy_from_user(tmp, name, len)) { |
1390 | memcpy(utsname()->domainname, tmp, len); | 1392 | struct new_utsname *u = utsname(); |
1391 | utsname()->domainname[len] = 0; | 1393 | |
1394 | memcpy(u->domainname, tmp, len); | ||
1395 | memset(u->domainname + len, 0, sizeof(u->domainname) - len); | ||
1392 | errno = 0; | 1396 | errno = 0; |
1393 | } | 1397 | } |
1394 | up_write(&uts_sem); | 1398 | up_write(&uts_sem); |
@@ -1441,14 +1445,22 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim) | |||
1441 | return -EINVAL; | 1445 | return -EINVAL; |
1442 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) | 1446 | if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) |
1443 | return -EFAULT; | 1447 | return -EFAULT; |
1444 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
1445 | return -EINVAL; | ||
1446 | old_rlim = current->signal->rlim + resource; | 1448 | old_rlim = current->signal->rlim + resource; |
1447 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && | 1449 | if ((new_rlim.rlim_max > old_rlim->rlim_max) && |
1448 | !capable(CAP_SYS_RESOURCE)) | 1450 | !capable(CAP_SYS_RESOURCE)) |
1449 | return -EPERM; | 1451 | return -EPERM; |
1450 | if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) | 1452 | |
1451 | return -EPERM; | 1453 | if (resource == RLIMIT_NOFILE) { |
1454 | if (new_rlim.rlim_max == RLIM_INFINITY) | ||
1455 | new_rlim.rlim_max = sysctl_nr_open; | ||
1456 | if (new_rlim.rlim_cur == RLIM_INFINITY) | ||
1457 | new_rlim.rlim_cur = sysctl_nr_open; | ||
1458 | if (new_rlim.rlim_max > sysctl_nr_open) | ||
1459 | return -EPERM; | ||
1460 | } | ||
1461 | |||
1462 | if (new_rlim.rlim_cur > new_rlim.rlim_max) | ||
1463 | return -EINVAL; | ||
1452 | 1464 | ||
1453 | retval = security_task_setrlimit(resource, &new_rlim); | 1465 | retval = security_task_setrlimit(resource, &new_rlim); |
1454 | if (retval) | 1466 | if (retval) |