aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/resource.h2
-rw-r--r--kernel/sys.c40
2 files changed, 26 insertions, 16 deletions
diff --git a/include/linux/resource.h b/include/linux/resource.h
index f1e914eefeab..cf8dc96653ee 100644
--- a/include/linux/resource.h
+++ b/include/linux/resource.h
@@ -73,6 +73,8 @@ struct rlimit {
73struct task_struct; 73struct task_struct;
74 74
75int getrusage(struct task_struct *p, int who, struct rusage __user *ru); 75int getrusage(struct task_struct *p, int who, struct rusage __user *ru);
76int do_setrlimit(struct task_struct *tsk, unsigned int resource,
77 struct rlimit *new_rlim);
76 78
77#endif /* __KERNEL__ */ 79#endif /* __KERNEL__ */
78 80
diff --git a/kernel/sys.c b/kernel/sys.c
index f2b2d7aa3818..b5b96e30e0d6 100644
--- a/kernel/sys.c
+++ b/kernel/sys.c
@@ -1272,42 +1272,41 @@ SYSCALL_DEFINE2(old_getrlimit, unsigned int, resource,
1272 1272
1273#endif 1273#endif
1274 1274
1275SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim) 1275int do_setrlimit(struct task_struct *tsk, unsigned int resource,
1276 struct rlimit *new_rlim)
1276{ 1277{
1277 struct rlimit new_rlim, *old_rlim; 1278 struct rlimit *old_rlim;
1278 int retval; 1279 int retval;
1279 1280
1280 if (resource >= RLIM_NLIMITS) 1281 if (resource >= RLIM_NLIMITS)
1281 return -EINVAL; 1282 return -EINVAL;
1282 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim))) 1283 if (new_rlim->rlim_cur > new_rlim->rlim_max)
1283 return -EFAULT;
1284 if (new_rlim.rlim_cur > new_rlim.rlim_max)
1285 return -EINVAL; 1284 return -EINVAL;
1286 if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > sysctl_nr_open) 1285 if (resource == RLIMIT_NOFILE && new_rlim->rlim_max > sysctl_nr_open)
1287 return -EPERM; 1286 return -EPERM;
1288 1287
1289 retval = security_task_setrlimit(current, resource, &new_rlim); 1288 retval = security_task_setrlimit(tsk->group_leader, resource, new_rlim);
1290 if (retval) 1289 if (retval)
1291 return retval; 1290 return retval;
1292 1291
1293 if (resource == RLIMIT_CPU && new_rlim.rlim_cur == 0) { 1292 if (resource == RLIMIT_CPU && new_rlim->rlim_cur == 0) {
1294 /* 1293 /*
1295 * The caller is asking for an immediate RLIMIT_CPU 1294 * The caller is asking for an immediate RLIMIT_CPU
1296 * expiry. But we use the zero value to mean "it was 1295 * expiry. But we use the zero value to mean "it was
1297 * never set". So let's cheat and make it one second 1296 * never set". So let's cheat and make it one second
1298 * instead 1297 * instead
1299 */ 1298 */
1300 new_rlim.rlim_cur = 1; 1299 new_rlim->rlim_cur = 1;
1301 } 1300 }
1302 1301
1303 old_rlim = current->signal->rlim + resource; 1302 old_rlim = tsk->signal->rlim + resource;
1304 task_lock(current->group_leader); 1303 task_lock(tsk->group_leader);
1305 if (new_rlim.rlim_max > old_rlim->rlim_max && 1304 if (new_rlim->rlim_max > old_rlim->rlim_max &&
1306 !capable(CAP_SYS_RESOURCE)) 1305 !capable(CAP_SYS_RESOURCE))
1307 retval = -EPERM; 1306 retval = -EPERM;
1308 else 1307 else
1309 *old_rlim = new_rlim; 1308 *old_rlim = *new_rlim;
1310 task_unlock(current->group_leader); 1309 task_unlock(tsk->group_leader);
1311 1310
1312 if (retval || resource != RLIMIT_CPU) 1311 if (retval || resource != RLIMIT_CPU)
1313 goto out; 1312 goto out;
@@ -1318,14 +1317,23 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1318 * very long-standing error, and fixing it now risks breakage of 1317 * very long-standing error, and fixing it now risks breakage of
1319 * applications, so we live with it 1318 * applications, so we live with it
1320 */ 1319 */
1321 if (new_rlim.rlim_cur == RLIM_INFINITY) 1320 if (new_rlim->rlim_cur == RLIM_INFINITY)
1322 goto out; 1321 goto out;
1323 1322
1324 update_rlimit_cpu(current, new_rlim.rlim_cur); 1323 update_rlimit_cpu(tsk, new_rlim->rlim_cur);
1325out: 1324out:
1326 return retval; 1325 return retval;
1327} 1326}
1328 1327
1328SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
1329{
1330 struct rlimit new_rlim;
1331
1332 if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1333 return -EFAULT;
1334 return do_setrlimit(current, resource, &new_rlim);
1335}
1336
1329/* 1337/*
1330 * It would make sense to put struct rusage in the task_struct, 1338 * It would make sense to put struct rusage in the task_struct,
1331 * except that would make the task_struct be *really big*. After 1339 * except that would make the task_struct be *really big*. After