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