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