4 * Copyright (C) 1991, 1992 Linus Torvalds
8 #include <linux/utsname.h>
9 #include <linux/mman.h>
10 #include <linux/smp_lock.h>
11 #include <linux/notifier.h>
12 #include <linux/reboot.h>
13 #include <linux/prctl.h>
14 #include <linux/init.h>
15 #include <linux/highuid.h>
17 #include <asm/uaccess.h>
21 * this is where the system-wide overflow UID and GID are defined, for
22 * architectures that now have 32-bit UID/GID but didn't in the past
25 int overflowuid
= DEFAULT_OVERFLOWUID
;
26 int overflowgid
= DEFAULT_OVERFLOWGID
;
29 * the same as above, but for filesystems which can only store a 16-bit
30 * UID and GID. as such, this is needed on all architectures
33 int fs_overflowuid
= DEFAULT_FS_OVERFLOWUID
;
34 int fs_overflowgid
= DEFAULT_FS_OVERFLOWUID
;
37 * this indicates whether you can reboot with ctrl-alt-del: the default is yes
44 * Notifier list for kernel code which wants to be called
45 * at shutdown. This is used to stop any idling DMA operations
49 struct notifier_block
*reboot_notifier_list
= NULL
;
51 int register_reboot_notifier(struct notifier_block
* nb
)
53 return notifier_chain_register(&reboot_notifier_list
, nb
);
56 int unregister_reboot_notifier(struct notifier_block
* nb
)
58 return notifier_chain_unregister(&reboot_notifier_list
, nb
);
61 asmlinkage
long sys_ni_syscall(void)
66 static int proc_sel(struct task_struct
*p
, int which
, int who
)
72 if (!who
&& p
== current
)
74 return(p
->pid
== who
);
78 return(p
->pgrp
== who
);
82 return(p
->uid
== who
);
88 asmlinkage
long sys_setpriority(int which
, int who
, int niceval
)
90 struct task_struct
*p
;
91 unsigned int priority
;
94 if (which
> 2 || which
< 0)
97 /* normalize: avoid signed division (rounding problems) */
104 priority
= (priority
* DEF_PRIORITY
+ 10) / 20 + DEF_PRIORITY
;
107 priority
= 2*DEF_PRIORITY
- priority
;
112 read_lock(&tasklist_lock
);
114 if (!proc_sel(p
, which
, who
))
116 if (p
->uid
!= current
->euid
&&
117 p
->uid
!= current
->uid
&& !capable(CAP_SYS_NICE
)) {
123 if (priority
> p
->priority
&& !capable(CAP_SYS_NICE
))
126 p
->priority
= priority
;
128 read_unlock(&tasklist_lock
);
134 * Ugh. To avoid negative return values, "getpriority()" will
135 * not return the normal nice-value, but a value that has been
136 * offset by 20 (ie it returns 0..40 instead of -20..20)
138 asmlinkage
long sys_getpriority(int which
, int who
)
140 struct task_struct
*p
;
141 long max_prio
= -ESRCH
;
143 if (which
> 2 || which
< 0)
146 read_lock(&tasklist_lock
);
148 if (!proc_sel(p
, which
, who
))
150 if (p
->priority
> max_prio
)
151 max_prio
= p
->priority
;
153 read_unlock(&tasklist_lock
);
155 /* scale the priority from timeslice to 0..40 */
157 max_prio
= (max_prio
* 20 + DEF_PRIORITY
/2) / DEF_PRIORITY
;
163 * Reboot system call: for obvious reasons only root may call it,
164 * and even root needs to set up some magic numbers in the registers
165 * so that some mistake won't make this reboot the whole machine.
166 * You can also set the meaning of the ctrl-alt-del-key here.
168 * reboot doesn't sync: do that yourself before calling this.
170 asmlinkage
long sys_reboot(int magic1
, int magic2
, int cmd
, void * arg
)
174 /* We only trust the superuser with rebooting the system. */
175 if (!capable(CAP_SYS_BOOT
))
178 /* For safety, we require "magic" arguments. */
179 if (magic1
!= LINUX_REBOOT_MAGIC1
||
180 (magic2
!= LINUX_REBOOT_MAGIC2
&& magic2
!= LINUX_REBOOT_MAGIC2A
&&
181 magic2
!= LINUX_REBOOT_MAGIC2B
))
186 case LINUX_REBOOT_CMD_RESTART
:
187 notifier_call_chain(&reboot_notifier_list
, SYS_RESTART
, NULL
);
188 printk(KERN_EMERG
"Restarting system.\n");
189 machine_restart(NULL
);
192 case LINUX_REBOOT_CMD_CAD_ON
:
196 case LINUX_REBOOT_CMD_CAD_OFF
:
200 case LINUX_REBOOT_CMD_HALT
:
201 notifier_call_chain(&reboot_notifier_list
, SYS_HALT
, NULL
);
202 printk(KERN_EMERG
"System halted.\n");
207 case LINUX_REBOOT_CMD_POWER_OFF
:
208 notifier_call_chain(&reboot_notifier_list
, SYS_POWER_OFF
, NULL
);
209 printk(KERN_EMERG
"Power down.\n");
214 case LINUX_REBOOT_CMD_RESTART2
:
215 if (strncpy_from_user(&buffer
[0], (char *)arg
, sizeof(buffer
) - 1) < 0) {
219 buffer
[sizeof(buffer
) - 1] = '\0';
221 notifier_call_chain(&reboot_notifier_list
, SYS_RESTART
, buffer
);
222 printk(KERN_EMERG
"Restarting system with command '%s'.\n", buffer
);
223 machine_restart(buffer
);
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)
242 notifier_call_chain(&reboot_notifier_list
, SYS_RESTART
, NULL
);
243 machine_restart(NULL
);
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
long 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
) ||
280 if (egid
!= (gid_t
) -1) {
281 if ((old_rgid
== egid
) ||
282 (current
->egid
== egid
) ||
283 (current
->sgid
== egid
) ||
285 current
->fsgid
= current
->egid
= egid
;
287 current
->gid
= old_rgid
;
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;
301 * setgid() is implemented like SysV w/ SAVED_IDS
303 * SMP: Same implicit races as above.
305 asmlinkage
long 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
;
316 if (current
->egid
!= old_egid
)
317 current
->dumpable
= 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
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
340 extern inline void cap_emulate_setxuid(int old_ruid
, int old_euid
,
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
long 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
) ||
386 if (euid
!= (uid_t
) -1) {
387 if ((old_ruid
== euid
) ||
388 (current
->euid
== euid
) ||
389 (current
->suid
== euid
) ||
391 current
->fsuid
= current
->euid
= euid
;
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
409 current
->uid
= new_ruid
;
413 if (!issecure(SECURE_NO_SETUID_FIXUP
)) {
414 cap_emulate_setxuid(old_ruid
, old_euid
, old_suid
);
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
long 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
;
447 if (current
->euid
!= old_euid
)
448 current
->dumpable
= 0;
450 if (new_ruid
!= old_ruid
) {
451 /* See comment above about NPROC rlimit issues... */
453 current
->uid
= new_ruid
;
457 if (!issecure(SECURE_NO_SETUID_FIXUP
)) {
458 cap_emulate_setxuid(old_ruid
, old_euid
, old_suid
);
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
long 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
))
479 if ((euid
!= (uid_t
) -1) && (euid
!= current
->uid
) &&
480 (euid
!= current
->euid
) && (euid
!= current
->suid
))
482 if ((suid
!= (uid_t
) -1) && (suid
!= current
->uid
) &&
483 (suid
!= current
->euid
) && (suid
!= current
->suid
))
486 if (ruid
!= (uid_t
) -1) {
487 /* See above commentary about NPROC rlimit issues here. */
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
);
508 asmlinkage
long sys_getresuid(uid_t
*ruid
, uid_t
*euid
, uid_t
*suid
)
512 if (!(retval
= put_user(current
->uid
, ruid
)) &&
513 !(retval
= put_user(current
->euid
, euid
)))
514 retval
= put_user(current
->suid
, suid
);
520 * Same as above, but for rgid, egid, sgid.
522 asmlinkage
long 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
))
528 if ((egid
!= (gid_t
) -1) && (egid
!= current
->gid
) &&
529 (egid
!= current
->egid
) && (egid
!= current
->sgid
))
531 if ((sgid
!= (gid_t
) -1) && (sgid
!= current
->gid
) &&
532 (sgid
!= current
->egid
) && (sgid
!= current
->sgid
))
535 if (rgid
!= (gid_t
) -1)
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
;
548 asmlinkage
long sys_getresgid(gid_t
*rgid
, gid_t
*egid
, gid_t
*sgid
)
552 if (!(retval
= put_user(current
->gid
, rgid
)) &&
553 !(retval
= put_user(current
->egid
, egid
)))
554 retval
= put_user(current
->sgid
, sgid
);
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
long sys_setfsuid(uid_t uid
)
570 old_fsuid
= current
->fsuid
;
571 if (uid
== current
->uid
|| uid
== current
->euid
||
572 uid
== current
->suid
|| uid
== current
->fsuid
||
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
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 cap_t(current
->cap_effective
) &= ~CAP_FS_MASK
;
591 if (old_fsuid
!= 0 && current
->fsuid
== 0) {
592 cap_t(current
->cap_effective
) |=
593 (cap_t(current
->cap_permitted
) & CAP_FS_MASK
);
601 * Samma på svenska..
603 asmlinkage
long sys_setfsgid(gid_t gid
)
607 old_fsgid
= current
->fsgid
;
608 if (gid
== current
->gid
|| gid
== current
->egid
||
609 gid
== current
->sgid
|| gid
== current
->fsgid
||
611 current
->fsgid
= gid
;
612 if (current
->fsgid
!= old_fsgid
)
613 current
->dumpable
= 0;
618 asmlinkage
long sys_times(struct tms
* tbuf
)
623 * In the SMP world we might just be unlucky and have one of
624 * the times increment as we use it. Since the value is an
625 * atomically safe type this is just fine. Conceptually its
626 * as if the syscall took an instant longer to occur.
629 temp
.tms_utime
= HZ_TO_STD(current
->times
.tms_utime
);
630 temp
.tms_stime
= HZ_TO_STD(current
->times
.tms_stime
);
631 temp
.tms_cutime
= HZ_TO_STD(current
->times
.tms_cutime
);
632 temp
.tms_cstime
= HZ_TO_STD(current
->times
.tms_cstime
);
633 if (copy_to_user(tbuf
, &temp
, sizeof(struct tms
)))
636 return HZ_TO_STD(jiffies
);
640 * This needs some heavy checking ...
641 * I just haven't the stomach for it. I also don't fully
642 * understand sessions/pgrp etc. Let somebody who does explain it.
644 * OK, I think I have the protection semantics right.... this is really
645 * only important on a multi-user system anyway, to make sure one user
646 * can't send a signal to a process owned by another. -TYT, 12/12/91
648 * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
652 asmlinkage
long sys_setpgid(pid_t pid
, pid_t pgid
)
654 struct task_struct
* p
;
664 /* From this point forward we keep holding onto the tasklist lock
665 * so that our parent does not change from under us. -DaveM
667 read_lock(&tasklist_lock
);
670 p
= find_task_by_pid(pid
);
674 if (p
->p_pptr
== current
|| p
->p_opptr
== current
) {
676 if (p
->session
!= current
->session
)
681 } else if (p
!= current
)
687 struct task_struct
* tmp
;
688 for_each_task (tmp
) {
689 if (tmp
->pgrp
== pgid
&&
690 tmp
->session
== current
->session
)
700 /* All paths lead to here, thus we are safe. -DaveM */
701 read_unlock(&tasklist_lock
);
705 asmlinkage
long sys_getpgid(pid_t pid
)
708 return current
->pgrp
;
711 struct task_struct
*p
;
713 read_lock(&tasklist_lock
);
714 p
= find_task_by_pid(pid
);
719 read_unlock(&tasklist_lock
);
724 asmlinkage
long sys_getpgrp(void)
726 /* SMP - assuming writes are word atomic this is fine */
727 return current
->pgrp
;
730 asmlinkage
long sys_getsid(pid_t pid
)
733 return current
->session
;
736 struct task_struct
*p
;
738 read_lock(&tasklist_lock
);
739 p
= find_task_by_pid(pid
);
744 read_unlock(&tasklist_lock
);
749 asmlinkage
long sys_setsid(void)
751 struct task_struct
* p
;
754 read_lock(&tasklist_lock
);
756 if (p
->pgrp
== current
->pid
)
761 current
->session
= current
->pgrp
= current
->pid
;
763 current
->tty_old_pgrp
= 0;
766 read_unlock(&tasklist_lock
);
771 * Supplementary group IDs
773 asmlinkage
long sys_getgroups(int gidsetsize
, gid_t
*grouplist
)
778 * SMP: Nobody else can change our grouplist. Thus we are
784 i
= current
->ngroups
;
788 if (copy_to_user(grouplist
, current
->groups
, sizeof(gid_t
)*i
))
795 * SMP: Our groups are not shared. We can copy to/from them safely
796 * without another task interfering.
799 asmlinkage
long sys_setgroups(int gidsetsize
, gid_t
*grouplist
)
801 if (!capable(CAP_SETGID
))
803 if ((unsigned) gidsetsize
> NGROUPS
)
805 if(copy_from_user(current
->groups
, grouplist
, gidsetsize
* sizeof(gid_t
)))
807 current
->ngroups
= gidsetsize
;
811 int in_group_p(gid_t grp
)
813 if (grp
!= current
->fsgid
) {
814 int i
= current
->ngroups
;
816 gid_t
*groups
= current
->groups
;
830 DECLARE_RWSEM(uts_sem
);
832 asmlinkage
long sys_newuname(struct new_utsname
* name
)
837 if (copy_to_user(name
,&system_utsname
,sizeof *name
))
843 asmlinkage
long sys_sethostname(char *name
, int len
)
847 if (!capable(CAP_SYS_ADMIN
))
849 if (len
< 0 || len
> __NEW_UTS_LEN
)
851 down_write(&uts_sem
);
853 if (!copy_from_user(system_utsname
.nodename
, name
, len
)) {
854 system_utsname
.nodename
[len
] = 0;
861 asmlinkage
long sys_gethostname(char *name
, int len
)
868 i
= 1 + strlen(system_utsname
.nodename
);
872 if (copy_to_user(name
, system_utsname
.nodename
, i
))
879 * Only setdomainname; getdomainname can be implemented by calling
882 asmlinkage
long sys_setdomainname(char *name
, int len
)
886 if (!capable(CAP_SYS_ADMIN
))
888 if (len
< 0 || len
> __NEW_UTS_LEN
)
891 down_write(&uts_sem
);
893 if (!copy_from_user(system_utsname
.domainname
, name
, len
)) {
895 system_utsname
.domainname
[len
] = 0;
901 asmlinkage
long sys_getrlimit(unsigned int resource
, struct rlimit
*rlim
)
903 if (resource
>= RLIM_NLIMITS
)
906 return copy_to_user(rlim
, current
->rlim
+ resource
, sizeof(*rlim
))
910 #if !defined(__ia64__)
913 * Back compatibility for getrlimit. Needed for some apps.
916 asmlinkage
long sys_old_getrlimit(unsigned int resource
, struct rlimit
*rlim
)
919 if (resource
>= RLIM_NLIMITS
)
922 memcpy(&x
, current
->rlim
+ resource
, sizeof(*rlim
));
923 if(x
.rlim_cur
> 0x7FFFFFFF)
924 x
.rlim_cur
= 0x7FFFFFFF;
925 if(x
.rlim_max
> 0x7FFFFFFF)
926 x
.rlim_max
= 0x7FFFFFFF;
927 return copy_to_user(rlim
, &x
, sizeof(x
))?-EFAULT
:0;
932 asmlinkage
long sys_setrlimit(unsigned int resource
, struct rlimit
*rlim
)
934 struct rlimit new_rlim
, *old_rlim
;
936 if (resource
>= RLIM_NLIMITS
)
938 if(copy_from_user(&new_rlim
, rlim
, sizeof(*rlim
)))
940 if (new_rlim
.rlim_cur
< 0 || new_rlim
.rlim_max
< 0)
942 old_rlim
= current
->rlim
+ resource
;
943 if (((new_rlim
.rlim_cur
> old_rlim
->rlim_max
) ||
944 (new_rlim
.rlim_max
> old_rlim
->rlim_max
)) &&
945 !capable(CAP_SYS_RESOURCE
))
947 if (resource
== RLIMIT_NOFILE
) {
948 if (new_rlim
.rlim_cur
> NR_OPEN
|| new_rlim
.rlim_max
> NR_OPEN
)
951 *old_rlim
= new_rlim
;
956 * It would make sense to put struct rusage in the task_struct,
957 * except that would make the task_struct be *really big*. After
958 * task_struct gets moved into malloc'ed memory, it would
959 * make sense to do this. It will make moving the rest of the information
960 * a lot simpler! (Which we're not doing right now because we're not
961 * measuring them yet).
963 * This is SMP safe. Either we are called from sys_getrusage on ourselves
964 * below (we know we aren't going to exit/disappear and only we change our
965 * rusage counters), or we are called from wait4() on a process which is
966 * either stopped or zombied. In the zombied case the task won't get
967 * reaped till shortly after the call to getrusage(), in both cases the
968 * task being examined is in a frozen state so the counters won't change.
970 * FIXME! Get the fault counts properly!
972 int getrusage(struct task_struct
*p
, int who
, struct rusage
*ru
)
976 memset((char *) &r
, 0, sizeof(r
));
979 r
.ru_utime
.tv_sec
= CT_TO_SECS(p
->times
.tms_utime
);
980 r
.ru_utime
.tv_usec
= CT_TO_USECS(p
->times
.tms_utime
);
981 r
.ru_stime
.tv_sec
= CT_TO_SECS(p
->times
.tms_stime
);
982 r
.ru_stime
.tv_usec
= CT_TO_USECS(p
->times
.tms_stime
);
983 r
.ru_minflt
= p
->min_flt
;
984 r
.ru_majflt
= p
->maj_flt
;
985 r
.ru_nswap
= p
->nswap
;
987 case RUSAGE_CHILDREN
:
988 r
.ru_utime
.tv_sec
= CT_TO_SECS(p
->times
.tms_cutime
);
989 r
.ru_utime
.tv_usec
= CT_TO_USECS(p
->times
.tms_cutime
);
990 r
.ru_stime
.tv_sec
= CT_TO_SECS(p
->times
.tms_cstime
);
991 r
.ru_stime
.tv_usec
= CT_TO_USECS(p
->times
.tms_cstime
);
992 r
.ru_minflt
= p
->cmin_flt
;
993 r
.ru_majflt
= p
->cmaj_flt
;
994 r
.ru_nswap
= p
->cnswap
;
997 r
.ru_utime
.tv_sec
= CT_TO_SECS(p
->times
.tms_utime
+ p
->times
.tms_cutime
);
998 r
.ru_utime
.tv_usec
= CT_TO_USECS(p
->times
.tms_utime
+ p
->times
.tms_cutime
);
999 r
.ru_stime
.tv_sec
= CT_TO_SECS(p
->times
.tms_stime
+ p
->times
.tms_cstime
);
1000 r
.ru_stime
.tv_usec
= CT_TO_USECS(p
->times
.tms_stime
+ p
->times
.tms_cstime
);
1001 r
.ru_minflt
= p
->min_flt
+ p
->cmin_flt
;
1002 r
.ru_majflt
= p
->maj_flt
+ p
->cmaj_flt
;
1003 r
.ru_nswap
= p
->nswap
+ p
->cnswap
;
1006 return copy_to_user(ru
, &r
, sizeof(r
)) ? -EFAULT
: 0;
1009 asmlinkage
long sys_getrusage(int who
, struct rusage
*ru
)
1011 if (who
!= RUSAGE_SELF
&& who
!= RUSAGE_CHILDREN
)
1013 return getrusage(current
, who
, ru
);
1016 asmlinkage
long sys_umask(int mask
)
1018 mask
= xchg(¤t
->fs
->umask
, mask
& S_IRWXUGO
);
1022 asmlinkage
long sys_prctl(int option
, unsigned long arg2
, unsigned long arg3
,
1023 unsigned long arg4
, unsigned long arg5
)
1029 case PR_SET_PDEATHSIG
:
1035 current
->pdeath_signal
= sig
;
1037 case PR_GET_PDEATHSIG
:
1038 error
= put_user(current
->pdeath_signal
, (int *)arg2
);
1040 case PR_GET_DUMPABLE
:
1041 if (current
->dumpable
)
1044 case PR_SET_DUMPABLE
:
1045 if (arg2
!= 0 && arg2
!= 1) {
1049 current
->dumpable
= arg2
;
1051 case PR_SET_UNALIGN
:
1052 #ifdef SET_UNALIGN_CTL
1053 error
= SET_UNALIGN_CTL(current
, arg2
);
1059 case PR_GET_UNALIGN
:
1060 #ifdef GET_UNALIGN_CTL
1061 error
= GET_UNALIGN_CTL(current
, arg2
);