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 
notifier_chain_register(struct notifier_block ** list,struct notifier_block * n)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 
notifier_chain_unregister(struct notifier_block ** nl,struct notifier_block * n)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 
notifier_call_chain(struct notifier_block ** n,unsigned long val,void * v)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 
register_reboot_notifier(struct notifier_block * nb)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 
unregister_reboot_notifier(struct notifier_block * nb)184 int unregister_reboot_notifier(struct notifier_block * nb)
185 {
186 	return notifier_chain_unregister(&reboot_notifier_list, nb);
187 }
188 
sys_ni_syscall(void)189 asmlinkage long sys_ni_syscall(void)
190 {
191 	return -ENOSYS;
192 }
193 
proc_sel(struct task_struct * p,int which,int who)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 
sys_setpriority(int which,int who,int niceval)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  */
sys_getpriority(int which,int who)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  */
sys_reboot(int magic1,int magic2,unsigned int cmd,void * arg)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 
deferred_cad(void * dummy)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  */
ctrl_alt_del(void)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  */
sys_setregid(gid_t rgid,gid_t egid)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  */
sys_setgid(gid_t gid)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  */
cap_emulate_setxuid(int old_ruid,int old_euid,int old_suid)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 
set_user(uid_t new_ruid,int dumpclear)512 static int set_user(uid_t new_ruid, int dumpclear)
513 {
514 	struct user_struct *new_user;
515 
516 	new_user = alloc_uid(new_ruid);
517 	if (!new_user)
518 		return -EAGAIN;
519 	switch_uid(new_user);
520 
521 	if(dumpclear)
522 	{
523 		current->mm->dumpable = 0;
524 		wmb();
525 	}
526 	current->uid = new_ruid;
527 	return 0;
528 }
529 
530 /*
531  * Unprivileged users may change the real uid to the effective uid
532  * or vice versa.  (BSD-style)
533  *
534  * If you set the real uid at all, or set the effective uid to a value not
535  * equal to the real uid, then the saved uid is set to the new effective uid.
536  *
537  * This makes it possible for a setuid program to completely drop its
538  * privileges, which is often a useful assertion to make when you are doing
539  * a security audit over a program.
540  *
541  * The general idea is that a program which uses just setreuid() will be
542  * 100% compatible with BSD.  A program which uses just setuid() will be
543  * 100% compatible with POSIX with saved IDs.
544  */
sys_setreuid(uid_t ruid,uid_t euid)545 asmlinkage long sys_setreuid(uid_t ruid, uid_t euid)
546 {
547 	int old_ruid, old_euid, old_suid, new_ruid, new_euid;
548 
549 	new_ruid = old_ruid = current->uid;
550 	new_euid = old_euid = current->euid;
551 	old_suid = current->suid;
552 
553 	if (ruid != (uid_t) -1) {
554 		new_ruid = ruid;
555 		if ((old_ruid != ruid) &&
556 		    (current->euid != ruid) &&
557 		    !capable(CAP_SETUID))
558 			return -EPERM;
559 	}
560 
561 	if (euid != (uid_t) -1) {
562 		new_euid = euid;
563 		if ((old_ruid != euid) &&
564 		    (current->euid != euid) &&
565 		    (current->suid != euid) &&
566 		    !capable(CAP_SETUID))
567 			return -EPERM;
568 	}
569 
570 	if (new_ruid != old_ruid && set_user(new_ruid, new_euid != old_euid) < 0)
571 		return -EAGAIN;
572 
573 	if (new_euid != old_euid)
574 	{
575 		current->mm->dumpable=0;
576 		wmb();
577 	}
578 	current->fsuid = current->euid = new_euid;
579 	if (ruid != (uid_t) -1 ||
580 	    (euid != (uid_t) -1 && euid != old_ruid))
581 		current->suid = current->euid;
582 	current->fsuid = current->euid;
583 
584 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
585 		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
586 	}
587 
588 	return 0;
589 }
590 
591 
592 
593 /*
594  * setuid() is implemented like SysV with SAVED_IDS
595  *
596  * Note that SAVED_ID's is deficient in that a setuid root program
597  * like sendmail, for example, cannot set its uid to be a normal
598  * user and then switch back, because if you're root, setuid() sets
599  * the saved uid too.  If you don't like this, blame the bright people
600  * in the POSIX committee and/or USG.  Note that the BSD-style setreuid()
601  * will allow a root program to temporarily drop privileges and be able to
602  * regain them by swapping the real and effective uid.
603  */
sys_setuid(uid_t uid)604 asmlinkage long sys_setuid(uid_t uid)
605 {
606 	int old_euid = current->euid;
607 	int old_ruid, old_suid, new_ruid, new_suid;
608 
609 	old_ruid = new_ruid = current->uid;
610 	old_suid = current->suid;
611 	new_suid = old_suid;
612 
613 	if (capable(CAP_SETUID)) {
614 		if (uid != old_ruid && set_user(uid, old_euid != uid) < 0)
615 			return -EAGAIN;
616 		new_suid = uid;
617 	} else if ((uid != current->uid) && (uid != new_suid))
618 		return -EPERM;
619 
620 	if (old_euid != uid)
621 	{
622 		current->mm->dumpable = 0;
623 		wmb();
624 	}
625 	current->fsuid = current->euid = uid;
626 	current->suid = new_suid;
627 
628 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
629 		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
630 	}
631 
632 	return 0;
633 }
634 
635 
636 /*
637  * This function implements a generic ability to update ruid, euid,
638  * and suid.  This allows you to implement the 4.4 compatible seteuid().
639  */
sys_setresuid(uid_t ruid,uid_t euid,uid_t suid)640 asmlinkage long sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
641 {
642 	int old_ruid = current->uid;
643 	int old_euid = current->euid;
644 	int old_suid = current->suid;
645 
646 	if (!capable(CAP_SETUID)) {
647 		if ((ruid != (uid_t) -1) && (ruid != current->uid) &&
648 		    (ruid != current->euid) && (ruid != current->suid))
649 			return -EPERM;
650 		if ((euid != (uid_t) -1) && (euid != current->uid) &&
651 		    (euid != current->euid) && (euid != current->suid))
652 			return -EPERM;
653 		if ((suid != (uid_t) -1) && (suid != current->uid) &&
654 		    (suid != current->euid) && (suid != current->suid))
655 			return -EPERM;
656 	}
657 	if (ruid != (uid_t) -1) {
658 		if (ruid != current->uid && set_user(ruid, euid != current->euid) < 0)
659 			return -EAGAIN;
660 	}
661 	if (euid != (uid_t) -1) {
662 		if (euid != current->euid)
663 		{
664 			current->mm->dumpable = 0;
665 			wmb();
666 		}
667 		current->euid = euid;
668 	}
669 	current->fsuid = current->euid;
670 	if (suid != (uid_t) -1)
671 		current->suid = suid;
672 
673 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
674 		cap_emulate_setxuid(old_ruid, old_euid, old_suid);
675 	}
676 
677 	return 0;
678 }
679 
sys_getresuid(uid_t * ruid,uid_t * euid,uid_t * suid)680 asmlinkage long sys_getresuid(uid_t *ruid, uid_t *euid, uid_t *suid)
681 {
682 	int retval;
683 
684 	if (!(retval = put_user(current->uid, ruid)) &&
685 	    !(retval = put_user(current->euid, euid)))
686 		retval = put_user(current->suid, suid);
687 
688 	return retval;
689 }
690 
691 /*
692  * Same as above, but for rgid, egid, sgid.
693  */
sys_setresgid(gid_t rgid,gid_t egid,gid_t sgid)694 asmlinkage long sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
695 {
696 	if (!capable(CAP_SETGID)) {
697 		if ((rgid != (gid_t) -1) && (rgid != current->gid) &&
698 		    (rgid != current->egid) && (rgid != current->sgid))
699 			return -EPERM;
700 		if ((egid != (gid_t) -1) && (egid != current->gid) &&
701 		    (egid != current->egid) && (egid != current->sgid))
702 			return -EPERM;
703 		if ((sgid != (gid_t) -1) && (sgid != current->gid) &&
704 		    (sgid != current->egid) && (sgid != current->sgid))
705 			return -EPERM;
706 	}
707 	if (egid != (gid_t) -1) {
708 		if (egid != current->egid)
709 		{
710 			current->mm->dumpable = 0;
711 			wmb();
712 		}
713 		current->egid = egid;
714 	}
715 	current->fsgid = current->egid;
716 	if (rgid != (gid_t) -1)
717 		current->gid = rgid;
718 	if (sgid != (gid_t) -1)
719 		current->sgid = sgid;
720 	return 0;
721 }
722 
sys_getresgid(gid_t * rgid,gid_t * egid,gid_t * sgid)723 asmlinkage long sys_getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid)
724 {
725 	int retval;
726 
727 	if (!(retval = put_user(current->gid, rgid)) &&
728 	    !(retval = put_user(current->egid, egid)))
729 		retval = put_user(current->sgid, sgid);
730 
731 	return retval;
732 }
733 
734 
735 /*
736  * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
737  * is used for "access()" and for the NFS daemon (letting nfsd stay at
738  * whatever uid it wants to). It normally shadows "euid", except when
739  * explicitly set by setfsuid() or for access..
740  */
sys_setfsuid(uid_t uid)741 asmlinkage long sys_setfsuid(uid_t uid)
742 {
743 	int old_fsuid;
744 
745 	old_fsuid = current->fsuid;
746 	if (uid == current->uid || uid == current->euid ||
747 	    uid == current->suid || uid == current->fsuid ||
748 	    capable(CAP_SETUID))
749 	{
750 		if (uid != old_fsuid)
751 		{
752 			current->mm->dumpable = 0;
753 			wmb();
754 		}
755 		current->fsuid = uid;
756 	}
757 
758 	/* We emulate fsuid by essentially doing a scaled-down version
759 	 * of what we did in setresuid and friends. However, we only
760 	 * operate on the fs-specific bits of the process' effective
761 	 * capabilities
762 	 *
763 	 * FIXME - is fsuser used for all CAP_FS_MASK capabilities?
764 	 *          if not, we might be a bit too harsh here.
765 	 */
766 
767 	if (!issecure(SECURE_NO_SETUID_FIXUP)) {
768 		if (old_fsuid == 0 && current->fsuid != 0) {
769 			cap_t(current->cap_effective) &= ~CAP_FS_MASK;
770 		}
771 		if (old_fsuid != 0 && current->fsuid == 0) {
772 			cap_t(current->cap_effective) |=
773 				(cap_t(current->cap_permitted) & CAP_FS_MASK);
774 		}
775 	}
776 
777 	return old_fsuid;
778 }
779 
780 /*
781  * Samma p� svenska..
782  */
sys_setfsgid(gid_t gid)783 asmlinkage long sys_setfsgid(gid_t gid)
784 {
785 	int old_fsgid;
786 
787 	old_fsgid = current->fsgid;
788 	if (gid == current->gid || gid == current->egid ||
789 	    gid == current->sgid || gid == current->fsgid ||
790 	    capable(CAP_SETGID))
791 	{
792 		if (gid != old_fsgid)
793 		{
794 			current->mm->dumpable = 0;
795 			wmb();
796 		}
797 		current->fsgid = gid;
798 	}
799 	return old_fsgid;
800 }
801 
sys_times(struct tms * tbuf)802 asmlinkage long sys_times(struct tms * tbuf)
803 {
804 	/*
805 	 *	In the SMP world we might just be unlucky and have one of
806 	 *	the times increment as we use it. Since the value is an
807 	 *	atomically safe type this is just fine. Conceptually its
808 	 *	as if the syscall took an instant longer to occur.
809 	 */
810 	if (tbuf)
811 		if (copy_to_user(tbuf, &current->times, sizeof(struct tms)))
812 			return -EFAULT;
813 	return jiffies;
814 }
815 
816 /*
817  * This needs some heavy checking ...
818  * I just haven't the stomach for it. I also don't fully
819  * understand sessions/pgrp etc. Let somebody who does explain it.
820  *
821  * OK, I think I have the protection semantics right.... this is really
822  * only important on a multi-user system anyway, to make sure one user
823  * can't send a signal to a process owned by another.  -TYT, 12/12/91
824  *
825  * Auch. Had to add the 'did_exec' flag to conform completely to POSIX.
826  * LBT 04.03.94
827  */
828 
sys_setpgid(pid_t pid,pid_t pgid)829 asmlinkage long sys_setpgid(pid_t pid, pid_t pgid)
830 {
831 	struct task_struct * p;
832 	int err = -EINVAL;
833 
834 	if (!pid)
835 		pid = current->pid;
836 	if (!pgid)
837 		pgid = pid;
838 	if (pgid < 0)
839 		return -EINVAL;
840 
841 	/* From this point forward we keep holding onto the tasklist lock
842 	 * so that our parent does not change from under us. -DaveM
843 	 */
844 	read_lock(&tasklist_lock);
845 
846 	err = -ESRCH;
847 	p = find_task_by_pid(pid);
848 	if (!p)
849 		goto out;
850 
851 	if (p->p_pptr == current || p->p_opptr == current) {
852 		err = -EPERM;
853 		if (p->session != current->session)
854 			goto out;
855 		err = -EACCES;
856 		if (p->did_exec)
857 			goto out;
858 	} else if (p != current)
859 		goto out;
860 	err = -EPERM;
861 	if (p->leader)
862 		goto out;
863 	if (pgid != pid) {
864 		struct task_struct * tmp;
865 		for_each_task (tmp) {
866 			if (tmp->pgrp == pgid &&
867 			    tmp->session == current->session)
868 				goto ok_pgid;
869 		}
870 		goto out;
871 	}
872 
873 ok_pgid:
874 	p->pgrp = pgid;
875 	err = 0;
876 out:
877 	/* All paths lead to here, thus we are safe. -DaveM */
878 	read_unlock(&tasklist_lock);
879 	return err;
880 }
881 
sys_getpgid(pid_t pid)882 asmlinkage long sys_getpgid(pid_t pid)
883 {
884 	if (!pid) {
885 		return current->pgrp;
886 	} else {
887 		int retval;
888 		struct task_struct *p;
889 
890 		read_lock(&tasklist_lock);
891 		p = find_task_by_pid(pid);
892 
893 		retval = -ESRCH;
894 		if (p)
895 			retval = p->pgrp;
896 		read_unlock(&tasklist_lock);
897 		return retval;
898 	}
899 }
900 
sys_getpgrp(void)901 asmlinkage long sys_getpgrp(void)
902 {
903 	/* SMP - assuming writes are word atomic this is fine */
904 	return current->pgrp;
905 }
906 
sys_getsid(pid_t pid)907 asmlinkage long sys_getsid(pid_t pid)
908 {
909 	if (!pid) {
910 		return current->session;
911 	} else {
912 		int retval;
913 		struct task_struct *p;
914 
915 		read_lock(&tasklist_lock);
916 		p = find_task_by_pid(pid);
917 
918 		retval = -ESRCH;
919 		if(p)
920 			retval = p->session;
921 		read_unlock(&tasklist_lock);
922 		return retval;
923 	}
924 }
925 
sys_setsid(void)926 asmlinkage long sys_setsid(void)
927 {
928 	struct task_struct * p;
929 	int err = -EPERM;
930 
931 	read_lock(&tasklist_lock);
932 	for_each_task(p) {
933 		if (p->pgrp == current->pid)
934 			goto out;
935 	}
936 
937 	current->leader = 1;
938 	current->session = current->pgrp = current->pid;
939 	current->tty = NULL;
940 	current->tty_old_pgrp = 0;
941 	err = current->pgrp;
942 out:
943 	read_unlock(&tasklist_lock);
944 	return err;
945 }
946 
947 /*
948  * Supplementary group IDs
949  */
sys_getgroups(int gidsetsize,gid_t * grouplist)950 asmlinkage long sys_getgroups(int gidsetsize, gid_t *grouplist)
951 {
952 	int i;
953 
954 	/*
955 	 *	SMP: Nobody else can change our grouplist. Thus we are
956 	 *	safe.
957 	 */
958 
959 	if (gidsetsize < 0)
960 		return -EINVAL;
961 	i = current->ngroups;
962 	if (gidsetsize) {
963 		if (i > gidsetsize)
964 			return -EINVAL;
965 		if (copy_to_user(grouplist, current->groups, sizeof(gid_t)*i))
966 			return -EFAULT;
967 	}
968 	return i;
969 }
970 
971 /*
972  *	SMP: Our groups are not shared. We can copy to/from them safely
973  *	without another task interfering.
974  */
975 
sys_setgroups(int gidsetsize,gid_t * grouplist)976 asmlinkage long sys_setgroups(int gidsetsize, gid_t *grouplist)
977 {
978 	if (!capable(CAP_SETGID))
979 		return -EPERM;
980 	if ((unsigned) gidsetsize > NGROUPS)
981 		return -EINVAL;
982 	if(copy_from_user(current->groups, grouplist, gidsetsize * sizeof(gid_t)))
983 		return -EFAULT;
984 	current->ngroups = gidsetsize;
985 	return 0;
986 }
987 
supplemental_group_member(gid_t grp)988 static int supplemental_group_member(gid_t grp)
989 {
990 	int i = current->ngroups;
991 
992 	if (i) {
993 		gid_t *groups = current->groups;
994 		do {
995 			if (*groups == grp)
996 				return 1;
997 			groups++;
998 			i--;
999 		} while (i);
1000 	}
1001 	return 0;
1002 }
1003 
1004 /*
1005  * Check whether we're fsgid/egid or in the supplemental group..
1006  */
in_group_p(gid_t grp)1007 int in_group_p(gid_t grp)
1008 {
1009 	int retval = 1;
1010 	if (grp != current->fsgid)
1011 		retval = supplemental_group_member(grp);
1012 	return retval;
1013 }
1014 
in_egroup_p(gid_t grp)1015 int in_egroup_p(gid_t grp)
1016 {
1017 	int retval = 1;
1018 	if (grp != current->egid)
1019 		retval = supplemental_group_member(grp);
1020 	return retval;
1021 }
1022 
1023 DECLARE_RWSEM(uts_sem);
1024 
sys_newuname(struct new_utsname * name)1025 asmlinkage long sys_newuname(struct new_utsname * name)
1026 {
1027 	int errno = 0;
1028 
1029 	down_read(&uts_sem);
1030 	if (copy_to_user(name,&system_utsname,sizeof *name))
1031 		errno = -EFAULT;
1032 	up_read(&uts_sem);
1033 	return errno;
1034 }
1035 
sys_sethostname(char * name,int len)1036 asmlinkage long sys_sethostname(char *name, int len)
1037 {
1038 	int errno;
1039 	char tmp[__NEW_UTS_LEN];
1040 
1041 	if (!capable(CAP_SYS_ADMIN))
1042 		return -EPERM;
1043 	if (len < 0 || len > __NEW_UTS_LEN)
1044 		return -EINVAL;
1045 	down_write(&uts_sem);
1046 	errno = -EFAULT;
1047 	if (!copy_from_user(tmp, name, len)) {
1048 		memcpy(system_utsname.nodename, tmp, len);
1049 		system_utsname.nodename[len] = 0;
1050 		errno = 0;
1051 	}
1052 	up_write(&uts_sem);
1053 	return errno;
1054 }
1055 
sys_gethostname(char * name,int len)1056 asmlinkage long sys_gethostname(char *name, int len)
1057 {
1058 	int i, errno;
1059 
1060 	if (len < 0)
1061 		return -EINVAL;
1062 	down_read(&uts_sem);
1063 	i = 1 + strlen(system_utsname.nodename);
1064 	if (i > len)
1065 		i = len;
1066 	errno = 0;
1067 	if (copy_to_user(name, system_utsname.nodename, i))
1068 		errno = -EFAULT;
1069 	up_read(&uts_sem);
1070 	return errno;
1071 }
1072 
1073 /*
1074  * Only setdomainname; getdomainname can be implemented by calling
1075  * uname()
1076  */
sys_setdomainname(char * name,int len)1077 asmlinkage long sys_setdomainname(char *name, int len)
1078 {
1079 	int errno;
1080 	char tmp[__NEW_UTS_LEN];
1081 
1082 	if (!capable(CAP_SYS_ADMIN))
1083 		return -EPERM;
1084 	if (len < 0 || len > __NEW_UTS_LEN)
1085 		return -EINVAL;
1086 
1087 	down_write(&uts_sem);
1088 	errno = -EFAULT;
1089 	if (!copy_from_user(tmp, name, len)) {
1090 		memcpy(system_utsname.domainname, tmp, len);
1091 		system_utsname.domainname[len] = 0;
1092 		errno = 0;
1093 	}
1094 	up_write(&uts_sem);
1095 	return errno;
1096 }
1097 
sys_getrlimit(unsigned int resource,struct rlimit * rlim)1098 asmlinkage long sys_getrlimit(unsigned int resource, struct rlimit *rlim)
1099 {
1100 	if (resource >= RLIM_NLIMITS)
1101 		return -EINVAL;
1102 	else
1103 		return copy_to_user(rlim, current->rlim + resource, sizeof(*rlim))
1104 			? -EFAULT : 0;
1105 }
1106 
1107 #if !defined(__ia64__)
1108 
1109 /*
1110  *	Back compatibility for getrlimit. Needed for some apps.
1111  */
1112 
sys_old_getrlimit(unsigned int resource,struct rlimit * rlim)1113 asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit *rlim)
1114 {
1115 	struct rlimit x;
1116 	if (resource >= RLIM_NLIMITS)
1117 		return -EINVAL;
1118 
1119 	memcpy(&x, current->rlim + resource, sizeof(*rlim));
1120 	if(x.rlim_cur > 0x7FFFFFFF)
1121 		x.rlim_cur = 0x7FFFFFFF;
1122 	if(x.rlim_max > 0x7FFFFFFF)
1123 		x.rlim_max = 0x7FFFFFFF;
1124 	return copy_to_user(rlim, &x, sizeof(x))?-EFAULT:0;
1125 }
1126 
1127 #endif
1128 
sys_setrlimit(unsigned int resource,struct rlimit * rlim)1129 asmlinkage long sys_setrlimit(unsigned int resource, struct rlimit *rlim)
1130 {
1131 	struct rlimit new_rlim, *old_rlim;
1132 
1133 	if (resource >= RLIM_NLIMITS)
1134 		return -EINVAL;
1135 	if(copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
1136 		return -EFAULT;
1137        if (new_rlim.rlim_cur > new_rlim.rlim_max)
1138                return -EINVAL;
1139 	old_rlim = current->rlim + resource;
1140 	if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
1141 	     (new_rlim.rlim_max > old_rlim->rlim_max)) &&
1142 	    !capable(CAP_SYS_RESOURCE))
1143 		return -EPERM;
1144 	if (resource == RLIMIT_NOFILE) {
1145 		if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
1146 			return -EPERM;
1147 	}
1148 	*old_rlim = new_rlim;
1149 	return 0;
1150 }
1151 
1152 /*
1153  * It would make sense to put struct rusage in the task_struct,
1154  * except that would make the task_struct be *really big*.  After
1155  * task_struct gets moved into malloc'ed memory, it would
1156  * make sense to do this.  It will make moving the rest of the information
1157  * a lot simpler!  (Which we're not doing right now because we're not
1158  * measuring them yet).
1159  *
1160  * This is SMP safe.  Either we are called from sys_getrusage on ourselves
1161  * below (we know we aren't going to exit/disappear and only we change our
1162  * rusage counters), or we are called from wait4() on a process which is
1163  * either stopped or zombied.  In the zombied case the task won't get
1164  * reaped till shortly after the call to getrusage(), in both cases the
1165  * task being examined is in a frozen state so the counters won't change.
1166  *
1167  * FIXME! Get the fault counts properly!
1168  */
getrusage(struct task_struct * p,int who,struct rusage * ru)1169 int getrusage(struct task_struct *p, int who, struct rusage *ru)
1170 {
1171 	struct rusage r;
1172 
1173 	memset((char *) &r, 0, sizeof(r));
1174 	switch (who) {
1175 		case RUSAGE_SELF:
1176 			r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime);
1177 			r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime);
1178 			r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime);
1179 			r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime);
1180 			r.ru_minflt = p->min_flt;
1181 			r.ru_majflt = p->maj_flt;
1182 			r.ru_nswap = p->nswap;
1183 			break;
1184 		case RUSAGE_CHILDREN:
1185 			r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_cutime);
1186 			r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_cutime);
1187 			r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_cstime);
1188 			r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_cstime);
1189 			r.ru_minflt = p->cmin_flt;
1190 			r.ru_majflt = p->cmaj_flt;
1191 			r.ru_nswap = p->cnswap;
1192 			break;
1193 		default:
1194 			r.ru_utime.tv_sec = CT_TO_SECS(p->times.tms_utime + p->times.tms_cutime);
1195 			r.ru_utime.tv_usec = CT_TO_USECS(p->times.tms_utime + p->times.tms_cutime);
1196 			r.ru_stime.tv_sec = CT_TO_SECS(p->times.tms_stime + p->times.tms_cstime);
1197 			r.ru_stime.tv_usec = CT_TO_USECS(p->times.tms_stime + p->times.tms_cstime);
1198 			r.ru_minflt = p->min_flt + p->cmin_flt;
1199 			r.ru_majflt = p->maj_flt + p->cmaj_flt;
1200 			r.ru_nswap = p->nswap + p->cnswap;
1201 			break;
1202 	}
1203 	return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
1204 }
1205 
sys_getrusage(int who,struct rusage * ru)1206 asmlinkage long sys_getrusage(int who, struct rusage *ru)
1207 {
1208 	if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
1209 		return -EINVAL;
1210 	return getrusage(current, who, ru);
1211 }
1212 
sys_umask(int mask)1213 asmlinkage long sys_umask(int mask)
1214 {
1215 	mask = xchg(&current->fs->umask, mask & S_IRWXUGO);
1216 	return mask;
1217 }
1218 
sys_prctl(int option,unsigned long arg2,unsigned long arg3,unsigned long arg4,unsigned long arg5)1219 asmlinkage long sys_prctl(int option, unsigned long arg2, unsigned long arg3,
1220 			  unsigned long arg4, unsigned long arg5)
1221 {
1222 	int error = 0;
1223 	int sig;
1224 
1225 	switch (option) {
1226 		case PR_SET_PDEATHSIG:
1227 			sig = arg2;
1228 			if (sig < 0 || sig > _NSIG) {
1229 				error = -EINVAL;
1230 				break;
1231 			}
1232 			current->pdeath_signal = sig;
1233 			break;
1234 		case PR_GET_PDEATHSIG:
1235 			error = put_user(current->pdeath_signal, (int *)arg2);
1236 			break;
1237 		case PR_GET_DUMPABLE:
1238 			if (is_dumpable(current))
1239 				error = 1;
1240 			break;
1241 		case PR_SET_DUMPABLE:
1242 			if (arg2 != 0 && arg2 != 1) {
1243 				error = -EINVAL;
1244 				break;
1245 			}
1246 			current->mm->dumpable = arg2;
1247 			break;
1248 
1249 	        case PR_SET_UNALIGN:
1250 			error = SET_UNALIGN_CTL(current, arg2);
1251 			break;
1252 	        case PR_GET_UNALIGN:
1253 			error = GET_UNALIGN_CTL(current, arg2);
1254 			break;
1255 	        case PR_SET_FPEMU:
1256 			error = SET_FPEMU_CTL(current, arg2);
1257 			break;
1258 	        case PR_GET_FPEMU:
1259 			error = GET_FPEMU_CTL(current, arg2);
1260 			break;
1261 		case PR_SET_FPEXC:
1262 			error = SET_FPEXC_CTL(current, arg2);
1263 			break;
1264 		case PR_GET_FPEXC:
1265 			error = GET_FPEXC_CTL(current, arg2);
1266 			break;
1267 
1268 		case PR_GET_KEEPCAPS:
1269 			if (current->keep_capabilities)
1270 				error = 1;
1271 			break;
1272 		case PR_SET_KEEPCAPS:
1273 			if (arg2 != 0 && arg2 != 1) {
1274 				error = -EINVAL;
1275 				break;
1276 			}
1277 			current->keep_capabilities = arg2;
1278 			break;
1279 		default:
1280 			error = -EINVAL;
1281 			break;
1282 	}
1283 	return error;
1284 }
1285 
1286 EXPORT_SYMBOL(notifier_chain_register);
1287 EXPORT_SYMBOL(notifier_chain_unregister);
1288 EXPORT_SYMBOL(notifier_call_chain);
1289 EXPORT_SYMBOL(register_reboot_notifier);
1290 EXPORT_SYMBOL(unregister_reboot_notifier);
1291 EXPORT_SYMBOL(in_group_p);
1292 EXPORT_SYMBOL(in_egroup_p);
1293