kern_resource.c revision 1.116.2.4 1 /* $NetBSD: kern_resource.c,v 1.116.2.4 2007/07/14 22:09:43 ad Exp $ */
2
3 /*-
4 * Copyright (c) 1982, 1986, 1991, 1993
5 * The Regents of the University of California. All rights reserved.
6 * (c) UNIX System Laboratories, Inc.
7 * All or some portions of this file are derived from material licensed
8 * to the University of California by American Telephone and Telegraph
9 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
10 * the permission of UNIX System Laboratories, Inc.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. Neither the name of the University nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 * SUCH DAMAGE.
35 *
36 * @(#)kern_resource.c 8.8 (Berkeley) 2/14/95
37 */
38
39 #include <sys/cdefs.h>
40 __KERNEL_RCSID(0, "$NetBSD: kern_resource.c,v 1.116.2.4 2007/07/14 22:09:43 ad Exp $");
41
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/kernel.h>
45 #include <sys/file.h>
46 #include <sys/resourcevar.h>
47 #include <sys/malloc.h>
48 #include <sys/namei.h>
49 #include <sys/pool.h>
50 #include <sys/proc.h>
51 #include <sys/sysctl.h>
52 #include <sys/kauth.h>
53
54 #include <sys/mount.h>
55 #include <sys/syscallargs.h>
56
57 #include <uvm/uvm_extern.h>
58
59 /*
60 * Maximum process data and stack limits.
61 * They are variables so they are patchable.
62 */
63 rlim_t maxdmap = MAXDSIZ;
64 rlim_t maxsmap = MAXSSIZ;
65
66 struct uihashhead *uihashtbl;
67 u_long uihash; /* size of hash table - 1 */
68 kmutex_t uihashtbl_lock;
69
70 /*
71 * Resource controls and accounting.
72 */
73
74 int
75 sys_getpriority(struct lwp *l, void *v, register_t *retval)
76 {
77 struct sys_getpriority_args /* {
78 syscallarg(int) which;
79 syscallarg(id_t) who;
80 } */ *uap = v;
81 struct proc *curp = l->l_proc, *p;
82 int low = NZERO + PRIO_MAX + 1;
83 int who = SCARG(uap, who);
84
85 mutex_enter(&proclist_lock);
86 switch (SCARG(uap, which)) {
87 case PRIO_PROCESS:
88 if (who == 0)
89 p = curp;
90 else
91 p = p_find(who, PFIND_LOCKED);
92 if (p != NULL)
93 low = p->p_nice;
94 break;
95
96 case PRIO_PGRP: {
97 struct pgrp *pg;
98
99 if (who == 0)
100 pg = curp->p_pgrp;
101 else if ((pg = pg_find(who, PFIND_LOCKED)) == NULL)
102 break;
103 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
104 if (p->p_nice < low)
105 low = p->p_nice;
106 }
107 break;
108 }
109
110 case PRIO_USER:
111 if (who == 0)
112 who = (int)kauth_cred_geteuid(l->l_cred);
113 PROCLIST_FOREACH(p, &allproc) {
114 mutex_enter(&p->p_mutex);
115 if (kauth_cred_geteuid(p->p_cred) ==
116 (uid_t)who && p->p_nice < low)
117 low = p->p_nice;
118 mutex_exit(&p->p_mutex);
119 }
120 break;
121
122 default:
123 mutex_exit(&proclist_lock);
124 return (EINVAL);
125 }
126 mutex_exit(&proclist_lock);
127
128 if (low == NZERO + PRIO_MAX + 1)
129 return (ESRCH);
130 *retval = low - NZERO;
131 return (0);
132 }
133
134 /* ARGSUSED */
135 int
136 sys_setpriority(struct lwp *l, void *v, register_t *retval)
137 {
138 struct sys_setpriority_args /* {
139 syscallarg(int) which;
140 syscallarg(id_t) who;
141 syscallarg(int) prio;
142 } */ *uap = v;
143 struct proc *curp = l->l_proc, *p;
144 int found = 0, error = 0;
145 int who = SCARG(uap, who);
146
147 mutex_enter(&proclist_lock);
148 switch (SCARG(uap, which)) {
149 case PRIO_PROCESS:
150 if (who == 0)
151 p = curp;
152 else
153 p = p_find(who, PFIND_LOCKED);
154 if (p != 0) {
155 mutex_enter(&p->p_mutex);
156 error = donice(l, p, SCARG(uap, prio));
157 mutex_exit(&p->p_mutex);
158 }
159 found++;
160 break;
161
162 case PRIO_PGRP: {
163 struct pgrp *pg;
164
165 if (who == 0)
166 pg = curp->p_pgrp;
167 else if ((pg = pg_find(who, PFIND_LOCKED)) == NULL)
168 break;
169 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
170 mutex_enter(&p->p_mutex);
171 error = donice(l, p, SCARG(uap, prio));
172 mutex_exit(&p->p_mutex);
173 found++;
174 }
175 break;
176 }
177
178 case PRIO_USER:
179 if (who == 0)
180 who = (int)kauth_cred_geteuid(l->l_cred);
181 PROCLIST_FOREACH(p, &allproc) {
182 mutex_enter(&p->p_mutex);
183 if (kauth_cred_geteuid(p->p_cred) ==
184 (uid_t)SCARG(uap, who)) {
185 error = donice(l, p, SCARG(uap, prio));
186 found++;
187 }
188 mutex_exit(&p->p_mutex);
189 }
190 break;
191
192 default:
193 error = EINVAL;
194 break;
195 }
196 mutex_exit(&proclist_lock);
197 if (found == 0)
198 return (ESRCH);
199 return (error);
200 }
201
202 /*
203 * Renice a process.
204 *
205 * Call with the target process' credentials locked.
206 */
207 int
208 donice(struct lwp *l, struct proc *chgp, int n)
209 {
210 kauth_cred_t cred = l->l_cred;
211 int onice;
212
213 KASSERT(mutex_owned(&chgp->p_mutex));
214
215 if (n > PRIO_MAX)
216 n = PRIO_MAX;
217 if (n < PRIO_MIN)
218 n = PRIO_MIN;
219 n += NZERO;
220 onice = chgp->p_nice;
221 onice = chgp->p_nice;
222
223 again:
224 if (kauth_authorize_process(cred, KAUTH_PROCESS_NICE, chgp,
225 KAUTH_ARG(n), NULL, NULL))
226 return (EACCES);
227 mutex_spin_enter(&chgp->p_stmutex);
228 if (onice != chgp->p_nice) {
229 mutex_spin_exit(&chgp->p_stmutex);
230 goto again;
231 }
232 sched_nice(chgp, n);
233 mutex_spin_exit(&chgp->p_stmutex);
234 return (0);
235 }
236
237 /* ARGSUSED */
238 int
239 sys_setrlimit(struct lwp *l, void *v, register_t *retval)
240 {
241 struct sys_setrlimit_args /* {
242 syscallarg(int) which;
243 syscallarg(const struct rlimit *) rlp;
244 } */ *uap = v;
245 int which = SCARG(uap, which);
246 struct rlimit alim;
247 int error;
248
249 error = copyin(SCARG(uap, rlp), &alim, sizeof(struct rlimit));
250 if (error)
251 return (error);
252 return (dosetrlimit(l, l->l_proc, which, &alim));
253 }
254
255 int
256 dosetrlimit(struct lwp *l, struct proc *p, int which, struct rlimit *limp)
257 {
258 struct rlimit *alimp;
259 struct plimit *oldplim;
260 int error;
261
262 if ((u_int)which >= RLIM_NLIMITS)
263 return (EINVAL);
264
265 if (limp->rlim_cur < 0 || limp->rlim_max < 0)
266 return (EINVAL);
267
268 alimp = &p->p_rlimit[which];
269 /* if we don't change the value, no need to limcopy() */
270 if (limp->rlim_cur == alimp->rlim_cur &&
271 limp->rlim_max == alimp->rlim_max)
272 return 0;
273
274 if (limp->rlim_cur > limp->rlim_max) {
275 /*
276 * This is programming error. According to SUSv2, we should
277 * return error in this case.
278 */
279 return (EINVAL);
280 }
281 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_RLIMIT,
282 p, limp, KAUTH_ARG(which), NULL);
283 if (error)
284 return (error);
285
286 mutex_enter(&p->p_mutex);
287 if (p->p_limit->p_refcnt > 1 &&
288 (p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
289 oldplim = p->p_limit;
290 p->p_limit = limcopy(p);
291 limfree(oldplim);
292 alimp = &p->p_rlimit[which];
293 }
294
295 switch (which) {
296
297 case RLIMIT_DATA:
298 if (limp->rlim_cur > maxdmap)
299 limp->rlim_cur = maxdmap;
300 if (limp->rlim_max > maxdmap)
301 limp->rlim_max = maxdmap;
302 break;
303
304 case RLIMIT_STACK:
305 if (limp->rlim_cur > maxsmap)
306 limp->rlim_cur = maxsmap;
307 if (limp->rlim_max > maxsmap)
308 limp->rlim_max = maxsmap;
309
310 /*
311 * Return EINVAL if the new stack size limit is lower than
312 * current usage. Otherwise, the process would get SIGSEGV the
313 * moment it would try to access anything on it's current stack.
314 * This conforms to SUSv2.
315 */
316 if (limp->rlim_cur < p->p_vmspace->vm_ssize * PAGE_SIZE
317 || limp->rlim_max < p->p_vmspace->vm_ssize * PAGE_SIZE) {
318 mutex_exit(&p->p_mutex);
319 return (EINVAL);
320 }
321
322 /*
323 * Stack is allocated to the max at exec time with
324 * only "rlim_cur" bytes accessible (In other words,
325 * allocates stack dividing two contiguous regions at
326 * "rlim_cur" bytes boundary).
327 *
328 * Since allocation is done in terms of page, roundup
329 * "rlim_cur" (otherwise, contiguous regions
330 * overlap). If stack limit is going up make more
331 * accessible, if going down make inaccessible.
332 */
333 limp->rlim_cur = round_page(limp->rlim_cur);
334 if (limp->rlim_cur != alimp->rlim_cur) {
335 vaddr_t addr;
336 vsize_t size;
337 vm_prot_t prot;
338
339 if (limp->rlim_cur > alimp->rlim_cur) {
340 prot = VM_PROT_READ | VM_PROT_WRITE;
341 size = limp->rlim_cur - alimp->rlim_cur;
342 addr = (vaddr_t)p->p_vmspace->vm_minsaddr -
343 limp->rlim_cur;
344 } else {
345 prot = VM_PROT_NONE;
346 size = alimp->rlim_cur - limp->rlim_cur;
347 addr = (vaddr_t)p->p_vmspace->vm_minsaddr -
348 alimp->rlim_cur;
349 }
350 (void) uvm_map_protect(&p->p_vmspace->vm_map,
351 addr, addr+size, prot, false);
352 }
353 break;
354
355 case RLIMIT_NOFILE:
356 if (limp->rlim_cur > maxfiles)
357 limp->rlim_cur = maxfiles;
358 if (limp->rlim_max > maxfiles)
359 limp->rlim_max = maxfiles;
360 break;
361
362 case RLIMIT_NPROC:
363 if (limp->rlim_cur > maxproc)
364 limp->rlim_cur = maxproc;
365 if (limp->rlim_max > maxproc)
366 limp->rlim_max = maxproc;
367 break;
368 }
369 *alimp = *limp;
370 mutex_exit(&p->p_mutex);
371 return (0);
372 }
373
374 /* ARGSUSED */
375 int
376 sys_getrlimit(struct lwp *l, void *v, register_t *retval)
377 {
378 struct sys_getrlimit_args /* {
379 syscallarg(int) which;
380 syscallarg(struct rlimit *) rlp;
381 } */ *uap = v;
382 struct proc *p = l->l_proc;
383 int which = SCARG(uap, which);
384
385 if ((u_int)which >= RLIM_NLIMITS)
386 return (EINVAL);
387 return (copyout(&p->p_rlimit[which], SCARG(uap, rlp),
388 sizeof(struct rlimit)));
389 }
390
391 /*
392 * Transform the running time and tick information in proc p into user,
393 * system, and interrupt time usage.
394 *
395 * Should be called with p->p_smutex held unless called from exit1().
396 */
397 void
398 calcru(struct proc *p, struct timeval *up, struct timeval *sp,
399 struct timeval *ip, struct timeval *rp)
400 {
401 u_quad_t u, st, ut, it, tot;
402 unsigned long sec;
403 long usec;
404 struct timeval tv;
405 struct lwp *l;
406
407 mutex_spin_enter(&p->p_stmutex);
408 st = p->p_sticks;
409 ut = p->p_uticks;
410 it = p->p_iticks;
411 mutex_spin_exit(&p->p_stmutex);
412
413 sec = p->p_rtime.tv_sec;
414 usec = p->p_rtime.tv_usec;
415
416 LIST_FOREACH(l, &p->p_lwps, l_sibling) {
417 lwp_lock(l);
418 sec += l->l_rtime.tv_sec;
419 if ((usec += l->l_rtime.tv_usec) >= 1000000) {
420 sec++;
421 usec -= 1000000;
422 }
423 if ((l->l_flag & LW_RUNNING) != 0) {
424 /*
425 * Adjust for the current time slice. This is
426 * actually fairly important since the error
427 * here is on the order of a time quantum,
428 * which is much greater than the sampling
429 * error.
430 */
431 microtime(&tv);
432 sec += tv.tv_sec - l->l_stime.tv_sec;
433 usec += tv.tv_usec - l->l_stime.tv_usec;
434 if (usec >= 1000000) {
435 sec++;
436 usec -= 1000000;
437 }
438 }
439 lwp_unlock(l);
440 }
441
442 tot = st + ut + it;
443 u = sec * 1000000ull + usec;
444
445 if (tot == 0) {
446 /* No ticks, so can't use to share time out, split 50-50 */
447 st = ut = u / 2;
448 } else {
449 st = (u * st) / tot;
450 ut = (u * ut) / tot;
451 }
452 if (sp != NULL) {
453 sp->tv_sec = st / 1000000;
454 sp->tv_usec = st % 1000000;
455 }
456 if (up != NULL) {
457 up->tv_sec = ut / 1000000;
458 up->tv_usec = ut % 1000000;
459 }
460 if (ip != NULL) {
461 if (it != 0)
462 it = (u * it) / tot;
463 ip->tv_sec = it / 1000000;
464 ip->tv_usec = it % 1000000;
465 }
466 if (rp != NULL) {
467 rp->tv_sec = sec;
468 rp->tv_usec = usec;
469 }
470 }
471
472 /* ARGSUSED */
473 int
474 sys_getrusage(struct lwp *l, void *v, register_t *retval)
475 {
476 struct sys_getrusage_args /* {
477 syscallarg(int) who;
478 syscallarg(struct rusage *) rusage;
479 } */ *uap = v;
480 struct rusage *rup;
481 struct proc *p = l->l_proc;
482
483 switch (SCARG(uap, who)) {
484
485 case RUSAGE_SELF:
486 rup = &p->p_stats->p_ru;
487 mutex_enter(&p->p_smutex);
488 calcru(p, &rup->ru_utime, &rup->ru_stime, NULL, NULL);
489 mutex_exit(&p->p_smutex);
490 break;
491
492 case RUSAGE_CHILDREN:
493 rup = &p->p_stats->p_cru;
494 break;
495
496 default:
497 return (EINVAL);
498 }
499 return (copyout(rup, SCARG(uap, rusage), sizeof(struct rusage)));
500 }
501
502 void
503 ruadd(struct rusage *ru, struct rusage *ru2)
504 {
505 long *ip, *ip2;
506 int i;
507
508 timeradd(&ru->ru_utime, &ru2->ru_utime, &ru->ru_utime);
509 timeradd(&ru->ru_stime, &ru2->ru_stime, &ru->ru_stime);
510 if (ru->ru_maxrss < ru2->ru_maxrss)
511 ru->ru_maxrss = ru2->ru_maxrss;
512 ip = &ru->ru_first; ip2 = &ru2->ru_first;
513 for (i = &ru->ru_last - &ru->ru_first; i >= 0; i--)
514 *ip++ += *ip2++;
515 }
516
517 /*
518 * Make a copy of the plimit structure.
519 * We share these structures copy-on-write after fork,
520 * and copy when a limit is changed.
521 *
522 * XXXSMP This is atrocious, need to simplify.
523 */
524 struct plimit *
525 limcopy(struct proc *p)
526 {
527 struct plimit *lim, *newlim;
528 char *corename;
529 size_t l;
530
531 KASSERT(mutex_owned(&p->p_mutex));
532
533 mutex_exit(&p->p_mutex);
534 newlim = pool_get(&plimit_pool, PR_WAITOK);
535 mutex_init(&newlim->p_lock, MUTEX_DEFAULT, IPL_NONE);
536 newlim->p_lflags = 0;
537 newlim->p_refcnt = 1;
538 mutex_enter(&p->p_mutex);
539
540 for (;;) {
541 lim = p->p_limit;
542 mutex_enter(&lim->p_lock);
543 if (lim->pl_corename != defcorename) {
544 l = strlen(lim->pl_corename) + 1;
545
546 mutex_exit(&lim->p_lock);
547 mutex_exit(&p->p_mutex);
548 corename = malloc(l, M_TEMP, M_WAITOK);
549 mutex_enter(&p->p_mutex);
550 mutex_enter(&lim->p_lock);
551
552 if (l != strlen(lim->pl_corename) + 1) {
553 mutex_exit(&lim->p_lock);
554 mutex_exit(&p->p_mutex);
555 free(corename, M_TEMP);
556 mutex_enter(&p->p_mutex);
557 continue;
558 }
559 } else
560 l = 0;
561
562 memcpy(newlim->pl_rlimit, lim->pl_rlimit,
563 sizeof(struct rlimit) * RLIM_NLIMITS);
564 if (l != 0)
565 strlcpy(newlim->pl_corename, lim->pl_corename, l);
566 else
567 newlim->pl_corename = defcorename;
568 mutex_exit(&lim->p_lock);
569 break;
570 }
571
572 return (newlim);
573 }
574
575 void
576 limfree(struct plimit *lim)
577 {
578 int n;
579
580 mutex_enter(&lim->p_lock);
581 n = --lim->p_refcnt;
582 mutex_exit(&lim->p_lock);
583 if (n > 0)
584 return;
585 #ifdef DIAGNOSTIC
586 if (n < 0)
587 panic("limfree");
588 #endif
589 if (lim->pl_corename != defcorename)
590 free(lim->pl_corename, M_TEMP);
591 mutex_destroy(&lim->p_lock);
592 pool_put(&plimit_pool, lim);
593 }
594
595 struct pstats *
596 pstatscopy(struct pstats *ps)
597 {
598
599 struct pstats *newps;
600
601 newps = pool_get(&pstats_pool, PR_WAITOK);
602
603 memset(&newps->pstat_startzero, 0,
604 (unsigned) ((char *)&newps->pstat_endzero -
605 (char *)&newps->pstat_startzero));
606 memcpy(&newps->pstat_startcopy, &ps->pstat_startcopy,
607 ((char *)&newps->pstat_endcopy -
608 (char *)&newps->pstat_startcopy));
609
610 return (newps);
611
612 }
613
614 void
615 pstatsfree(struct pstats *ps)
616 {
617
618 pool_put(&pstats_pool, ps);
619 }
620
621 /*
622 * sysctl interface in five parts
623 */
624
625 /*
626 * a routine for sysctl proc subtree helpers that need to pick a valid
627 * process by pid.
628 */
629 static int
630 sysctl_proc_findproc(struct lwp *l, struct proc **p2, pid_t pid)
631 {
632 struct proc *ptmp;
633 int error = 0;
634
635 if (pid == PROC_CURPROC)
636 ptmp = l->l_proc;
637 else if ((ptmp = pfind(pid)) == NULL)
638 error = ESRCH;
639
640 *p2 = ptmp;
641 return (error);
642 }
643
644 /*
645 * sysctl helper routine for setting a process's specific corefile
646 * name. picks the process based on the given pid and checks the
647 * correctness of the new value.
648 */
649 static int
650 sysctl_proc_corename(SYSCTLFN_ARGS)
651 {
652 struct proc *ptmp;
653 struct plimit *lim;
654 int error = 0, len;
655 char *cname;
656 char *tmp;
657 struct sysctlnode node;
658
659 /*
660 * is this all correct?
661 */
662 if (namelen != 0)
663 return (EINVAL);
664 if (name[-1] != PROC_PID_CORENAME)
665 return (EINVAL);
666
667 /*
668 * whom are we tweaking?
669 */
670 error = sysctl_proc_findproc(l, &ptmp, (pid_t)name[-2]);
671 if (error)
672 return (error);
673
674 /* XXX this should be in p_find() */
675 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
676 ptmp, NULL, NULL, NULL);
677 if (error)
678 return (error);
679
680 cname = PNBUF_GET();
681 /*
682 * let them modify a temporary copy of the core name
683 */
684 node = *rnode;
685 strlcpy(cname, ptmp->p_limit->pl_corename, MAXPATHLEN);
686 node.sysctl_data = cname;
687 error = sysctl_lookup(SYSCTLFN_CALL(&node));
688
689 /*
690 * if that failed, or they have nothing new to say, or we've
691 * heard it before...
692 */
693 if (error || newp == NULL ||
694 strcmp(cname, ptmp->p_limit->pl_corename) == 0) {
695 goto done;
696 }
697
698 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CORENAME,
699 ptmp, cname, NULL, NULL);
700 if (error)
701 return (error);
702
703 /*
704 * no error yet and cname now has the new core name in it.
705 * let's see if it looks acceptable. it must be either "core"
706 * or end in ".core" or "/core".
707 */
708 len = strlen(cname);
709 if (len < 4) {
710 error = EINVAL;
711 } else if (strcmp(cname + len - 4, "core") != 0) {
712 error = EINVAL;
713 } else if (len > 4 && cname[len - 5] != '/' && cname[len - 5] != '.') {
714 error = EINVAL;
715 }
716 if (error != 0) {
717 goto done;
718 }
719
720 /*
721 * hmm...looks good. now...where do we put it?
722 */
723 tmp = malloc(len + 1, M_TEMP, M_WAITOK|M_CANFAIL);
724 if (tmp == NULL) {
725 error = ENOMEM;
726 goto done;
727 }
728 strlcpy(tmp, cname, len + 1);
729
730 mutex_enter(&ptmp->p_mutex);
731 lim = ptmp->p_limit;
732 if (lim->p_refcnt > 1 && (lim->p_lflags & PL_SHAREMOD) == 0) {
733 ptmp->p_limit = limcopy(ptmp);
734 limfree(lim);
735 lim = ptmp->p_limit;
736 }
737 if (lim->pl_corename != defcorename)
738 free(lim->pl_corename, M_TEMP);
739 lim->pl_corename = tmp;
740 mutex_exit(&ptmp->p_mutex);
741 done:
742 PNBUF_PUT(cname);
743 return error;
744 }
745
746 /*
747 * sysctl helper routine for checking/setting a process's stop flags,
748 * one for fork and one for exec.
749 */
750 static int
751 sysctl_proc_stop(SYSCTLFN_ARGS)
752 {
753 struct proc *ptmp;
754 int i, f, error = 0;
755 struct sysctlnode node;
756
757 if (namelen != 0)
758 return (EINVAL);
759
760 error = sysctl_proc_findproc(l, &ptmp, (pid_t)name[-2]);
761 if (error)
762 return (error);
763
764 /* XXX this should be in p_find() */
765 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
766 ptmp, NULL, NULL, NULL);
767 if (error)
768 return (error);
769
770 switch (rnode->sysctl_num) {
771 case PROC_PID_STOPFORK:
772 f = PS_STOPFORK;
773 break;
774 case PROC_PID_STOPEXEC:
775 f = PS_STOPEXEC;
776 break;
777 case PROC_PID_STOPEXIT:
778 f = PS_STOPEXIT;
779 break;
780 default:
781 return (EINVAL);
782 }
783
784 i = (ptmp->p_flag & f) ? 1 : 0;
785 node = *rnode;
786 node.sysctl_data = &i;
787 error = sysctl_lookup(SYSCTLFN_CALL(&node));
788 if (error || newp == NULL)
789 return (error);
790
791 mutex_enter(&ptmp->p_smutex);
792 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_STOPFLAG,
793 ptmp, KAUTH_ARG(f), NULL, NULL);
794 if (error)
795 return (error);
796 if (i)
797 ptmp->p_sflag |= f;
798 else
799 ptmp->p_sflag &= ~f;
800 mutex_exit(&ptmp->p_smutex);
801
802 return (0);
803 }
804
805 /*
806 * sysctl helper routine for a process's rlimits as exposed by sysctl.
807 */
808 static int
809 sysctl_proc_plimit(SYSCTLFN_ARGS)
810 {
811 struct proc *ptmp;
812 u_int limitno;
813 int which, error = 0;
814 struct rlimit alim;
815 struct sysctlnode node;
816
817 if (namelen != 0)
818 return (EINVAL);
819
820 which = name[-1];
821 if (which != PROC_PID_LIMIT_TYPE_SOFT &&
822 which != PROC_PID_LIMIT_TYPE_HARD)
823 return (EINVAL);
824
825 limitno = name[-2] - 1;
826 if (limitno >= RLIM_NLIMITS)
827 return (EINVAL);
828
829 if (name[-3] != PROC_PID_LIMIT)
830 return (EINVAL);
831
832 error = sysctl_proc_findproc(l, &ptmp, (pid_t)name[-4]);
833 if (error)
834 return (error);
835
836 /* XXX this should be in p_find() */
837 error = kauth_authorize_process(l->l_cred, KAUTH_PROCESS_CANSEE,
838 ptmp, NULL, NULL, NULL);
839 if (error)
840 return (error);
841
842 node = *rnode;
843 memcpy(&alim, &ptmp->p_rlimit[limitno], sizeof(alim));
844 if (which == PROC_PID_LIMIT_TYPE_HARD)
845 node.sysctl_data = &alim.rlim_max;
846 else
847 node.sysctl_data = &alim.rlim_cur;
848
849 error = sysctl_lookup(SYSCTLFN_CALL(&node));
850 if (error || newp == NULL)
851 return (error);
852
853 return (dosetrlimit(l, ptmp, limitno, &alim));
854 }
855
856 /*
857 * and finally, the actually glue that sticks it to the tree
858 */
859 SYSCTL_SETUP(sysctl_proc_setup, "sysctl proc subtree setup")
860 {
861
862 sysctl_createv(clog, 0, NULL, NULL,
863 CTLFLAG_PERMANENT,
864 CTLTYPE_NODE, "proc", NULL,
865 NULL, 0, NULL, 0,
866 CTL_PROC, CTL_EOL);
867 sysctl_createv(clog, 0, NULL, NULL,
868 CTLFLAG_PERMANENT|CTLFLAG_ANYNUMBER,
869 CTLTYPE_NODE, "curproc",
870 SYSCTL_DESCR("Per-process settings"),
871 NULL, 0, NULL, 0,
872 CTL_PROC, PROC_CURPROC, CTL_EOL);
873
874 sysctl_createv(clog, 0, NULL, NULL,
875 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_ANYWRITE,
876 CTLTYPE_STRING, "corename",
877 SYSCTL_DESCR("Core file name"),
878 sysctl_proc_corename, 0, NULL, MAXPATHLEN,
879 CTL_PROC, PROC_CURPROC, PROC_PID_CORENAME, CTL_EOL);
880 sysctl_createv(clog, 0, NULL, NULL,
881 CTLFLAG_PERMANENT,
882 CTLTYPE_NODE, "rlimit",
883 SYSCTL_DESCR("Process limits"),
884 NULL, 0, NULL, 0,
885 CTL_PROC, PROC_CURPROC, PROC_PID_LIMIT, CTL_EOL);
886
887 #define create_proc_plimit(s, n) do { \
888 sysctl_createv(clog, 0, NULL, NULL, \
889 CTLFLAG_PERMANENT, \
890 CTLTYPE_NODE, s, \
891 SYSCTL_DESCR("Process " s " limits"), \
892 NULL, 0, NULL, 0, \
893 CTL_PROC, PROC_CURPROC, PROC_PID_LIMIT, n, \
894 CTL_EOL); \
895 sysctl_createv(clog, 0, NULL, NULL, \
896 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_ANYWRITE, \
897 CTLTYPE_QUAD, "soft", \
898 SYSCTL_DESCR("Process soft " s " limit"), \
899 sysctl_proc_plimit, 0, NULL, 0, \
900 CTL_PROC, PROC_CURPROC, PROC_PID_LIMIT, n, \
901 PROC_PID_LIMIT_TYPE_SOFT, CTL_EOL); \
902 sysctl_createv(clog, 0, NULL, NULL, \
903 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_ANYWRITE, \
904 CTLTYPE_QUAD, "hard", \
905 SYSCTL_DESCR("Process hard " s " limit"), \
906 sysctl_proc_plimit, 0, NULL, 0, \
907 CTL_PROC, PROC_CURPROC, PROC_PID_LIMIT, n, \
908 PROC_PID_LIMIT_TYPE_HARD, CTL_EOL); \
909 } while (0/*CONSTCOND*/)
910
911 create_proc_plimit("cputime", PROC_PID_LIMIT_CPU);
912 create_proc_plimit("filesize", PROC_PID_LIMIT_FSIZE);
913 create_proc_plimit("datasize", PROC_PID_LIMIT_DATA);
914 create_proc_plimit("stacksize", PROC_PID_LIMIT_STACK);
915 create_proc_plimit("coredumpsize", PROC_PID_LIMIT_CORE);
916 create_proc_plimit("memoryuse", PROC_PID_LIMIT_RSS);
917 create_proc_plimit("memorylocked", PROC_PID_LIMIT_MEMLOCK);
918 create_proc_plimit("maxproc", PROC_PID_LIMIT_NPROC);
919 create_proc_plimit("descriptors", PROC_PID_LIMIT_NOFILE);
920 create_proc_plimit("sbsize", PROC_PID_LIMIT_SBSIZE);
921
922 #undef create_proc_plimit
923
924 sysctl_createv(clog, 0, NULL, NULL,
925 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_ANYWRITE,
926 CTLTYPE_INT, "stopfork",
927 SYSCTL_DESCR("Stop process at fork(2)"),
928 sysctl_proc_stop, 0, NULL, 0,
929 CTL_PROC, PROC_CURPROC, PROC_PID_STOPFORK, CTL_EOL);
930 sysctl_createv(clog, 0, NULL, NULL,
931 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_ANYWRITE,
932 CTLTYPE_INT, "stopexec",
933 SYSCTL_DESCR("Stop process at execve(2)"),
934 sysctl_proc_stop, 0, NULL, 0,
935 CTL_PROC, PROC_CURPROC, PROC_PID_STOPEXEC, CTL_EOL);
936 sysctl_createv(clog, 0, NULL, NULL,
937 CTLFLAG_PERMANENT|CTLFLAG_READWRITE|CTLFLAG_ANYWRITE,
938 CTLTYPE_INT, "stopexit",
939 SYSCTL_DESCR("Stop process before completing exit"),
940 sysctl_proc_stop, 0, NULL, 0,
941 CTL_PROC, PROC_CURPROC, PROC_PID_STOPEXIT, CTL_EOL);
942 }
943
944 void
945 uid_init(void)
946 {
947
948 /*
949 * XXXSMP This could be at IPL_SOFTNET, but for now we want
950 * to to be deadlock free, so it must be at IPL_VM.
951 */
952 mutex_init(&uihashtbl_lock, MUTEX_DRIVER, IPL_VM);
953
954 /*
955 * Ensure that uid 0 is always in the user hash table, as
956 * sbreserve() expects it available from interrupt context.
957 */
958 (void)uid_find(0);
959 }
960
961 struct uidinfo *
962 uid_find(uid_t uid)
963 {
964 struct uidinfo *uip;
965 struct uidinfo *newuip = NULL;
966 struct uihashhead *uipp;
967
968 uipp = UIHASH(uid);
969
970 again:
971 mutex_enter(&uihashtbl_lock);
972 LIST_FOREACH(uip, uipp, ui_hash)
973 if (uip->ui_uid == uid) {
974 mutex_exit(&uihashtbl_lock);
975 if (newuip) {
976 free(newuip, M_PROC);
977 mutex_destroy(&newuip->ui_lock);
978 }
979 return uip;
980 }
981 if (newuip == NULL) {
982 mutex_exit(&uihashtbl_lock);
983 /* Must not be called from interrupt context. */
984 newuip = malloc(sizeof(*uip), M_PROC, M_WAITOK | M_ZERO);
985 mutex_init(&newuip->ui_lock, MUTEX_DRIVER, IPL_SOFTNET);
986 goto again;
987 }
988 uip = newuip;
989
990 LIST_INSERT_HEAD(uipp, uip, ui_hash);
991 uip->ui_uid = uid;
992 mutex_exit(&uihashtbl_lock);
993
994 return uip;
995 }
996
997 /*
998 * Change the count associated with number of processes
999 * a given user is using.
1000 */
1001 int
1002 chgproccnt(uid_t uid, int diff)
1003 {
1004 struct uidinfo *uip;
1005
1006 if (diff == 0)
1007 return 0;
1008
1009 uip = uid_find(uid);
1010 mutex_enter(&uip->ui_lock);
1011 uip->ui_proccnt += diff;
1012 KASSERT(uip->ui_proccnt >= 0);
1013 mutex_exit(&uip->ui_lock);
1014 return uip->ui_proccnt;
1015 }
1016
1017 int
1018 chgsbsize(struct uidinfo *uip, u_long *hiwat, u_long to, rlim_t xmax)
1019 {
1020 rlim_t nsb;
1021
1022 mutex_enter(&uip->ui_lock);
1023 nsb = uip->ui_sbsize + to - *hiwat;
1024 if (to > *hiwat && nsb > xmax) {
1025 mutex_exit(&uip->ui_lock);
1026 return 0;
1027 }
1028 *hiwat = to;
1029 uip->ui_sbsize = nsb;
1030 KASSERT(uip->ui_sbsize >= 0);
1031 mutex_exit(&uip->ui_lock);
1032 return 1;
1033 }
1034