make oldconfig will rebuild these...
[linux-2.4.21-pre4.git] / kernel / sys.c
1 /*
2  *  linux/kernel/sys.c
3  *
4  *  Copyright (C) 1991, 1992  Linus Torvalds
5  */
6
7 #include <linux/module.h>
8 #include <linux/mm.h>
9 #include <linux/utsname.h>
10 #include <linux/mman.h>
11 #include <linux/smp_lock.h>
12 #include <linux/notifier.h>
13 #include <linux/reboot.h>
14 #include <linux/prctl.h>
15 #include <linux/init.h>
16 #include <linux/highuid.h>
17
18 #include <asm/uaccess.h>
19 #include <asm/io.h>
20
21 #ifndef SET_UNALIGN_CTL
22 # define SET_UNALIGN_CTL(a,b)   (-EINVAL)
23 #endif
24 #ifndef GET_UNALIGN_CTL
25 # define GET_UNALIGN_CTL(a,b)   (-EINVAL)
26 #endif
27 #ifndef SET_FPEMU_CTL
28 # define SET_FPEMU_CTL(a,b)     (-EINVAL)
29 #endif
30 #ifndef GET_FPEMU_CTL
31 # define GET_FPEMU_CTL(a,b)     (-EINVAL)
32 #endif
33 #ifndef SET_FPEXC_CTL
34 # define SET_FPEXC_CTL(a,b)     (-EINVAL)
35 #endif
36 #ifndef GET_FPEXC_CTL
37 # define GET_FPEXC_CTL(a,b)     (-EINVAL)
38 #endif
39
40 /*
41  * this is where the system-wide overflow UID and GID are defined, for
42  * architectures that now have 32-bit UID/GID but didn't in the past
43  */
44
45 int overflowuid = DEFAULT_OVERFLOWUID;
46 int overflowgid = DEFAULT_OVERFLOWGID;
47
48 /*
49  * the same as above, but for filesystems which can only store a 16-bit
50  * UID and GID. as such, this is needed on all architectures
51  */
52
53 int fs_overflowuid = DEFAULT_FS_OVERFLOWUID;
54 int fs_overflowgid = DEFAULT_FS_OVERFLOWUID;
55
56 /*
57  * this indicates whether you can reboot with ctrl-alt-del: the default is yes
58  */
59
60 int C_A_D = 1;
61 int cad_pid = 1;
62
63
64 /*
65  *      Notifier list for kernel code which wants to be called
66  *      at shutdown. This is used to stop any idling DMA operations
67  *      and the like. 
68  */
69
70 static struct notifier_block *reboot_notifier_list;
71 rwlock_t notifier_lock = RW_LOCK_UNLOCKED;
72
73 /**
74  *      notifier_chain_register - Add notifier to a notifier chain
75  *      @list: Pointer to root list pointer
76  *      @n: New entry in notifier chain
77  *
78  *      Adds a notifier to a notifier chain.
79  *
80  *      Currently always returns zero.
81  */
82  
83 int notifier_chain_register(struct notifier_block **list, struct notifier_block *n)
84 {
85         write_lock(&notifier_lock);
86         while(*list)
87         {
88                 if(n->priority > (*list)->priority)
89                         break;
90                 list= &((*list)->next);
91         }
92         n->next = *list;
93         *list=n;
94         write_unlock(&notifier_lock);
95         return 0;
96 }
97
98 /**
99  *      notifier_chain_unregister - Remove notifier from a notifier chain
100  *      @nl: Pointer to root list pointer
101  *      @n: New entry in notifier chain
102  *
103  *      Removes a notifier from a notifier chain.
104  *
105  *      Returns zero on success, or %-ENOENT on failure.
106  */
107  
108 int notifier_chain_unregister(struct notifier_block **nl, struct notifier_block *n)
109 {
110         write_lock(&notifier_lock);
111         while((*nl)!=NULL)
112         {
113                 if((*nl)==n)
114                 {
115                         *nl=n->next;
116                         write_unlock(&notifier_lock);
117                         return 0;
118                 }
119                 nl=&((*nl)->next);
120         }
121         write_unlock(&notifier_lock);
122         return -ENOENT;
123 }
124
125 /**
126  *      notifier_call_chain - Call functions in a notifier chain
127  *      @n: Pointer to root pointer of notifier chain
128  *      @val: Value passed unmodified to notifier function
129  *      @v: Pointer passed unmodified to notifier function
130  *
131  *      Calls each function in a notifier chain in turn.
132  *
133  *      If the return value of the notifier can be and'd
134  *      with %NOTIFY_STOP_MASK, then notifier_call_chain
135  *      will return immediately, with the return value of
136  *      the notifier function which halted execution.
137  *      Otherwise, the return value is the return value
138  *      of the last notifier function called.
139  */
140  
141 int notifier_call_chain(struct notifier_block **n, unsigned long val, void *v)
142 {
143         int ret=NOTIFY_DONE;
144         struct notifier_block *nb = *n;
145
146         while(nb)
147         {
148                 ret=nb->notifier_call(nb,val,v);
149                 if(ret&NOTIFY_STOP_MASK)
150                 {
151                         return ret;
152                 }
153                 nb=nb->next;
154         }
155         return ret;
156 }
157
158 /**
159  *      register_reboot_notifier - Register function to be called at reboot time
160  *      @nb: Info about notifier function to be called
161  *
162  *      Registers a function with the list of functions
163  *      to be called at reboot time.
164  *
165  *      Currently always returns zero, as notifier_chain_register
166  *      always returns zero.
167  */
168  
169 int register_reboot_notifier(struct notifier_block * nb)
170 {
171         return notifier_chain_register(&reboot_notifier_list, nb);
172 }
173
174 /**
175  *      unregister_reboot_notifier - Unregister previously registered reboot notifier
176  *      @nb: Hook to be unregistered
177  *
178  *      Unregisters a previously registered reboot
179  *      notifier function.
180  *
181  *      Returns zero on success, or %-ENOENT on failure.
182  */
183  
184 int unregister_reboot_notifier(struct notifier_block * nb)
185 {
186         return notifier_chain_unregister(&reboot_notifier_list, nb);
187 }
188
189 asmlinkage long sys_ni_syscall(void)
190 {
191         return -ENOSYS;
192 }
193
194 static int proc_sel(struct task_struct *p, int which, int who)
195 {
196         if(p->pid)
197         {
198                 switch (which) {
199                         case PRIO_PROCESS:
200                                 if (!who && p == current)
201                                         return 1;
202                                 return(p->pid == who);
203                         case PRIO_PGRP:
204                                 if (!who)
205                                         who = current->pgrp;
206                                 return(p->pgrp == who);
207                         case PRIO_USER:
208                                 if (!who)
209                                         who = current->uid;
210                                 return(p->uid == who);
211                 }
212         }
213         return 0;
214 }
215
216 asmlinkage long sys_setpriority(int which, int who, int niceval)
217 {
218         struct task_struct *p;
219         int error;
220
221         if (which > 2 || which < 0)
222                 return -EINVAL;
223
224         /* normalize: avoid signed division (rounding problems) */
225         error = -ESRCH;
226         if (niceval < -20)
227                 niceval = -20;
228         if (niceval > 19)
229                 niceval = 19;
230
231         read_lock(&tasklist_lock);
232         for_each_task(p) {
233                 if (!proc_sel(p, which, who))
234                         continue;
235                 if (p->uid != current->euid &&
236                         p->uid != current->uid && !capable(CAP_SYS_NICE)) {
237                         error = -EPERM;
238                         continue;
239                 }
240                 if (error == -ESRCH)
241                         error = 0;
242                 if (niceval < p->nice && !capable(CAP_SYS_NICE))
243                         error = -EACCES;
244                 else
245                         p->nice = niceval;
246         }
247         read_unlock(&tasklist_lock);
248
249         return error;
250 }
251
252 /*
253  * Ugh. To avoid negative return values, "getpriority()" will
254  * not return the normal nice-value, but a negated value that
255  * has been offset by 20 (ie it returns 40..1 instead of -20..19)
256  * to stay compatible.
257  */
258 asmlinkage long sys_getpriority(int which, int who)
259 {
260         struct task_struct *p;
261         long retval = -ESRCH;
262
263         if (which > 2 || which < 0)
264                 return -EINVAL;
265
266         read_lock(&tasklist_lock);
267         for_each_task (p) {
268                 long niceval;
269                 if (!proc_sel(p, which, who))
270                         continue;
271                 niceval = 20 - p->nice;
272                 if (niceval > retval)
273                         retval = niceval;
274         }
275         read_unlock(&tasklist_lock);
276
277         return retval;
278 }
279
280
281 /*
282  * Reboot system call: for obvious reasons only root may call it,
283  * and even root needs to set up some magic numbers in the registers
284  * so that some mistake won't make this reboot the whole machine.
285  * You can also set the meaning of the ctrl-alt-del-key here.
286  *
287  * reboot doesn't sync: do that yourself before calling this.
288  */
289 asmlinkage long sys_reboot(int magic1, int magic2, unsigned int cmd, void * arg)
290 {
291         char buffer[256];
292
293         /* We only trust the superuser with rebooting the system. */
294         if (!capable(CAP_SYS_BOOT))
295                 return -EPERM;
296
297         /* For safety, we require "magic" arguments. */
298         if (magic1 != LINUX_REBOOT_MAGIC1 ||
299             (magic2 != LINUX_REBOOT_MAGIC2 && magic2 != LINUX_REBOOT_MAGIC2A &&
300                         magic2 != LINUX_REBOOT_MAGIC2B))
301                 return -EINVAL;
302
303         lock_kernel();
304         switch (cmd) {
305         case LINUX_REBOOT_CMD_RESTART:
306                 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
307                 printk(KERN_EMERG "Restarting system.\n");
308                 machine_restart(NULL);
309                 break;
310
311         case LINUX_REBOOT_CMD_CAD_ON:
312                 C_A_D = 1;
313                 break;
314
315         case LINUX_REBOOT_CMD_CAD_OFF:
316                 C_A_D = 0;
317                 break;
318
319         case LINUX_REBOOT_CMD_HALT:
320                 notifier_call_chain(&reboot_notifier_list, SYS_HALT, NULL);
321                 printk(KERN_EMERG "System halted.\n");
322                 machine_halt();
323                 do_exit(0);
324                 break;
325
326         case LINUX_REBOOT_CMD_POWER_OFF:
327                 notifier_call_chain(&reboot_notifier_list, SYS_POWER_OFF, NULL);
328                 printk(KERN_EMERG "Power down.\n");
329                 machine_power_off();
330                 do_exit(0);
331                 break;
332
333         case LINUX_REBOOT_CMD_RESTART2:
334                 if (strncpy_from_user(&buffer[0], (char *)arg, sizeof(buffer) - 1) < 0) {
335                         unlock_kernel();
336                         return -EFAULT;
337                 }
338                 buffer[sizeof(buffer) - 1] = '\0';
339
340                 notifier_call_chain(&reboot_notifier_list, SYS_RESTART, buffer);
341                 printk(KERN_EMERG "Restarting system with command '%s'.\n", buffer);
342                 machine_restart(buffer);
343                 break;
344
345         default:
346                 unlock_kernel();
347                 return -EINVAL;
348         }
349         unlock_kernel();
350         return 0;
351 }
352
353 static void deferred_cad(void *dummy)
354 {
355         notifier_call_chain(&reboot_notifier_list, SYS_RESTART, NULL);
356         machine_restart(NULL);
357 }
358
359 /*
360  * This function gets called by ctrl-alt-del - ie the keyboard interrupt.
361  * As it's called within an interrupt, it may NOT sync: the only choice
362  * is whether to reboot at once, or just ignore the ctrl-alt-del.
363  */
364 void ctrl_alt_del(void)
365 {
366         static struct tq_struct cad_tq = {
367                 routine: deferred_cad,
368         };
369
370         if (C_A_D)
371                 schedule_task(&cad_tq);
372         else
373                 kill_proc(cad_pid, SIGINT, 1);
374 }
375         
376
377 /*
378  * Unprivileged users may change the real gid to the effective gid
379  * or vice versa.  (BSD-style)
380  *
381  * If you set the real gid at all, or set the effective gid to a value not
382  * equal to the real gid, then the saved gid is set to the new effective gid.
383  *
384  * This makes it possible for a setgid program to completely drop its
385  * privileges, which is often a useful assertion to make when you are doing
386  * a security audit over a program.
387  *
388  * The general idea is that a program which uses just setregid() will be
389  * 100% compatible with BSD.  A program which uses just setgid() will be
390  * 100% compatible with POSIX with saved IDs. 
391  *
392  * SMP: There are not races, the GIDs are checked only by filesystem
393  *      operations (as far as semantic preservation is concerned).
394  */
395 asmlinkage long sys_setregid(gid_t rgid, gid_t egid)
396 {
397         int old_rgid = current->gid;
398         int old_egid = current->egid;
399         int new_rgid = old_rgid;
400         int new_egid = old_egid;
401
402         if (rgid != (gid_t) -1) {
403                 if ((old_rgid == rgid) ||
404                     (current->egid==rgid) ||
405                     capable(CAP_SETGID))
406                         new_rgid = rgid;
407                 else
408                         return -EPERM;
409         }
410         if (egid != (gid_t) -1) {
411                 if ((old_rgid == egid) ||
412                     (current->egid == egid) ||
413                     (current->sgid == egid) ||
414                     capable(CAP_SETGID))
415                         new_egid = egid;
416                 else {
417                         return -EPERM;
418                 }
419         }
420         if (new_egid != old_egid)
421         {
422                 current->mm->dumpable = 0;
423                 wmb();
424         }
425         if (rgid != (gid_t) -1 ||
426             (egid != (gid_t) -1 && egid != old_rgid))
427                 current->sgid = new_egid;
428         current->fsgid = new_egid;
429         current->egid = new_egid;
430         current->gid = new_rgid;
431         return 0;
432 }
433
434 /*
435  * setgid() is implemented like SysV w/ SAVED_IDS 
436  *
437  * SMP: Same implicit races as above.
438  */
439 asmlinkage long sys_setgid(gid_t gid)
440 {
441         int old_egid = current->egid;
442
443         if (capable(CAP_SETGID))
444         {
445                 if(old_egid != gid)
446                 {
447                         current->mm->dumpable=0;
448                         wmb();
449                 }
450                 current->gid = current->egid = current->sgid = current->fsgid = gid;
451         }
452         else if ((gid == current->gid) || (gid == current->sgid))
453         {
454                 if(old_egid != gid)
455                 {
456                         current->mm->dumpable=0;
457                         wmb();
458                 }
459                 current->egid = current->fsgid = gid;
460         }
461         else
462                 return -EPERM;
463         return 0;
464 }
465   
466 /* 
467  * cap_emulate_setxuid() fixes the effective / permitted capabilities of
468  * a process after a call to setuid, setreuid, or setresuid.
469  *
470  *  1) When set*uiding _from_ one of {r,e,s}uid == 0 _to_ all of
471  *  {r,e,s}uid != 0, the permitted and effective capabilities are
472  *  cleared.
473  *
474  *  2) When set*uiding _from_ euid == 0 _to_ euid != 0, the effective
475  *  capabilities of the process are cleared.
476  *
477  *  3) When set*uiding _from_ euid != 0 _to_ euid == 0, the effective
478  *  capabilities are set to the permitted capabilities.
479  *
480  *  fsuid is handled elsewhere. fsuid == 0 and {r,e,s}uid!= 0 should 
481  *  never happen.
482  *
483  *  -astor 
484  *
485  * cevans - New behaviour, Oct '99
486  * A process may, via prctl(), elect to keep its capabilities when it
487  * calls setuid() and switches away from uid==0. Both permitted and
488  * effective sets will be retained.
489  * Without this change, it was impossible for a daemon to drop only some
490  * of its privilege. The call to setuid(!=0) would drop all privileges!
491  * Keeping uid 0 is not an option because uid 0 owns too many vital
492  * files..
493  * Thanks to Olaf Kirch and Peter Benie for spotting this.
494  */
495 static inline void cap_emulate_setxuid(int old_ruid, int old_euid, 
496                                        int old_suid)
497 {
498         if ((old_ruid == 0 || old_euid == 0 || old_suid == 0) &&
499             (current->uid != 0 && current->euid != 0 && current->suid != 0) &&
500             !current->keep_capabilities) {
501                 cap_clear(current->cap_permitted);
502                 cap_clear(current->cap_effective);
503         }
504         if (old_euid == 0 && current->euid != 0) {
505                 cap_clear(current->cap_effective);
506         }
507         if (old_euid != 0 && current->euid == 0) {
508                 current->cap_effective = current->cap_permitted;
509         }
510 }
511
512 static int set_user(uid_t new_ruid, int dumpclear)
513 {
514         struct user_struct *new_user, *old_user;
515
516         /* What if a process setreuid()'s and this brings the
517          * new uid over his NPROC rlimit?  We can check this now
518          * cheaply with the new uid cache, so if it matters
519          * we should be checking for it.  -DaveM
520          */
521         new_user = alloc_uid(new_ruid);
522         if (!new_user)
523                 return -EAGAIN;
524         old_user = current->user;
525         atomic_dec(&old_user->processes);
526         atomic_inc(&new_user->processes);
527
528         if(dumpclear)
529         {
530                 current->mm->dumpable = 0;
531                 wmb();
532         }
533         current->uid = new_ruid;
534         current->user = new_user;
535         free_uid(old_user);
536         return 0;
537 }
538
539 /*
540  * Unprivileged users may change the real uid to the effective uid
541  * or vice versa.  (BSD-style)
542  *
543  * If you set the real uid at all, or set the effective uid to a value not
544  * equal to the real uid, then the saved uid is set to the new effective uid.
545  *
546  * This makes it possible for a setuid program to completely drop its
547  * privileges, which is often a useful assertion to make when you are doing
548  * a security audit over a program.
549  *
550  * The general idea is that a program which uses just setreuid() will be
551  * 100% compatible with BSD.  A program which uses just setuid() will be
552  * 100% compatible with POSIX with saved IDs. 
553  */
554 asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
555 {
556         int old_ruid, old_euid, old_suid, new_ruid, new_euid;
557
558         new_ruid = old_ruid = current->uid;
559         new_euid = old_euid = current->euid;
560         old_suid = current->suid;
561
562         if (ruid != (uid_t) -1) {
563                 new_ruid = ruid;
564                 if ((old_ruid != ruid) &&
565                     (current->euid != ruid) &&
566                     !capable(CAP_SETUID))
567                         return -EPERM;
568         }
569
570         if (euid != (uid_t) -1) {
571                 new_euid = euid;
572                 if ((old_ruid != euid) &&
573                     (current->euid != euid) &&
574                     (current->suid != euid) &&
575                     !capable(CAP_SETUID))
576                         return -EPERM;
577         }
578
579         if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
580                 return -EAGAIN;
581
582         if (new_euid != old_euid)
583         {
584                 current->mm->dumpable=0;
585                 wmb();
586         }
587         current->fsuid = current->euid = new_euid;
588         if (ruid != (uid_t) -1 ||
589             (euid != (uid_t) -1 && euid != old_ruid))
590                 current->suid = current->euid;
591         current->fsuid = current->euid;
592
593         if (!issecure(SECURE_NO_SETUID_FIXUP)) {
594                 cap_emulate_setxuid(old_ruid, old_euid, old_suid);
595         }
596
597         return 0;
598 }
599
600
601                 
602 /*
603  * setuid() is implemented like SysV with SAVED_IDS 
604  * 
605  * Note that SAVED_ID's is deficient in that a setuid root program
606  * like sendmail, for example, cannot set its uid to be a normal 
607  * user and then switch back, because if you're root, setuid() sets
608  * the saved uid too.  If you don't like this, blame the bright people
609  * in the POSIX committee and/or USG.  Note that the BSD-style setreuid()
610  * will allow a root program to temporarily drop privileges and be able to
611  * regain them by swapping the real and effective uid.  
612  */
613 asmlinkage long sys_setuid(uid_t uid)
614 {
615         int old_euid = current->euid;
616         int old_ruid, old_suid, new_ruid, new_suid;
617
618         old_ruid = new_ruid = current->uid;
619         old_suid = current->suid;
620         new_suid = old_suid;
621         
622         if (capable(CAP_SETUID)) {
623                 if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
624                         return -EAGAIN;
625                 new_suid = uid;
626         } else if ((uid != current->uid) && (uid != new_suid))
627                 return -EPERM;
628
629         if (old_euid != uid)
630         {
631                 current->mm->dumpable = 0;
632                 wmb();
633         }
634         current->fsuid = current->euid = uid;
635         current->suid = new_suid;
636
637         if (!issecure(SECURE_NO_SETUID_FIXUP)) {
638                 cap_emulate_setxuid(old_ruid, old_euid, old_suid);
639         }
640
641         return 0;
642 }
643
644
645 /*
646  * This function implements a generic ability to update ruid, euid,
647  * and suid.  This allows you to implement the 4.4 compatible seteuid().
648  */
649 asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
650 {
651         int old_ruid = current->uid;
652         int old_euid = current->euid;
653         int old_suid = current->suid;
654
655         if (!capable(CAP_SETUID)) {
656                 if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
657                     (ruid != current->euid) && (ruid != current->suid))
658                         return -EPERM;
659                 if ((euid != (uid_t) -1) && (euid != current->uid) &&
660                     (euid != current->euid) && (euid != current->suid))
661                         return -EPERM;
662                 if ((suid != (uid_t) -1) && (suid != current->uid) &&
663                     (suid != current->euid) && (suid != current->suid))
664                         return -EPERM;
665         }
666         if (ruid != (uid_t) -1) {
667                 if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
668                         return -EAGAIN;
669         }
670         if (euid != (uid_t) -1) {
671                 if (euid != current->euid)
672                 {
673                         current->mm->dumpable = 0;
674                         wmb();
675                 }
676                 current->euid = euid;
677         }
678         current->fsuid = current->euid;
679         if (suid != (uid_t) -1)
680                 current->suid = suid;
681
682         if (!issecure(SECURE_NO_SETUID_FIXUP)) {
683                 cap_emulate_setxuid(old_ruid, old_euid, old_suid);
684         }
685
686         return 0;
687 }
688
689 asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
690 {
691         int retval;
692
693         if (!(retval = put_user(current->uid, ruid)) &&
694             !(retval = put_user(current->euid, euid)))
695                 retval = put_user(current->suid, suid);
696
697         return retval;
698 }
699
700 /*
701  * Same as above, but for rgid, egid, sgid.
702  */
703 asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
704 {
705         if (!capable(CAP_SETGID)) {
706                 if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
707                     (rgid != current->egid) && (rgid != current->sgid))
708                         return -EPERM;
709                 if ((egid != (gid_t) -1) && (egid != current->gid) &&
710                     (egid != current->egid) && (egid != current->sgid))
711                         return -EPERM;
712                 if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
713                     (sgid != current->egid) && (sgid != current->sgid))
714                         return -EPERM;
715         }
716         if (egid != (gid_t) -1) {
717                 if (egid != current->egid)
718                 {
719                         current->mm->dumpable = 0;
720                         wmb();
721                 }
722                 current->egid = egid;
723         }
724         current->fsgid = current->egid;
725         if (rgid != (gid_t) -1)
726                 current->gid = rgid;
727         if (sgid != (gid_t) -1)
728                 current->sgid = sgid;
729         return 0;
730 }
731
732 asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
733 {
734         int retval;
735
736         if (!(retval = put_user(current->gid, rgid)) &&
737             !(retval = put_user(current->egid, egid)))
738                 retval = put_user(current->sgid, sgid);
739
740         return retval;
741 }
742
743
744 /*
745  * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
746  * is used for "access()" and for the NFS daemon (letting nfsd stay at
747  * whatever uid it wants to). It normally shadows "euid", except when
748  * explicitly set by setfsuid() or for access..
749  */
750 asmlinkage long sys_setfsuid(uid_t uid)
751 {
752         int old_fsuid;
753
754         old_fsuid = current->fsuid;
755         if (uid == current->uid || uid == current->euid ||
756             uid == current->suid || uid == current->fsuid || 
757             capable(CAP_SETUID))
758         {
759                 if (uid != old_fsuid)
760                 {
761                         current->mm->dumpable = 0;
762                         wmb();
763                 }
764                 current->fsuid = uid;
765         }
766
767         /* We emulate fsuid by essentially doing a scaled-down version
768          * of what we did in setresuid and friends. However, we only
769          * operate on the fs-specific bits of the process' effective
770          * capabilities 
771          *
772          * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
773          *          if not, we might be a bit too harsh here.
774          */
775         
776         if (!issecure(SECURE_NO_SETUID_FIXUP)) {
777                 if (old_fsuid == 0 && current->fsuid != 0) {
778                         cap_t(current->cap_effective) &= ~CAP_FS_MASK;
779                 }
780                 if (old_fsuid != 0 && current->fsuid == 0) {
781                         cap_t(current->cap_effective) |=
782                                 (cap_t(current->cap_permitted) & CAP_FS_MASK);
783                 }
784         }
785
786         return old_fsuid;
787 }
788
789 /*
790  * Samma pÃ¥ svenska..
791  */
792 asmlinkage long sys_setfsgid(gid_t gid)
793 {
794         int old_fsgid;
795
796         old_fsgid = current->fsgid;
797         if (gid == current->gid || gid == current->egid ||
798             gid == current->sgid || gid == current->fsgid || 
799             capable(CAP_SETGID))
800         {
801                 if (gid != old_fsgid)
802                 {
803                         current->mm->dumpable = 0;
804                         wmb();
805                 }
806                 current->fsgid = gid;
807         }
808         return old_fsgid;
809 }
810
811 asmlinkage long sys_times(struct tms * tbuf)
812 {
813         /*
814          *      In the SMP world we might just be unlucky and have one of
815          *      the times increment as we use it. Since the value is an
816          *      atomically safe type this is just fine. Conceptually its
817          *      as if the syscall took an instant longer to occur.
818          */
819         if (tbuf)
820                 if (copy_to_user(tbuf, &current->times, sizeof(struct tms)))
821                         return -EFAULT;
822         return jiffies;
823 }
824
825 /*
826  * This needs some heavy checking ...
827  * I just haven't the stomach for it. I also don't fully
828  * understand sessions/pgrp etc. Let somebody who does explain it.
829  *
830  * OK, I think I have the protection semantics right.... this is really
831  * only important on a multi-user system anyway, to make sure one user
832  * can't send a signal to a process owned by another.  -TYT, 12/12/91
833  *
834  * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
835  * LBT 04.03.94
836  */
837
838 asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
839 {
840         struct task_struct * p;
841         int err = -EINVAL;
842
843         if (!pid)
844                 pid = current->pid;
845         if (!pgid)
846                 pgid = pid;
847         if (pgid < 0)
848                 return -EINVAL;
849
850         /* From this point forward we keep holding onto the tasklist lock
851          * so that our parent does not change from under us. -DaveM
852          */
853         read_lock(&tasklist_lock);
854
855         err = -ESRCH;
856         p = find_task_by_pid(pid);
857         if (!p)
858                 goto out;
859
860         if (p->p_pptr == current || p->p_opptr == current) {
861                 err = -EPERM;
862                 if (p->session != current->session)
863                         goto out;
864                 err = -EACCES;
865                 if (p->did_exec)
866                         goto out;
867         } else if (p != current)
868                 goto out;
869         err = -EPERM;
870         if (p->leader)
871                 goto out;
872         if (pgid != pid) {
873                 struct task_struct * tmp;
874                 for_each_task (tmp) {
875                         if (tmp->pgrp == pgid &&
876                             tmp->session == current->session)
877                                 goto ok_pgid;
878                 }
879                 goto out;
880         }
881
882 ok_pgid:
883         p->pgrp = pgid;
884         err = 0;
885 out:
886         /* All paths lead to here, thus we are safe. -DaveM */
887         read_unlock(&tasklist_lock);
888         return err;
889 }
890
891 asmlinkage long sys_getpgid(pid_t pid)
892 {
893         if (!pid) {
894                 return current->pgrp;
895         } else {
896                 int retval;
897                 struct task_struct *p;
898
899                 read_lock(&tasklist_lock);
900                 p = find_task_by_pid(pid);
901
902                 retval = -ESRCH;
903                 if (p)
904                         retval = p->pgrp;
905                 read_unlock(&tasklist_lock);
906                 return retval;
907         }
908 }
909
910 asmlinkage long sys_getpgrp(void)
911 {
912         /* SMP - assuming writes are word atomic this is fine */
913         return current->pgrp;
914 }
915
916 asmlinkage long sys_getsid(pid_t pid)
917 {
918         if (!pid) {
919                 return current->session;
920         } else {
921                 int retval;
922                 struct task_struct *p;
923
924                 read_lock(&tasklist_lock);
925                 p = find_task_by_pid(pid);
926
927                 retval = -ESRCH;
928                 if(p)
929                         retval = p->session;
930                 read_unlock(&tasklist_lock);
931                 return retval;
932         }
933 }
934
935 asmlinkage long sys_setsid(void)
936 {
937         struct task_struct * p;
938         int err = -EPERM;
939
940         read_lock(&tasklist_lock);
941         for_each_task(p) {
942                 if (p->pgrp == current->pid)
943                         goto out;
944         }
945
946         current->leader = 1;
947         current->session = current->pgrp = current->pid;
948         current->tty = NULL;
949         current->tty_old_pgrp = 0;
950         err = current->pgrp;
951 out:
952         read_unlock(&tasklist_lock);
953         return err;
954 }
955
956 /*
957  * Supplementary group IDs
958  */
959 asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist)
960 {
961         int i;
962         
963         /*
964          *      SMP: Nobody else can change our grouplist. Thus we are
965          *      safe.
966          */
967
968         if (gidsetsize < 0)
969                 return -EINVAL;
970         i = current->ngroups;
971         if (gidsetsize) {
972                 if (i > gidsetsize)
973                         return -EINVAL;
974                 if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
975                         return -EFAULT;
976         }
977         return i;
978 }
979
980 /*
981  *      SMP: Our groups are not shared. We can copy to/from them safely
982  *      without another task interfering.
983  */
984  
985 asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist)
986 {
987         if (!capable(CAP_SETGID))
988                 return -EPERM;
989         if ((unsigned) gidsetsize > NGROUPS)
990                 return -EINVAL;
991         if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
992                 return -EFAULT;
993         current->ngroups = gidsetsize;
994         return 0;
995 }
996
997 static int supplemental_group_member(gid_t grp)
998 {
999         int i = current->ngroups;
1000
1001         if (i) {
1002                 gid_t *groups = current->groups;
1003                 do {
1004                         if (*groups == grp)
1005                                 return 1;
1006                         groups++;
1007                         i--;
1008                 } while (i);
1009         }
1010         return 0;
1011 }
1012
1013 /*
1014  * Check whether we're fsgid/egid or in the supplemental group..
1015  */
1016 int in_group_p(gid_t grp)
1017 {
1018         int retval = 1;
1019         if (grp != current->fsgid)
1020                 retval = supplemental_group_member(grp);
1021         return retval;
1022 }
1023
1024 int in_egroup_p(gid_t grp)
1025 {
1026         int retval = 1;
1027         if (grp != current->egid)
1028                 retval = supplemental_group_member(grp);
1029         return retval;
1030 }
1031
1032 DECLARE_RWSEM(uts_sem);
1033
1034 asmlinkage long sys_newuname(struct new_utsname * name)
1035 {
1036         int errno = 0;
1037
1038         down_read(&uts_sem);
1039         if (copy_to_user(name,&system_utsname,sizeof *name))
1040                 errno = -EFAULT;
1041         up_read(&uts_sem);
1042         return errno;
1043 }
1044
1045 asmlinkage long sys_sethostname(char *name, int len)
1046 {
1047         int errno;
1048
1049         if (!capable(CAP_SYS_ADMIN))
1050                 return -EPERM;
1051         if (len < 0 || len > __NEW_UTS_LEN)
1052                 return -EINVAL;
1053         down_write(&uts_sem);
1054         errno = -EFAULT;
1055         if (!copy_from_user(system_utsname.nodename, name, len)) {
1056                 system_utsname.nodename[len] = 0;
1057                 errno = 0;
1058         }
1059         up_write(&uts_sem);
1060         return errno;
1061 }
1062
1063 asmlinkage long sys_gethostname(char *name, int len)
1064 {
1065         int i, errno;
1066
1067         if (len < 0)
1068                 return -EINVAL;
1069         down_read(&uts_sem);
1070         i = 1 + strlen(system_utsname.nodename);
1071         if (i > len)
1072                 i = len;
1073         errno = 0;
1074         if (copy_to_user(name, system_utsname.nodename, i))
1075                 errno = -EFAULT;
1076         up_read(&uts_sem);
1077         return errno;
1078 }
1079
1080 /*
1081  * Only setdomainname; getdomainname can be implemented by calling
1082  * uname()
1083  */
1084 asmlinkage long sys_setdomainname(char *name, int len)
1085 {
1086         int errno;
1087
1088         if (!capable(CAP_SYS_ADMIN))
1089                 return -EPERM;
1090         if (len < 0 || len > __NEW_UTS_LEN)
1091                 return -EINVAL;
1092
1093         down_write(&uts_sem);
1094         errno = -EFAULT;
1095         if (!copy_from_user(system_utsname.domainname, name, len)) {
1096                 errno = 0;
1097                 system_utsname.domainname[len] = 0;
1098         }
1099         up_write(&uts_sem);
1100         return errno;
1101 }
1102
1103 asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim)
1104 {
1105         if (resource >= RLIM_NLIMITS)
1106                 return -EINVAL;
1107         else
1108                 return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
1109                         ? -EFAULT : 0;
1110 }
1111
1112 #if !defined(__ia64__) 
1113
1114 /*
1115  *      Back compatibility for getrlimit. Needed for some apps.
1116  */
1117  
1118 asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim)
1119 {
1120         struct rlimit x;
1121         if (resource >= RLIM_NLIMITS)
1122                 return -EINVAL;
1123
1124         memcpy(&x, current->rlim + resource, sizeof(*rlim));
1125         if(x.rlim_cur > 0x7FFFFFFF)
1126                 x.rlim_cur = 0x7FFFFFFF;
1127         if(x.rlim_max > 0x7FFFFFFF)
1128                 x.rlim_max = 0x7FFFFFFF;
1129         return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;
1130 }
1131
1132 #endif
1133
1134 asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim)
1135 {
1136         struct rlimit new_rlim, *old_rlim;
1137
1138         if (resource >= RLIM_NLIMITS)
1139                 return -EINVAL;
1140         if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1141                 return -EFAULT;
1142         old_rlim = current->rlim + resource;
1143         if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
1144              (new_rlim.rlim_max > old_rlim->rlim_max)) &&
1145             !capable(CAP_SYS_RESOURCE))
1146                 return -EPERM;
1147         if (resource == RLIMIT_NOFILE) {
1148                 if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
1149                         return -EPERM;
1150         }
1151         *old_rlim = new_rlim;
1152         return 0;
1153 }
1154
1155 /*
1156  * It would make sense to put struct rusage in the task_struct,
1157  * except that would make the task_struct be *really big*.  After
1158  * task_struct gets moved into malloc'ed memory, it would
1159  * make sense to do this.  It will make moving the rest of the information
1160  * a lot simpler!  (Which we're not doing right now because we're not
1161  * measuring them yet).
1162  *
1163  * This is SMP safe.  Either we are called from sys_getrusage on ourselves
1164  * below (we know we aren't going to exit/disappear and only we change our
1165  * rusage counters), or we are called from wait4() on a process which is
1166  * either stopped or zombied.  In the zombied case the task won't get
1167  * reaped till shortly after the call to getrusage(), in both cases the
1168  * task being examined is in a frozen state so the counters won't change.
1169  *
1170  * FIXME! Get the fault counts properly!
1171  */
1172 int getrusage(struct task_struct *p, int who, struct rusage *ru)
1173 {
1174         struct rusage r;
1175
1176         memset((char *) &r, 0, sizeof(r));
1177         switch (who) {
1178                 case RUSAGE_SELF:
1179                         r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime);
1180                         r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime);
1181                         r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime);
1182                         r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime);
1183                         r.ru_minflt = p->min_flt;
1184                         r.ru_majflt = p->maj_flt;
1185                         r.ru_nswap = p->nswap;
1186                         break;
1187                 case RUSAGE_CHILDREN:
1188                         r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime);
1189                         r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_cutime);
1190                         r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_cstime);
1191                         r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_cstime);
1192                         r.ru_minflt = p->cmin_flt;
1193                         r.ru_majflt = p->cmaj_flt;
1194                         r.ru_nswap = p->cnswap;
1195                         break;
1196                 default:
1197                         r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime);
1198                         r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime + p->times.tms_cutime);
1199                         r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime);
1200                         r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime);
1201                         r.ru_minflt = p->min_flt + p->cmin_flt;
1202                         r.ru_majflt = p->maj_flt + p->cmaj_flt;
1203                         r.ru_nswap = p->nswap + p->cnswap;
1204                         break;
1205         }
1206         return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1207 }
1208
1209 asmlinkage long sys_getrusage(int who, struct rusage *ru)
1210 {
1211         if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
1212                 return -EINVAL;
1213         return getrusage(current, who, ru);
1214 }
1215
1216 asmlinkage long sys_umask(int mask)
1217 {
1218         mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
1219         return mask;
1220 }
1221     
1222 asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1223                           unsigned long arg4, unsigned long arg5)
1224 {
1225         int error = 0;
1226         int sig;
1227
1228         switch (option) {
1229                 case PR_SET_PDEATHSIG:
1230                         sig = arg2;
1231                         if (sig < 0 || sig > _NSIG) {
1232                                 error = -EINVAL;
1233                                 break;
1234                         }
1235                         current->pdeath_signal = sig;
1236                         break;
1237                 case PR_GET_PDEATHSIG:
1238                         error = put_user(current->pdeath_signal, (int *)arg2);
1239                         break;
1240                 case PR_GET_DUMPABLE:
1241                         if (current->mm->dumpable)
1242                                 error = 1;
1243                         break;
1244                 case PR_SET_DUMPABLE:
1245                         if (arg2 != 0 && arg2 != 1) {
1246                                 error = -EINVAL;
1247                                 break;
1248                         }
1249                         current->mm->dumpable = arg2;
1250                         break;
1251
1252                 case PR_SET_UNALIGN:
1253                         error = SET_UNALIGN_CTL(current, arg2);
1254                         break;
1255                 case PR_GET_UNALIGN:
1256                         error = GET_UNALIGN_CTL(current, arg2);
1257                         break;
1258                 case PR_SET_FPEMU:
1259                         error = SET_FPEMU_CTL(current, arg2);
1260                         break;
1261                 case PR_GET_FPEMU:
1262                         error = GET_FPEMU_CTL(current, arg2);
1263                         break;
1264                 case PR_SET_FPEXC:
1265                         error = SET_FPEXC_CTL(current, arg2);
1266                         break;
1267                 case PR_GET_FPEXC:
1268                         error = GET_FPEXC_CTL(current, arg2);
1269                         break;
1270
1271                 case PR_GET_KEEPCAPS:
1272                         if (current->keep_capabilities)
1273                                 error = 1;
1274                         break;
1275                 case PR_SET_KEEPCAPS:
1276                         if (arg2 != 0 && arg2 != 1) {
1277                                 error = -EINVAL;
1278                                 break;
1279                         }
1280                         current->keep_capabilities = arg2;
1281                         break;
1282
1283 #ifdef SET_FP_EXC_MODE
1284                 case PR_SET_FP_EXC:
1285                         error = SET_FP_EXC_MODE(current, arg2);
1286                         break;
1287                 case PR_GET_FP_EXC:
1288                         error = GET_FP_EXC_MODE(current);
1289                         break;
1290 #endif
1291
1292                 default:
1293                         error = -EINVAL;
1294                         break;
1295         }
1296         return error;
1297 }
1298
1299 EXPORT_SYMBOL(notifier_chain_register);
1300 EXPORT_SYMBOL(notifier_chain_unregister);
1301 EXPORT_SYMBOL(notifier_call_chain);
1302 EXPORT_SYMBOL(register_reboot_notifier);
1303 EXPORT_SYMBOL(unregister_reboot_notifier);
1304 EXPORT_SYMBOL(in_group_p);
1305 EXPORT_SYMBOL(in_egroup_p);