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