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 unsigned long rlim;
418
419 rlim = current->rlim[RLIMIT_DATA].rlim_cur;
420 if (rlim >= RLIM_INFINITY)
421 rlim = 0xffffffff;
422 if (end_data_seg >= current->end_code &&
423 end_data_seg-current->end_code <= rlim &&
424 end_data_seg < current->start_stack - 16384)
425 current->brk = end_data_seg;
426 return current->brk;
427 }
428
429
430
431
432
433
434
435
436
437
438 int sys_setpgid(pid_t pid, pid_t pgid)
439 {
440 int i;
441
442 if (!pid)
443 pid = current->pid;
444 if (!pgid)
445 pgid = current->pid;
446 if (pgid < 0)
447 return -EINVAL;
448 for (i=0 ; i<NR_TASKS ; i++)
449 if (task[i] && (task[i]->pid == pid) &&
450 ((task[i]->p_pptr == current) ||
451 (task[i] == current))) {
452 if (task[i]->leader)
453 return -EPERM;
454 if ((task[i]->session != current->session) ||
455 ((pgid != pid) &&
456 (session_of_pgrp(pgid) != current->session)))
457 return -EPERM;
458 task[i]->pgrp = pgid;
459 return 0;
460 }
461 return -ESRCH;
462 }
463
464 int sys_getpgrp(void)
465 {
466 return current->pgrp;
467 }
468
469 int sys_setsid(void)
470 {
471 if (current->leader && !suser())
472 return -EPERM;
473 current->leader = 1;
474 current->session = current->pgrp = current->pid;
475 current->tty = -1;
476 return current->pgrp;
477 }
478
479
480
481
482 int sys_getgroups(int gidsetsize, gid_t *grouplist)
483 {
484 int i;
485
486 if (gidsetsize)
487 verify_area(grouplist, sizeof(gid_t) * gidsetsize);
488
489 for (i = 0; (i < NGROUPS) && (current->groups[i] != NOGROUP);
490 i++, grouplist++) {
491 if (gidsetsize) {
492 if (i >= gidsetsize)
493 return -EINVAL;
494 put_fs_word(current->groups[i], (short *) grouplist);
495 }
496 }
497 return(i);
498 }
499
500 int sys_setgroups(int gidsetsize, gid_t *grouplist)
501 {
502 int i;
503
504 if (!suser())
505 return -EPERM;
506 if (gidsetsize > NGROUPS)
507 return -EINVAL;
508 for (i = 0; i < gidsetsize; i++, grouplist++) {
509 current->groups[i] = get_fs_word((unsigned short *) grouplist);
510 }
511 if (i < NGROUPS)
512 current->groups[i] = NOGROUP;
513 return 0;
514 }
515
516 int in_group_p(gid_t grp)
517 {
518 int i;
519
520 if (grp == current->egid)
521 return 1;
522
523 for (i = 0; i < NGROUPS; i++) {
524 if (current->groups[i] == NOGROUP)
525 break;
526 if (current->groups[i] == grp)
527 return 1;
528 }
529 return 0;
530 }
531
532 int sys_newuname(struct new_utsname * name)
533 {
534 if (!name)
535 return -EFAULT;
536 verify_area(name, sizeof *name);
537 memcpy_tofs(name,&system_utsname,sizeof *name);
538 return 0;
539 }
540
541 int sys_uname(struct old_utsname * name)
542 {
543 if (!name)
544 return -EINVAL;
545 verify_area(name,sizeof *name);
546 memcpy_tofs(&name->sysname,&system_utsname.sysname,__OLD_UTS_LEN);
547 put_fs_byte(0,name->sysname+__OLD_UTS_LEN);
548 memcpy_tofs(&name->nodename,&system_utsname.nodename,__OLD_UTS_LEN);
549 put_fs_byte(0,name->nodename+__OLD_UTS_LEN);
550 memcpy_tofs(&name->release,&system_utsname.release,__OLD_UTS_LEN);
551 put_fs_byte(0,name->release+__OLD_UTS_LEN);
552 memcpy_tofs(&name->version,&system_utsname.version,__OLD_UTS_LEN);
553 put_fs_byte(0,name->version+__OLD_UTS_LEN);
554 memcpy_tofs(&name->machine,&system_utsname.machine,__OLD_UTS_LEN);
555 put_fs_byte(0,name->machine+__OLD_UTS_LEN);
556 return 0;
557 }
558
559
560
561
562 int sys_sethostname(char *name, int len)
563 {
564 int i;
565
566 if (!suser())
567 return -EPERM;
568 if (len > __NEW_UTS_LEN)
569 return -EINVAL;
570 for (i=0; i < len; i++) {
571 if ((system_utsname.nodename[i] = get_fs_byte(name+i)) == 0)
572 return 0;
573 }
574 system_utsname.nodename[i] = 0;
575 return 0;
576 }
577
578 int sys_getrlimit(unsigned int resource, struct rlimit *rlim)
579 {
580 if (resource >= RLIM_NLIMITS)
581 return -EINVAL;
582 verify_area(rlim,sizeof *rlim);
583 put_fs_long(current->rlim[resource].rlim_cur,
584 (unsigned long *) rlim);
585 put_fs_long(current->rlim[resource].rlim_max,
586 ((unsigned long *) rlim)+1);
587 return 0;
588 }
589
590 int sys_setrlimit(unsigned int resource, struct rlimit *rlim)
591 {
592 struct rlimit new, *old;
593
594 if (resource >= RLIM_NLIMITS)
595 return -EINVAL;
596 old = current->rlim + resource;
597 new.rlim_cur = get_fs_long((unsigned long *) rlim);
598 new.rlim_max = get_fs_long(((unsigned long *) rlim)+1);
599 if (((new.rlim_cur > old->rlim_max) ||
600 (new.rlim_max > old->rlim_max)) &&
601 !suser())
602 return -EPERM;
603 *old = new;
604 return 0;
605 }
606
607
608
609
610
611
612
613
614
615 void getrusage(struct task_struct *p, int who, struct rusage *ru)
616 {
617 struct rusage r;
618 unsigned long *lp, *lpend, *dest;
619
620 verify_area(ru, sizeof *ru);
621 memset((char *) &r, 0, sizeof(r));
622 switch (who) {
623 case RUSAGE_SELF:
624 r.ru_utime.tv_sec = CT_TO_SECS(p->utime);
625 r.ru_utime.tv_usec = CT_TO_USECS(p->utime);
626 r.ru_stime.tv_sec = CT_TO_SECS(p->stime);
627 r.ru_stime.tv_usec = CT_TO_USECS(p->stime);
628 r.ru_minflt = p->min_flt;
629 r.ru_majflt = p->maj_flt;
630 break;
631 case RUSAGE_CHILDREN:
632 r.ru_utime.tv_sec = CT_TO_SECS(p->cutime);
633 r.ru_utime.tv_usec = CT_TO_USECS(p->cutime);
634 r.ru_stime.tv_sec = CT_TO_SECS(p->cstime);
635 r.ru_stime.tv_usec = CT_TO_USECS(p->cstime);
636 r.ru_minflt = p->cmin_flt;
637 r.ru_majflt = p->cmaj_flt;
638 break;
639 default:
640 r.ru_utime.tv_sec = CT_TO_SECS(p->utime + p->cutime);
641 r.ru_utime.tv_usec = CT_TO_USECS(p->utime + p->cutime);
642 r.ru_stime.tv_sec = CT_TO_SECS(p->stime + p->cstime);
643 r.ru_stime.tv_usec = CT_TO_USECS(p->stime + p->cstime);
644 r.ru_minflt = p->min_flt + p->cmin_flt;
645 r.ru_majflt = p->maj_flt + p->cmaj_flt;
646 break;
647 }
648 lp = (unsigned long *) &r;
649 lpend = (unsigned long *) (&r+1);
650 dest = (unsigned long *) ru;
651 for (; lp < lpend; lp++, dest++)
652 put_fs_long(*lp, dest);
653 }
654
655 int sys_getrusage(int who, struct rusage *ru)
656 {
657 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
658 return -EINVAL;
659 getrusage(current, who, ru);
660 return(0);
661 }
662
663 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
664 {
665 if (tv) {
666 unsigned long nowtime = jiffies+jiffies_offset;
667 verify_area(tv, sizeof *tv);
668 put_fs_long(startup_time + CT_TO_SECS(nowtime),
669 (unsigned long *) tv);
670 put_fs_long(CT_TO_USECS(nowtime),
671 ((unsigned long *) tv)+1);
672 }
673 if (tz) {
674 verify_area(tz, sizeof *tz);
675 put_fs_long(sys_tz.tz_minuteswest, (unsigned long *) tz);
676 put_fs_long(sys_tz.tz_dsttime, ((unsigned long *) tz)+1);
677 }
678 return 0;
679 }
680
681
682
683
684
685
686
687
688
689
690 int sys_settimeofday(struct timeval *tv, struct timezone *tz)
691 {
692 static int firsttime = 1;
693 void adjust_clock();
694
695 if (!suser())
696 return -EPERM;
697 if (tz) {
698 sys_tz.tz_minuteswest = get_fs_long((unsigned long *) tz);
699 sys_tz.tz_dsttime = get_fs_long(((unsigned long *) tz)+1);
700 if (firsttime) {
701 firsttime = 0;
702 if (!tv)
703 adjust_clock();
704 }
705 }
706 if (tv) {
707 int sec, usec;
708
709 sec = get_fs_long((unsigned long *)tv);
710 usec = get_fs_long(((unsigned long *)tv)+1);
711
712 startup_time = sec - jiffies/HZ;
713 jiffies_offset = usec * HZ / 1000000 - jiffies%HZ;
714 }
715 return 0;
716 }
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734 void adjust_clock()
735 {
736 startup_time += sys_tz.tz_minuteswest*60;
737 }
738
739 int sys_umask(int mask)
740 {
741 int old = current->umask;
742
743 current->umask = mask & 0777;
744 return (old);
745 }
746