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