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
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 = current->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 struct vm_area_struct * vma;
400
401 if (brk < current->mm->end_code)
402 return current->mm->brk;
403 newbrk = PAGE_ALIGN(brk);
404 oldbrk = PAGE_ALIGN(current->mm->brk);
405 if (oldbrk == newbrk)
406 return current->mm->brk = brk;
407
408
409
410
411 if (brk <= current->mm->brk) {
412 current->mm->brk = brk;
413 do_munmap(newbrk, oldbrk-newbrk);
414 return brk;
415 }
416
417
418
419 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
420 if (rlim >= RLIM_INFINITY)
421 rlim = ~0;
422 if (brk - current->mm->end_code > rlim ||
423 brk >= current->mm->start_stack - 16384)
424 return current->mm->brk;
425
426
427
428 for (vma = current->mm->mmap; vma; vma = vma->vm_next) {
429 if (newbrk <= vma->vm_start)
430 break;
431 if (oldbrk < vma->vm_end)
432 return current->mm->brk;
433 }
434
435
436
437
438
439 freepages = buffermem >> 12;
440 freepages += nr_free_pages;
441 freepages += nr_swap_pages;
442 freepages -= (high_memory - 0x100000) >> 16;
443 freepages -= (newbrk-oldbrk) >> 12;
444 if (freepages < 0)
445 return current->mm->brk;
446 #if 0
447 freepages += current->mm->rss;
448 freepages -= oldbrk >> 12;
449 if (freepages < 0)
450 return current->mm->brk;
451 #endif
452
453
454
455 current->mm->brk = brk;
456 do_mmap(NULL, oldbrk, newbrk-oldbrk,
457 PROT_READ|PROT_WRITE|PROT_EXEC,
458 MAP_FIXED|MAP_PRIVATE, 0);
459 return brk;
460 }
461
462
463
464
465
466
467
468
469
470
471
472
473
474 asmlinkage int sys_setpgid(pid_t pid, pid_t pgid)
475 {
476 struct task_struct * p;
477
478 if (!pid)
479 pid = current->pid;
480 if (!pgid)
481 pgid = pid;
482 if (pgid < 0)
483 return -EINVAL;
484 for_each_task(p) {
485 if (p->pid == pid)
486 goto found_task;
487 }
488 return -ESRCH;
489
490 found_task:
491 if (p->p_pptr == current || p->p_opptr == current) {
492 if (p->session != current->session)
493 return -EPERM;
494 if (p->did_exec)
495 return -EACCES;
496 } else if (p != current)
497 return -ESRCH;
498 if (p->leader)
499 return -EPERM;
500 if (pgid != pid) {
501 struct task_struct * tmp;
502 for_each_task (tmp) {
503 if (tmp->pgrp == pgid &&
504 tmp->session == current->session)
505 goto ok_pgid;
506 }
507 return -EPERM;
508 }
509
510 ok_pgid:
511 p->pgrp = pgid;
512 return 0;
513 }
514
515 asmlinkage int sys_getpgid(pid_t pid)
516 {
517 struct task_struct * p;
518
519 if (!pid)
520 return current->pgrp;
521 for_each_task(p) {
522 if (p->pid == pid)
523 return p->pgrp;
524 }
525 return -ESRCH;
526 }
527
528 asmlinkage int sys_getpgrp(void)
529 {
530 return current->pgrp;
531 }
532
533 asmlinkage int sys_setsid(void)
534 {
535 if (current->leader)
536 return -EPERM;
537 current->leader = 1;
538 current->session = current->pgrp = current->pid;
539 current->tty = NULL;
540 return current->pgrp;
541 }
542
543
544
545
546 asmlinkage int sys_getgroups(int gidsetsize, gid_t *grouplist)
547 {
548 int i;
549
550 if (gidsetsize) {
551 i = verify_area(VERIFY_WRITE, grouplist, sizeof(gid_t) * gidsetsize);
552 if (i)
553 return i;
554 }
555 for (i = 0 ; (i < NGROUPS) && (current->groups[i] != NOGROUP) ; i++) {
556 if (!gidsetsize)
557 continue;
558 if (i >= gidsetsize)
559 break;
560 put_fs_word(current->groups[i], (short *) grouplist);
561 grouplist++;
562 }
563 return(i);
564 }
565
566 asmlinkage int sys_setgroups(int gidsetsize, gid_t *grouplist)
567 {
568 int i;
569
570 if (!suser())
571 return -EPERM;
572 if (gidsetsize > NGROUPS)
573 return -EINVAL;
574 for (i = 0; i < gidsetsize; i++, grouplist++) {
575 current->groups[i] = get_fs_word((unsigned short *) grouplist);
576 }
577 if (i < NGROUPS)
578 current->groups[i] = NOGROUP;
579 return 0;
580 }
581
582 int in_group_p(gid_t grp)
583 {
584 int i;
585
586 if (grp == current->fsgid)
587 return 1;
588
589 for (i = 0; i < NGROUPS; i++) {
590 if (current->groups[i] == NOGROUP)
591 break;
592 if (current->groups[i] == grp)
593 return 1;
594 }
595 return 0;
596 }
597
598 asmlinkage int sys_newuname(struct new_utsname * name)
599 {
600 int error;
601
602 if (!name)
603 return -EFAULT;
604 error = verify_area(VERIFY_WRITE, name, sizeof *name);
605 if (!error)
606 memcpy_tofs(name,&system_utsname,sizeof *name);
607 return error;
608 }
609
610 asmlinkage int sys_uname(struct old_utsname * name)
611 {
612 int error;
613 if (!name)
614 return -EFAULT;
615 error = verify_area(VERIFY_WRITE, name,sizeof *name);
616 if (error)
617 return error;
618 memcpy_tofs(&name->sysname,&system_utsname.sysname,
619 sizeof (system_utsname.sysname));
620 memcpy_tofs(&name->nodename,&system_utsname.nodename,
621 sizeof (system_utsname.nodename));
622 memcpy_tofs(&name->release,&system_utsname.release,
623 sizeof (system_utsname.release));
624 memcpy_tofs(&name->version,&system_utsname.version,
625 sizeof (system_utsname.version));
626 memcpy_tofs(&name->machine,&system_utsname.machine,
627 sizeof (system_utsname.machine));
628 return 0;
629 }
630
631 asmlinkage int sys_olduname(struct oldold_utsname * name)
632 {
633 int error;
634 if (!name)
635 return -EFAULT;
636 error = verify_area(VERIFY_WRITE, name,sizeof *name);
637 if (error)
638 return error;
639 memcpy_tofs(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
640 put_fs_byte(0,name->sysname+__OLD_UTS_LEN);
641 memcpy_tofs(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
642 put_fs_byte(0,name->nodename+__OLD_UTS_LEN);
643 memcpy_tofs(&name->release,&system_utsname.release,__OLD_UTS_LEN);
644 put_fs_byte(0,name->release+__OLD_UTS_LEN);
645 memcpy_tofs(&name->version,&system_utsname.version,__OLD_UTS_LEN);
646 put_fs_byte(0,name->version+__OLD_UTS_LEN);
647 memcpy_tofs(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
648 put_fs_byte(0,name->machine+__OLD_UTS_LEN);
649 return 0;
650 }
651
652
653
654
655 asmlinkage int sys_sethostname(char *name, int len)
656 {
657 int i;
658
659 if (!suser())
660 return -EPERM;
661 if (len > __NEW_UTS_LEN)
662 return -EINVAL;
663 for (i=0; i < len; i++) {
664 if ((system_utsname.nodename[i] = get_fs_byte(name+i)) == 0)
665 return 0;
666 }
667 system_utsname.nodename[i] = 0;
668 return 0;
669 }
670
671
672
673
674
675 asmlinkage int sys_setdomainname(char *name, int len)
676 {
677 int i;
678
679 if (!suser())
680 return -EPERM;
681 if (len > __NEW_UTS_LEN)
682 return -EINVAL;
683 for (i=0; i < len; i++) {
684 if ((system_utsname.domainname[i] = get_fs_byte(name+i)) == 0)
685 return 0;
686 }
687 system_utsname.domainname[i] = 0;
688 return 0;
689 }
690
691 asmlinkage int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
692 {
693 int error;
694
695 if (resource >= RLIM_NLIMITS)
696 return -EINVAL;
697 error = verify_area(VERIFY_WRITE,rlim,sizeof *rlim);
698 if (error)
699 return error;
700 put_fs_long(current->rlim[resource].rlim_cur,
701 (unsigned long *) rlim);
702 put_fs_long(current->rlim[resource].rlim_max,
703 ((unsigned long *) rlim)+1);
704 return 0;
705 }
706
707 asmlinkage int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
708 {
709 struct rlimit new_rlim, *old_rlim;
710 int err;
711
712 if (resource >= RLIM_NLIMITS)
713 return -EINVAL;
714 err = verify_area(VERIFY_READ, rlim, sizeof(*rlim));
715 if (err)
716 return err;
717 memcpy_fromfs(&new_rlim, rlim, sizeof(*rlim));
718 old_rlim = current->rlim + resource;
719 if (((new_rlim.rlim_cur > old_rlim->rlim_max) ||
720 (new_rlim.rlim_max > old_rlim->rlim_max)) &&
721 !suser())
722 return -EPERM;
723 *old_rlim = new_rlim;
724 return 0;
725 }
726
727
728
729
730
731
732
733
734
735 int getrusage(struct task_struct *p, int who, struct rusage *ru)
736 {
737 int error;
738 struct rusage r;
739
740 error = verify_area(VERIFY_WRITE, ru, sizeof *ru);
741 if (error)
742 return error;
743 memset((char *) &r, 0, sizeof(r));
744 switch (who) {
745 case RUSAGE_SELF:
746 r.ru_utime.tv_sec = CT_TO_SECS(p->utime);
747 r.ru_utime.tv_usec = CT_TO_USECS(p->utime);
748 r.ru_stime.tv_sec = CT_TO_SECS(p->stime);
749 r.ru_stime.tv_usec = CT_TO_USECS(p->stime);
750 r.ru_minflt = p->mm->min_flt;
751 r.ru_majflt = p->mm->maj_flt;
752 break;
753 case RUSAGE_CHILDREN:
754 r.ru_utime.tv_sec = CT_TO_SECS(p->cutime);
755 r.ru_utime.tv_usec = CT_TO_USECS(p->cutime);
756 r.ru_stime.tv_sec = CT_TO_SECS(p->cstime);
757 r.ru_stime.tv_usec = CT_TO_USECS(p->cstime);
758 r.ru_minflt = p->mm->cmin_flt;
759 r.ru_majflt = p->mm->cmaj_flt;
760 break;
761 default:
762 r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime);
763 r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime);
764 r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime);
765 r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime);
766 r.ru_minflt = p->mm->min_flt + p->mm->cmin_flt;
767 r.ru_majflt = p->mm->maj_flt + p->mm->cmaj_flt;
768 break;
769 }
770 memcpy_tofs(ru, &r, sizeof(r));
771 return 0;
772 }
773
774 asmlinkage int sys_getrusage(int who, struct rusage *ru)
775 {
776 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
777 return -EINVAL;
778 return getrusage(current, who, ru);
779 }
780
781 asmlinkage int sys_umask(int mask)
782 {
783 int old = current->fs->umask;
784
785 current->fs->umask = mask & S_IRWXUGO;
786 return (old);
787 }