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