This source file includes following definitions.
- sys_ni_syscall
- proc_sel
- sys_setpriority
- sys_getpriority
- sys_profil
- sys_ftime
- sys_break
- sys_stty
- sys_gtty
- sys_prof
- sys_reboot
- ctrl_alt_del
- sys_setregid
- sys_setgid
- sys_acct
- sys_phys
- sys_lock
- sys_mpx
- sys_ulimit
- sys_old_syscall
- sys_setreuid
- sys_setuid
- sys_setfsuid
- sys_setfsgid
- sys_times
- sys_brk
- sys_setpgid
- sys_getpgid
- sys_getpgrp
- sys_setsid
- sys_getgroups
- sys_setgroups
- in_group_p
- sys_newuname
- sys_uname
- sys_olduname
- sys_sethostname
- sys_setdomainname
- sys_getrlimit
- sys_setrlimit
- getrusage
- sys_getrusage
- sys_umask
1
2
3
4
5
6
7 #include <linux/errno.h>
8 #include <linux/sched.h>
9 #include <linux/kernel.h>
10 #include <linux/times.h>
11 #include <linux/utsname.h>
12 #include <linux/param.h>
13 #include <linux/resource.h>
14 #include <linux/signal.h>
15 #include <linux/string.h>
16 #include <linux/ptrace.h>
17 #include <linux/stat.h>
18 #include <linux/mman.h>
19 #include <linux/mm.h>
20
21 #include <asm/segment.h>
22 #include <asm/io.h>
23
24
25
26
27 static int C_A_D = 1;
28
29 extern void adjust_clock(void);
30
31 #define PZERO 15
32
33 asmlinkage int sys_ni_syscall(void)
34 {
35 return -ENOSYS;
36 }
37
38 static int proc_sel(struct task_struct *p, int which, int who)
39 {
40 switch (which) {
41 case PRIO_PROCESS:
42 if (!who && p == current)
43 return 1;
44 return(p->pid == who);
45 case PRIO_PGRP:
46 if (!who)
47 who = current->pgrp;
48 return(p->pgrp == who);
49 case PRIO_USER:
50 if (!who)
51 who = current->uid;
52 return(p->uid == who);
53 }
54 return 0;
55 }
56
57 asmlinkage int sys_setpriority(int which, int who, int niceval)
58 {
59 struct task_struct **p;
60 int error = ESRCH;
61 int priority;
62
63 if (which > 2 || which < 0)
64 return -EINVAL;
65
66 if ((priority = PZERO - niceval) <= 0)
67 priority = 1;
68
69 for(p = &LAST_TASK; p > &FIRST_TASK; --p) {
70 if (!*p || !proc_sel(*p, which, who))
71 continue;
72 if ((*p)->uid != current->euid &&
73 (*p)->uid != current->uid && !suser()) {
74 error = EPERM;
75 continue;
76 }
77 if (error == ESRCH)
78 error = 0;
79 if (priority > (*p)->priority && !suser())
80 error = EACCES;
81 else
82 (*p)->priority = priority;
83 }
84 return -error;
85 }
86
87 asmlinkage int sys_getpriority(int which, int who)
88 {
89 struct task_struct **p;
90 int max_prio = 0;
91
92 if (which > 2 || which < 0)
93 return -EINVAL;
94
95 for(p = &LAST_TASK; p > &FIRST_TASK; --p) {
96 if (!*p || !proc_sel(*p, which, who))
97 continue;
98 if ((*p)->priority > max_prio)
99 max_prio = (*p)->priority;
100 }
101 return(max_prio ? max_prio : -ESRCH);
102 }
103
104 asmlinkage int sys_profil(void)
105 {
106 return -ENOSYS;
107 }
108
109 asmlinkage int sys_ftime(void)
110 {
111 return -ENOSYS;
112 }
113
114 asmlinkage int sys_break(void)
115 {
116 return -ENOSYS;
117 }
118
119 asmlinkage int sys_stty(void)
120 {
121 return -ENOSYS;
122 }
123
124 asmlinkage int sys_gtty(void)
125 {
126 return -ENOSYS;
127 }
128
129 asmlinkage int sys_prof(void)
130 {
131 return -ENOSYS;
132 }
133
134 extern void hard_reset_now(void);
135 extern asmlinkage sys_kill(int, int);
136
137
138
139
140
141
142
143
144
145 asmlinkage int sys_reboot(int magic, int magic_too, int flag)
146 {
147 if (!suser())
148 return -EPERM;
149 if (magic != 0xfee1dead || magic_too != 672274793)
150 return -EINVAL;
151 if (flag == 0x01234567)
152 hard_reset_now();
153 else if (flag == 0x89ABCDEF)
154 C_A_D = 1;
155 else if (!flag)
156 C_A_D = 0;
157 else if (flag == 0xCDEF0123) {
158 printk(KERN_EMERG "System halted\n");
159 sys_kill(-1, SIGKILL);
160 do_exit(0);
161 } else
162 return -EINVAL;
163 return (0);
164 }
165
166
167
168
169
170
171 void ctrl_alt_del(void)
172 {
173 if (C_A_D)
174 hard_reset_now();
175 else {
176 int i;
177 send_sig(SIGINT,task[1],1);
178 for (i = 2; i < NR_TASKS; i++)
179 send_sig(SIGHUP,task[i],1);
180 }
181 }
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199 asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
200 {
201 int old_rgid = current->gid;
202
203 if (rgid != (gid_t) -1) {
204 if ((old_rgid == rgid) ||
205 (current->egid==rgid) ||
206 suser())
207 current->gid = rgid;
208 else
209 return(-EPERM);
210 }
211 if (egid != (gid_t) -1) {
212 if ((old_rgid == egid) ||
213 (current->egid == egid) ||
214 (current->sgid == egid) ||
215 suser())
216 current->egid = egid;
217 else {
218 current->gid = old_rgid;
219 return(-EPERM);
220 }
221 }
222 if (rgid != (gid_t) -1 ||
223 (egid != (gid_t) -1 && egid != old_rgid))
224 current->sgid = current->egid;
225 current->fsgid = current->egid;
226 return 0;
227 }
228
229
230
231
232 asmlinkage int sys_setgid(gid_t gid)
233 {
234 if (suser())
235 current->gid = current->egid = current->sgid = current->fsgid = gid;
236 else if ((gid == current->gid) || (gid == current->sgid))
237 current->egid = current->fsgid = gid;
238 else
239 return -EPERM;
240 return 0;
241 }
242
243 asmlinkage int sys_acct(void)
244 {
245 return -ENOSYS;
246 }
247
248 asmlinkage int sys_phys(void)
249 {
250 return -ENOSYS;
251 }
252
253 asmlinkage int sys_lock(void)
254 {
255 return -ENOSYS;
256 }
257
258 asmlinkage int sys_mpx(void)
259 {
260 return -ENOSYS;
261 }
262
263 asmlinkage int sys_ulimit(void)
264 {
265 return -ENOSYS;
266 }
267
268 asmlinkage int sys_old_syscall(void)
269 {
270 return -ENOSYS;
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
289 {
290 int old_ruid = current->uid;
291
292 if (ruid != (uid_t) -1) {
293 if ((old_ruid == ruid) ||
294 (current->euid==ruid) ||
295 suser())
296 current->uid = ruid;
297 else
298 return(-EPERM);
299 }
300 if (euid != (uid_t) -1) {
301 if ((old_ruid == euid) ||
302 (current->euid == euid) ||
303 (current->suid == euid) ||
304 suser())
305 current->euid = euid;
306 else {
307 current->uid = old_ruid;
308 return(-EPERM);
309 }
310 }
311 if (ruid != (uid_t) -1 ||
312 (euid != (uid_t) -1 && euid != old_ruid))
313 current->suid = current->euid;
314 current->fsuid = current->euid;
315 return 0;
316 }
317
318
319
320
321
322
323
324
325
326
327
328
329 asmlinkage int sys_setuid(uid_t uid)
330 {
331 if (suser())
332 current->uid = current->euid = current->suid = current->fsuid = uid;
333 else if ((uid == current->uid) || (uid == current->suid))
334 current->fsuid = current->euid = uid;
335 else
336 return -EPERM;
337 return(0);
338 }
339
340
341
342
343
344
345
346 asmlinkage int sys_setfsuid(uid_t uid)
347 {
348 int old_fsuid = current->fsuid;
349
350 if (uid == current->uid || uid == current->euid ||
351 uid == current->suid || uid == current->fsuid || suser())
352 current->fsuid = uid;
353 return old_fsuid;
354 }
355
356
357
358
359 asmlinkage int sys_setfsgid(gid_t gid)
360 {
361 int old_fsgid = current->fsgid;
362
363 if (gid == current->gid || gid == current->egid ||
364 gid == current->sgid || gid == current->fsgid || suser())
365 current->fsgid = gid;
366 return old_fsgid;
367 }
368
369 asmlinkage int sys_times(struct tms * tbuf)
370 {
371 if (tbuf) {
372 int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
373 if (error)
374 return error;
375 put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime);
376 put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime);
377 put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime);
378 put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime);
379 }
380 return jiffies;
381 }
382
383 asmlinkage int sys_brk(unsigned long brk)
384 {
385 int freepages;
386 unsigned long rlim;
387 unsigned long newbrk, oldbrk;
388
389 if (brk < current->mm->end_code)
390 return current->mm->brk;
391 newbrk = PAGE_ALIGN(brk);
392 oldbrk = PAGE_ALIGN(current->mm->brk);
393 if (oldbrk == newbrk)
394 return current->mm->brk = brk;
395
396
397
398
399 if (brk <= current->mm->brk) {
400 current->mm->brk = brk;
401 do_munmap(newbrk, oldbrk-newbrk);
402 return brk;
403 }
404
405
406
407 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
408 if (rlim >= RLIM_INFINITY)
409 rlim = ~0;
410 if (brk - current->mm->end_code > rlim ||
411 brk >= current->mm->start_stack - 16384)
412 return current->mm->brk;
413
414
415
416 if (find_vma_intersection(current, oldbrk, newbrk))
417 return current->mm->brk;
418
419
420
421
422
423 freepages = buffermem >> 12;
424 freepages += nr_free_pages;
425 freepages += nr_swap_pages;
426 freepages -= (high_memory - 0x100000) >> 16;
427 freepages -= (newbrk-oldbrk) >> 12;
428 if (freepages < 0)
429 return current->mm->brk;
430 #if 0
431 freepages += current->mm->rss;
432 freepages -= oldbrk >> 12;
433 if (freepages < 0)
434 return current->mm->brk;
435 #endif
436
437
438
439 current->mm->brk = brk;
440 do_mmap(NULL, oldbrk, newbrk-oldbrk,
441 PROT_READ|PROT_WRITE|PROT_EXEC,
442 MAP_FIXED|MAP_PRIVATE, 0);
443 return brk;
444 }
445
446
447
448
449
450
451
452
453
454
455
456
457
458 asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
459 {
460 struct task_struct * p;
461
462 if (!pid)
463 pid = current->pid;
464 if (!pgid)
465 pgid = pid;
466 if (pgid < 0)
467 return -EINVAL;
468 for_each_task(p) {
469 if (p->pid == pid)
470 goto found_task;
471 }
472 return -ESRCH;
473
474 found_task:
475 if (p->p_pptr == current || p->p_opptr == current) {
476 if (p->session != current->session)
477 return -EPERM;
478 if (p->did_exec)
479 return -EACCES;
480 } else if (p != current)
481 return -ESRCH;
482 if (p->leader)
483 return -EPERM;
484 if (pgid != pid) {
485 struct task_struct * tmp;
486 for_each_task (tmp) {
487 if (tmp->pgrp == pgid &&
488 tmp->session == current->session)
489 goto ok_pgid;
490 }
491 return -EPERM;
492 }
493
494 ok_pgid:
495 p->pgrp = pgid;
496 return 0;
497 }
498
499 asmlinkage int sys_getpgid(pid_t pid)
500 {
501 struct task_struct * p;
502
503 if (!pid)
504 return current->pgrp;
505 for_each_task(p) {
506 if (p->pid == pid)
507 return p->pgrp;
508 }
509 return -ESRCH;
510 }
511
512 asmlinkage int sys_getpgrp(void)
513 {
514 return current->pgrp;
515 }
516
517 asmlinkage int sys_setsid(void)
518 {
519 if (current->leader)
520 return -EPERM;
521 current->leader = 1;
522 current->session = current->pgrp = current->pid;
523 current->tty = NULL;
524 current->tty_old_pgrp = 0;
525 return current->pgrp;
526 }
527
528
529
530
531 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
532 {
533 int i;
534
535 if (gidsetsize) {
536 i = verify_area(VERIFY_WRITE, grouplist, sizeof(gid_t) * gidsetsize);
537 if (i)
538 return i;
539 }
540 for (i = 0 ; (i < NGROUPS) && (current->groups[i] != NOGROUP) ; i++) {
541 if (!gidsetsize)
542 continue;
543 if (i >= gidsetsize)
544 break;
545 put_fs_word(current->groups[i], (short *) grouplist);
546 grouplist++;
547 }
548 return(i);
549 }
550
551 asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
552 {
553 int i;
554
555 if (!suser())
556 return -EPERM;
557 if (gidsetsize > NGROUPS)
558 return -EINVAL;
559 for (i = 0; i < gidsetsize; i++, grouplist++) {
560 current->groups[i] = get_fs_word((unsigned short *) grouplist);
561 }
562 if (i < NGROUPS)
563 current->groups[i] = NOGROUP;
564 return 0;
565 }
566
567 int in_group_p(gid_t grp)
568 {
569 int i;
570
571 if (grp == current->fsgid)
572 return 1;
573
574 for (i = 0; i < NGROUPS; i++) {
575 if (current->groups[i] == NOGROUP)
576 break;
577 if (current->groups[i] == grp)
578 return 1;
579 }
580 return 0;
581 }
582
583 asmlinkage int sys_newuname(struct new_utsname * name)
584 {
585 int error;
586
587 if (!name)
588 return -EFAULT;
589 error = verify_area(VERIFY_WRITE, name, sizeof *name);
590 if (!error)
591 memcpy_tofs(name,&system_utsname,sizeof *name);
592 return error;
593 }
594
595 asmlinkage int sys_uname(struct old_utsname * name)
596 {
597 int error;
598 if (!name)
599 return -EFAULT;
600 error = verify_area(VERIFY_WRITE, name,sizeof *name);
601 if (error)
602 return error;
603 memcpy_tofs(&name->sysname,&system_utsname.sysname,
604 sizeof (system_utsname.sysname));
605 memcpy_tofs(&name->nodename,&system_utsname.nodename,
606 sizeof (system_utsname.nodename));
607 memcpy_tofs(&name->release,&system_utsname.release,
608 sizeof (system_utsname.release));
609 memcpy_tofs(&name->version,&system_utsname.version,
610 sizeof (system_utsname.version));
611 memcpy_tofs(&name->machine,&system_utsname.machine,
612 sizeof (system_utsname.machine));
613 return 0;
614 }
615
616 asmlinkage int sys_olduname(struct oldold_utsname * name)
617 {
618 int error;
619 if (!name)
620 return -EFAULT;
621 error = verify_area(VERIFY_WRITE, name,sizeof *name);
622 if (error)
623 return error;
624 memcpy_tofs(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
625 put_fs_byte(0,name->sysname+__OLD_UTS_LEN);
626 memcpy_tofs(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
627 put_fs_byte(0,name->nodename+__OLD_UTS_LEN);
628 memcpy_tofs(&name->release,&system_utsname.release,__OLD_UTS_LEN);
629 put_fs_byte(0,name->release+__OLD_UTS_LEN);
630 memcpy_tofs(&name->version,&system_utsname.version,__OLD_UTS_LEN);
631 put_fs_byte(0,name->version+__OLD_UTS_LEN);
632 memcpy_tofs(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
633 put_fs_byte(0,name->machine+__OLD_UTS_LEN);
634 return 0;
635 }
636
637
638
639
640 asmlinkage int sys_sethostname(char *name, int len)
641 {
642 int i;
643
644 if (!suser())
645 return -EPERM;
646 if (len > __NEW_UTS_LEN)
647 return -EINVAL;
648 for (i=0; i < len; i++) {
649 if ((system_utsname.nodename[i] = get_fs_byte(name+i)) == 0)
650 return 0;
651 }
652 system_utsname.nodename[i] = 0;
653 return 0;
654 }
655
656
657
658
659
660 asmlinkage int sys_setdomainname(char *name, int len)
661 {
662 int i;
663
664 if (!suser())
665 return -EPERM;
666 if (len > __NEW_UTS_LEN)
667 return -EINVAL;
668 for (i=0; i < len; i++) {
669 if ((system_utsname.domainname[i] = get_fs_byte(name+i)) == 0)
670 return 0;
671 }
672 system_utsname.domainname[i] = 0;
673 return 0;
674 }
675
676 asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
677 {
678 int error;
679
680 if (resource >= RLIM_NLIMITS)
681 return -EINVAL;
682 error = verify_area(VERIFY_WRITE,rlim,sizeof *rlim);
683 if (error)
684 return error;
685 put_fs_long(current->rlim[resource].rlim_cur,
686 (unsigned long *) rlim);
687 put_fs_long(current->rlim[resource].rlim_max,
688 ((unsigned long *) rlim)+1);
689 return 0;
690 }
691
692 asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
693 {
694 struct rlimit new_rlim, *old_rlim;
695 int err;
696
697 if (resource >= RLIM_NLIMITS)
698 return -EINVAL;
699 err = verify_area(VERIFY_READ, rlim, sizeof(*rlim));
700 if (err)
701 return err;
702 memcpy_fromfs(&new_rlim, rlim, sizeof(*rlim));
703 old_rlim = current->rlim + resource;
704 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
705 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
706 !suser())
707 return -EPERM;
708 if (resource == RLIMIT_NOFILE) {
709 if (new_rlim.rlim_cur > NR_OPEN || new_rlim.rlim_max > NR_OPEN)
710 return -EPERM;
711 }
712 *old_rlim = new_rlim;
713 return 0;
714 }
715
716
717
718
719
720
721
722
723
724 int getrusage(struct task_struct *p, int who, struct rusage *ru)
725 {
726 int error;
727 struct rusage r;
728
729 error = verify_area(VERIFY_WRITE, ru, sizeof *ru);
730 if (error)
731 return error;
732 memset((char *) &r, 0, sizeof(r));
733 switch (who) {
734 case RUSAGE_SELF:
735 r.ru_utime.tv_sec = CT_TO_SECS(p->utime);
736 r.ru_utime.tv_usec = CT_TO_USECS(p->utime);
737 r.ru_stime.tv_sec = CT_TO_SECS(p->stime);
738 r.ru_stime.tv_usec = CT_TO_USECS(p->stime);
739 r.ru_minflt = p->mm->min_flt;
740 r.ru_majflt = p->mm->maj_flt;
741 break;
742 case RUSAGE_CHILDREN:
743 r.ru_utime.tv_sec = CT_TO_SECS(p->cutime);
744 r.ru_utime.tv_usec = CT_TO_USECS(p->cutime);
745 r.ru_stime.tv_sec = CT_TO_SECS(p->cstime);
746 r.ru_stime.tv_usec = CT_TO_USECS(p->cstime);
747 r.ru_minflt = p->mm->cmin_flt;
748 r.ru_majflt = p->mm->cmaj_flt;
749 break;
750 default:
751 r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime);
752 r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime);
753 r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime);
754 r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime);
755 r.ru_minflt = p->mm->min_flt + p->mm->cmin_flt;
756 r.ru_majflt = p->mm->maj_flt + p->mm->cmaj_flt;
757 break;
758 }
759 memcpy_tofs(ru, &r, sizeof(r));
760 return 0;
761 }
762
763 asmlinkage int sys_getrusage(int who, struct rusage *ru)
764 {
765 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
766 return -EINVAL;
767 return getrusage(current, who, ru);
768 }
769
770 asmlinkage int sys_umask(int mask)
771 {
772 int old = current->fs->umask;
773
774 current->fs->umask = mask & S_IRWXUGO;
775 return (old);
776 }