This commit was manufactured by cvs2svn to create branch
[linux-2.6.git] / kernel / sys.c
1 /*
2  *  linux/kernel/sys.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/config.h>
8 #include <linux/module.h>
9 #include <linux/mm.h>
10 #include <linux/utsname.h>
11 #include <linux/mman.h>
12 #include <linux/smp_lock.h>
13 #include <linux/notifier.h>
14 #include <linux/kmod.h>
15 #include <linux/reboot.h>
16 #include <linux/prctl.h>
17 #include <linux/init.h>
18 #include <linux/highuid.h>
19 #include <linux/fs.h>
20 #include <linux/kernel.h>
21 #include <linux/kexec.h>
22 #include <linux/workqueue.h>
23 #include <linux/device.h>
24 #include <linux/key.h>
25 #include <linux/times.h>
26 #include <linux/posix-timers.h>
27 #include <linux/security.h>
28 #include <linux/dcookies.h>
29 #include <linux/suspend.h>
30 #include <linux/tty.h>
31 #include <linux/signal.h>
32
33 #include <linux/compat.h>
34 #include <linux/syscalls.h>
35 #include <linux/vs_cvirt.h>
36
37 #include <asm/uaccess.h>
38 #include <asm/io.h>
39 #include <asm/unistd.h>
40
41 #ifndef SET_UNALIGN_CTL
42 # define SET_UNALIGN_CTL(a,b)   (-EINVAL)
43 #endif
44 #ifndef GET_UNALIGN_CTL
45 # define GET_UNALIGN_CTL(a,b)   (-EINVAL)
46 #endif
47 #ifndef SET_FPEMU_CTL
48 # define SET_FPEMU_CTL(a,b)     (-EINVAL)
49 #endif
50 #ifndef GET_FPEMU_CTL
51 # define GET_FPEMU_CTL(a,b)     (-EINVAL)
52 #endif
53 #ifndef SET_FPEXC_CTL
54 # define SET_FPEXC_CTL(a,b)     (-EINVAL)
55 #endif
56 #ifndef GET_FPEXC_CTL
57 # define GET_FPEXC_CTL(a,b)     (-EINVAL)
58 #endif
59
60 /*
61  * this is where the system-wide overflow UID and GID are defined, for
62  * architectures that now have 32-bit UID/GID but didn't in the past
63  */
64
65 int overflowuid = DEFAULT_OVERFLOWUID;
66 int overflowgid = DEFAULT_OVERFLOWGID;
67
68 #ifdef CONFIG_UID16
69 EXPORT_SYMBOL(overflowuid);
70 EXPORT_SYMBOL(overflowgid);
71 #endif
72
73 /*
74  * the same as above, but for filesystems which can only store a 16-bit
75  * UID and GID. as such, this is needed on all architectures
76  */
77
78 int fs_overflowuid = DEFAULT_FS_OVERFLOWUID;
79 int fs_overflowgid = DEFAULT_FS_OVERFLOWUID;
80
81 EXPORT_SYMBOL(fs_overflowuid);
82 EXPORT_SYMBOL(fs_overflowgid);
83
84 /*
85  * this indicates whether you can reboot with ctrl-alt-del: the default is yes
86  */
87
88 int C_A_D = 1;
89 int cad_pid = 1;
90
91 /*
92  *      Notifier list for kernel code which wants to be called
93  *      at shutdown. This is used to stop any idling DMA operations
94  *      and the like. 
95  */
96
97 static struct notifier_block *reboot_notifier_list;
98 static DEFINE_RWLOCK(notifier_lock);
99
100 /**
101  *      notifier_chain_register - Add notifier to a notifier chain
102  *      @list: Pointer to root list pointer
103  *      @n: New entry in notifier chain
104  *
105  *      Adds a notifier to a notifier chain.
106  *
107  *      Currently always returns zero.
108  */
109  
110 int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
111 {
112         write_lock(&notifier_lock);
113         while(*list)
114         {
115                 if(n->priority > (*list)->priority)
116                         break;
117                 list= &((*list)->next);
118         }
119         n->next = *list;
120         *list=n;
121         write_unlock(&notifier_lock);
122         return 0;
123 }
124
125 EXPORT_SYMBOL(notifier_chain_register);
126
127 /**
128  *      notifier_chain_unregister - Remove notifier from a notifier chain
129  *      @nl: Pointer to root list pointer
130  *      @n: New entry in notifier chain
131  *
132  *      Removes a notifier from a notifier chain.
133  *
134  *      Returns zero on success, or %-ENOENT on failure.
135  */
136  
137 int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
138 {
139         write_lock(&notifier_lock);
140         while((*nl)!=NULL)
141         {
142                 if((*nl)==n)
143                 {
144                         *nl=n->next;
145                         write_unlock(&notifier_lock);
146                         return 0;
147                 }
148                 nl=&((*nl)->next);
149         }
150         write_unlock(&notifier_lock);
151         return -ENOENT;
152 }
153
154 EXPORT_SYMBOL(notifier_chain_unregister);
155
156 /**
157  *      notifier_call_chain - Call functions in a notifier chain
158  *      @n: Pointer to root pointer of notifier chain
159  *      @val: Value passed unmodified to notifier function
160  *      @v: Pointer passed unmodified to notifier function
161  *
162  *      Calls each function in a notifier chain in turn.
163  *
164  *      If the return value of the notifier can be and'd
165  *      with %NOTIFY_STOP_MASK, then notifier_call_chain
166  *      will return immediately, with the return value of
167  *      the notifier function which halted execution.
168  *      Otherwise, the return value is the return value
169  *      of the last notifier function called.
170  */
171  
172 int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
173 {
174         int ret=NOTIFY_DONE;
175         struct notifier_block *nb = *n;
176
177         while(nb)
178         {
179                 ret=nb->notifier_call(nb,val,v);
180                 if(ret&NOTIFY_STOP_MASK)
181                 {
182                         return ret;
183                 }
184                 nb=nb->next;
185         }
186         return ret;
187 }
188
189 EXPORT_SYMBOL(notifier_call_chain);
190
191 /**
192  *      register_reboot_notifier - Register function to be called at reboot time
193  *      @nb: Info about notifier function to be called
194  *
195  *      Registers a function with the list of functions
196  *      to be called at reboot time.
197  *
198  *      Currently always returns zero, as notifier_chain_register
199  *      always returns zero.
200  */
201  
202 int register_reboot_notifier(struct notifier_block * nb)
203 {
204         return notifier_chain_register(&reboot_notifier_list, nb);
205 }
206
207 EXPORT_SYMBOL(register_reboot_notifier);
208
209 /**
210  *      unregister_reboot_notifier - Unregister previously registered reboot notifier
211  *      @nb: Hook to be unregistered
212  *
213  *      Unregisters a previously registered reboot
214  *      notifier function.
215  *
216  *      Returns zero on success, or %-ENOENT on failure.
217  */
218  
219 int unregister_reboot_notifier(struct notifier_block * nb)
220 {
221         return notifier_chain_unregister(&reboot_notifier_list, nb);
222 }
223
224 EXPORT_SYMBOL(unregister_reboot_notifier);
225
226 static int set_one_prio(struct task_struct *p, int niceval, int error)
227 {
228         int no_nice;
229
230         if (p->uid != current->euid &&
231                 p->euid != current->euid && !capable(CAP_SYS_NICE)) {
232                 error = -EPERM;
233                 goto out;
234         }
235         if (niceval < task_nice(p) && !can_nice(p, niceval)) {
236                 if (vx_flags(VXF_IGNEG_NICE, 0))
237                         error = 0;
238                 else
239                         error = -EACCES;
240                 goto out;
241         }
242         no_nice = security_task_setnice(p, niceval);
243         if (no_nice) {
244                 error = no_nice;
245                 goto out;
246         }
247         if (error == -ESRCH)
248                 error = 0;
249         set_user_nice(p, niceval);
250 out:
251         return error;
252 }
253
254 asmlinkage long sys_setpriority(int which, int who, int niceval)
255 {
256         struct task_struct *g, *p;
257         struct user_struct *user;
258         int error = -EINVAL;
259
260         if (which > 2 || which < 0)
261                 goto out;
262
263         /* normalize: avoid signed division (rounding problems) */
264         error = -ESRCH;
265         if (niceval < -20)
266                 niceval = -20;
267         if (niceval > 19)
268                 niceval = 19;
269
270         read_lock(&tasklist_lock);
271         switch (which) {
272                 case PRIO_PROCESS:
273                         if (!who)
274                                 who = current->pid;
275                         p = find_task_by_pid(who);
276                         if (p)
277                                 error = set_one_prio(p, niceval, error);
278                         break;
279                 case PRIO_PGRP:
280                         if (!who)
281                                 who = process_group(current);
282                         do_each_task_pid(who, PIDTYPE_PGID, p) {
283                                 error = set_one_prio(p, niceval, error);
284                         } while_each_task_pid(who, PIDTYPE_PGID, p);
285                         break;
286                 case PRIO_USER:
287                         user = current->user;
288                         if (!who)
289                                 who = current->uid;
290                         else
291                                 if ((who != current->uid) &&
292                                         !(user = find_user(vx_current_xid(), who)))
293                                         goto out_unlock;        /* No processes for this user */
294
295                         do_each_thread(g, p)
296                                 if (p->uid == who)
297                                         error = set_one_prio(p, niceval, error);
298                         while_each_thread(g, p);
299                         if (who != current->uid)
300                                 free_uid(user);         /* For find_user() */
301                         break;
302         }
303 out_unlock:
304         read_unlock(&tasklist_lock);
305 out:
306         return error;
307 }
308
309 /*
310  * Ugh. To avoid negative return values, "getpriority()" will
311  * not return the normal nice-value, but a negated value that
312  * has been offset by 20 (ie it returns 40..1 instead of -20..19)
313  * to stay compatible.
314  */
315 asmlinkage long sys_getpriority(int which, int who)
316 {
317         struct task_struct *g, *p;
318         struct user_struct *user;
319         long niceval, retval = -ESRCH;
320
321         if (which > 2 || which < 0)
322                 return -EINVAL;
323
324         read_lock(&tasklist_lock);
325         switch (which) {
326                 case PRIO_PROCESS:
327                         if (!who)
328                                 who = current->pid;
329                         p = find_task_by_pid(who);
330                         if (p) {
331                                 niceval = 20 - task_nice(p);
332                                 if (niceval > retval)
333                                         retval = niceval;
334                         }
335                         break;
336                 case PRIO_PGRP:
337                         if (!who)
338                                 who = process_group(current);
339                         do_each_task_pid(who, PIDTYPE_PGID, p) {
340                                 niceval = 20 - task_nice(p);
341                                 if (niceval > retval)
342                                         retval = niceval;
343                         } while_each_task_pid(who, PIDTYPE_PGID, p);
344                         break;
345                 case PRIO_USER:
346                         user = current->user;
347                         if (!who)
348                                 who = current->uid;
349                         else
350                                 if ((who != current->uid) &&
351                                         !(user = find_user(vx_current_xid(), who)))
352                                         goto out_unlock;        /* No processes for this user */
353
354                         do_each_thread(g, p)
355                                 if (p->uid == who) {
356                                         niceval = 20 - task_nice(p);
357                                         if (niceval > retval)
358                                                 retval = niceval;
359                                 }
360                         while_each_thread(g, p);
361                         if (who != current->uid)
362                                 free_uid(user);         /* for find_user() */
363                         break;
364         }
365 out_unlock:
366         read_unlock(&tasklist_lock);
367
368         return retval;
369 }
370
371 long vs_reboot(unsigned int, void *);
372
373 /*
374  * Reboot system call: for obvious reasons only root may call it,
375  * and even root needs to set up some magic numbers in the registers
376  * so that some mistake won't make this reboot the whole machine.
377  * You can also set the meaning of the ctrl-alt-del-key here.
378  *
379  * reboot doesn't sync: do that yourself before calling this.
380  */
381 asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void __user * arg)
382 {
383         char buffer[256];
384
385         /* We only trust the superuser with rebooting the system. */
386         if (!capable(CAP_SYS_BOOT))
387                 return -EPERM;
388
389         /* For safety, we require "magic" arguments. */
390         if (magic1 != LINUX_REBOOT_MAGIC1 ||
391             (magic2 != LINUX_REBOOT_MAGIC2 &&
392                         magic2 != LINUX_REBOOT_MAGIC2A &&
393                         magic2 != LINUX_REBOOT_MAGIC2B &&
394                         magic2 != LINUX_REBOOT_MAGIC2C))
395                 return -EINVAL;
396
397         if (!vx_check(0, VX_ADMIN|VX_WATCH))
398                 return vs_reboot(cmd, arg);
399
400         lock_kernel();
401         switch (cmd) {
402         case LINUX_REBOOT_CMD_RESTART:
403                 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
404                 system_state = SYSTEM_RESTART;
405                 device_shutdown();
406                 printk(KERN_EMERG "Restarting system.\n");
407                 machine_restart(NULL);
408                 break;
409
410         case LINUX_REBOOT_CMD_CAD_ON:
411                 C_A_D = 1;
412                 break;
413
414         case LINUX_REBOOT_CMD_CAD_OFF:
415                 C_A_D = 0;
416                 break;
417
418         case LINUX_REBOOT_CMD_HALT:
419                 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
420                 system_state = SYSTEM_HALT;
421                 device_shutdown();
422                 printk(KERN_EMERG "System halted.\n");
423                 machine_halt();
424                 unlock_kernel();
425                 do_exit(0);
426                 break;
427
428         case LINUX_REBOOT_CMD_POWER_OFF:
429                 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
430                 system_state = SYSTEM_POWER_OFF;
431                 device_shutdown();
432                 printk(KERN_EMERG "Power down.\n");
433                 machine_power_off();
434                 unlock_kernel();
435                 do_exit(0);
436                 break;
437
438         case LINUX_REBOOT_CMD_RESTART2:
439                 if (strncpy_from_user(&buffer[0], arg, sizeof(buffer) - 1) < 0) {
440                         unlock_kernel();
441                         return -EFAULT;
442                 }
443                 buffer[sizeof(buffer) - 1] = '\0';
444
445                 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
446                 system_state = SYSTEM_RESTART;
447                 device_shutdown();
448                 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
449                 machine_restart(buffer);
450                 break;
451
452 #ifdef CONFIG_KEXEC
453         case LINUX_REBOOT_CMD_KEXEC:
454         {
455                 struct kimage *image;
456                 image = xchg(&kexec_image, 0);
457                 if (!image) {
458                         unlock_kernel();
459                         return -EINVAL;
460                 }
461                 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
462                 system_state = SYSTEM_RESTART;
463                 device_shutdown();
464                 system_state = SYSTEM_BOOTING;
465                 printk(KERN_EMERG "Starting new kernel\n");
466                 machine_shutdown();
467                 machine_kexec(image);
468                 break;
469         }
470 #endif
471
472 #ifdef CONFIG_SOFTWARE_SUSPEND
473         case LINUX_REBOOT_CMD_SW_SUSPEND:
474                 {
475                         int ret = software_suspend();
476                         unlock_kernel();
477                         return ret;
478                 }
479 #endif
480
481         default:
482                 unlock_kernel();
483                 return -EINVAL;
484         }
485         unlock_kernel();
486         return 0;
487 }
488
489 static void deferred_cad(void *dummy)
490 {
491         notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
492         machine_restart(NULL);
493 }
494
495 /*
496  * This function gets called by ctrl-alt-del - ie the keyboard interrupt.
497  * As it's called within an interrupt, it may NOT sync: the only choice
498  * is whether to reboot at once, or just ignore the ctrl-alt-del.
499  */
500 void ctrl_alt_del(void)
501 {
502         static DECLARE_WORK(cad_work, deferred_cad, NULL);
503
504         if (C_A_D)
505                 schedule_work(&cad_work);
506         else
507                 kill_proc(cad_pid, SIGINT, 1);
508 }
509         
510
511 /*
512  * Unprivileged users may change the real gid to the effective gid
513  * or vice versa.  (BSD-style)
514  *
515  * If you set the real gid at all, or set the effective gid to a value not
516  * equal to the real gid, then the saved gid is set to the new effective gid.
517  *
518  * This makes it possible for a setgid program to completely drop its
519  * privileges, which is often a useful assertion to make when you are doing
520  * a security audit over a program.
521  *
522  * The general idea is that a program which uses just setregid() will be
523  * 100% compatible with BSD.  A program which uses just setgid() will be
524  * 100% compatible with POSIX with saved IDs. 
525  *
526  * SMP: There are not races, the GIDs are checked only by filesystem
527  *      operations (as far as semantic preservation is concerned).
528  */
529 asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
530 {
531         int old_rgid = current->gid;
532         int old_egid = current->egid;
533         int new_rgid = old_rgid;
534         int new_egid = old_egid;
535         int retval;
536
537         retval = security_task_setgid(rgid, egid, (gid_t)-1, LSM_SETID_RE);
538         if (retval)
539                 return retval;
540
541         if (rgid != (gid_t) -1) {
542                 if ((old_rgid == rgid) ||
543                     (current->egid==rgid) ||
544                     capable(CAP_SETGID))
545                         new_rgid = rgid;
546                 else
547                         return -EPERM;
548         }
549         if (egid != (gid_t) -1) {
550                 if ((old_rgid == egid) ||
551                     (current->egid == egid) ||
552                     (current->sgid == egid) ||
553                     capable(CAP_SETGID))
554                         new_egid = egid;
555                 else {
556                         return -EPERM;
557                 }
558         }
559         if (new_egid != old_egid)
560         {
561                 current->mm->dumpable = 0;
562                 smp_wmb();
563         }
564         if (rgid != (gid_t) -1 ||
565             (egid != (gid_t) -1 && egid != old_rgid))
566                 current->sgid = new_egid;
567         current->fsgid = new_egid;
568         current->egid = new_egid;
569         current->gid = new_rgid;
570         key_fsgid_changed(current);
571         return 0;
572 }
573
574 /*
575  * setgid() is implemented like SysV w/ SAVED_IDS 
576  *
577  * SMP: Same implicit races as above.
578  */
579 asmlinkage long sys_setgid(gid_t gid)
580 {
581         int old_egid = current->egid;
582         int retval;
583
584         retval = security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_ID);
585         if (retval)
586                 return retval;
587
588         if (capable(CAP_SETGID))
589         {
590                 if(old_egid != gid)
591                 {
592                         current->mm->dumpable=0;
593                         smp_wmb();
594                 }
595                 current->gid = current->egid = current->sgid = current->fsgid = gid;
596         }
597         else if ((gid == current->gid) || (gid == current->sgid))
598         {
599                 if(old_egid != gid)
600                 {
601                         current->mm->dumpable=0;
602                         smp_wmb();
603                 }
604                 current->egid = current->fsgid = gid;
605         }
606         else
607                 return -EPERM;
608
609         key_fsgid_changed(current);
610         return 0;
611 }
612   
613 static int set_user(uid_t new_ruid, int dumpclear)
614 {
615         struct user_struct *new_user;
616
617         new_user = alloc_uid(vx_current_xid(), new_ruid);
618         if (!new_user)
619                 return -EAGAIN;
620
621         if (atomic_read(&new_user->processes) >=
622                                 current->signal->rlim[RLIMIT_NPROC].rlim_cur &&
623                         new_user != &root_user) {
624                 free_uid(new_user);
625                 return -EAGAIN;
626         }
627
628         switch_uid(new_user);
629
630         if(dumpclear)
631         {
632                 current->mm->dumpable = 0;
633                 smp_wmb();
634         }
635         current->uid = new_ruid;
636         return 0;
637 }
638
639 /*
640  * Unprivileged users may change the real uid to the effective uid
641  * or vice versa.  (BSD-style)
642  *
643  * If you set the real uid at all, or set the effective uid to a value not
644  * equal to the real uid, then the saved uid is set to the new effective uid.
645  *
646  * This makes it possible for a setuid program to completely drop its
647  * privileges, which is often a useful assertion to make when you are doing
648  * a security audit over a program.
649  *
650  * The general idea is that a program which uses just setreuid() will be
651  * 100% compatible with BSD.  A program which uses just setuid() will be
652  * 100% compatible with POSIX with saved IDs. 
653  */
654 asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
655 {
656         int old_ruid, old_euid, old_suid, new_ruid, new_euid;
657         int retval;
658
659         retval = security_task_setuid(ruid, euid, (uid_t)-1, LSM_SETID_RE);
660         if (retval)
661                 return retval;
662
663         new_ruid = old_ruid = current->uid;
664         new_euid = old_euid = current->euid;
665         old_suid = current->suid;
666
667         if (ruid != (uid_t) -1) {
668                 new_ruid = ruid;
669                 if ((old_ruid != ruid) &&
670                     (current->euid != ruid) &&
671                     !capable(CAP_SETUID))
672                         return -EPERM;
673         }
674
675         if (euid != (uid_t) -1) {
676                 new_euid = euid;
677                 if ((old_ruid != euid) &&
678                     (current->euid != euid) &&
679                     (current->suid != euid) &&
680                     !capable(CAP_SETUID))
681                         return -EPERM;
682         }
683
684         if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
685                 return -EAGAIN;
686
687         if (new_euid != old_euid)
688         {
689                 current->mm->dumpable=0;
690                 smp_wmb();
691         }
692         current->fsuid = current->euid = new_euid;
693         if (ruid != (uid_t) -1 ||
694             (euid != (uid_t) -1 && euid != old_ruid))
695                 current->suid = current->euid;
696         current->fsuid = current->euid;
697
698         key_fsuid_changed(current);
699
700         return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RE);
701 }
702
703
704                 
705 /*
706  * setuid() is implemented like SysV with SAVED_IDS 
707  * 
708  * Note that SAVED_ID's is deficient in that a setuid root program
709  * like sendmail, for example, cannot set its uid to be a normal 
710  * user and then switch back, because if you're root, setuid() sets
711  * the saved uid too.  If you don't like this, blame the bright people
712  * in the POSIX committee and/or USG.  Note that the BSD-style setreuid()
713  * will allow a root program to temporarily drop privileges and be able to
714  * regain them by swapping the real and effective uid.  
715  */
716 asmlinkage long sys_setuid(uid_t uid)
717 {
718         int old_euid = current->euid;
719         int old_ruid, old_suid, new_ruid, new_suid;
720         int retval;
721
722         retval = security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_ID);
723         if (retval)
724                 return retval;
725
726         old_ruid = new_ruid = current->uid;
727         old_suid = current->suid;
728         new_suid = old_suid;
729         
730         if (capable(CAP_SETUID)) {
731                 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
732                         return -EAGAIN;
733                 new_suid = uid;
734         } else if ((uid != current->uid) && (uid != new_suid))
735                 return -EPERM;
736
737         if (old_euid != uid)
738         {
739                 current->mm->dumpable = 0;
740                 smp_wmb();
741         }
742         current->fsuid = current->euid = uid;
743         current->suid = new_suid;
744
745         key_fsuid_changed(current);
746
747         return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_ID);
748 }
749
750
751 /*
752  * This function implements a generic ability to update ruid, euid,
753  * and suid.  This allows you to implement the 4.4 compatible seteuid().
754  */
755 asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
756 {
757         int old_ruid = current->uid;
758         int old_euid = current->euid;
759         int old_suid = current->suid;
760         int retval;
761
762         retval = security_task_setuid(ruid, euid, suid, LSM_SETID_RES);
763         if (retval)
764                 return retval;
765
766         if (!capable(CAP_SETUID)) {
767                 if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
768                     (ruid != current->euid) && (ruid != current->suid))
769                         return -EPERM;
770                 if ((euid != (uid_t) -1) && (euid != current->uid) &&
771                     (euid != current->euid) && (euid != current->suid))
772                         return -EPERM;
773                 if ((suid != (uid_t) -1) && (suid != current->uid) &&
774                     (suid != current->euid) && (suid != current->suid))
775                         return -EPERM;
776         }
777         if (ruid != (uid_t) -1) {
778                 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
779                         return -EAGAIN;
780         }
781         if (euid != (uid_t) -1) {
782                 if (euid != current->euid)
783                 {
784                         current->mm->dumpable = 0;
785                         smp_wmb();
786                 }
787                 current->euid = euid;
788         }
789         current->fsuid = current->euid;
790         if (suid != (uid_t) -1)
791                 current->suid = suid;
792
793         key_fsuid_changed(current);
794
795         return security_task_post_setuid(old_ruid, old_euid, old_suid, LSM_SETID_RES);
796 }
797
798 asmlinkage long sys_getresuid(uid_t __user *ruid, uid_t __user *euid, uid_t __user *suid)
799 {
800         int retval;
801
802         if (!(retval = put_user(current->uid, ruid)) &&
803             !(retval = put_user(current->euid, euid)))
804                 retval = put_user(current->suid, suid);
805
806         return retval;
807 }
808
809 /*
810  * Same as above, but for rgid, egid, sgid.
811  */
812 asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
813 {
814         int retval;
815
816         retval = security_task_setgid(rgid, egid, sgid, LSM_SETID_RES);
817         if (retval)
818                 return retval;
819
820         if (!capable(CAP_SETGID)) {
821                 if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
822                     (rgid != current->egid) && (rgid != current->sgid))
823                         return -EPERM;
824                 if ((egid != (gid_t) -1) && (egid != current->gid) &&
825                     (egid != current->egid) && (egid != current->sgid))
826                         return -EPERM;
827                 if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
828                     (sgid != current->egid) && (sgid != current->sgid))
829                         return -EPERM;
830         }
831         if (egid != (gid_t) -1) {
832                 if (egid != current->egid)
833                 {
834                         current->mm->dumpable = 0;
835                         smp_wmb();
836                 }
837                 current->egid = egid;
838         }
839         current->fsgid = current->egid;
840         if (rgid != (gid_t) -1)
841                 current->gid = rgid;
842         if (sgid != (gid_t) -1)
843                 current->sgid = sgid;
844
845         key_fsgid_changed(current);
846         return 0;
847 }
848
849 asmlinkage long sys_getresgid(gid_t __user *rgid, gid_t __user *egid, gid_t __user *sgid)
850 {
851         int retval;
852
853         if (!(retval = put_user(current->gid, rgid)) &&
854             !(retval = put_user(current->egid, egid)))
855                 retval = put_user(current->sgid, sgid);
856
857         return retval;
858 }
859
860
861 /*
862  * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
863  * is used for "access()" and for the NFS daemon (letting nfsd stay at
864  * whatever uid it wants to). It normally shadows "euid", except when
865  * explicitly set by setfsuid() or for access..
866  */
867 asmlinkage long sys_setfsuid(uid_t uid)
868 {
869         int old_fsuid;
870
871         old_fsuid = current->fsuid;
872         if (security_task_setuid(uid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS))
873                 return old_fsuid;
874
875         if (uid == current->uid || uid == current->euid ||
876             uid == current->suid || uid == current->fsuid || 
877             capable(CAP_SETUID))
878         {
879                 if (uid != old_fsuid)
880                 {
881                         current->mm->dumpable = 0;
882                         smp_wmb();
883                 }
884                 current->fsuid = uid;
885         }
886
887         key_fsuid_changed(current);
888
889         security_task_post_setuid(old_fsuid, (uid_t)-1, (uid_t)-1, LSM_SETID_FS);
890
891         return old_fsuid;
892 }
893
894 /*
895  * Samma pÃ¥ svenska..
896  */
897 asmlinkage long sys_setfsgid(gid_t gid)
898 {
899         int old_fsgid;
900
901         old_fsgid = current->fsgid;
902         if (security_task_setgid(gid, (gid_t)-1, (gid_t)-1, LSM_SETID_FS))
903                 return old_fsgid;
904
905         if (gid == current->gid || gid == current->egid ||
906             gid == current->sgid || gid == current->fsgid || 
907             capable(CAP_SETGID))
908         {
909                 if (gid != old_fsgid)
910                 {
911                         current->mm->dumpable = 0;
912                         smp_wmb();
913                 }
914                 current->fsgid = gid;
915                 key_fsgid_changed(current);
916         }
917         return old_fsgid;
918 }
919
920 asmlinkage long sys_times(struct tms __user * tbuf)
921 {
922         /*
923          *      In the SMP world we might just be unlucky and have one of
924          *      the times increment as we use it. Since the value is an
925          *      atomically safe type this is just fine. Conceptually its
926          *      as if the syscall took an instant longer to occur.
927          */
928         if (tbuf) {
929                 struct tms tmp;
930                 struct task_struct *tsk = current;
931                 struct task_struct *t;
932                 cputime_t utime, stime, cutime, cstime;
933
934                 read_lock(&tasklist_lock);
935                 utime = tsk->signal->utime;
936                 stime = tsk->signal->stime;
937                 t = tsk;
938                 do {
939                         utime = cputime_add(utime, t->utime);
940                         stime = cputime_add(stime, t->stime);
941                         t = next_thread(t);
942                 } while (t != tsk);
943
944                 /*
945                  * While we have tasklist_lock read-locked, no dying thread
946                  * can be updating current->signal->[us]time.  Instead,
947                  * we got their counts included in the live thread loop.
948                  * However, another thread can come in right now and
949                  * do a wait call that updates current->signal->c[us]time.
950                  * To make sure we always see that pair updated atomically,
951                  * we take the siglock around fetching them.
952                  */
953                 spin_lock_irq(&tsk->sighand->siglock);
954                 cutime = tsk->signal->cutime;
955                 cstime = tsk->signal->cstime;
956                 spin_unlock_irq(&tsk->sighand->siglock);
957                 read_unlock(&tasklist_lock);
958
959                 tmp.tms_utime = cputime_to_clock_t(utime);
960                 tmp.tms_stime = cputime_to_clock_t(stime);
961                 tmp.tms_cutime = cputime_to_clock_t(cutime);
962                 tmp.tms_cstime = cputime_to_clock_t(cstime);
963                 if (copy_to_user(tbuf, &tmp, sizeof(struct tms)))
964                         return -EFAULT;
965         }
966         return (long) jiffies_64_to_clock_t(get_jiffies_64());
967 }
968
969 /*
970  * This needs some heavy checking ...
971  * I just haven't the stomach for it. I also don't fully
972  * understand sessions/pgrp etc. Let somebody who does explain it.
973  *
974  * OK, I think I have the protection semantics right.... this is really
975  * only important on a multi-user system anyway, to make sure one user
976  * can't send a signal to a process owned by another.  -TYT, 12/12/91
977  *
978  * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
979  * LBT 04.03.94
980  */
981
982 asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
983 {
984         struct task_struct *p;
985         int err = -EINVAL;
986         pid_t rpgid;
987
988         if (!pid)
989                 pid = vx_map_pid(current->pid);
990         if (!pgid)
991                 pgid = pid;
992         if (pgid < 0)
993                 return -EINVAL;
994
995         rpgid = vx_rmap_pid(pgid);
996
997         /* From this point forward we keep holding onto the tasklist lock
998          * so that our parent does not change from under us. -DaveM
999          */
1000         write_lock_irq(&tasklist_lock);
1001
1002         err = -ESRCH;
1003         p = find_task_by_pid(pid);
1004         if (!p)
1005                 goto out;
1006
1007         err = -EINVAL;
1008         if (!thread_group_leader(p))
1009                 goto out;
1010
1011         if (p->parent == current || p->real_parent == current) {
1012                 err = -EPERM;
1013                 if (p->signal->session != current->signal->session)
1014                         goto out;
1015                 err = -EACCES;
1016                 if (p->did_exec)
1017                         goto out;
1018         } else {
1019                 err = -ESRCH;
1020                 if (p != current)
1021                         goto out;
1022         }
1023
1024         err = -EPERM;
1025         if (p->signal->leader)
1026                 goto out;
1027
1028         if (pgid != pid) {
1029                 struct task_struct *p;
1030
1031                 do_each_task_pid(rpgid, PIDTYPE_PGID, p) {
1032                         if (p->signal->session == current->signal->session)
1033                                 goto ok_pgid;
1034                 } while_each_task_pid(rpgid, PIDTYPE_PGID, p);
1035                 goto out;
1036         }
1037
1038 ok_pgid:
1039         err = security_task_setpgid(p, rpgid);
1040         if (err)
1041                 goto out;
1042
1043         if (process_group(p) != rpgid) {
1044                 detach_pid(p, PIDTYPE_PGID);
1045                 p->signal->pgrp = rpgid;
1046                 attach_pid(p, PIDTYPE_PGID, rpgid);
1047         }
1048
1049         err = 0;
1050 out:
1051         /* All paths lead to here, thus we are safe. -DaveM */
1052         write_unlock_irq(&tasklist_lock);
1053         return err;
1054 }
1055
1056 asmlinkage long sys_getpgid(pid_t pid)
1057 {
1058         if (!pid) {
1059                 return vx_rmap_pid(process_group(current));
1060         } else {
1061                 int retval;
1062                 struct task_struct *p;
1063
1064                 read_lock(&tasklist_lock);
1065                 p = find_task_by_pid(pid);
1066
1067                 retval = -ESRCH;
1068                 if (p) {
1069                         retval = security_task_getpgid(p);
1070                         if (!retval)
1071                                 retval = vx_rmap_pid(process_group(p));
1072                 }
1073                 read_unlock(&tasklist_lock);
1074                 return retval;
1075         }
1076 }
1077
1078 #ifdef __ARCH_WANT_SYS_GETPGRP
1079
1080 asmlinkage long sys_getpgrp(void)
1081 {
1082         /* SMP - assuming writes are word atomic this is fine */
1083         return process_group(current);
1084 }
1085
1086 #endif
1087
1088 asmlinkage long sys_getsid(pid_t pid)
1089 {
1090         if (!pid) {
1091                 return current->signal->session;
1092         } else {
1093                 int retval;
1094                 struct task_struct *p;
1095
1096                 read_lock(&tasklist_lock);
1097                 p = find_task_by_pid(pid);
1098
1099                 retval = -ESRCH;
1100                 if(p) {
1101                         retval = security_task_getsid(p);
1102                         if (!retval)
1103                                 retval = p->signal->session;
1104                 }
1105                 read_unlock(&tasklist_lock);
1106                 return retval;
1107         }
1108 }
1109
1110 asmlinkage long sys_setsid(void)
1111 {
1112         struct pid *pid;
1113         int err = -EPERM;
1114
1115         if (!thread_group_leader(current))
1116                 return -EINVAL;
1117
1118         down(&tty_sem);
1119         write_lock_irq(&tasklist_lock);
1120
1121         pid = find_pid(PIDTYPE_PGID, current->pid);
1122         if (pid)
1123                 goto out;
1124
1125         current->signal->leader = 1;
1126         __set_special_pids(current->pid, current->pid);
1127         current->signal->tty = NULL;
1128         current->signal->tty_old_pgrp = 0;
1129         err = process_group(current);
1130 out:
1131         write_unlock_irq(&tasklist_lock);
1132         up(&tty_sem);
1133         return err;
1134 }
1135
1136 /*
1137  * Supplementary group IDs
1138  */
1139
1140 /* init to 2 - one for init_task, one to ensure it is never freed */
1141 struct group_info init_groups = { .usage = ATOMIC_INIT(2) };
1142
1143 struct group_info *groups_alloc(int gidsetsize)
1144 {
1145         struct group_info *group_info;
1146         int nblocks;
1147         int i;
1148
1149         nblocks = (gidsetsize + NGROUPS_PER_BLOCK - 1) / NGROUPS_PER_BLOCK;
1150         /* Make sure we always allocate at least one indirect block pointer */
1151         nblocks = nblocks ? : 1;
1152         group_info = kmalloc(sizeof(*group_info) + nblocks*sizeof(gid_t *), GFP_USER);
1153         if (!group_info)
1154                 return NULL;
1155         group_info->ngroups = gidsetsize;
1156         group_info->nblocks = nblocks;
1157         atomic_set(&group_info->usage, 1);
1158
1159         if (gidsetsize <= NGROUPS_SMALL) {
1160                 group_info->blocks[0] = group_info->small_block;
1161         } else {
1162                 for (i = 0; i < nblocks; i++) {
1163                         gid_t *b;
1164                         b = (void *)__get_free_page(GFP_USER);
1165                         if (!b)
1166                                 goto out_undo_partial_alloc;
1167                         group_info->blocks[i] = b;
1168                 }
1169         }
1170         return group_info;
1171
1172 out_undo_partial_alloc:
1173         while (--i >= 0) {
1174                 free_page((unsigned long)group_info->blocks[i]);
1175         }
1176         kfree(group_info);
1177         return NULL;
1178 }
1179
1180 EXPORT_SYMBOL(groups_alloc);
1181
1182 void groups_free(struct group_info *group_info)
1183 {
1184         if (group_info->blocks[0] != group_info->small_block) {
1185                 int i;
1186                 for (i = 0; i < group_info->nblocks; i++)
1187                         free_page((unsigned long)group_info->blocks[i]);
1188         }
1189         kfree(group_info);
1190 }
1191
1192 EXPORT_SYMBOL(groups_free);
1193
1194 /* export the group_info to a user-space array */
1195 static int groups_to_user(gid_t __user *grouplist,
1196     struct group_info *group_info)
1197 {
1198         int i;
1199         int count = group_info->ngroups;
1200
1201         for (i = 0; i < group_info->nblocks; i++) {
1202                 int cp_count = min(NGROUPS_PER_BLOCK, count);
1203                 int off = i * NGROUPS_PER_BLOCK;
1204                 int len = cp_count * sizeof(*grouplist);
1205
1206                 if (copy_to_user(grouplist+off, group_info->blocks[i], len))
1207                         return -EFAULT;
1208
1209                 count -= cp_count;
1210         }
1211         return 0;
1212 }
1213
1214 /* fill a group_info from a user-space array - it must be allocated already */
1215 static int groups_from_user(struct group_info *group_info,
1216     gid_t __user *grouplist)
1217  {
1218         int i;
1219         int count = group_info->ngroups;
1220
1221         for (i = 0; i < group_info->nblocks; i++) {
1222                 int cp_count = min(NGROUPS_PER_BLOCK, count);
1223                 int off = i * NGROUPS_PER_BLOCK;
1224                 int len = cp_count * sizeof(*grouplist);
1225
1226                 if (copy_from_user(group_info->blocks[i], grouplist+off, len))
1227                         return -EFAULT;
1228
1229                 count -= cp_count;
1230         }
1231         return 0;
1232 }
1233
1234 /* a simple Shell sort */
1235 static void groups_sort(struct group_info *group_info)
1236 {
1237         int base, max, stride;
1238         int gidsetsize = group_info->ngroups;
1239
1240         for (stride = 1; stride < gidsetsize; stride = 3 * stride + 1)
1241                 ; /* nothing */
1242         stride /= 3;
1243
1244         while (stride) {
1245                 max = gidsetsize - stride;
1246                 for (base = 0; base < max; base++) {
1247                         int left = base;
1248                         int right = left + stride;
1249                         gid_t tmp = GROUP_AT(group_info, right);
1250
1251                         while (left >= 0 && GROUP_AT(group_info, left) > tmp) {
1252                                 GROUP_AT(group_info, right) =
1253                                     GROUP_AT(group_info, left);
1254                                 right = left;
1255                                 left -= stride;
1256                         }
1257                         GROUP_AT(group_info, right) = tmp;
1258                 }
1259                 stride /= 3;
1260         }
1261 }
1262
1263 /* a simple bsearch */
1264 static int groups_search(struct group_info *group_info, gid_t grp)
1265 {
1266         int left, right;
1267
1268         if (!group_info)
1269                 return 0;
1270
1271         left = 0;
1272         right = group_info->ngroups;
1273         while (left < right) {
1274                 int mid = (left+right)/2;
1275                 int cmp = grp - GROUP_AT(group_info, mid);
1276                 if (cmp > 0)
1277                         left = mid + 1;
1278                 else if (cmp < 0)
1279                         right = mid;
1280                 else
1281                         return 1;
1282         }
1283         return 0;
1284 }
1285
1286 /* validate and set current->group_info */
1287 int set_current_groups(struct group_info *group_info)
1288 {
1289         int retval;
1290         struct group_info *old_info;
1291
1292         retval = security_task_setgroups(group_info);
1293         if (retval)
1294                 return retval;
1295
1296         groups_sort(group_info);
1297         get_group_info(group_info);
1298
1299         task_lock(current);
1300         old_info = current->group_info;
1301         current->group_info = group_info;
1302         task_unlock(current);
1303
1304         put_group_info(old_info);
1305
1306         return 0;
1307 }
1308
1309 EXPORT_SYMBOL(set_current_groups);
1310
1311 asmlinkage long sys_getgroups(int gidsetsize, gid_t __user *grouplist)
1312 {
1313         int i = 0;
1314
1315         /*
1316          *      SMP: Nobody else can change our grouplist. Thus we are
1317          *      safe.
1318          */
1319
1320         if (gidsetsize < 0)
1321                 return -EINVAL;
1322
1323         /* no need to grab task_lock here; it cannot change */
1324         get_group_info(current->group_info);
1325         i = current->group_info->ngroups;
1326         if (gidsetsize) {
1327                 if (i > gidsetsize) {
1328                         i = -EINVAL;
1329                         goto out;
1330                 }
1331                 if (groups_to_user(grouplist, current->group_info)) {
1332                         i = -EFAULT;
1333                         goto out;
1334                 }
1335         }
1336 out:
1337         put_group_info(current->group_info);
1338         return i;
1339 }
1340
1341 /*
1342  *      SMP: Our groups are copy-on-write. We can set them safely
1343  *      without another task interfering.
1344  */
1345  
1346 asmlinkage long sys_setgroups(int gidsetsize, gid_t __user *grouplist)
1347 {
1348         struct group_info *group_info;
1349         int retval;
1350
1351         if (!capable(CAP_SETGID))
1352                 return -EPERM;
1353         if ((unsigned)gidsetsize > NGROUPS_MAX)
1354                 return -EINVAL;
1355
1356         group_info = groups_alloc(gidsetsize);
1357         if (!group_info)
1358                 return -ENOMEM;
1359         retval = groups_from_user(group_info, grouplist);
1360         if (retval) {
1361                 put_group_info(group_info);
1362                 return retval;
1363         }
1364
1365         retval = set_current_groups(group_info);
1366         put_group_info(group_info);
1367
1368         return retval;
1369 }
1370
1371 /*
1372  * Check whether we're fsgid/egid or in the supplemental group..
1373  */
1374 int in_group_p(gid_t grp)
1375 {
1376         int retval = 1;
1377         if (grp != current->fsgid) {
1378                 get_group_info(current->group_info);
1379                 retval = groups_search(current->group_info, grp);
1380                 put_group_info(current->group_info);
1381         }
1382         return retval;
1383 }
1384
1385 EXPORT_SYMBOL(in_group_p);
1386
1387 int in_egroup_p(gid_t grp)
1388 {
1389         int retval = 1;
1390         if (grp != current->egid) {
1391                 get_group_info(current->group_info);
1392                 retval = groups_search(current->group_info, grp);
1393                 put_group_info(current->group_info);
1394         }
1395         return retval;
1396 }
1397
1398 EXPORT_SYMBOL(in_egroup_p);
1399
1400 DECLARE_RWSEM(uts_sem);
1401
1402 EXPORT_SYMBOL(uts_sem);
1403
1404 asmlinkage long sys_newuname(struct new_utsname __user * name)
1405 {
1406         int errno = 0;
1407
1408         down_read(&uts_sem);
1409         if (copy_to_user(name, vx_new_utsname(), sizeof *name))
1410                 errno = -EFAULT;
1411         up_read(&uts_sem);
1412         return errno;
1413 }
1414
1415 asmlinkage long sys_sethostname(char __user *name, int len)
1416 {
1417         int errno;
1418         char tmp[__NEW_UTS_LEN];
1419
1420         if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME))
1421                 return -EPERM;
1422         if (len < 0 || len > __NEW_UTS_LEN)
1423                 return -EINVAL;
1424         down_write(&uts_sem);
1425         errno = -EFAULT;
1426         if (!copy_from_user(tmp, name, len)) {
1427                 char *ptr = vx_new_uts(nodename);
1428
1429                 memcpy(ptr, tmp, len);
1430                 ptr[len] = 0;
1431                 errno = 0;
1432         }
1433         up_write(&uts_sem);
1434         return errno;
1435 }
1436
1437 #ifdef __ARCH_WANT_SYS_GETHOSTNAME
1438
1439 asmlinkage long sys_gethostname(char __user *name, int len)
1440 {
1441         int i, errno;
1442         char *ptr;
1443
1444         if (len < 0)
1445                 return -EINVAL;
1446         down_read(&uts_sem);
1447         ptr = vx_new_uts(nodename);
1448         i = 1 + strlen(ptr);
1449         if (i > len)
1450                 i = len;
1451         errno = 0;
1452         if (copy_to_user(name, ptr, i))
1453                 errno = -EFAULT;
1454         up_read(&uts_sem);
1455         return errno;
1456 }
1457
1458 #endif
1459
1460 /*
1461  * Only setdomainname; getdomainname can be implemented by calling
1462  * uname()
1463  */
1464 asmlinkage long sys_setdomainname(char __user *name, int len)
1465 {
1466         int errno;
1467         char tmp[__NEW_UTS_LEN];
1468
1469         if (!capable(CAP_SYS_ADMIN) && !vx_ccaps(VXC_SET_UTSNAME))
1470                 return -EPERM;
1471         if (len < 0 || len > __NEW_UTS_LEN)
1472                 return -EINVAL;
1473
1474         down_write(&uts_sem);
1475         errno = -EFAULT;
1476         if (!copy_from_user(tmp, name, len)) {
1477                 char *ptr = vx_new_uts(domainname);
1478
1479                 memcpy(ptr, tmp, len);
1480                 ptr[len] = 0;
1481                 errno = 0;
1482         }
1483         up_write(&uts_sem);
1484         return errno;
1485 }
1486
1487 asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit __user *rlim)
1488 {
1489         if (resource >= RLIM_NLIMITS)
1490                 return -EINVAL;
1491         else {
1492                 struct rlimit value;
1493                 task_lock(current->group_leader);
1494                 value = current->signal->rlim[resource];
1495                 task_unlock(current->group_leader);
1496                 return copy_to_user(rlim, &value, sizeof(*rlim)) ? -EFAULT : 0;
1497         }
1498 }
1499
1500 #ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT
1501
1502 /*
1503  *      Back compatibility for getrlimit. Needed for some apps.
1504  */
1505  
1506 asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim)
1507 {
1508         struct rlimit x;
1509         if (resource >= RLIM_NLIMITS)
1510                 return -EINVAL;
1511
1512         task_lock(current->group_leader);
1513         x = current->signal->rlim[resource];
1514         task_unlock(current->group_leader);
1515         if(x.rlim_cur > 0x7FFFFFFF)
1516                 x.rlim_cur = 0x7FFFFFFF;
1517         if(x.rlim_max > 0x7FFFFFFF)
1518                 x.rlim_max = 0x7FFFFFFF;
1519         return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;
1520 }
1521
1522 #endif
1523
1524 asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit __user *rlim)
1525 {
1526         struct rlimit new_rlim, *old_rlim;
1527         int retval;
1528
1529         if (resource >= RLIM_NLIMITS)
1530                 return -EINVAL;
1531         if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1532                 return -EFAULT;
1533        if (new_rlim.rlim_cur > new_rlim.rlim_max)
1534                return -EINVAL;
1535         old_rlim = current->signal->rlim + resource;
1536         if ((new_rlim.rlim_max > old_rlim->rlim_max) &&
1537             !capable(CAP_SYS_RESOURCE) && !vx_ccaps(VXC_SET_RLIMIT))
1538                 return -EPERM;
1539         if (resource == RLIMIT_NOFILE && new_rlim.rlim_max > NR_OPEN)
1540                         return -EPERM;
1541
1542         retval = security_task_setrlimit(resource, &new_rlim);
1543         if (retval)
1544                 return retval;
1545
1546         task_lock(current->group_leader);
1547         *old_rlim = new_rlim;
1548         task_unlock(current->group_leader);
1549
1550         if (resource == RLIMIT_CPU && new_rlim.rlim_cur != RLIM_INFINITY &&
1551             (cputime_eq(current->signal->it_prof_expires, cputime_zero) ||
1552              new_rlim.rlim_cur <= cputime_to_secs(
1553                      current->signal->it_prof_expires))) {
1554                 cputime_t cputime = secs_to_cputime(new_rlim.rlim_cur);
1555                 read_lock(&tasklist_lock);
1556                 spin_lock_irq(&current->sighand->siglock);
1557                 set_process_cpu_timer(current, CPUCLOCK_PROF,
1558                                       &cputime, NULL);
1559                 spin_unlock_irq(&current->sighand->siglock);
1560                 read_unlock(&tasklist_lock);
1561         }
1562
1563         return 0;
1564 }
1565
1566 /*
1567  * It would make sense to put struct rusage in the task_struct,
1568  * except that would make the task_struct be *really big*.  After
1569  * task_struct gets moved into malloc'ed memory, it would
1570  * make sense to do this.  It will make moving the rest of the information
1571  * a lot simpler!  (Which we're not doing right now because we're not
1572  * measuring them yet).
1573  *
1574  * This expects to be called with tasklist_lock read-locked or better,
1575  * and the siglock not locked.  It may momentarily take the siglock.
1576  *
1577  * When sampling multiple threads for RUSAGE_SELF, under SMP we might have
1578  * races with threads incrementing their own counters.  But since word
1579  * reads are atomic, we either get new values or old values and we don't
1580  * care which for the sums.  We always take the siglock to protect reading
1581  * the c* fields from p->signal from races with exit.c updating those
1582  * fields when reaping, so a sample either gets all the additions of a
1583  * given child after it's reaped, or none so this sample is before reaping.
1584  */
1585
1586 static void k_getrusage(struct task_struct *p, int who, struct rusage *r)
1587 {
1588         struct task_struct *t;
1589         unsigned long flags;
1590         cputime_t utime, stime;
1591
1592         memset((char *) r, 0, sizeof *r);
1593
1594         if (unlikely(!p->signal))
1595                 return;
1596
1597         switch (who) {
1598                 case RUSAGE_CHILDREN:
1599                         spin_lock_irqsave(&p->sighand->siglock, flags);
1600                         utime = p->signal->cutime;
1601                         stime = p->signal->cstime;
1602                         r->ru_nvcsw = p->signal->cnvcsw;
1603                         r->ru_nivcsw = p->signal->cnivcsw;
1604                         r->ru_minflt = p->signal->cmin_flt;
1605                         r->ru_majflt = p->signal->cmaj_flt;
1606                         spin_unlock_irqrestore(&p->sighand->siglock, flags);
1607                         cputime_to_timeval(utime, &r->ru_utime);
1608                         cputime_to_timeval(stime, &r->ru_stime);
1609                         break;
1610                 case RUSAGE_SELF:
1611                         spin_lock_irqsave(&p->sighand->siglock, flags);
1612                         utime = stime = cputime_zero;
1613                         goto sum_group;
1614                 case RUSAGE_BOTH:
1615                         spin_lock_irqsave(&p->sighand->siglock, flags);
1616                         utime = p->signal->cutime;
1617                         stime = p->signal->cstime;
1618                         r->ru_nvcsw = p->signal->cnvcsw;
1619                         r->ru_nivcsw = p->signal->cnivcsw;
1620                         r->ru_minflt = p->signal->cmin_flt;
1621                         r->ru_majflt = p->signal->cmaj_flt;
1622                 sum_group:
1623                         utime = cputime_add(utime, p->signal->utime);
1624                         stime = cputime_add(stime, p->signal->stime);
1625                         r->ru_nvcsw += p->signal->nvcsw;
1626                         r->ru_nivcsw += p->signal->nivcsw;
1627                         r->ru_minflt += p->signal->min_flt;
1628                         r->ru_majflt += p->signal->maj_flt;
1629                         t = p;
1630                         do {
1631                                 utime = cputime_add(utime, t->utime);
1632                                 stime = cputime_add(stime, t->stime);
1633                                 r->ru_nvcsw += t->nvcsw;
1634                                 r->ru_nivcsw += t->nivcsw;
1635                                 r->ru_minflt += t->min_flt;
1636                                 r->ru_majflt += t->maj_flt;
1637                                 t = next_thread(t);
1638                         } while (t != p);
1639                         spin_unlock_irqrestore(&p->sighand->siglock, flags);
1640                         cputime_to_timeval(utime, &r->ru_utime);
1641                         cputime_to_timeval(stime, &r->ru_stime);
1642                         break;
1643                 default:
1644                         BUG();
1645         }
1646 }
1647
1648 int getrusage(struct task_struct *p, int who, struct rusage __user *ru)
1649 {
1650         struct rusage r;
1651         read_lock(&tasklist_lock);
1652         k_getrusage(p, who, &r);
1653         read_unlock(&tasklist_lock);
1654         return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1655 }
1656
1657 asmlinkage long sys_getrusage(int who, struct rusage __user *ru)
1658 {
1659         if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
1660                 return -EINVAL;
1661         return getrusage(current, who, ru);
1662 }
1663
1664 asmlinkage long sys_umask(int mask)
1665 {
1666         mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
1667         return mask;
1668 }
1669     
1670 asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1671                           unsigned long arg4, unsigned long arg5)
1672 {
1673         long error;
1674         int sig;
1675
1676         error = security_task_prctl(option, arg2, arg3, arg4, arg5);
1677         if (error)
1678                 return error;
1679
1680         switch (option) {
1681                 case PR_SET_PDEATHSIG:
1682                         sig = arg2;
1683                         if (!valid_signal(sig)) {
1684                                 error = -EINVAL;
1685                                 break;
1686                         }
1687                         current->pdeath_signal = sig;
1688                         break;
1689                 case PR_GET_PDEATHSIG:
1690                         error = put_user(current->pdeath_signal, (int __user *)arg2);
1691                         break;
1692                 case PR_GET_DUMPABLE:
1693                         if (current->mm->dumpable)
1694                                 error = 1;
1695                         break;
1696                 case PR_SET_DUMPABLE:
1697                         if (arg2 != 0 && arg2 != 1) {
1698                                 error = -EINVAL;
1699                                 break;
1700                         }
1701                         current->mm->dumpable = arg2;
1702                         break;
1703
1704                 case PR_SET_UNALIGN:
1705                         error = SET_UNALIGN_CTL(current, arg2);
1706                         break;
1707                 case PR_GET_UNALIGN:
1708                         error = GET_UNALIGN_CTL(current, arg2);
1709                         break;
1710                 case PR_SET_FPEMU:
1711                         error = SET_FPEMU_CTL(current, arg2);
1712                         break;
1713                 case PR_GET_FPEMU:
1714                         error = GET_FPEMU_CTL(current, arg2);
1715                         break;
1716                 case PR_SET_FPEXC:
1717                         error = SET_FPEXC_CTL(current, arg2);
1718                         break;
1719                 case PR_GET_FPEXC:
1720                         error = GET_FPEXC_CTL(current, arg2);
1721                         break;
1722                 case PR_GET_TIMING:
1723                         error = PR_TIMING_STATISTICAL;
1724                         break;
1725                 case PR_SET_TIMING:
1726                         if (arg2 == PR_TIMING_STATISTICAL)
1727                                 error = 0;
1728                         else
1729                                 error = -EINVAL;
1730                         break;
1731
1732                 case PR_GET_KEEPCAPS:
1733                         if (current->keep_capabilities)
1734                                 error = 1;
1735                         break;
1736                 case PR_SET_KEEPCAPS:
1737                         if (arg2 != 0 && arg2 != 1) {
1738                                 error = -EINVAL;
1739                                 break;
1740                         }
1741                         current->keep_capabilities = arg2;
1742                         break;
1743                 case PR_SET_NAME: {
1744                         struct task_struct *me = current;
1745                         unsigned char ncomm[sizeof(me->comm)];
1746
1747                         ncomm[sizeof(me->comm)-1] = 0;
1748                         if (strncpy_from_user(ncomm, (char __user *)arg2,
1749                                                 sizeof(me->comm)-1) < 0)
1750                                 return -EFAULT;
1751                         set_task_comm(me, ncomm);
1752                         return 0;
1753                 }
1754                 case PR_GET_NAME: {
1755                         struct task_struct *me = current;
1756                         unsigned char tcomm[sizeof(me->comm)];
1757
1758                         get_task_comm(tcomm, me);
1759                         if (copy_to_user((char __user *)arg2, tcomm, sizeof(tcomm)))
1760                                 return -EFAULT;
1761                         return 0;
1762                 }
1763                 default:
1764                         error = -EINVAL;
1765                         break;
1766         }
1767         return error;
1768 }