Change kern.proc.rlimit sysctl to:
- retrive only one, specified limit for a process, not the whole array, as it was previously (the sysctl has been added recently and has not been backported to stable yet, so this change is ok); - allow to set a resource limit for another process. Submitted by: Andrey Zonov <andrey at zonov.org> Discussed with: kib Reviewed by: kib MFC after: 2 weeks
This commit is contained in:
parent
661268263e
commit
8854fe3915
@ -2372,7 +2372,7 @@ sysctl_kern_proc_groups(SYSCTL_HANDLER_ARGS)
|
||||
}
|
||||
|
||||
/*
|
||||
* This sysctl allows a process to retrieve the resource limits for
|
||||
* This sysctl allows a process to retrieve or/and set the resource limit for
|
||||
* another process.
|
||||
*/
|
||||
static int
|
||||
@ -2380,30 +2380,53 @@ sysctl_kern_proc_rlimit(SYSCTL_HANDLER_ARGS)
|
||||
{
|
||||
int *name = (int *)arg1;
|
||||
u_int namelen = arg2;
|
||||
struct plimit *limp;
|
||||
struct rlimit rlim;
|
||||
struct proc *p;
|
||||
int error = 0;
|
||||
u_int which;
|
||||
int flags, error;
|
||||
|
||||
if (namelen != 1)
|
||||
if (namelen != 2)
|
||||
return (EINVAL);
|
||||
|
||||
error = pget((pid_t)name[0], PGET_CANSEE, &p);
|
||||
which = (u_int)name[1];
|
||||
if (which >= RLIM_NLIMITS)
|
||||
return (EINVAL);
|
||||
|
||||
if (req->newptr != NULL && req->newlen != sizeof(rlim))
|
||||
return (EINVAL);
|
||||
|
||||
flags = PGET_HOLD | PGET_NOTWEXIT;
|
||||
if (req->newptr != NULL)
|
||||
flags |= PGET_CANDEBUG;
|
||||
else
|
||||
flags |= PGET_CANSEE;
|
||||
error = pget((pid_t)name[0], flags, &p);
|
||||
if (error != 0)
|
||||
return (error);
|
||||
|
||||
/*
|
||||
* Check the request size. We alow sizes smaller rlimit array for
|
||||
* backward binary compatibility: the number of resource limits may
|
||||
* grow.
|
||||
* Retrieve limit.
|
||||
*/
|
||||
if (sizeof(limp->pl_rlimit) < req->oldlen) {
|
||||
if (req->oldptr != NULL) {
|
||||
PROC_LOCK(p);
|
||||
lim_rlimit(p, which, &rlim);
|
||||
PROC_UNLOCK(p);
|
||||
return (EINVAL);
|
||||
}
|
||||
error = SYSCTL_OUT(req, &rlim, sizeof(rlim));
|
||||
if (error != 0)
|
||||
goto errout;
|
||||
|
||||
/*
|
||||
* Set limit.
|
||||
*/
|
||||
if (req->newptr != NULL) {
|
||||
error = SYSCTL_IN(req, &rlim, sizeof(rlim));
|
||||
if (error == 0)
|
||||
error = kern_proc_setrlimit(curthread, p, which, &rlim);
|
||||
}
|
||||
|
||||
limp = lim_hold(p->p_limit);
|
||||
PROC_UNLOCK(p);
|
||||
error = SYSCTL_OUT(req, limp->pl_rlimit, req->oldlen);
|
||||
lim_free(limp);
|
||||
errout:
|
||||
PRELE(p);
|
||||
return (error);
|
||||
}
|
||||
|
||||
@ -2544,8 +2567,9 @@ static SYSCTL_NODE(_kern_proc, KERN_PROC_KSTACK, kstack, CTLFLAG_RD |
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_GROUPS, groups, CTLFLAG_RD |
|
||||
CTLFLAG_MPSAFE, sysctl_kern_proc_groups, "Process groups");
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_RLIMIT, rlimit, CTLFLAG_RD |
|
||||
CTLFLAG_MPSAFE, sysctl_kern_proc_rlimit, "Process resource limits");
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_RLIMIT, rlimit, CTLFLAG_RW |
|
||||
CTLFLAG_ANYBODY | CTLFLAG_MPSAFE, sysctl_kern_proc_rlimit,
|
||||
"Process resource limits");
|
||||
|
||||
static SYSCTL_NODE(_kern_proc, KERN_PROC_PS_STRINGS, ps_strings,
|
||||
CTLFLAG_RW | CTLFLAG_ANYBODY | CTLFLAG_MPSAFE,
|
||||
|
@ -649,13 +649,17 @@ lim_cb(void *arg)
|
||||
}
|
||||
|
||||
int
|
||||
kern_setrlimit(td, which, limp)
|
||||
struct thread *td;
|
||||
u_int which;
|
||||
struct rlimit *limp;
|
||||
kern_setrlimit(struct thread *td, u_int which, struct rlimit *limp)
|
||||
{
|
||||
|
||||
return (kern_proc_setrlimit(td, td->td_proc, which, limp));
|
||||
}
|
||||
|
||||
int
|
||||
kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
|
||||
struct rlimit *limp)
|
||||
{
|
||||
struct plimit *newlim, *oldlim;
|
||||
struct proc *p;
|
||||
register struct rlimit *alimp;
|
||||
struct rlimit oldssiz;
|
||||
int error;
|
||||
@ -672,7 +676,6 @@ kern_setrlimit(td, which, limp)
|
||||
limp->rlim_max = RLIM_INFINITY;
|
||||
|
||||
oldssiz.rlim_cur = 0;
|
||||
p = td->td_proc;
|
||||
newlim = lim_alloc();
|
||||
PROC_LOCK(p);
|
||||
oldlim = p->p_limit;
|
||||
|
@ -120,6 +120,8 @@ int chgsbsize(struct uidinfo *uip, u_int *hiwat, u_int to,
|
||||
rlim_t maxval);
|
||||
int chgptscnt(struct uidinfo *uip, int diff, rlim_t maxval);
|
||||
int fuswintr(void *base);
|
||||
int kern_proc_setrlimit(struct thread *td, struct proc *p, u_int which,
|
||||
struct rlimit *limp);
|
||||
struct plimit
|
||||
*lim_alloc(void);
|
||||
void lim_copy(struct plimit *dst, struct plimit *src);
|
||||
|
Loading…
Reference in New Issue
Block a user