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