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