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