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 -EINVAL;
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
156
157
158
159
160
161
162
163
164 asmlinkage int sys_reboot(int magic, int magic_too, int flag)
165 {
166 if (!suser())
167 return -EPERM;
168 if (magic != 0xfee1dead || magic_too != 672274793)
169 return -EINVAL;
170 if (flag == 0x01234567)
171 hard_reset_now();
172 else if (flag == 0x89ABCDEF)
173 C_A_D = 1;
174 else if (!flag)
175 C_A_D = 0;
176 else
177 return -EINVAL;
178 return (0);
179 }
180
181
182
183
184
185
186 void ctrl_alt_del(void)
187 {
188 if (C_A_D)
189 hard_reset_now();
190 else
191 send_sig(SIGINT,task[1],1);
192 }
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210 asmlinkage int sys_setregid(gid_t rgid, gid_t egid)
211 {
212 int old_rgid = current->gid;
213
214 if (rgid != (gid_t) -1) {
215 if ((old_rgid == rgid) ||
216 (current->egid==rgid) ||
217 suser())
218 current->gid = rgid;
219 else
220 return(-EPERM);
221 }
222 if (egid != (gid_t) -1) {
223 if ((old_rgid == egid) ||
224 (current->egid == egid) ||
225 (current->sgid == egid) ||
226 suser())
227 current->egid = egid;
228 else {
229 current->gid = old_rgid;
230 return(-EPERM);
231 }
232 }
233 if (rgid != (gid_t) -1 ||
234 (egid != (gid_t) -1 && egid != old_rgid))
235 current->sgid = current->egid;
236 current->fsgid = current->egid;
237 return 0;
238 }
239
240
241
242
243 asmlinkage int sys_setgid(gid_t gid)
244 {
245 if (suser())
246 current->gid = current->egid = current->sgid = current->fsgid = gid;
247 else if ((gid == current->gid) || (gid == current->sgid))
248 current->egid = current->fsgid = gid;
249 else
250 return -EPERM;
251 return 0;
252 }
253
254 asmlinkage int sys_acct(void)
255 {
256 return -ENOSYS;
257 }
258
259 asmlinkage int sys_phys(void)
260 {
261 return -ENOSYS;
262 }
263
264 asmlinkage int sys_lock(void)
265 {
266 return -ENOSYS;
267 }
268
269 asmlinkage int sys_mpx(void)
270 {
271 return -ENOSYS;
272 }
273
274 asmlinkage int sys_ulimit(void)
275 {
276 return -ENOSYS;
277 }
278
279 asmlinkage int sys_old_syscall(void)
280 {
281 return -ENOSYS;
282 }
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299 asmlinkage int sys_setreuid(uid_t ruid, uid_t euid)
300 {
301 int old_ruid = current->uid;
302
303 if (ruid != (uid_t) -1) {
304 if ((old_ruid == ruid) ||
305 (current->euid==ruid) ||
306 suser())
307 current->uid = ruid;
308 else
309 return(-EPERM);
310 }
311 if (euid != (uid_t) -1) {
312 if ((old_ruid == euid) ||
313 (current->euid == euid) ||
314 (current->suid == euid) ||
315 suser())
316 current->euid = euid;
317 else {
318 current->uid = old_ruid;
319 return(-EPERM);
320 }
321 }
322 if (ruid != (uid_t) -1 ||
323 (euid != (uid_t) -1 && euid != old_ruid))
324 current->suid = current->euid;
325 current->fsuid = euid;
326 return 0;
327 }
328
329
330
331
332
333
334
335
336
337
338
339
340 asmlinkage int sys_setuid(uid_t uid)
341 {
342 if (suser())
343 current->uid = current->euid = current->suid = current->fsuid = uid;
344 else if ((uid == current->uid) || (uid == current->suid))
345 current->fsuid = current->euid = uid;
346 else
347 return -EPERM;
348 return(0);
349 }
350
351
352
353
354
355
356
357 asmlinkage int sys_setfsuid(uid_t uid)
358 {
359 int old_fsuid = current->fsuid;
360
361 if (uid == current->uid || uid == current->euid ||
362 uid == current->suid || uid == current->fsuid || suser())
363 current->fsuid = uid;
364 return old_fsuid;
365 }
366
367
368
369
370 asmlinkage int sys_setfsgid(gid_t gid)
371 {
372 int old_fsgid = current->fsgid;
373
374 if (gid == current->gid || gid == current->egid ||
375 gid == current->sgid || gid == current->fsgid || suser())
376 current->fsgid = gid;
377 return old_fsgid;
378 }
379
380 asmlinkage int sys_times(struct tms * tbuf)
381 {
382 if (tbuf) {
383 int error = verify_area(VERIFY_WRITE,tbuf,sizeof *tbuf);
384 if (error)
385 return error;
386 put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime);
387 put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime);
388 put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime);
389 put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime);
390 }
391 return jiffies;
392 }
393
394 asmlinkage int sys_brk(unsigned long brk)
395 {
396 int freepages;
397 unsigned long rlim;
398 unsigned long newbrk, oldbrk;
399
400 if (brk < current->mm->end_code)
401 return current->mm->brk;
402 newbrk = PAGE_ALIGN(brk);
403 oldbrk = PAGE_ALIGN(current->mm->brk);
404 if (oldbrk == newbrk)
405 return current->mm->brk = brk;
406
407
408
409
410 if (brk <= current->mm->brk) {
411 current->mm->brk = brk;
412 do_munmap(newbrk, oldbrk-newbrk);
413 return brk;
414 }
415
416
417
418 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
419 if (rlim >= RLIM_INFINITY)
420 rlim = ~0;
421 if (brk - current->mm->end_code > rlim ||
422 brk >= current->mm->start_stack - 16384)
423 return current->mm->brk;
424
425
426
427
428
429 freepages = buffermem >> 12;
430 freepages += nr_free_pages;
431 freepages += nr_swap_pages;
432 freepages -= (high_memory - 0x100000) >> 16;
433 freepages -= (newbrk-oldbrk) >> 12;
434 if (freepages < 0)
435 return current->mm->brk;
436 #if 0
437 freepages += current->mm->rss;
438 freepages -= oldbrk >> 12;
439 if (freepages < 0)
440 return current->mm->brk;
441 #endif
442
443
444
445 current->mm->brk = brk;
446 do_mmap(NULL, oldbrk, newbrk-oldbrk,
447 PROT_READ|PROT_WRITE|PROT_EXEC,
448 MAP_FIXED|MAP_PRIVATE, 0);
449 return brk;
450 }
451
452
453
454
455
456
457
458
459
460
461
462
463
464 asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
465 {
466 struct task_struct * p;
467
468 if (!pid)
469 pid = current->pid;
470 if (!pgid)
471 pgid = pid;
472 if (pgid < 0)
473 return -EINVAL;
474 for_each_task(p) {
475 if (p->pid == pid)
476 goto found_task;
477 }
478 return -ESRCH;
479
480 found_task:
481 if (p->p_pptr == current || p->p_opptr == current) {
482 if (p->session != current->session)
483 return -EPERM;
484 if (p->did_exec)
485 return -EACCES;
486 } else if (p != current)
487 return -ESRCH;
488 if (p->leader)
489 return -EPERM;
490 if (pgid != pid) {
491 struct task_struct * tmp;
492 for_each_task (tmp) {
493 if (tmp->pgrp == pgid &&
494 tmp->session == current->session)
495 goto ok_pgid;
496 }
497 return -EPERM;
498 }
499
500 ok_pgid:
501 p->pgrp = pgid;
502 return 0;
503 }
504
505 asmlinkage int sys_getpgid(pid_t pid)
506 {
507 struct task_struct * p;
508
509 if (!pid)
510 return current->pgrp;
511 for_each_task(p) {
512 if (p->pid == pid)
513 return p->pgrp;
514 }
515 return -ESRCH;
516 }
517
518 asmlinkage int sys_getpgrp(void)
519 {
520 return current->pgrp;
521 }
522
523 asmlinkage int sys_setsid(void)
524 {
525 if (current->leader)
526 return -EPERM;
527 current->leader = 1;
528 current->session = current->pgrp = current->pid;
529 current->tty = NULL;
530 return current->pgrp;
531 }
532
533
534
535
536 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
537 {
538 int i;
539
540 if (gidsetsize) {
541 i = verify_area(VERIFY_WRITE, grouplist, sizeof(gid_t) * gidsetsize);
542 if (i)
543 return i;
544 }
545 for (i = 0 ; (i < NGROUPS) && (current->groups[i] != NOGROUP) ; i++) {
546 if (!gidsetsize)
547 continue;
548 if (i >= gidsetsize)
549 break;
550 put_fs_word(current->groups[i], (short *) grouplist);
551 grouplist++;
552 }
553 return(i);
554 }
555
556 asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
557 {
558 int i;
559
560 if (!suser())
561 return -EPERM;
562 if (gidsetsize > NGROUPS)
563 return -EINVAL;
564 for (i = 0; i < gidsetsize; i++, grouplist++) {
565 current->groups[i] = get_fs_word((unsigned short *) grouplist);
566 }
567 if (i < NGROUPS)
568 current->groups[i] = NOGROUP;
569 return 0;
570 }
571
572 int in_group_p(gid_t grp)
573 {
574 int i;
575
576 if (grp == current->fsgid)
577 return 1;
578
579 for (i = 0; i < NGROUPS; i++) {
580 if (current->groups[i] == NOGROUP)
581 break;
582 if (current->groups[i] == grp)
583 return 1;
584 }
585 return 0;
586 }
587
588 asmlinkage int sys_newuname(struct new_utsname * name)
589 {
590 int error;
591
592 if (!name)
593 return -EFAULT;
594 error = verify_area(VERIFY_WRITE, name, sizeof *name);
595 if (!error)
596 memcpy_tofs(name,&system_utsname,sizeof *name);
597 return error;
598 }
599
600 asmlinkage int sys_uname(struct old_utsname * name)
601 {
602 int error;
603 if (!name)
604 return -EFAULT;
605 error = verify_area(VERIFY_WRITE, name,sizeof *name);
606 if (error)
607 return error;
608 memcpy_tofs(&name->sysname,&system_utsname.sysname,
609 sizeof (system_utsname.sysname));
610 memcpy_tofs(&name->nodename,&system_utsname.nodename,
611 sizeof (system_utsname.nodename));
612 memcpy_tofs(&name->release,&system_utsname.release,
613 sizeof (system_utsname.release));
614 memcpy_tofs(&name->version,&system_utsname.version,
615 sizeof (system_utsname.version));
616 memcpy_tofs(&name->machine,&system_utsname.machine,
617 sizeof (system_utsname.machine));
618 return 0;
619 }
620
621 asmlinkage int sys_olduname(struct oldold_utsname * name)
622 {
623 int error;
624 if (!name)
625 return -EFAULT;
626 error = verify_area(VERIFY_WRITE, name,sizeof *name);
627 if (error)
628 return error;
629 memcpy_tofs(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
630 put_fs_byte(0,name->sysname+__OLD_UTS_LEN);
631 memcpy_tofs(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
632 put_fs_byte(0,name->nodename+__OLD_UTS_LEN);
633 memcpy_tofs(&name->release,&system_utsname.release,__OLD_UTS_LEN);
634 put_fs_byte(0,name->release+__OLD_UTS_LEN);
635 memcpy_tofs(&name->version,&system_utsname.version,__OLD_UTS_LEN);
636 put_fs_byte(0,name->version+__OLD_UTS_LEN);
637 memcpy_tofs(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
638 put_fs_byte(0,name->machine+__OLD_UTS_LEN);
639 return 0;
640 }
641
642
643
644
645 asmlinkage int sys_sethostname(char *name, int len)
646 {
647 int i;
648
649 if (!suser())
650 return -EPERM;
651 if (len > __NEW_UTS_LEN)
652 return -EINVAL;
653 for (i=0; i < len; i++) {
654 if ((system_utsname.nodename[i] = get_fs_byte(name+i)) == 0)
655 return 0;
656 }
657 system_utsname.nodename[i] = 0;
658 return 0;
659 }
660
661
662
663
664
665 asmlinkage int sys_setdomainname(char *name, int len)
666 {
667 int i;
668
669 if (!suser())
670 return -EPERM;
671 if (len > __NEW_UTS_LEN)
672 return -EINVAL;
673 for (i=0; i < len; i++) {
674 if ((system_utsname.domainname[i] = get_fs_byte(name+i)) == 0)
675 return 0;
676 }
677 system_utsname.domainname[i] = 0;
678 return 0;
679 }
680
681 asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
682 {
683 int error;
684
685 if (resource >= RLIM_NLIMITS)
686 return -EINVAL;
687 error = verify_area(VERIFY_WRITE,rlim,sizeof *rlim);
688 if (error)
689 return error;
690 put_fs_long(current->rlim[resource].rlim_cur,
691 (unsigned long *) rlim);
692 put_fs_long(current->rlim[resource].rlim_max,
693 ((unsigned long *) rlim)+1);
694 return 0;
695 }
696
697 asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
698 {
699 struct rlimit new_rlim, *old_rlim;
700
701 if (resource >= RLIM_NLIMITS)
702 return -EINVAL;
703 old_rlim = current->rlim + resource;
704 new_rlim.rlim_cur = get_fs_long((unsigned long *) rlim);
705 new_rlim.rlim_max = get_fs_long(((unsigned long *) rlim)+1);
706 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
707 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
708 !suser())
709 return -EPERM;
710 *old_rlim = new_rlim;
711 return 0;
712 }
713
714
715
716
717
718
719
720
721
722 int getrusage(struct task_struct *p, int who, struct rusage *ru)
723 {
724 int error;
725 struct rusage r;
726 unsigned long *lp, *lpend, *dest;
727
728 error = verify_area(VERIFY_WRITE, ru, sizeof *ru);
729 if (error)
730 return error;
731 memset((char *) &r, 0, sizeof(r));
732 switch (who) {
733 case RUSAGE_SELF:
734 r.ru_utime.tv_sec = CT_TO_SECS(p->utime);
735 r.ru_utime.tv_usec = CT_TO_USECS(p->utime);
736 r.ru_stime.tv_sec = CT_TO_SECS(p->stime);
737 r.ru_stime.tv_usec = CT_TO_USECS(p->stime);
738 r.ru_minflt = p->mm->min_flt;
739 r.ru_majflt = p->mm->maj_flt;
740 break;
741 case RUSAGE_CHILDREN:
742 r.ru_utime.tv_sec = CT_TO_SECS(p->cutime);
743 r.ru_utime.tv_usec = CT_TO_USECS(p->cutime);
744 r.ru_stime.tv_sec = CT_TO_SECS(p->cstime);
745 r.ru_stime.tv_usec = CT_TO_USECS(p->cstime);
746 r.ru_minflt = p->mm->cmin_flt;
747 r.ru_majflt = p->mm->cmaj_flt;
748 break;
749 default:
750 r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime);
751 r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime);
752 r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime);
753 r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime);
754 r.ru_minflt = p->mm->min_flt + p->mm->cmin_flt;
755 r.ru_majflt = p->mm->maj_flt + p->mm->cmaj_flt;
756 break;
757 }
758 lp = (unsigned long *) &r;
759 lpend = (unsigned long *) (&r+1);
760 dest = (unsigned long *) ru;
761 for (; lp < lpend; lp++, dest++)
762 put_fs_long(*lp, dest);
763 return 0;
764 }
765
766 asmlinkage int sys_getrusage(int who, struct rusage *ru)
767 {
768 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
769 return -EINVAL;
770 return getrusage(current, who, ru);
771 }
772
773 asmlinkage int sys_umask(int mask)
774 {
775 int old = current->fs->umask;
776
777 current->fs->umask = mask & S_IRWXUGO;
778 return (old);
779 }