aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c34
1 files changed, 24 insertions, 10 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index 234d9454294e..0bc8fa3c2288 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1349,8 +1349,10 @@ asmlinkage long sys_sethostname(char __user *name, int len)
1349 down_write(&uts_sem); 1349 down_write(&uts_sem);
1350 errno = -EFAULT; 1350 errno = -EFAULT;
1351 if (!copy_from_user(tmp, name, len)) { 1351 if (!copy_from_user(tmp, name, len)) {
1352 memcpy(utsname()->nodename, tmp, len); 1352 struct new_utsname *u = utsname();
1353 utsname()->nodename[len] = 0; 1353
1354 memcpy(u->nodename, tmp, len);
1355 memset(u->nodename + len, 0, sizeof(u->nodename) - len);
1354 errno = 0; 1356 errno = 0;
1355 } 1357 }
1356 up_write(&uts_sem); 1358 up_write(&uts_sem);
@@ -1362,15 +1364,17 @@ asmlinkage long sys_sethostname(char __user *name, int len)
1362asmlinkage long sys_gethostname(char __user *name, int len) 1364asmlinkage long sys_gethostname(char __user *name, int len)
1363{ 1365{
1364 int i, errno; 1366 int i, errno;
1367 struct new_utsname *u;
1365 1368
1366 if (len < 0) 1369 if (len < 0)
1367 return -EINVAL; 1370 return -EINVAL;
1368 down_read(&uts_sem); 1371 down_read(&uts_sem);
1369 i = 1 + strlen(utsname()->nodename); 1372 u = utsname();
1373 i = 1 + strlen(u->nodename);
1370 if (i > len) 1374 if (i > len)
1371 i = len; 1375 i = len;
1372 errno = 0; 1376 errno = 0;
1373 if (copy_to_user(name, utsname()->nodename, i)) 1377 if (copy_to_user(name, u->nodename, i))
1374 errno = -EFAULT; 1378 errno = -EFAULT;
1375 up_read(&uts_sem); 1379 up_read(&uts_sem);
1376 return errno; 1380 return errno;
@@ -1395,8 +1399,10 @@ asmlinkage long sys_setdomainname(char __user *name, int len)
1395 down_write(&uts_sem); 1399 down_write(&uts_sem);
1396 errno = -EFAULT; 1400 errno = -EFAULT;
1397 if (!copy_from_user(tmp, name, len)) { 1401 if (!copy_from_user(tmp, name, len)) {
1398 memcpy(utsname()->domainname, tmp, len); 1402 struct new_utsname *u = utsname();
1399 utsname()->domainname[len] = 0; 1403
1404 memcpy(u->domainname, tmp, len);
1405 memset(u->domainname + len, 0, sizeof(u->domainname) - len);
1400 errno = 0; 1406 errno = 0;
1401 } 1407 }
1402 up_write(&uts_sem); 1408 up_write(&uts_sem);
@@ -1450,14 +1456,22 @@ asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
1450 return -EINVAL; 1456 return -EINVAL;
1451 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) 1457 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1452 return -EFAULT; 1458 return -EFAULT;
1453 if (new_rlim.rlim_cur > new_rlim.rlim_max)
1454 return -EINVAL;
1455 old_rlim = current->signal->rlim + resource; 1459 old_rlim = current->signal->rlim + resource;
1456 if ((new_rlim.rlim_max > old_rlim->rlim_max) && 1460 if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
1457 !capable(CAP_SYS_RESOURCE)) 1461 !capable(CAP_SYS_RESOURCE))
1458 return -EPERM; 1462 return -EPERM;
1459 if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) 1463
1460 return -EPERM; 1464 if (resource == RLIMIT_NOFILE) {
1465 if (new_rlim.rlim_max == RLIM_INFINITY)
1466 new_rlim.rlim_max = sysctl_nr_open;
1467 if (new_rlim.rlim_cur == RLIM_INFINITY)
1468 new_rlim.rlim_cur = sysctl_nr_open;
1469 if (new_rlim.rlim_max > sysctl_nr_open)
1470 return -EPERM;
1471 }
1472
1473 if (new_rlim.rlim_cur > new_rlim.rlim_max)
1474 return -EINVAL;
1461 1475
1462 retval = security_task_setrlimit(resource, &new_rlim); 1476 retval = security_task_setrlimit(resource, &new_rlim);
1463 if (retval) 1477 if (retval)