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_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 <errno.h>
8
9 #include <linux/sched.h>
10 #include <linux/tty.h>
11 #include <linux/kernel.h>
12 #include <linux/config.h>
13 #include <asm/segment.h>
14 #include <sys/times.h>
15 #include <sys/utsname.h>
16 #include <sys/param.h>
17 #include <sys/resource.h>
18 #include <linux/string.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 }
168
169
170
171
172
173
174
175
176
177
178
179
180
181 int sys_setregid(int rgid, int egid)
182 {
183 if (rgid>0) {
184 if ((current->gid == rgid) ||
185 suser())
186 current->gid = rgid;
187 else
188 return(-EPERM);
189 }
190 if (egid>0) {
191 if ((current->gid == egid) ||
192 (current->egid == egid) ||
193 suser()) {
194 current->egid = egid;
195 current->sgid = egid;
196 } else
197 return(-EPERM);
198 }
199 return 0;
200 }
201
202
203
204
205 int sys_setgid(int gid)
206 {
207 if (suser())
208 current->gid = current->egid = current->sgid = gid;
209 else if ((gid == current->gid) || (gid == current->sgid))
210 current->egid = gid;
211 else
212 return -EPERM;
213 return 0;
214 }
215
216 int sys_acct()
217 {
218 return -ENOSYS;
219 }
220
221 int sys_phys()
222 {
223 return -ENOSYS;
224 }
225
226 int sys_lock()
227 {
228 return -ENOSYS;
229 }
230
231 int sys_mpx()
232 {
233 return -ENOSYS;
234 }
235
236 int sys_ulimit()
237 {
238 return -ENOSYS;
239 }
240
241 int sys_time(long * tloc)
242 {
243 int i;
244
245 i = CURRENT_TIME;
246 if (tloc) {
247 verify_area(tloc,4);
248 put_fs_long(i,(unsigned long *)tloc);
249 }
250 return i;
251 }
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266 int sys_setreuid(int ruid, int euid)
267 {
268 int old_ruid = current->uid;
269
270 if (ruid>0) {
271 if ((current->euid==ruid) ||
272 (old_ruid == ruid) ||
273 suser())
274 current->uid = ruid;
275 else
276 return(-EPERM);
277 }
278 if (euid>0) {
279 if ((old_ruid == euid) ||
280 (current->euid == euid) ||
281 suser()) {
282 current->euid = euid;
283 current->suid = euid;
284 } else {
285 current->uid = old_ruid;
286 return(-EPERM);
287 }
288 }
289 return 0;
290 }
291
292
293
294
295
296
297
298
299
300
301
302
303 int sys_setuid(int uid)
304 {
305 if (suser())
306 current->uid = current->euid = current->suid = uid;
307 else if ((uid == current->uid) || (uid == current->suid))
308 current->euid = uid;
309 else
310 return -EPERM;
311 return(0);
312 }
313
314 int sys_stime(long * tptr)
315 {
316 if (!suser())
317 return -EPERM;
318 startup_time = get_fs_long((unsigned long *)tptr) - jiffies/HZ;
319 jiffies_offset = 0;
320 return 0;
321 }
322
323 int sys_times(struct tms * tbuf)
324 {
325 if (tbuf) {
326 verify_area(tbuf,sizeof *tbuf);
327 put_fs_long(current->utime,(unsigned long *)&tbuf->tms_utime);
328 put_fs_long(current->stime,(unsigned long *)&tbuf->tms_stime);
329 put_fs_long(current->cutime,(unsigned long *)&tbuf->tms_cutime);
330 put_fs_long(current->cstime,(unsigned long *)&tbuf->tms_cstime);
331 }
332 return jiffies;
333 }
334
335 int sys_brk(unsigned long end_data_seg)
336 {
337 if (end_data_seg >= current->end_code &&
338 end_data_seg < current->start_stack - 16384)
339 current->brk = end_data_seg;
340 return current->brk;
341 }
342
343
344
345
346
347
348
349
350
351
352 int sys_setpgid(int pid, int pgid)
353 {
354 int i;
355
356 if (!pid)
357 pid = current->pid;
358 if (!pgid)
359 pgid = current->pid;
360 if (pgid < 0)
361 return -EINVAL;
362 for (i=0 ; i<NR_TASKS ; i++)
363 if (task[i] && (task[i]->pid == pid) &&
364 ((task[i]->p_pptr == current) ||
365 (task[i] == current))) {
366 if (task[i]->leader)
367 return -EPERM;
368 if ((task[i]->session != current->session) ||
369 ((pgid != pid) &&
370 (session_of_pgrp(pgid) != current->session)))
371 return -EPERM;
372 task[i]->pgrp = pgid;
373 return 0;
374 }
375 return -ESRCH;
376 }
377
378 int sys_getpgrp(void)
379 {
380 return current->pgrp;
381 }
382
383 int sys_setsid(void)
384 {
385 if (current->leader && !suser())
386 return -EPERM;
387 current->leader = 1;
388 current->session = current->pgrp = current->pid;
389 current->tty = -1;
390 return current->pgrp;
391 }
392
393
394
395
396 int sys_getgroups(int gidsetsize, gid_t *grouplist)
397 {
398 int i;
399
400 if (gidsetsize)
401 verify_area(grouplist, sizeof(gid_t) * gidsetsize);
402
403 for (i = 0; (i < NGROUPS) && (current->groups[i] != NOGROUP);
404 i++, grouplist++) {
405 if (gidsetsize) {
406 if (i >= gidsetsize)
407 return -EINVAL;
408 put_fs_word(current->groups[i], (short *) grouplist);
409 }
410 }
411 return(i);
412 }
413
414 int sys_setgroups(int gidsetsize, gid_t *grouplist)
415 {
416 int i;
417
418 if (!suser())
419 return -EPERM;
420 if (gidsetsize > NGROUPS)
421 return -EINVAL;
422 for (i = 0; i < gidsetsize; i++, grouplist++) {
423 current->groups[i] = get_fs_word((unsigned short *) grouplist);
424 }
425 if (i < NGROUPS)
426 current->groups[i] = NOGROUP;
427 return 0;
428 }
429
430 int in_group_p(gid_t grp)
431 {
432 int i;
433
434 if (grp == current->egid)
435 return 1;
436
437 for (i = 0; i < NGROUPS; i++) {
438 if (current->groups[i] == NOGROUP)
439 break;
440 if (current->groups[i] == grp)
441 return 1;
442 }
443 return 0;
444 }
445
446 static struct utsname thisname = {
447 UTS_SYSNAME, UTS_NODENAME, UTS_RELEASE, UTS_VERSION, UTS_MACHINE
448 };
449
450 int sys_uname(struct utsname * name)
451 {
452 int i;
453
454 if (!name)
455 return -EINVAL;
456 verify_area(name,sizeof *name);
457 for(i=0;i<sizeof *name;i++)
458 put_fs_byte(((char *) &thisname)[i],i+(char *) name);
459 return 0;
460 }
461
462
463
464
465 int sys_sethostname(char *name, int len)
466 {
467 int i;
468
469 if (!suser())
470 return -EPERM;
471 if (len > MAXHOSTNAMELEN)
472 return -EINVAL;
473 for (i=0; i < len; i++) {
474 if ((thisname.nodename[i] = get_fs_byte(name+i)) == 0)
475 break;
476 }
477 if (thisname.nodename[i]) {
478 thisname.nodename[i>MAXHOSTNAMELEN ? MAXHOSTNAMELEN : i] = 0;
479 }
480 return 0;
481 }
482
483 int sys_getrlimit(int resource, struct rlimit *rlim)
484 {
485 if (resource >= RLIM_NLIMITS)
486 return -EINVAL;
487 verify_area(rlim,sizeof *rlim);
488 put_fs_long(current->rlim[resource].rlim_cur,
489 (unsigned long *) rlim);
490 put_fs_long(current->rlim[resource].rlim_max,
491 ((unsigned long *) rlim)+1);
492 return 0;
493 }
494
495 int sys_setrlimit(int resource, struct rlimit *rlim)
496 {
497 struct rlimit new, *old;
498
499 if (resource >= RLIM_NLIMITS)
500 return -EINVAL;
501 old = current->rlim + resource;
502 new.rlim_cur = get_fs_long((unsigned long *) rlim);
503 new.rlim_max = get_fs_long(((unsigned long *) rlim)+1);
504 if (((new.rlim_cur > old->rlim_max) ||
505 (new.rlim_max > old->rlim_max)) &&
506 !suser())
507 return -EPERM;
508 *old = new;
509 return 0;
510 }
511
512
513
514
515
516
517
518
519
520 int sys_getrusage(int who, struct rusage *ru)
521 {
522 struct rusage r;
523 unsigned long *lp, *lpend, *dest;
524
525 if (who != RUSAGE_SELF && who != RUSAGE_CHILDREN)
526 return -EINVAL;
527 verify_area(ru, sizeof *ru);
528 memset((char *) &r, 0, sizeof(r));
529 if (who == RUSAGE_SELF) {
530 r.ru_utime.tv_sec = CT_TO_SECS(current->utime);
531 r.ru_utime.tv_usec = CT_TO_USECS(current->utime);
532 r.ru_stime.tv_sec = CT_TO_SECS(current->stime);
533 r.ru_stime.tv_usec = CT_TO_USECS(current->stime);
534 r.ru_minflt = current->min_flt;
535 r.ru_majflt = current->maj_flt;
536 } else {
537 r.ru_utime.tv_sec = CT_TO_SECS(current->cutime);
538 r.ru_utime.tv_usec = CT_TO_USECS(current->cutime);
539 r.ru_stime.tv_sec = CT_TO_SECS(current->cstime);
540 r.ru_stime.tv_usec = CT_TO_USECS(current->cstime);
541 r.ru_minflt = current->cmin_flt;
542 r.ru_majflt = current->cmaj_flt;
543 }
544 lp = (unsigned long *) &r;
545 lpend = (unsigned long *) (&r+1);
546 dest = (unsigned long *) ru;
547 for (; lp < lpend; lp++, dest++)
548 put_fs_long(*lp, dest);
549 return(0);
550 }
551
552 int sys_gettimeofday(struct timeval *tv, struct timezone *tz)
553 {
554 if (tv) {
555 verify_area(tv, sizeof *tv);
556 put_fs_long(startup_time + CT_TO_SECS(jiffies+jiffies_offset),
557 (unsigned long *) tv);
558 put_fs_long(CT_TO_USECS(jiffies+jiffies_offset),
559 ((unsigned long *) tv)+1);
560 }
561 if (tz) {
562 verify_area(tz, sizeof *tz);
563 put_fs_long(sys_tz.tz_minuteswest, (unsigned long *) tz);
564 put_fs_long(sys_tz.tz_dsttime, ((unsigned long *) tz)+1);
565 }
566 return 0;
567 }
568
569
570
571
572
573
574
575
576
577
578 int sys_settimeofday(struct timeval *tv, struct timezone *tz)
579 {
580 static int firsttime = 1;
581 void adjust_clock();
582
583 if (!suser())
584 return -EPERM;
585 if (tz) {
586 sys_tz.tz_minuteswest = get_fs_long((unsigned long *) tz);
587 sys_tz.tz_dsttime = get_fs_long(((unsigned long *) tz)+1);
588 if (firsttime) {
589 firsttime = 0;
590 if (!tv)
591 adjust_clock();
592 }
593 }
594 if (tv) {
595 int sec, usec;
596
597 sec = get_fs_long((unsigned long *)tv);
598 usec = get_fs_long(((unsigned long *)tv)+1);
599
600 startup_time = sec - jiffies/HZ;
601 jiffies_offset = usec * HZ / 1000000 - jiffies%HZ;
602 }
603 return 0;
604 }
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622 void adjust_clock()
623 {
624 startup_time += sys_tz.tz_minuteswest*60;
625 }
626
627 int sys_umask(int mask)
628 {
629 int old = current->umask;
630
631 current->umask = mask & 0777;
632 return (old);
633 }
634