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