aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/sys.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/sys.c')
-rw-r--r--kernel/sys.c204
1 files changed, 160 insertions, 44 deletions
diff --git a/kernel/sys.c b/kernel/sys.c
index e83ddbbaf89d..7f5a0cd296a9 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -931,6 +931,7 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid)
931 pgid = pid; 931 pgid = pid;
932 if (pgid < 0) 932 if (pgid < 0)
933 return -EINVAL; 933 return -EINVAL;
934 rcu_read_lock();
934 935
935 /* From this point forward we keep holding onto the tasklist lock 936 /* From this point forward we keep holding onto the tasklist lock
936 * so that our parent does not change from under us. -DaveM 937 * so that our parent does not change from under us. -DaveM
@@ -984,6 +985,7 @@ SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid)
984out: 985out:
985 /* All paths lead to here, thus we are safe. -DaveM */ 986 /* All paths lead to here, thus we are safe. -DaveM */
986 write_unlock_irq(&tasklist_lock); 987 write_unlock_irq(&tasklist_lock);
988 rcu_read_unlock();
987 return err; 989 return err;
988} 990}
989 991
@@ -1236,15 +1238,14 @@ SYSCALL_DEFINE2(setdomainname, char __user *, name, int, len)
1236 1238
1237SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim) 1239SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1238{ 1240{
1239 if (resource >= RLIM_NLIMITS) 1241 struct rlimit value;
1240 return -EINVAL; 1242 int ret;
1241 else { 1243
1242 struct rlimit value; 1244 ret = do_prlimit(current, resource, NULL, &value);
1243 task_lock(current->group_leader); 1245 if (!ret)
1244 value = current->signal->rlim[resource]; 1246 ret = copy_to_user(rlim, &value, sizeof(*rlim)) ? -EFAULT : 0;
1245 task_unlock(current->group_leader); 1247
1246 return copy_to_user(rlim, &value, sizeof(*rlim)) ? -EFAULT : 0; 1248 return ret;
1247 }
1248} 1249}
1249 1250
1250#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT 1251#ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
@@ -1272,44 +1273,89 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
1272 1273
1273#endif 1274#endif
1274 1275
1275SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) 1276static inline bool rlim64_is_infinity(__u64 rlim64)
1276{ 1277{
1277 struct rlimit new_rlim, *old_rlim; 1278#if BITS_PER_LONG < 64
1278 int retval; 1279 return rlim64 >= ULONG_MAX;
1280#else
1281 return rlim64 == RLIM64_INFINITY;
1282#endif
1283}
1284
1285static void rlim_to_rlim64(const struct rlimit *rlim, struct rlimit64 *rlim64)
1286{
1287 if (rlim->rlim_cur == RLIM_INFINITY)
1288 rlim64->rlim_cur = RLIM64_INFINITY;
1289 else
1290 rlim64->rlim_cur = rlim->rlim_cur;
1291 if (rlim->rlim_max == RLIM_INFINITY)
1292 rlim64->rlim_max = RLIM64_INFINITY;
1293 else
1294 rlim64->rlim_max = rlim->rlim_max;
1295}
1296
1297static void rlim64_to_rlim(const struct rlimit64 *rlim64, struct rlimit *rlim)
1298{
1299 if (rlim64_is_infinity(rlim64->rlim_cur))
1300 rlim->rlim_cur = RLIM_INFINITY;
1301 else
1302 rlim->rlim_cur = (unsigned long)rlim64->rlim_cur;
1303 if (rlim64_is_infinity(rlim64->rlim_max))
1304 rlim->rlim_max = RLIM_INFINITY;
1305 else
1306 rlim->rlim_max = (unsigned long)rlim64->rlim_max;
1307}
1308
1309/* make sure you are allowed to change @tsk limits before calling this */
1310int do_prlimit(struct task_struct *tsk, unsigned int resource,
1311 struct rlimit *new_rlim, struct rlimit *old_rlim)
1312{
1313 struct rlimit *rlim;
1314 int retval = 0;
1279 1315
1280 if (resource >= RLIM_NLIMITS) 1316 if (resource >= RLIM_NLIMITS)
1281 return -EINVAL; 1317 return -EINVAL;
1282 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) 1318 if (new_rlim) {
1283 return -EFAULT; 1319 if (new_rlim->rlim_cur > new_rlim->rlim_max)
1284 if (new_rlim.rlim_cur > new_rlim.rlim_max) 1320 return -EINVAL;
1285 return -EINVAL; 1321 if (resource == RLIMIT_NOFILE &&
1286 old_rlim = current->signal->rlim + resource; 1322 new_rlim->rlim_max > sysctl_nr_open)
1287 if ((new_rlim.rlim_max > old_rlim->rlim_max) && 1323 return -EPERM;
1288 !capable(CAP_SYS_RESOURCE))
1289 return -EPERM;
1290 if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open)
1291 return -EPERM;
1292
1293 retval = security_task_setrlimit(resource, &new_rlim);
1294 if (retval)
1295 return retval;
1296
1297 if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) {
1298 /*
1299 * The caller is asking for an immediate RLIMIT_CPU
1300 * expiry. But we use the zero value to mean "it was
1301 * never set". So let's cheat and make it one second
1302 * instead
1303 */
1304 new_rlim.rlim_cur = 1;
1305 } 1324 }
1306 1325
1307 task_lock(current->group_leader); 1326 /* protect tsk->signal and tsk->sighand from disappearing */
1308 *old_rlim = new_rlim; 1327 read_lock(&tasklist_lock);
1309 task_unlock(current->group_leader); 1328 if (!tsk->sighand) {
1310 1329 retval = -ESRCH;
1311 if (resource != RLIMIT_CPU)
1312 goto out; 1330 goto out;
1331 }
1332
1333 rlim = tsk->signal->rlim + resource;
1334 task_lock(tsk->group_leader);
1335 if (new_rlim) {
1336 if (new_rlim->rlim_max > rlim->rlim_max &&
1337 !capable(CAP_SYS_RESOURCE))
1338 retval = -EPERM;
1339 if (!retval)
1340 retval = security_task_setrlimit(tsk->group_leader,
1341 resource, new_rlim);
1342 if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
1343 /*
1344 * The caller is asking for an immediate RLIMIT_CPU
1345 * expiry. But we use the zero value to mean "it was
1346 * never set". So let's cheat and make it one second
1347 * instead
1348 */
1349 new_rlim->rlim_cur = 1;
1350 }
1351 }
1352 if (!retval) {
1353 if (old_rlim)
1354 *old_rlim = *rlim;
1355 if (new_rlim)
1356 *rlim = *new_rlim;
1357 }
1358 task_unlock(tsk->group_leader);
1313 1359
1314 /* 1360 /*
1315 * RLIMIT_CPU handling. Note that the kernel fails to return an error 1361 * RLIMIT_CPU handling. Note that the kernel fails to return an error
@@ -1317,14 +1363,84 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1317 * very long-standing error, and fixing it now risks breakage of 1363 * very long-standing error, and fixing it now risks breakage of
1318 * applications, so we live with it 1364 * applications, so we live with it
1319 */ 1365 */
1320 if (new_rlim.rlim_cur == RLIM_INFINITY) 1366 if (!retval && new_rlim && resource == RLIMIT_CPU &&
1321 goto out; 1367 new_rlim->rlim_cur != RLIM_INFINITY)
1322 1368 update_rlimit_cpu(tsk, new_rlim->rlim_cur);
1323 update_rlimit_cpu(new_rlim.rlim_cur);
1324out: 1369out:
1370 read_unlock(&tasklist_lock);
1371 return retval;
1372}
1373
1374/* rcu lock must be held */
1375static int check_prlimit_permission(struct task_struct *task)
1376{
1377 const struct cred *cred = current_cred(), *tcred;
1378
1379 tcred = __task_cred(task);
1380 if ((cred->uid != tcred->euid ||
1381 cred->uid != tcred->suid ||
1382 cred->uid != tcred->uid ||
1383 cred->gid != tcred->egid ||
1384 cred->gid != tcred->sgid ||
1385 cred->gid != tcred->gid) &&
1386 !capable(CAP_SYS_RESOURCE)) {
1387 return -EPERM;
1388 }
1389
1325 return 0; 1390 return 0;
1326} 1391}
1327 1392
1393SYSCALL_DEFINE4(prlimit64, pid_t, pid, unsigned int, resource,
1394 const struct rlimit64 __user *, new_rlim,
1395 struct rlimit64 __user *, old_rlim)
1396{
1397 struct rlimit64 old64, new64;
1398 struct rlimit old, new;
1399 struct task_struct *tsk;
1400 int ret;
1401
1402 if (new_rlim) {
1403 if (copy_from_user(&new64, new_rlim, sizeof(new64)))
1404 return -EFAULT;
1405 rlim64_to_rlim(&new64, &new);
1406 }
1407
1408 rcu_read_lock();
1409 tsk = pid ? find_task_by_vpid(pid) : current;
1410 if (!tsk) {
1411 rcu_read_unlock();
1412 return -ESRCH;
1413 }
1414 ret = check_prlimit_permission(tsk);
1415 if (ret) {
1416 rcu_read_unlock();
1417 return ret;
1418 }
1419 get_task_struct(tsk);
1420 rcu_read_unlock();
1421
1422 ret = do_prlimit(tsk, resource, new_rlim ? &new : NULL,
1423 old_rlim ? &old : NULL);
1424
1425 if (!ret && old_rlim) {
1426 rlim_to_rlim64(&old, &old64);
1427 if (copy_to_user(old_rlim, &old64, sizeof(old64)))
1428 ret = -EFAULT;
1429 }
1430
1431 put_task_struct(tsk);
1432 return ret;
1433}
1434
1435SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1436{
1437 struct rlimit new_rlim;
1438
1439 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1440 return -EFAULT;
1441 return do_prlimit(current, resource, &new_rlim, NULL);
1442}
1443
1328/* 1444/*
1329 * It would make sense to put struct rusage in the task_struct, 1445 * It would make sense to put struct rusage in the task_struct,
1330 * except that would make the task_struct be *really big*. After 1446 * except that would make the task_struct be *really big*. After