|
|
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;
234:
235: if (alim.rlim_cur > alimp->rlim_cur) {
236: prot = VM_PROT_ALL;
237: size = alim.rlim_cur - alimp->rlim_cur;
238: addr = USRSTACK - alim.rlim_cur;
239: } else {
240: prot = VM_PROT_NONE;
241: size = alimp->rlim_cur - alim.rlim_cur;
242: addr = USRSTACK - alimp->rlim_cur;
243: }
244: addr = trunc_page(addr);
245: size = round_page(size);
246: (void) vm_map_protect(&p->p_vmspace->vm_map,
247: addr, addr+size, prot, FALSE);
248: }
249: break;
250: }
251: p->p_rlimit[uap->which] = alim;
252: return (0);
253: }
254:
255: /* ARGSUSED */
256: getrlimit(p, uap, retval)
257: struct proc *p;
258: register struct args {
259: u_int which;
260: struct rlimit *rlp;
261: } *uap;
262: int *retval;
263: {
264:
265: if (uap->which >= RLIM_NLIMITS)
266: return (EINVAL);
267: return (copyout((caddr_t)&p->p_rlimit[uap->which], (caddr_t)uap->rlp,
268: sizeof (struct rlimit)));
269: }
270:
271: /* ARGSUSED */
272: getrusage(p, uap, retval)
273: register struct proc *p;
274: register struct args {
275: int who;
276: struct rusage *rusage;
277: } *uap;
278: int *retval;
279: {
280: register struct rusage *rup;
281:
282: switch (uap->who) {
283:
284: case RUSAGE_SELF: {
285: int s;
286:
287: rup = &p->p_stats->p_ru;
288: s = splclock();
289: rup->ru_stime = p->p_stime;
290: rup->ru_utime = p->p_utime;
291: splx(s);
292: break;
293: }
294:
295: case RUSAGE_CHILDREN:
296: rup = &p->p_stats->p_cru;
297: break;
298:
299: default:
300: return (EINVAL);
301: }
302: return (copyout((caddr_t)rup, (caddr_t)uap->rusage,
303: sizeof (struct rusage)));
304: }
305:
306: ruadd(ru, ru2)
307: register struct rusage *ru, *ru2;
308: {
309: register long *ip, *ip2;
310: register int i;
311:
312: timevaladd(&ru->ru_utime, &ru2->ru_utime);
313: timevaladd(&ru->ru_stime, &ru2->ru_stime);
314: if (ru->ru_maxrss < ru2->ru_maxrss)
315: ru->ru_maxrss = ru2->ru_maxrss;
316: ip = &ru->ru_first; ip2 = &ru2->ru_first;
317: for (i = &ru->ru_last - &ru->ru_first; i > 0; i--)
318: *ip++ += *ip2++;
319: }
320:
321: /*
322: * Make a copy of the plimit structure.
323: * We share these structures copy-on-write after fork,
324: * and copy when a limit is changed.
325: */
326: struct plimit *
327: limcopy(lim)
328: struct plimit *lim;
329: {
330: register struct plimit *copy;
331:
332: MALLOC(copy, struct plimit *, sizeof(struct plimit),
333: M_SUBPROC, M_WAITOK);
334: bcopy(lim->pl_rlimit, copy->pl_rlimit,
335: sizeof(struct rlimit) * RLIM_NLIMITS);
336: copy->p_lflags = 0;
337: copy->p_refcnt = 1;
338: return (copy);
339: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.