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