Import 2.1.116pre2
[davej-history.git] / kernel / sys.c
blob1b4c6df403524f54ef2cc2cd7626f5504c053190
1 /*
2 * linux/kernel/sys.c
4 * Copyright (C) 1991, 1992 Linus Torvalds
5 */
7 #include <linux/errno.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/times.h>
11 #include <linux/utsname.h>
12 #include <linux/param.h>
13 #include <linux/resource.h>
14 #include <linux/signal.h>
15 #include <linux/string.h>
16 #include <linux/ptrace.h>
17 #include <linux/stat.h>
18 #include <linux/mman.h>
19 #include <linux/mm.h>
20 #include <linux/fcntl.h>
21 #include <linux/tty.h>
22 #include <linux/smp.h>
23 #include <linux/smp_lock.h>
24 #include <linux/notifier.h>
25 #include <linux/reboot.h>
26 #include <linux/prctl.h>
28 #include <asm/uaccess.h>
29 #include <asm/io.h>
32 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
35 int C_A_D = 1;
39 * Notifier list for kernel code which wants to be called
40 * at shutdown. This is used to stop any idling DMA operations
41 * and the like.
44 struct notifier_block *reboot_notifier_list = NULL;
46 int register_reboot_notifier(struct notifier_block * nb)
48 return notifier_chain_register(&reboot_notifier_list, nb);
51 int unregister_reboot_notifier(struct notifier_block * nb)
53 return notifier_chain_unregister(&reboot_notifier_list, nb);
58 extern void adjust_clock(void);
60 asmlinkage int sys_ni_syscall(void)
62 return -ENOSYS;
65 static int proc_sel(struct task_struct *p, int which, int who)
67 if(p->pid)
69 switch (which) {
70 case PRIO_PROCESS:
71 if (!who && p == current)
72 return 1;
73 return(p->pid == who);
74 case PRIO_PGRP:
75 if (!who)
76 who = current->pgrp;
77 return(p->pgrp == who);
78 case PRIO_USER:
79 if (!who)
80 who = current->uid;
81 return(p->uid == who);
84 return 0;
87 asmlinkage int sys_setpriority(int which, int who, int niceval)
89 struct task_struct *p;
90 unsigned int priority;
91 int error;
93 if (which > 2 || which < 0)
94 return -EINVAL;
96 /* normalize: avoid signed division (rounding problems) */
97 error = ESRCH;
98 priority = niceval;
99 if (niceval < 0)
100 priority = -niceval;
101 if (priority > 20)
102 priority = 20;
103 priority = (priority * DEF_PRIORITY + 10) / 20 + DEF_PRIORITY;
105 if (niceval >= 0) {
106 priority = 2*DEF_PRIORITY - priority;
107 if (!priority)
108 priority = 1;
111 read_lock(&tasklist_lock);
112 for_each_task(p) {
113 if (!proc_sel(p, which, who))
114 continue;
115 if (p->uid != current->euid &&
116 p->uid != current->uid && !capable(CAP_SYS_NICE)) {
117 error = EPERM;
118 continue;
120 if (error == ESRCH)
121 error = 0;
122 if (priority > p->priority && !capable(CAP_SYS_NICE))
123 error = EACCES;
124 else
125 p->priority = priority;
127 read_unlock(&tasklist_lock);
129 return -error;
133 * Ugh. To avoid negative return values, "getpriority()" will
134 * not return the normal nice-value, but a value that has been
135 * offset by 20 (ie it returns 0..40 instead of -20..20)
137 asmlinkage int sys_getpriority(int which, int who)
139 struct task_struct *p;
140 long max_prio = -ESRCH;
142 if (which > 2 || which < 0)
143 return -EINVAL;
145 read_lock(&tasklist_lock);
146 for_each_task (p) {
147 if (!proc_sel(p, which, who))
148 continue;
149 if (p->priority > max_prio)
150 max_prio = p->priority;
152 read_unlock(&tasklist_lock);
154 /* scale the priority from timeslice to 0..40 */
155 if (max_prio > 0)
156 max_prio = (max_prio * 20 + DEF_PRIORITY/2) / DEF_PRIORITY;
157 return max_prio;
162 * Reboot system call: for obvious reasons only root may call it,
163 * and even root needs to set up some magic numbers in the registers
164 * so that some mistake won't make this reboot the whole machine.
165 * You can also set the meaning of the ctrl-alt-del-key here.
167 * reboot doesn't sync: do that yourself before calling this.
169 asmlinkage int sys_reboot(int magic1, int magic2, int cmd, void * arg)
171 char buffer[256];
173 /* We only trust the superuser with rebooting the system. */
174 if (!capable(CAP_SYS_BOOT))
175 return -EPERM;
177 /* For safety, we require "magic" arguments. */
178 if (magic1 != LINUX_REBOOT_MAGIC1 ||
179 (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
180 magic2 != LINUX_REBOOT_MAGIC2B))
181 return -EINVAL;
183 lock_kernel();
184 switch (cmd) {
185 case LINUX_REBOOT_CMD_RESTART:
186 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
187 printk(KERN_EMERG "Restarting system.\n");
188 machine_restart(NULL);
189 break;
191 case LINUX_REBOOT_CMD_CAD_ON:
192 C_A_D = 1;
193 break;
195 case LINUX_REBOOT_CMD_CAD_OFF:
196 C_A_D = 0;
197 break;
199 case LINUX_REBOOT_CMD_HALT:
200 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
201 printk(KERN_EMERG "System halted.\n");
202 machine_halt();
203 do_exit(0);
204 break;
206 case LINUX_REBOOT_CMD_POWER_OFF:
207 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
208 printk(KERN_EMERG "Power down.\n");
209 machine_power_off();
210 do_exit(0);
211 break;
213 case LINUX_REBOOT_CMD_RESTART2:
214 if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0) {
215 unlock_kernel();
216 return -EFAULT;
218 buffer[sizeof(buffer) - 1] = '\0';
220 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
221 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
222 machine_restart(buffer);
223 break;
225 default:
226 unlock_kernel();
227 return -EINVAL;
228 break;
230 unlock_kernel();
231 return 0;
235 * This function gets called by ctrl-alt-del - ie the keyboard interrupt.
236 * As it's called within an interrupt, it may NOT sync: the only choice
237 * is whether to reboot at once, or just ignore the ctrl-alt-del.
239 void ctrl_alt_del(void)
241 if (C_A_D) {
242 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
243 machine_restart(NULL);
244 } else
245 kill_proc(1, SIGINT, 1);
250 * Unprivileged users may change the real gid to the effective gid
251 * or vice versa. (BSD-style)
253 * If you set the real gid at all, or set the effective gid to a value not
254 * equal to the real gid, then the saved gid is set to the new effective gid.
256 * This makes it possible for a setgid program to completely drop its
257 * privileges, which is often a useful assertion to make when you are doing
258 * a security audit over a program.
260 * The general idea is that a program which uses just setregid() will be
261 * 100% compatible with BSD. A program which uses just setgid() will be
262 * 100% compatible with POSIX with saved IDs.
264 * SMP: There are not races, the GIDs are checked only by filesystem
265 * operations (as far as semantic preservation is concerned).
267 asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
269 int old_rgid = current->gid;
270 int old_egid = current->egid;
272 if (rgid != (gid_t) -1) {
273 if ((old_rgid == rgid) ||
274 (current->egid==rgid) ||
275 capable(CAP_SETGID))
276 current->gid = rgid;
277 else
278 return -EPERM;
280 if (egid != (gid_t) -1) {
281 if ((old_rgid == egid) ||
282 (current->egid == egid) ||
283 (current->sgid == egid) ||
284 capable(CAP_SETGID))
285 current->fsgid = current->egid = egid;
286 else {
287 current->gid = old_rgid;
288 return -EPERM;
291 if (rgid != (gid_t) -1 ||
292 (egid != (gid_t) -1 && egid != old_rgid))
293 current->sgid = current->egid;
294 current->fsgid = current->egid;
295 if (current->egid != old_egid)
296 current->dumpable = 0;
297 return 0;
301 * setgid() is implemented like SysV w/ SAVED_IDS
303 * SMP: Same implicit races as above.
305 asmlinkage int sys_setgid(gid_t gid)
307 int old_egid = current->egid;
309 if (capable(CAP_SETGID))
310 current->gid = current->egid = current->sgid = current->fsgid = gid;
311 else if ((gid == current->gid) || (gid == current->sgid))
312 current->egid = current->fsgid = gid;
313 else
314 return -EPERM;
316 if (current->egid != old_egid)
317 current->dumpable = 0;
318 return 0;
322 * cap_emulate_setxuid() fixes the effective / permitted capabilities of
323 * a process after a call to setuid, setreuid, or setresuid.
325 * 1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
326 * {r,e,s}uid != 0, the permitted and effective capabilities are
327 * cleared.
329 * 2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
330 * capabilities of the process are cleared.
332 * 3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
333 * capabilities are set to the permitted capabilities.
335 * fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should
336 * never happen.
338 * -astor
340 extern inline void cap_emulate_setxuid(int old_ruid, int old_euid,
341 int old_suid)
343 if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
344 (current->uid != 0 && current->euid != 0 && current->suid != 0)) {
345 cap_clear(current->cap_permitted);
346 cap_clear(current->cap_effective);
348 if (old_euid == 0 && current->euid != 0) {
349 cap_clear(current->cap_effective);
351 if (old_euid != 0 && current->euid == 0) {
352 current->cap_effective = current->cap_permitted;
357 * Unprivileged users may change the real uid to the effective uid
358 * or vice versa. (BSD-style)
360 * If you set the real uid at all, or set the effective uid to a value not
361 * equal to the real uid, then the saved uid is set to the new effective uid.
363 * This makes it possible for a setuid program to completely drop its
364 * privileges, which is often a useful assertion to make when you are doing
365 * a security audit over a program.
367 * The general idea is that a program which uses just setreuid() will be
368 * 100% compatible with BSD. A program which uses just setuid() will be
369 * 100% compatible with POSIX with saved IDs.
371 asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
373 int old_ruid, old_euid, old_suid, new_ruid;
375 new_ruid = old_ruid = current->uid;
376 old_euid = current->euid;
377 old_suid = current->suid;
378 if (ruid != (uid_t) -1) {
379 if ((old_ruid == ruid) ||
380 (current->euid==ruid) ||
381 capable(CAP_SETUID))
382 new_ruid = ruid;
383 else
384 return -EPERM;
386 if (euid != (uid_t) -1) {
387 if ((old_ruid == euid) ||
388 (current->euid == euid) ||
389 (current->suid == euid) ||
390 capable(CAP_SETUID))
391 current->fsuid = current->euid = euid;
392 else
393 return -EPERM;
395 if (ruid != (uid_t) -1 ||
396 (euid != (uid_t) -1 && euid != old_ruid))
397 current->suid = current->euid;
398 current->fsuid = current->euid;
399 if (current->euid != old_euid)
400 current->dumpable = 0;
402 if(new_ruid != old_ruid) {
403 /* What if a process setreuid()'s and this brings the
404 * new uid over his NPROC rlimit? We can check this now
405 * cheaply with the new uid cache, so if it matters
406 * we should be checking for it. -DaveM
408 free_uid(current);
409 current->uid = new_ruid;
410 alloc_uid(current);
413 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
414 cap_emulate_setxuid(old_ruid, old_euid, old_suid);
417 return 0;
423 * setuid() is implemented like SysV with SAVED_IDS
425 * Note that SAVED_ID's is deficient in that a setuid root program
426 * like sendmail, for example, cannot set its uid to be a normal
427 * user and then switch back, because if you're root, setuid() sets
428 * the saved uid too. If you don't like this, blame the bright people
429 * in the POSIX committee and/or USG. Note that the BSD-style setreuid()
430 * will allow a root program to temporarily drop privileges and be able to
431 * regain them by swapping the real and effective uid.
433 asmlinkage int sys_setuid(uid_t uid)
435 int old_euid = current->euid;
436 int old_ruid, old_suid, new_ruid;
438 old_ruid = new_ruid = current->uid;
439 old_suid = current->suid;
440 if (capable(CAP_SETUID))
441 new_ruid = current->euid = current->suid = current->fsuid = uid;
442 else if ((uid == current->uid) || (uid == current->suid))
443 current->fsuid = current->euid = uid;
444 else
445 return -EPERM;
447 if (current->euid != old_euid)
448 current->dumpable = 0;
450 if (new_ruid != old_ruid) {
451 /* See comment above about NPROC rlimit issues... */
452 free_uid(current);
453 current->uid = new_ruid;
454 alloc_uid(current);
457 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
458 cap_emulate_setxuid(old_ruid, old_euid, old_suid);
461 return 0;
466 * This function implements a generic ability to update ruid, euid,
467 * and suid. This allows you to implement the 4.4 compatible seteuid().
469 asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
471 int old_ruid = current->uid;
472 int old_euid = current->euid;
473 int old_suid = current->suid;
475 if (!capable(CAP_SETUID)) {
476 if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
477 (ruid != current->euid) && (ruid != current->suid))
478 return -EPERM;
479 if ((euid != (uid_t) -1) && (euid != current->uid) &&
480 (euid != current->euid) && (euid != current->suid))
481 return -EPERM;
482 if ((suid != (uid_t) -1) && (suid != current->uid) &&
483 (suid != current->euid) && (suid != current->suid))
484 return -EPERM;
486 if (ruid != (uid_t) -1) {
487 /* See above commentary about NPROC rlimit issues here. */
488 free_uid(current);
489 current->uid = ruid;
490 alloc_uid(current);
492 if (euid != (uid_t) -1) {
493 if (euid != current->euid)
494 current->dumpable = 0;
495 current->euid = euid;
496 current->fsuid = euid;
498 if (suid != (uid_t) -1)
499 current->suid = suid;
501 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
502 cap_emulate_setxuid(old_ruid, old_euid, old_suid);
505 return 0;
508 asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
510 int retval;
512 if (!(retval = put_user(current->uid, ruid)) &&
513 !(retval = put_user(current->euid, euid)))
514 retval = put_user(current->suid, suid);
516 return retval;
520 * Same as above, but for rgid, egid, sgid.
522 asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
524 if (!capable(CAP_SETGID)) {
525 if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
526 (rgid != current->egid) && (rgid != current->sgid))
527 return -EPERM;
528 if ((egid != (gid_t) -1) && (egid != current->gid) &&
529 (egid != current->egid) && (egid != current->sgid))
530 return -EPERM;
531 if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
532 (sgid != current->egid) && (sgid != current->sgid))
533 return -EPERM;
535 if (rgid != (gid_t) -1)
536 current->gid = rgid;
537 if (egid != (gid_t) -1) {
538 if (egid != current->egid)
539 current->dumpable = 0;
540 current->egid = egid;
541 current->fsgid = egid;
543 if (sgid != (gid_t) -1)
544 current->sgid = sgid;
545 return 0;
548 asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
550 int retval;
552 if (!(retval = put_user(current->gid, rgid)) &&
553 !(retval = put_user(current->egid, egid)))
554 retval = put_user(current->sgid, sgid);
556 return retval;
561 * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
562 * is used for "access()" and for the NFS daemon (letting nfsd stay at
563 * whatever uid it wants to). It normally shadows "euid", except when
564 * explicitly set by setfsuid() or for access..
566 asmlinkage int sys_setfsuid(uid_t uid)
568 int old_fsuid;
570 old_fsuid = current->fsuid;
571 if (uid == current->uid || uid == current->euid ||
572 uid == current->suid || uid == current->fsuid ||
573 capable(CAP_SETUID))
574 current->fsuid = uid;
575 if (current->fsuid != old_fsuid)
576 current->dumpable = 0;
578 /* We emulate fsuid by essentially doing a scaled-down version
579 * of what we did in setresuid and friends. However, we only
580 * operate on the fs-specific bits of the process' effective
581 * capabilities
583 * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
584 * if not, we might be a bit too harsh here.
587 if (!issecure(SECURE_NO_SETUID_FIXUP)) {
588 if (old_fsuid == 0 && current->fsuid != 0) {
589 current->cap_effective.cap &= ~CAP_FS_MASK;
591 if (old_fsuid != 0 && current->fsuid == 0) {
592 current->cap_effective.cap |=
593 (current->cap_permitted.cap & CAP_FS_MASK);
597 return old_fsuid;
601 * Samma på svenska..
603 asmlinkage int sys_setfsgid(gid_t gid)
605 int old_fsgid;
607 old_fsgid = current->fsgid;
608 if (gid == current->gid || gid == current->egid ||
609 gid == current->sgid || gid == current->fsgid ||
610 capable(CAP_SETGID))
611 current->fsgid = gid;
612 if (current->fsgid != old_fsgid)
613 current->dumpable = 0;
615 return old_fsgid;
618 asmlinkage long sys_times(struct tms * tbuf)
621 * In the SMP world we might just be unlucky and have one of
622 * the times increment as we use it. Since the value is an
623 * atomically safe type this is just fine. Conceptually its
624 * as if the syscall took an instant longer to occur.
626 if (tbuf)
627 if (copy_to_user(tbuf, &current->times, sizeof(struct tms)))
628 return -EFAULT;
629 return jiffies;
633 * This needs some heavy checking ...
634 * I just haven't the stomach for it. I also don't fully
635 * understand sessions/pgrp etc. Let somebody who does explain it.
637 * OK, I think I have the protection semantics right.... this is really
638 * only important on a multi-user system anyway, to make sure one user
639 * can't send a signal to a process owned by another. -TYT, 12/12/91
641 * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
642 * LBT 04.03.94
645 asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
647 struct task_struct * p;
648 int err = -EINVAL;
650 if (!pid)
651 pid = current->pid;
652 if (!pgid)
653 pgid = pid;
654 if (pgid < 0)
655 return -EINVAL;
657 /* From this point forward we keep holding onto the tasklist lock
658 * so that our parent does not change from under us. -DaveM
660 read_lock(&tasklist_lock);
662 err = -ESRCH;
663 p = find_task_by_pid(pid);
664 if (!p)
665 goto out;
667 if (p->p_pptr == current || p->p_opptr == current) {
668 err = -EPERM;
669 if (p->session != current->session)
670 goto out;
671 err = -EACCES;
672 if (p->did_exec)
673 goto out;
674 } else if (p != current)
675 goto out;
676 err = -EPERM;
677 if (p->leader)
678 goto out;
679 if (pgid != pid) {
680 struct task_struct * tmp;
681 for_each_task (tmp) {
682 if (tmp->pgrp == pgid &&
683 tmp->session == current->session)
684 goto ok_pgid;
686 goto out;
689 ok_pgid:
690 p->pgrp = pgid;
691 err = 0;
692 out:
693 /* All paths lead to here, thus we are safe. -DaveM */
694 read_unlock(&tasklist_lock);
695 return err;
698 asmlinkage int sys_getpgid(pid_t pid)
700 if (!pid) {
701 return current->pgrp;
702 } else {
703 int retval;
704 struct task_struct *p;
706 read_lock(&tasklist_lock);
707 p = find_task_by_pid(pid);
709 retval = -ESRCH;
710 if (p)
711 retval = p->pgrp;
712 read_unlock(&tasklist_lock);
713 return retval;
717 asmlinkage int sys_getpgrp(void)
719 /* SMP - assuming writes are word atomic this is fine */
720 return current->pgrp;
723 asmlinkage int sys_getsid(pid_t pid)
725 if (!pid) {
726 return current->session;
727 } else {
728 int retval;
729 struct task_struct *p;
731 read_lock(&tasklist_lock);
732 p = find_task_by_pid(pid);
734 retval = -ESRCH;
735 if(p)
736 retval = p->session;
737 read_unlock(&tasklist_lock);
738 return retval;
742 asmlinkage int sys_setsid(void)
744 struct task_struct * p;
745 int err = -EPERM;
747 read_lock(&tasklist_lock);
748 for_each_task(p) {
749 if (p->pgrp == current->pid)
750 goto out;
753 current->leader = 1;
754 current->session = current->pgrp = current->pid;
755 current->tty = NULL;
756 current->tty_old_pgrp = 0;
757 err = current->pgrp;
758 out:
759 read_unlock(&tasklist_lock);
760 return err;
764 * Supplementary group IDs
766 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
768 int i;
771 * SMP: Nobody else can change our grouplist. Thus we are
772 * safe.
775 if (gidsetsize < 0)
776 return -EINVAL;
777 i = current->ngroups;
778 if (gidsetsize) {
779 if (i > gidsetsize)
780 return -EINVAL;
781 if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
782 return -EFAULT;
784 return i;
788 * SMP: Our groups are not shared. We can copy to/from them safely
789 * without another task interfering.
792 asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
794 if (!capable(CAP_SETGID))
795 return -EPERM;
796 if ((unsigned) gidsetsize > NGROUPS)
797 return -EINVAL;
798 if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
799 return -EFAULT;
800 current->ngroups = gidsetsize;
801 return 0;
804 int in_group_p(gid_t grp)
806 if (grp != current->fsgid) {
807 int i = current->ngroups;
808 if (i) {
809 gid_t *groups = current->groups;
810 do {
811 if (*groups == grp)
812 goto out;
813 groups++;
814 i--;
815 } while (i);
817 return 0;
819 out:
820 return 1;
824 * This should really be a blocking read-write lock
825 * rather than a semaphore. Anybody want to implement
826 * one?
828 struct semaphore uts_sem = MUTEX;
830 asmlinkage int sys_newuname(struct new_utsname * name)
832 int errno = 0;
834 down(&uts_sem);
835 if (copy_to_user(name,&system_utsname,sizeof *name))
836 errno = -EFAULT;
837 up(&uts_sem);
838 return errno;
841 asmlinkage int sys_sethostname(char *name, int len)
843 int errno;
845 if (!capable(CAP_SYS_ADMIN))
846 return -EPERM;
847 if (len < 0 || len > __NEW_UTS_LEN)
848 return -EINVAL;
849 down(&uts_sem);
850 errno = -EFAULT;
851 if (!copy_from_user(system_utsname.nodename, name, len)) {
852 system_utsname.nodename[len] = 0;
853 errno = 0;
855 up(&uts_sem);
856 return errno;
859 asmlinkage int sys_gethostname(char *name, int len)
861 int i, errno;
863 if (len < 0)
864 return -EINVAL;
865 down(&uts_sem);
866 i = 1 + strlen(system_utsname.nodename);
867 if (i > len)
868 i = len;
869 errno = 0;
870 if (copy_to_user(name, system_utsname.nodename, i))
871 errno = -EFAULT;
872 up(&uts_sem);
873 return errno;
877 * Only setdomainname; getdomainname can be implemented by calling
878 * uname()
880 asmlinkage int sys_setdomainname(char *name, int len)
882 int errno;
884 if (!capable(CAP_SYS_ADMIN))
885 return -EPERM;
886 if (len < 0 || len > __NEW_UTS_LEN)
887 return -EINVAL;
889 down(&uts_sem);
890 errno = -EFAULT;
891 if (!copy_from_user(system_utsname.domainname, name, len)) {
892 errno = 0;
893 system_utsname.domainname[len] = 0;
895 up(&uts_sem);
896 return errno;
899 asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
901 if (resource >= RLIM_NLIMITS)
902 return -EINVAL;
903 else
904 return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
905 ? -EFAULT : 0;
908 asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
910 struct rlimit new_rlim, *old_rlim;
912 if (resource >= RLIM_NLIMITS)
913 return -EINVAL;
914 if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
915 return -EFAULT;
916 old_rlim = current->rlim + resource;
917 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
918 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
919 !capable(CAP_SYS_RESOURCE))
920 return -EPERM;
921 if (resource == RLIMIT_NOFILE) {
922 if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
923 return -EPERM;
925 *old_rlim = new_rlim;
926 return 0;
930 * It would make sense to put struct rusage in the task_struct,
931 * except that would make the task_struct be *really big*. After
932 * task_struct gets moved into malloc'ed memory, it would
933 * make sense to do this. It will make moving the rest of the information
934 * a lot simpler! (Which we're not doing right now because we're not
935 * measuring them yet).
937 * This is SMP safe. Either we are called from sys_getrusage on ourselves
938 * below (we know we aren't going to exit/disappear and only we change our
939 * rusage counters), or we are called from wait4() on a process which is
940 * either stopped or zombied. In the zombied case the task won't get
941 * reaped till shortly after the call to getrusage(), in both cases the
942 * task being examined is in a frozen state so the counters won't change.
944 int getrusage(struct task_struct *p, int who, struct rusage *ru)
946 struct rusage r;
948 memset((char *) &r, 0, sizeof(r));
949 switch (who) {
950 case RUSAGE_SELF:
951 r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime);
952 r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime);
953 r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime);
954 r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime);
955 r.ru_minflt = p->min_flt;
956 r.ru_majflt = p->maj_flt;
957 r.ru_nswap = p->nswap;
958 break;
959 case RUSAGE_CHILDREN:
960 r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime);
961 r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_cutime);
962 r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_cstime);
963 r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_cstime);
964 r.ru_minflt = p->cmin_flt;
965 r.ru_majflt = p->cmaj_flt;
966 r.ru_nswap = p->cnswap;
967 break;
968 default:
969 r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime);
970 r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime + p->times.tms_cutime);
971 r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime);
972 r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime);
973 r.ru_minflt = p->min_flt + p->cmin_flt;
974 r.ru_majflt = p->maj_flt + p->cmaj_flt;
975 r.ru_nswap = p->nswap + p->cnswap;
976 break;
978 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
981 asmlinkage int sys_getrusage(int who, struct rusage *ru)
983 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
984 return -EINVAL;
985 return getrusage(current, who, ru);
988 asmlinkage int sys_umask(int mask)
990 mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
991 return mask;
994 asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
995 unsigned long arg4, unsigned long arg5)
997 int error = 0;
998 int sig;
1000 switch (option) {
1001 case PR_SET_PDEATHSIG:
1002 sig = arg2;
1003 if (sig > _NSIG) {
1004 error = -EINVAL;
1005 break;
1007 current->pdeath_signal = sig;
1008 break;
1009 default:
1010 error = -EINVAL;
1011 break;
1013 return error;