1
2
3
4
5
6
7#include <linux/config.h>
8#include <linux/errno.h>
9#include <linux/sched.h>
10#include <linux/kernel.h>
11#include <linux/times.h>
12#include <linux/utsname.h>
13#include <linux/param.h>
14#include <linux/resource.h>
15#include <linux/signal.h>
16#include <linux/string.h>
17#include <linux/ptrace.h>
18#include <linux/stat.h>
19#include <linux/mman.h>
20#include <linux/mm.h>
21#include <linux/fcntl.h>
22#include <linux/acct.h>
23#include <linux/tty.h>
24#include <linux/smp.h>
25#include <linux/smp_lock.h>
26#include <linux/notifier.h>
27#include <linux/reboot.h>
28#include <linux/prctl.h>
29
30#include <asm/uaccess.h>
31#include <asm/io.h>
32
33
34
35
36
37int C_A_D = 1;
38
39
40
41
42
43
44
45
46struct notifier_block *reboot_notifier_list = NULL;
47
48int register_reboot_notifier(struct notifier_block * nb)
49{
50 return notifier_chain_register(&reboot_notifier_list, nb);
51}
52
53int unregister_reboot_notifier(struct notifier_block * nb)
54{
55 return notifier_chain_unregister(&reboot_notifier_list, nb);
56}
57
58
59
60extern void adjust_clock(void);
61
62asmlinkage int sys_ni_syscall(void)
63{
64 return -ENOSYS;
65}
66
67static int proc_sel(struct task_struct *p, int which, int who)
68{
69 if(p->pid)
70 {
71 switch (which) {
72 case PRIO_PROCESS:
73 if (!who && p == current)
74 return 1;
75 return(p->pid == who);
76 case PRIO_PGRP:
77 if (!who)
78 who = current->pgrp;
79 return(p->pgrp == who);
80 case PRIO_USER:
81 if (!who)
82 who = current->uid;
83 return(p->uid == who);
84 }
85 }
86 return 0;
87}
88
89asmlinkage int sys_setpriority(int which, int who, int niceval)
90{
91 struct task_struct *p;
92 unsigned int priority;
93 int error;
94
95 if (which > 2 || which < 0)
96 return -EINVAL;
97
98
99 error = ESRCH;
100 priority = niceval;
101 if (niceval < 0)
102 priority = -niceval;
103 if (priority > 20)
104 priority = 20;
105 priority = (priority * DEF_PRIORITY + 10) / 20 + DEF_PRIORITY;
106
107 if (niceval >= 0) {
108 priority = 2*DEF_PRIORITY - priority;
109 if (!priority)
110 priority = 1;
111 }
112
113 read_lock(&tasklist_lock);
114 for_each_task(p) {
115 if (!proc_sel(p, which, who))
116 continue;
117 if (p->uid != current->euid &&
118 p->uid != current->uid && !suser()) {
119 error = EPERM;
120 continue;
121 }
122 if (error == ESRCH)
123 error = 0;
124 if (priority > p->priority && !suser())
125 error = EACCES;
126 else
127 p->priority = priority;
128 }
129 read_unlock(&tasklist_lock);
130
131 return -error;
132}
133
134
135
136
137
138
139asmlinkage int sys_getpriority(int which, int who)
140{
141 struct task_struct *p;
142 long max_prio = -ESRCH;
143
144 if (which > 2 || which < 0)
145 return -EINVAL;
146
147 read_lock(&tasklist_lock);
148 for_each_task (p) {
149 if (!proc_sel(p, which, who))
150 continue;
151 if (p->priority > max_prio)
152 max_prio = p->priority;
153 }
154 read_unlock(&tasklist_lock);
155
156
157 if (max_prio > 0)
158 max_prio = (max_prio * 20 + DEF_PRIORITY/2) / DEF_PRIORITY;
159 return max_prio;
160}
161
162
163extern asmlinkage int sys_kill(int, int);
164
165
166
167
168
169
170
171
172
173
174asmlinkage int sys_reboot(int magic1, int magic2, int cmd, void * arg)
175{
176 char buffer[256];
177
178
179 if (!suser())
180 return -EPERM;
181
182
183 if (magic1 != LINUX_REBOOT_MAGIC1 ||
184 (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A))
185 return -EINVAL;
186
187 lock_kernel();
188 switch (cmd) {
189 case LINUX_REBOOT_CMD_RESTART:
190 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
191 printk(KERN_EMERG "Restarting system.\n");
192 machine_restart(NULL);
193 break;
194
195 case LINUX_REBOOT_CMD_CAD_ON:
196 C_A_D = 1;
197 break;
198
199 case LINUX_REBOOT_CMD_CAD_OFF:
200 C_A_D = 0;
201 break;
202
203 case LINUX_REBOOT_CMD_HALT:
204 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
205 printk(KERN_EMERG "System halted.\n");
206 machine_halt();
207 do_exit(0);
208 break;
209
210 case LINUX_REBOOT_CMD_POWER_OFF:
211 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
212 printk(KERN_EMERG "Power down.\n");
213 machine_power_off();
214 do_exit(0);
215 break;
216
217 case LINUX_REBOOT_CMD_RESTART2:
218 if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0) {
219 unlock_kernel();
220 return -EFAULT;
221 }
222 buffer[sizeof(buffer) - 1] = '\0';
223
224 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
225 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
226 machine_restart(buffer);
227 break;
228
229 default:
230 unlock_kernel();
231 return -EINVAL;
232 break;
233 };
234 unlock_kernel();
235 return 0;
236}
237
238
239
240
241
242
243void ctrl_alt_del(void)
244{
245 if (C_A_D) {
246 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
247 machine_restart(NULL);
248 } else
249 kill_proc(1, SIGINT, 1);
250}
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
272{
273 int old_rgid = current->gid;
274 int old_egid = current->egid;
275
276 if (rgid != (gid_t) -1) {
277 if ((old_rgid == rgid) ||
278 (current->egid==rgid) ||
279 suser())
280 current->gid = rgid;
281 else
282 return -EPERM;
283 }
284 if (egid != (gid_t) -1) {
285 if ((old_rgid == egid) ||
286 (current->egid == egid) ||
287 (current->sgid == egid) ||
288 suser())
289 current->fsgid = current->egid = egid;
290 else {
291 current->gid = old_rgid;
292 return -EPERM;
293 }
294 }
295 if (rgid != (gid_t) -1 ||
296 (egid != (gid_t) -1 && egid != old_rgid))
297 current->sgid = current->egid;
298 current->fsgid = current->egid;
299 if (current->egid != old_egid)
300 current->dumpable = 0;
301 return 0;
302}
303
304
305
306
307
308
309asmlinkage int sys_setgid(gid_t gid)
310{
311 int old_egid = current->egid;
312
313 if (suser())
314 current->gid = current->egid = current->sgid = current->fsgid = gid;
315 else if ((gid == current->gid) || (gid == current->sgid))
316 current->egid = current->fsgid = gid;
317 else
318 return -EPERM;
319
320 if (current->egid != old_egid)
321 current->dumpable = 0;
322 return 0;
323}
324
325static char acct_active = 0;
326static struct file acct_file;
327
328int acct_process(long exitcode)
329{
330 struct acct ac;
331 unsigned long fs;
332
333 if (acct_active) {
334 strncpy(ac.ac_comm, current->comm, ACCT_COMM);
335 ac.ac_comm[ACCT_COMM-1] = '\0';
336 ac.ac_utime = current->times.tms_utime;
337 ac.ac_stime = current->times.tms_stime;
338 ac.ac_btime = CT_TO_SECS(current->start_time) + (xtime.tv_sec - (jiffies / HZ));
339 ac.ac_etime = CURRENT_TIME - ac.ac_btime;
340 ac.ac_uid = current->uid;
341 ac.ac_gid = current->gid;
342 ac.ac_tty = (current)->tty == NULL ? -1 :
343 kdev_t_to_nr(current->tty->device);
344 ac.ac_flag = 0;
345 if (current->flags & PF_FORKNOEXEC)
346 ac.ac_flag |= AFORK;
347 if (current->flags & PF_SUPERPRIV)
348 ac.ac_flag |= ASU;
349 if (current->flags & PF_DUMPCORE)
350 ac.ac_flag |= ACORE;
351 if (current->flags & PF_SIGNALED)
352 ac.ac_flag |= AXSIG;
353 ac.ac_minflt = current->min_flt;
354 ac.ac_majflt = current->maj_flt;
355 ac.ac_exitcode = exitcode;
356
357
358 fs = get_fs();
359 set_fs(KERNEL_DS);
360
361 acct_file.f_op->write(acct_file.f_dentry->d_inode, &acct_file,
362 (char *)&ac, sizeof(struct acct));
363 set_fs(fs);
364 }
365 return 0;
366}
367
368asmlinkage int sys_acct(const char *name)
369{
370 int error = -EPERM;
371
372 lock_kernel();
373 if (!suser())
374 goto out;
375
376 if (name == (char *)0) {
377 if (acct_active) {
378 if (acct_file.f_op->release)
379 acct_file.f_op->release(acct_file.f_dentry->d_inode, &acct_file);
380
381 if (acct_file.f_dentry != NULL)
382 dput(acct_file.f_dentry);
383
384 acct_active = 0;
385 }
386 error = 0;
387 } else {
388 error = -EBUSY;
389 if (!acct_active) {
390 struct dentry *dentry;
391 struct inode *inode;
392 char *tmp;
393
394 tmp = getname(name);
395 error = PTR_ERR(tmp);
396 if (IS_ERR(tmp))
397 goto out;
398
399 dentry = open_namei(tmp, O_RDWR, 0600);
400 putname(tmp);
401
402 error = PTR_ERR(dentry);
403 if (IS_ERR(dentry))
404 goto out;
405 inode = dentry->d_inode;
406
407 error = -EACCES;
408 if (!S_ISREG(inode->i_mode)) {
409 dput(dentry);
410 goto out;
411 }
412
413 error = -EIO;
414 if (!inode->i_op || !inode->i_op->default_file_ops ||
415 !inode->i_op->default_file_ops->write) {
416 dput(dentry);
417 goto out;
418 }
419
420 acct_file.f_mode = 3;
421 acct_file.f_flags = 0;
422 acct_file.f_count = 1;
423 acct_file.f_dentry = dentry;
424 acct_file.f_pos = inode->i_size;
425 acct_file.f_reada = 0;
426 acct_file.f_op = inode->i_op->default_file_ops;
427
428 if(acct_file.f_op->open) {
429 error = acct_file.f_op->open(inode, &acct_file);
430 if (error) {
431 dput(dentry);
432 goto out;
433 }
434 }
435
436 acct_active = 1;
437 error = 0;
438 }
439 }
440out:
441 unlock_kernel();
442 return error;
443}
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
462{
463 int old_ruid, old_euid, new_ruid;
464
465 new_ruid = old_ruid = current->uid;
466 old_euid = current->euid;
467 if (ruid != (uid_t) -1) {
468 if ((old_ruid == ruid) ||
469 (current->euid==ruid) ||
470 suser())
471 new_ruid = ruid;
472 else
473 return -EPERM;
474 }
475 if (euid != (uid_t) -1) {
476 if ((old_ruid == euid) ||
477 (current->euid == euid) ||
478 (current->suid == euid) ||
479 suser())
480 current->fsuid = current->euid = euid;
481 else
482 return -EPERM;
483 }
484 if (ruid != (uid_t) -1 ||
485 (euid != (uid_t) -1 && euid != old_ruid))
486 current->suid = current->euid;
487 current->fsuid = current->euid;
488 if (current->euid != old_euid)
489 current->dumpable = 0;
490
491 if(new_ruid != old_ruid) {
492
493
494
495
496
497 charge_uid(current, -1);
498 current->uid = new_ruid;
499 if(new_ruid)
500 charge_uid(current, 1);
501 }
502 return 0;
503}
504
505
506
507
508
509
510
511
512
513
514
515
516asmlinkage int sys_setuid(uid_t uid)
517{
518 int old_euid = current->euid;
519 int old_ruid, new_ruid;
520
521 old_ruid = new_ruid = current->uid;
522 if (suser())
523 new_ruid = current->euid = current->suid = current->fsuid = uid;
524 else if ((uid == current->uid) || (uid == current->suid))
525 current->fsuid = current->euid = uid;
526 else
527 return -EPERM;
528
529 if (current->euid != old_euid)
530 current->dumpable = 0;
531
532 if(new_ruid != old_ruid) {
533
534 charge_uid(current, -1);
535 current->uid = new_ruid;
536 if(new_ruid)
537 charge_uid(current, 1);
538 }
539 return 0;
540}
541
542
543
544
545
546
547asmlinkage int sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
548{
549 if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
550 if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
551 (ruid != current->euid) && (ruid != current->suid))
552 return -EPERM;
553 if ((euid != (uid_t) -1) && (euid != current->uid) &&
554 (euid != current->euid) && (euid != current->suid))
555 return -EPERM;
556 if ((suid != (uid_t) -1) && (suid != current->uid) &&
557 (suid != current->euid) && (suid != current->suid))
558 return -EPERM;
559 }
560 if (ruid != (uid_t) -1) {
561
562 charge_uid(current, -1);
563 current->uid = ruid;
564 if(ruid)
565 charge_uid(current, 1);
566 }
567 if (euid != (uid_t) -1) {
568 if (euid != current->euid)
569 current->dumpable = 0;
570 current->euid = euid;
571 current->fsuid = euid;
572 }
573 if (suid != (uid_t) -1)
574 current->suid = suid;
575 return 0;
576}
577
578asmlinkage int sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
579{
580 int retval;
581
582 if (!(retval = put_user(current->uid, ruid)) &&
583 !(retval = put_user(current->euid, euid)))
584 retval = put_user(current->suid, suid);
585
586 return retval;
587}
588
589
590
591
592asmlinkage int sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
593{
594 if (current->uid != 0 && current->euid != 0 && current->suid != 0) {
595 if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
596 (rgid != current->egid) && (rgid != current->sgid))
597 return -EPERM;
598 if ((egid != (gid_t) -1) && (egid != current->gid) &&
599 (egid != current->egid) && (egid != current->sgid))
600 return -EPERM;
601 if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
602 (sgid != current->egid) && (sgid != current->sgid))
603 return -EPERM;
604 }
605 if (rgid != (gid_t) -1)
606 current->gid = rgid;
607 if (egid != (gid_t) -1) {
608 if (egid != current->egid)
609 current->dumpable = 0;
610 current->egid = egid;
611 current->fsgid = egid;
612 }
613 if (sgid != (gid_t) -1)
614 current->sgid = sgid;
615 return 0;
616}
617
618asmlinkage int sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
619{
620 int retval;
621
622 if (!(retval = put_user(current->gid, rgid)) &&
623 !(retval = put_user(current->egid, egid)))
624 retval = put_user(current->sgid, sgid);
625
626 return retval;
627}
628
629
630
631
632
633
634
635
636asmlinkage int sys_setfsuid(uid_t uid)
637{
638 int old_fsuid;
639
640 old_fsuid = current->fsuid;
641 if (uid == current->uid || uid == current->euid ||
642 uid == current->suid || uid == current->fsuid || suser())
643 current->fsuid = uid;
644 if (current->fsuid != old_fsuid)
645 current->dumpable = 0;
646
647 return old_fsuid;
648}
649
650
651
652
653asmlinkage int sys_setfsgid(gid_t gid)
654{
655 int old_fsgid;
656
657 old_fsgid = current->fsgid;
658 if (gid == current->gid || gid == current->egid ||
659 gid == current->sgid || gid == current->fsgid || suser())
660 current->fsgid = gid;
661 if (current->fsgid != old_fsgid)
662 current->dumpable = 0;
663
664 return old_fsgid;
665}
666
667asmlinkage long sys_times(struct tms * tbuf)
668{
669
670
671
672
673
674
675 if (tbuf)
676 if (copy_to_user(tbuf, ¤t->times, sizeof(struct tms)))
677 return -EFAULT;
678 return jiffies;
679}
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
695{
696 struct task_struct * p;
697 int err = -EINVAL;
698
699 if (!pid)
700 pid = current->pid;
701 if (!pgid)
702 pgid = pid;
703 if (pgid < 0)
704 return -EINVAL;
705
706 if((p = find_task_by_pid(pid)) == NULL)
707 return -ESRCH;
708
709
710
711
712 read_lock(&tasklist_lock);
713 err = -ESRCH;
714 if (p->p_pptr == current || p->p_opptr == current) {
715 err = -EPERM;
716 if (p->session != current->session)
717 goto out;
718 err = -EACCES;
719 if (p->did_exec)
720 goto out;
721 } else if (p != current)
722 goto out;
723 err = -EPERM;
724 if (p->leader)
725 goto out;
726 if (pgid != pid) {
727 struct task_struct * tmp;
728 for_each_task (tmp) {
729 if (tmp->pgrp == pgid &&
730 tmp->session == current->session)
731 goto ok_pgid;
732 }
733 goto out;
734 }
735
736ok_pgid:
737 p->pgrp = pgid;
738 err = 0;
739out:
740
741 read_unlock(&tasklist_lock);
742 return err;
743}
744
745asmlinkage int sys_getpgid(pid_t pid)
746{
747 if (!pid) {
748 return current->pgrp;
749 } else {
750 struct task_struct *p = find_task_by_pid(pid);
751
752 if(p)
753 return p->pgrp;
754 else
755 return -ESRCH;
756 }
757}
758
759asmlinkage int sys_getpgrp(void)
760{
761
762 return current->pgrp;
763}
764
765asmlinkage int sys_getsid(pid_t pid)
766{
767 if (!pid) {
768 return current->session;
769 } else {
770 struct task_struct *p = find_task_by_pid(pid);
771
772 if(p)
773 return p->session;
774 else
775 return -ESRCH;
776 }
777}
778
779asmlinkage int sys_setsid(void)
780{
781 struct task_struct * p;
782 int err = -EPERM;
783
784 read_lock(&tasklist_lock);
785 for_each_task(p) {
786 if (p->pgrp == current->pid)
787 goto out;
788 }
789
790 current->leader = 1;
791 current->session = current->pgrp = current->pid;
792 current->tty = NULL;
793 current->tty_old_pgrp = 0;
794 err = current->pgrp;
795out:
796 read_unlock(&tasklist_lock);
797 return err;
798}
799
800
801
802
803asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
804{
805 int i;
806
807
808
809
810
811
812 if (gidsetsize < 0)
813 return -EINVAL;
814 i = current->ngroups;
815 if (gidsetsize) {
816 if (i > gidsetsize)
817 return -EINVAL;
818 if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
819 return -EFAULT;
820 }
821 return i;
822}
823
824
825
826
827
828
829asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
830{
831 if (!suser())
832 return -EPERM;
833 if ((unsigned) gidsetsize > NGROUPS)
834 return -EINVAL;
835 if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
836 return -EFAULT;
837 current->ngroups = gidsetsize;
838 return 0;
839}
840
841int in_group_p(gid_t grp)
842{
843 if (grp != current->fsgid) {
844 int i = current->ngroups;
845 if (i) {
846 gid_t *groups = current->groups;
847 do {
848 if (*groups == grp)
849 goto out;
850 groups++;
851 i--;
852 } while (i);
853 }
854 return 0;
855 }
856out:
857 return 1;
858}
859
860asmlinkage int sys_newuname(struct new_utsname * name)
861{
862 if (!name)
863 return -EFAULT;
864 if (copy_to_user(name,&system_utsname,sizeof *name))
865 return -EFAULT;
866 return 0;
867}
868
869asmlinkage int sys_sethostname(char *name, int len)
870{
871 if (!suser())
872 return -EPERM;
873 if (len < 0 || len > __NEW_UTS_LEN)
874 return -EINVAL;
875 if(copy_from_user(system_utsname.nodename, name, len))
876 return -EFAULT;
877 system_utsname.nodename[len] = 0;
878#ifdef CONFIG_TRANS_NAMES
879 translations_dirty = 1;
880#endif
881 return 0;
882}
883
884asmlinkage int sys_gethostname(char *name, int len)
885{
886 int i;
887
888 if (len < 0)
889 return -EINVAL;
890 i = 1 + strlen(system_utsname.nodename);
891 if (i > len)
892 i = len;
893 return copy_to_user(name, system_utsname.nodename, i) ? -EFAULT : 0;
894}
895
896
897
898
899
900asmlinkage int sys_setdomainname(char *name, int len)
901{
902 if (!suser())
903 return -EPERM;
904 if (len < 0 || len > __NEW_UTS_LEN)
905 return -EINVAL;
906 if(copy_from_user(system_utsname.domainname, name, len))
907 return -EFAULT;
908 system_utsname.domainname[len] = 0;
909#ifdef CONFIG_TRANS_NAMES
910 translations_dirty = 1;
911#endif
912 return 0;
913}
914
915asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
916{
917 if (resource >= RLIM_NLIMITS)
918 return -EINVAL;
919 else
920 return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
921 ? -EFAULT : 0;
922}
923
924asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
925{
926 struct rlimit new_rlim, *old_rlim;
927
928 if (resource >= RLIM_NLIMITS)
929 return -EINVAL;
930 if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
931 return -EFAULT;
932 old_rlim = current->rlim + resource;
933 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
934 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
935 !suser())
936 return -EPERM;
937 if (resource == RLIMIT_NOFILE) {
938 if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
939 return -EPERM;
940 }
941 *old_rlim = new_rlim;
942 return 0;
943}
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960int getrusage(struct task_struct *p, int who, struct rusage *ru)
961{
962 struct rusage r;
963
964 memset((char *) &r, 0, sizeof(r));
965 switch (who) {
966 case RUSAGE_SELF:
967 r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime);
968 r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime);
969 r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime);
970 r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime);
971 r.ru_minflt = p->min_flt;
972 r.ru_majflt = p->maj_flt;
973 r.ru_nswap = p->nswap;
974 break;
975 case RUSAGE_CHILDREN:
976 r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime);
977 r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_cutime);
978 r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_cstime);
979 r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_cstime);
980 r.ru_minflt = p->cmin_flt;
981 r.ru_majflt = p->cmaj_flt;
982 r.ru_nswap = p->cnswap;
983 break;
984 default:
985 r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime);
986 r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime + p->times.tms_cutime);
987 r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime);
988 r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime);
989 r.ru_minflt = p->min_flt + p->cmin_flt;
990 r.ru_majflt = p->maj_flt + p->cmaj_flt;
991 r.ru_nswap = p->nswap + p->cnswap;
992 break;
993 }
994 return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
995}
996
997asmlinkage int sys_getrusage(int who, struct rusage *ru)
998{
999 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
1000 return -EINVAL;
1001 return getrusage(current, who, ru);
1002}
1003
1004asmlinkage int sys_umask(int mask)
1005{
1006 mask = xchg(¤t->fs->umask, mask & S_IRWXUGO);
1007 return mask;
1008}
1009
1010asmlinkage int sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1011 unsigned long arg4, unsigned long arg5)
1012{
1013 int error = 0;
1014 int sig;
1015
1016 switch (option) {
1017 case PR_SET_PDEATHSIG:
1018 sig = arg2;
1019 if (sig > _NSIG) {
1020 error = -EINVAL;
1021 break;
1022 }
1023 current->pdeath_signal = sig;
1024 break;
1025 default:
1026 error = -EINVAL;
1027 break;
1028 }
1029 return error;
1030}
1031