|
|
1.1 root 1: /*-
2: * Copyright (c) 1982, 1986, 1991 The Regents of the University of California.
3: * All rights reserved.
4: *
5: * Redistribution and use in source and binary forms, with or without
6: * modification, are permitted provided that the following conditions
7: * are met:
8: * 1. Redistributions of source code must retain the above copyright
9: * notice, this list of conditions and the following disclaimer.
10: * 2. Redistributions in binary form must reproduce the above copyright
11: * notice, this list of conditions and the following disclaimer in the
12: * documentation and/or other materials provided with the distribution.
13: * 3. All advertising materials mentioning features or use of this software
14: * must display the following acknowledgement:
15: * This product includes software developed by the University of
16: * California, Berkeley and its contributors.
17: * 4. Neither the name of the University nor the names of its contributors
18: * may be used to endorse or promote products derived from this software
19: * without specific prior written permission.
20: *
21: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31: * SUCH DAMAGE.
32: *
33: * @(#)kern_resource.c 7.13 (Berkeley) 5/9/91
34: */
35:
36: #include "param.h"
37: #include "resourcevar.h"
38: #include "malloc.h"
39: #include "proc.h"
40:
41: #include "vm/vm.h"
42:
43: /*
44: * Resource controls and accounting.
45: */
46:
47: getpriority(curp, uap, retval)
48: struct proc *curp;
49: register struct args {
50: int which;
51: int who;
52: } *uap;
53: int *retval;
54: {
55: register struct proc *p;
56: register int low = PRIO_MAX + 1;
57:
58: switch (uap->which) {
59:
60: case PRIO_PROCESS:
61: if (uap->who == 0)
62: p = curp;
63: else
64: p = pfind(uap->who);
65: if (p == 0)
66: break;
67: low = p->p_nice;
68: break;
69:
70: case PRIO_PGRP: {
71: register struct pgrp *pg;
72:
73: if (uap->who == 0)
74: pg = curp->p_pgrp;
75: else if ((pg = pgfind(uap->who)) == NULL)
76: break;
77: for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
78: if (p->p_nice < low)
79: low = p->p_nice;
80: }
81: break;
82: }
83:
84: case PRIO_USER:
85: if (uap->who == 0)
86: uap->who = curp->p_ucred->cr_uid;
87: for (p = allproc; p != NULL; p = p->p_nxt) {
88: if (p->p_ucred->cr_uid == uap->who &&
89: p->p_nice < low)
90: low = p->p_nice;
91: }
92: break;
93:
94: default:
95: return (EINVAL);
96: }
97: if (low == PRIO_MAX + 1)
98: return (ESRCH);
99: *retval = low;
100: return (0);
101: }
102:
103: /* ARGSUSED */
104: setpriority(curp, uap, retval)
105: struct proc *curp;
106: register struct args {
107: int which;
108: int who;
109: int prio;
110: } *uap;
111: int *retval;
112: {
113: register struct proc *p;
114: int found = 0, error = 0;
115:
116: switch (uap->which) {
117:
118: case PRIO_PROCESS:
119: if (uap->who == 0)
120: p = curp;
121: else
122: p = pfind(uap->who);
123: if (p == 0)
124: break;
125: error = donice(curp, p, uap->prio);
126: found++;
127: break;
128:
129: case PRIO_PGRP: {
130: register struct pgrp *pg;
131:
132: if (uap->who == 0)
133: pg = curp->p_pgrp;
134: else if ((pg = pgfind(uap->who)) == NULL)
135: break;
136: for (p = pg->pg_mem; p != NULL; p = p->p_pgrpnxt) {
137: error = donice(curp, p, uap->prio);
138: found++;
139: }
140: break;
141: }
142:
143: case PRIO_USER:
144: if (uap->who == 0)
145: uap->who = curp->p_ucred->cr_uid;
146: for (p = allproc; p != NULL; p = p->p_nxt)
147: if (p->p_ucred->cr_uid == uap->who) {
148: error = donice(curp, p, uap->prio);
149: found++;
150: }
151: break;
152:
153: default:
154: return (EINVAL);
155: }
156: if (found == 0)
157: return (ESRCH);
158: return (0);
159: }
160:
161: donice(curp, chgp, n)
162: register struct proc *curp, *chgp;
163: register int n;
164: {
165: register struct pcred *pcred = curp->p_cred;
166:
167: if (pcred->pc_ucred->cr_uid && pcred->p_ruid &&
168: pcred->pc_ucred->cr_uid != chgp->p_ucred->cr_uid &&
169: pcred->p_ruid != chgp->p_ucred->cr_uid)
170: return (EPERM);
171: if (n > PRIO_MAX)
172: n = PRIO_MAX;
173: if (n < PRIO_MIN)
174: n = PRIO_MIN;
175: if (n < chgp->p_nice && suser(pcred->pc_ucred, &curp->p_acflag))
176: return (EACCES);
177: chgp->p_nice = n;
178: (void) setpri(chgp);
179: return (0);
180: }
181:
182: /* ARGSUSED */
183: setrlimit(p, uap, retval)
184: struct proc *p;
185: register struct args {
186: u_int which;
187: struct rlimit *lim;
188: } *uap;
189: int *retval;
190: {
191: struct rlimit alim;
192: register struct rlimit *alimp;
193: extern unsigned maxdmap;
194: int error;
195:
196: if (uap->which >= RLIM_NLIMITS)
197: return (EINVAL);
198: alimp = &p->p_rlimit[uap->which];
199: if (error =
200: copyin((caddr_t)uap->lim, (caddr_t)&alim, sizeof (struct rlimit)))
201: return (error);
202: if (alim.rlim_cur > alimp->rlim_max || alim.rlim_max > alimp->rlim_max)
203: if (error = suser(p->p_ucred, &p->p_acflag))
204: return (error);
205: if (p->p_limit->p_refcnt > 1 &&
206: (p->p_limit->p_lflags & PL_SHAREMOD) == 0) {
207: p->p_limit->p_refcnt--;
208: p->p_limit = limcopy(p->p_limit);
209: }
210:
211: switch (uap->which) {
212:
213: case RLIMIT_DATA:
214: if (alim.rlim_cur > maxdmap)
215: alim.rlim_cur = maxdmap;
216: if (alim.rlim_max > maxdmap)
217: alim.rlim_max = maxdmap;
218: break;
219:
220: case RLIMIT_STACK:
221: if (alim.rlim_cur > maxdmap)
222: alim.rlim_cur = maxdmap;
223: if (alim.rlim_max > maxdmap)
224: alim.rlim_max = maxdmap;
225: /*
226: * Stack is allocated to the max at exec time with only
227: * "rlim_cur" bytes accessible. If stack limit is going
228: * up make more accessible, if going down make inaccessible.
229: */
230: if (alim.rlim_cur != alimp->rlim_cur) {
231: vm_offset_t addr;
232: vm_size_t size;
233: vm_prot_t prot;
1.1.1.2 ! root 234: struct vmspace *vm = p->p_vmspace;
1.1 root 235:
1.1.1.2 ! root 236: addr = (unsigned) vm->vm_maxsaddr + MAXSSIZ;
1.1 root 237: if (alim.rlim_cur > alimp->rlim_cur) {
238: prot = VM_PROT_ALL;
239: size = alim.rlim_cur - alimp->rlim_cur;
1.1.1.2 ! root 240: addr -= alim.rlim_cur;
1.1 root 241: } else {
242: prot = VM_PROT_NONE;
243: size = alimp->rlim_cur - alim.rlim_cur;
1.1.1.2 ! root 244: addr -= alimp->rlim_cur;
1.1 root 245: }
246: addr = trunc_page(addr);
247: size = round_page(size);
248: (void) vm_map_protect(&p->p_vmspace->vm_map,
249: addr, addr+size, prot, FALSE);
250: }
251: break;
252: }
253: p->p_rlimit[uap->which] = alim;
254: return (0);
255: }
256:
257: /* ARGSUSED */
258: getrlimit(p, uap, retval)
259: struct proc *p;
260: register struct args {
261: u_int which;
262: struct rlimit *rlp;
263: } *uap;
264: int *retval;
265: {
266:
267: if (uap->which >= RLIM_NLIMITS)
268: return (EINVAL);
269: return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp,
270: sizeof (struct rlimit)));
271: }
272:
273: /* ARGSUSED */
274: getrusage(p, uap, retval)
275: register struct proc *p;
276: register struct args {
277: int who;
278: struct rusage *rusage;
279: } *uap;
280: int *retval;
281: {
282: register struct rusage *rup;
283:
284: switch (uap->who) {
285:
286: case RUSAGE_SELF: {
287: int s;
288:
289: rup = &p->p_stats->p_ru;
290: s = splclock();
291: rup->ru_stime = p->p_stime;
292: rup->ru_utime = p->p_utime;
293: splx(s);
294: break;
295: }
296:
297: case RUSAGE_CHILDREN:
298: rup = &p->p_stats->p_cru;
299: break;
300:
301: default:
302: return (EINVAL);
303: }
304: return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
305: sizeof (struct rusage)));
306: }
307:
308: ruadd(ru, ru2)
309: register struct rusage *ru, *ru2;
310: {
311: register long *ip, *ip2;
312: register int i;
313:
314: timevaladd(&ru->ru_utime, &ru2->ru_utime);
315: timevaladd(&ru->ru_stime, &ru2->ru_stime);
316: if (ru->ru_maxrss < ru2->ru_maxrss)
317: ru->ru_maxrss = ru2->ru_maxrss;
318: ip = &ru->ru_first; ip2 = &ru2->ru_first;
319: for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
320: *ip++ += *ip2++;
321: }
322:
323: /*
324: * Make a copy of the plimit structure.
325: * We share these structures copy-on-write after fork,
326: * and copy when a limit is changed.
327: */
328: struct plimit *
329: limcopy(lim)
330: struct plimit *lim;
331: {
332: register struct plimit *copy;
333:
334: MALLOC(copy, struct plimit *, sizeof(struct plimit),
335: M_SUBPROC, M_WAITOK);
336: bcopy(lim->pl_rlimit, copy->pl_rlimit,
337: sizeof(struct rlimit) * RLIM_NLIMITS);
338: copy->p_lflags = 0;
339: copy->p_refcnt = 1;
340: return (copy);
341: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.