GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

No menu could be recovered. Follow the blue links in the page.

This view

  • Original page
  • New address

GeezerVison is showing codebrowser.dev (truncated) — sys.c source code [linux/kernel/sys.c] - Codebrowser

Codebrowser logo
About
Contact
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * linux/kernel/sys.c
4 *
5 * Copyright (C) 1991, 1992 Linus Torvalds
6 */
7
8#include <linux/export.h>
9#include <linux/mm.h>
10#include <linux/mm_inline.h>
11#include <linux/utsname.h>
12#include <linux/mman.h>
13#include <linux/reboot.h>
14#include <linux/prctl.h>
15#include <linux/highuid.h>
16#include <linux/fs.h>
17#include <linux/kmod.h>
18#include <linux/ksm.h>
19#include <linux/perf_event.h>
20#include <linux/resource.h>
21#include <linux/kernel.h>
22#include <linux/workqueue.h>
23#include <linux/capability.h>
24#include <linux/device.h>
25#include <linux/key.h>
26#include <linux/times.h>
27#include <linux/posix-timers.h>
28#include <linux/security.h>
29#include <linux/random.h>
30#include <linux/suspend.h>
31#include <linux/tty.h>
32#include <linux/signal.h>
33#include <linux/cn_proc.h>
34#include <linux/getcpu.h>
35#include <linux/task_io_accounting_ops.h>
36#include <linux/seccomp.h>
37#include <linux/cpu.h>
38#include <linux/personality.h>
39#include <linux/ptrace.h>
40#include <linux/fs_struct.h>
41#include <linux/file.h>
42#include <linux/mount.h>
43#include <linux/gfp.h>
44#include <linux/syscore_ops.h>
45#include <linux/version.h>
46#include <linux/ctype.h>
47#include <linux/syscall_user_dispatch.h>
48
49#include <linux/compat.h>
50#include <linux/syscalls.h>
51#include <linux/kprobes.h>
52#include <linux/user_namespace.h>
53#include <linux/time_namespace.h>
54#include <linux/binfmts.h>
55#include <linux/futex.h>
56
57#include <linux/sched.h>
58#include <linux/sched/autogroup.h>
59#include <linux/sched/loadavg.h>
60#include <linux/sched/stat.h>
61#include <linux/sched/mm.h>
62#include <linux/sched/coredump.h>
63#include <linux/sched/task.h>
64#include <linux/sched/cputime.h>
65#include <linux/rcupdate.h>
66#include <linux/uidgid.h>
67#include <linux/cred.h>
68
69#include <linux/nospec.h>
70
71#include <linux/kmsg_dump.h>
72/* Move somewhere else to avoid recompiling? */
73#include <generated/utsrelease.h>
74
75#include <linux/uaccess.h>
76#include <asm/io.h>
77#include <asm/unistd.h>
78
79#include <trace/events/task.h>
80
81#include "uid16.h"
82
83#ifndef SET_UNALIGN_CTL
84# define SET_UNALIGN_CTL(a, b) (-EINVAL)
85#endif
86#ifndef GET_UNALIGN_CTL
87# define GET_UNALIGN_CTL(a, b) (-EINVAL)
88#endif
89#ifndef SET_FPEMU_CTL
90# define SET_FPEMU_CTL(a, b) (-EINVAL)
91#endif
92#ifndef GET_FPEMU_CTL
93# define GET_FPEMU_CTL(a, b) (-EINVAL)
94#endif
95#ifndef SET_FPEXC_CTL
96# define SET_FPEXC_CTL(a, b) (-EINVAL)
97#endif
98#ifndef GET_FPEXC_CTL
99# define GET_FPEXC_CTL(a, b) (-EINVAL)
100#endif
101#ifndef GET_ENDIAN
102# define GET_ENDIAN(a, b) (-EINVAL)
103#endif
104#ifndef SET_ENDIAN
105# define SET_ENDIAN(a, b) (-EINVAL)
106#endif
107#ifndef GET_TSC_CTL
108# define GET_TSC_CTL(a) (-EINVAL)
109#endif
110#ifndef SET_TSC_CTL
111# define SET_TSC_CTL(a) (-EINVAL)
112#endif
113#ifndef GET_FP_MODE
114# define GET_FP_MODE(a) (-EINVAL)
115#endif
116#ifndef SET_FP_MODE
117# define SET_FP_MODE(a,b) (-EINVAL)
118#endif
119#ifndef SVE_SET_VL
120# define SVE_SET_VL(a) (-EINVAL)
121#endif
122#ifndef SVE_GET_VL
123# define SVE_GET_VL() (-EINVAL)
124#endif
125#ifndef SME_SET_VL
126# define SME_SET_VL(a) (-EINVAL)
127#endif
128#ifndef SME_GET_VL
129# define SME_GET_VL() (-EINVAL)
130#endif
131#ifndef PAC_RESET_KEYS
132# define PAC_RESET_KEYS(a, b) (-EINVAL)
133#endif
134#ifndef PAC_SET_ENABLED_KEYS
135# define PAC_SET_ENABLED_KEYS(a, b, c) (-EINVAL)
136#endif
137#ifndef PAC_GET_ENABLED_KEYS
138# define PAC_GET_ENABLED_KEYS(a) (-EINVAL)
139#endif
140#ifndef SET_TAGGED_ADDR_CTRL
141# define SET_TAGGED_ADDR_CTRL(a) (-EINVAL)
142#endif
143#ifndef GET_TAGGED_ADDR_CTRL
144# define GET_TAGGED_ADDR_CTRL() (-EINVAL)
145#endif
146#ifndef RISCV_V_SET_CONTROL
147# define RISCV_V_SET_CONTROL(a) (-EINVAL)
148#endif
149#ifndef RISCV_V_GET_CONTROL
150# define RISCV_V_GET_CONTROL() (-EINVAL)
151#endif
152#ifndef RISCV_SET_ICACHE_FLUSH_CTX
153# define RISCV_SET_ICACHE_FLUSH_CTX(a, b) (-EINVAL)
154#endif
155#ifndef PPC_GET_DEXCR_ASPECT
156# define PPC_GET_DEXCR_ASPECT(a, b) (-EINVAL)
157#endif
158#ifndef PPC_SET_DEXCR_ASPECT
159# define PPC_SET_DEXCR_ASPECT(a, b, c) (-EINVAL)
160#endif
161
162/*
163 * this is where the system-wide overflow UID and GID are defined, for
164 * architectures that now have 32-bit UID/GID but didn't in the past
165 */
166
167int overflowuid = DEFAULT_OVERFLOWUID;
168int overflowgid = DEFAULT_OVERFLOWGID;
169
170EXPORT_SYMBOL(overflowuid);
171EXPORT_SYMBOL(overflowgid);
172
173/*
174 * the same as above, but for filesystems which can only store a 16-bit
175 * UID and GID. as such, this is needed on all architectures
176 */
177
178int fs_overflowuid = DEFAULT_FS_OVERFLOWUID;
179int fs_overflowgid = DEFAULT_FS_OVERFLOWGID;
180
181EXPORT_SYMBOL(fs_overflowuid);
182EXPORT_SYMBOL(fs_overflowgid);
183
184static const struct ctl_table overflow_sysctl_table[] = {
185 {
186 .procname = "overflowuid",
187 .data = &overflowuid,
188 .maxlen = sizeof(int),
189 .mode = 0644,
190 .proc_handler = proc_dointvec_minmax,
191 .extra1 = SYSCTL_ZERO,
192 .extra2 = SYSCTL_MAXOLDUID,
193 },
194 {
195 .procname = "overflowgid",
196 .data = &overflowgid,
197 .maxlen = sizeof(int),
198 .mode = 0644,
199 .proc_handler = proc_dointvec_minmax,
200 .extra1 = SYSCTL_ZERO,
201 .extra2 = SYSCTL_MAXOLDUID,
202 },
203};
204
205static int __init init_overflow_sysctl(void)
206{
207 register_sysctl_init("kernel", overflow_sysctl_table);
208 return 0;
209}
210
211postcore_initcall(init_overflow_sysctl);
212
213/*
214 * Returns true if current's euid is same as p's uid or euid,
215 * or has CAP_SYS_NICE to p's user_ns.
216 *
217 * Called with rcu_read_lock, creds are safe
218 */
219static bool set_one_prio_perm(struct task_struct *p)
220{
221 const struct cred *cred = current_cred(), *pcred = __task_cred(p);
222
223 if (uid_eq(left: pcred->uid, right: cred->euid) ||
224 uid_eq(left: pcred->euid, right: cred->euid))
225 return true;
226 if (ns_capable(ns: pcred->user_ns, CAP_SYS_NICE))
227 return true;
228 return false;
229}
230
231/*
232 * set the priority of a task
233 * - the caller must hold the RCU read lock
234 */
235static int set_one_prio(struct task_struct *p, int niceval, int error)
236{
237 int no_nice;
238
239 if (!set_one_prio_perm(p)) {
240 error = -EPERM;
241 goto out;
242 }
243 if (niceval < task_nice(p) && !can_nice(p, nice: niceval)) {
244 error = -EACCES;
245 goto out;
246 }
247 no_nice = security_task_setnice(p, nice: niceval);
248 if (no_nice) {
249 error = no_nice;
250 goto out;
251 }
252 if (error == -ESRCH)
253 error = 0;
254 set_user_nice(p, nice: niceval);
255out:
256 return error;
257}
258
259SYSCALL_DEFINE3(setpriority, int, which, int, who, int, niceval)
260{
261 struct task_struct *g, *p;
262 struct user_struct *user;
263 const struct cred *cred = current_cred();
264 int error = -EINVAL;
265 struct pid *pgrp;
266 kuid_t uid;
267
268 if (which > PRIO_USER || which < PRIO_PROCESS)
269 goto out;
270
271 /* normalize: avoid signed division (rounding problems) */
272 error = -ESRCH;
273 if (niceval < MIN_NICE)
274 niceval = MIN_NICE;
275 if (niceval > MAX_NICE)
276 niceval = MAX_NICE;
277
278 rcu_read_lock();
279 switch (which) {
280 case PRIO_PROCESS:
281 if (who)
282 p = find_task_by_vpid(nr: who);
283 else
284 p = current;
285 if (p)
286 error = set_one_prio(p, niceval, error);
287 break;
288 case PRIO_PGRP:
289 if (who)
290 pgrp = find_vpid(nr: who);
291 else
292 pgrp = task_pgrp(current);
293 read_lock(&tasklist_lock);
294 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
295 error = set_one_prio(p, niceval, error);
296 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
297 read_unlock(&tasklist_lock);
298 break;
299 case PRIO_USER:
300 uid = make_kuid(from: cred->user_ns, uid: who);
301 user = cred->user;
302 if (!who)
303 uid = cred->uid;
304 else if (!uid_eq(left: uid, right: cred->uid)) {
305 user = find_user(uid);
306 if (!user)
307 goto out_unlock; /* No processes for this user */
308 }
309 for_each_process_thread(g, p) {
310 if (uid_eq(task_uid(p), right: uid) && task_pid_vnr(tsk: p))
311 error = set_one_prio(p, niceval, error);
312 }
313 if (!uid_eq(left: uid, right: cred->uid))
314 free_uid(user); /* For find_user() */
315 break;
316 }
317out_unlock:
318 rcu_read_unlock();
319out:
320 return error;
321}
322
323/*
324 * Ugh. To avoid negative return values, "getpriority()" will
325 * not return the normal nice-value, but a negated value that
326 * has been offset by 20 (ie it returns 40..1 instead of -20..19)
327 * to stay compatible.
328 */
329SYSCALL_DEFINE2(getpriority, int, which, int, who)
330{
331 struct task_struct *g, *p;
332 struct user_struct *user;
333 const struct cred *cred = current_cred();
334 long niceval, retval = -ESRCH;
335 struct pid *pgrp;
336 kuid_t uid;
337
338 if (which > PRIO_USER || which < PRIO_PROCESS)
339 return -EINVAL;
340
341 rcu_read_lock();
342 switch (which) {
343 case PRIO_PROCESS:
344 if (who)
345 p = find_task_by_vpid(nr: who);
346 else
347 p = current;
348 if (p) {
349 niceval = nice_to_rlimit(nice: task_nice(p));
350 if (niceval > retval)
351 retval = niceval;
352 }
353 break;
354 case PRIO_PGRP:
355 if (who)
356 pgrp = find_vpid(nr: who);
357 else
358 pgrp = task_pgrp(current);
359 read_lock(&tasklist_lock);
360 do_each_pid_thread(pgrp, PIDTYPE_PGID, p) {
361 niceval = nice_to_rlimit(nice: task_nice(p));
362 if (niceval > retval)
363 retval = niceval;
364 } while_each_pid_thread(pgrp, PIDTYPE_PGID, p);
365 read_unlock(&tasklist_lock);
366 break;
367 case PRIO_USER:
368 uid = make_kuid(from: cred->user_ns, uid: who);
369 user = cred->user;
370 if (!who)
371 uid = cred->uid;
372 else if (!uid_eq(left: uid, right: cred->uid)) {
373 user = find_user(uid);
374 if (!user)
375 goto out_unlock; /* No processes for this user */
376 }
377 for_each_process_thread(g, p) {
378 if (uid_eq(task_uid(p), right: uid) && task_pid_vnr(tsk: p)) {
379 niceval = nice_to_rlimit(nice: task_nice(p));
380 if (niceval > retval)
381 retval = niceval;
382 }
383 }
384 if (!uid_eq(left: uid, right: cred->uid))
385 free_uid(user); /* for find_user() */
386 break;
387 }
388out_unlock:
389 rcu_read_unlock();
390
391 return retval;
392}
393
394/*
395 * Unprivileged users may change the real gid to the effective gid
396 * or vice versa. (BSD-style)
397 *
398 * If you set the real gid at all, or set the effective gid to a value not
399 * equal to the real gid, then the saved gid is set to the new effective gid.
400 *
401 * This makes it possible for a setgid program to completely drop its
402 * privileges, which is often a useful assertion to make when you are doing
403 * a security audit over a program.
404 *
405 * The general idea is that a program which uses just setregid() will be
406 * 100% compatible with BSD. A program which uses just setgid() will be
407 * 100% compatible with POSIX with saved IDs.
408 *
409 * SMP: There are not races, the GIDs are checked only by filesystem
410 * operations (as far as semantic preservation is concerned).
411 */
412#ifdef CONFIG_MULTIUSER
413long __sys_setregid(gid_t rgid, gid_t egid)
414{
415 struct user_namespace *ns = current_user_ns();
416 const struct cred *old;
417 struct cred *new;
418 int retval;
419 kgid_t krgid, kegid;
420
421 krgid = make_kgid(from: ns, gid: rgid);
422 kegid = make_kgid(from: ns, gid: egid);
423
424 if ((rgid != (gid_t) -1) && !gid_valid(gid: krgid))
425 return -EINVAL;
426 if ((egid != (gid_t) -1) && !gid_valid(gid: kegid))
427 return -EINVAL;
428
429 new = prepare_creds();
430 if (!new)
431 return -ENOMEM;
432 old = current_cred();
433
434 retval = -EPERM;
435 if (rgid != (gid_t) -1) {
436 if (gid_eq(left: old->gid, right: krgid) ||
437 gid_eq(left: old->egid, right: krgid) ||
438 ns_capable_setid(ns: old->user_ns, CAP_SETGID))
439 new->gid = krgid;
440 else
441 goto error;
442 }
443 if (egid != (gid_t) -1) {
444 if (gid_eq(left: old->gid, right: kegid) ||
445 gid_eq(left: old->egid, right: kegid) ||
446 gid_eq(left: old->sgid, right: kegid) ||
447 ns_capable_setid(ns: old->user_ns, CAP_SETGID))
448 new->egid = kegid;
449 else
450 goto error;
451 }
452
453 if (rgid != (gid_t) -1 ||
454 (egid != (gid_t) -1 && !gid_eq(left: kegid, right: old->gid)))
455 new->sgid = new->egid;
456 new->fsgid = new->egid;
457
458 retval = security_task_fix_setgid(new, old, LSM_SETID_RE);
459 if (retval < 0)
460 goto error;
461
462 return commit_creds(new);
463
464error:
465 abort_creds(new);
466 return retval;
467}
468
469SYSCALL_DEFINE2(setregid, gid_t, rgid, gid_t, egid)
470{
471 return __sys_setregid(rgid, egid);
472}
473
474/*
475 * setgid() is implemented like SysV w/ SAVED_IDS
476 *
477 * SMP: Same implicit races as above.
478 */
479long __sys_setgid(gid_t gid)
480{
481 struct user_namespace *ns = current_user_ns();
482 const struct cred *old;
483 struct cred *new;
484 int retval;
485 kgid_t kgid;
486
487 kgid = make_kgid(from: ns, gid);
488 if (!gid_valid(gid: kgid))
489 return -EINVAL;
490
491 new = prepare_creds();
492 if (!new)
493 return -ENOMEM;
494 old = current_cred();
495
496 retval = -EPERM;
497 if (ns_capable_setid(ns: old->user_ns, CAP_SETGID))
498 new->gid = new->egid = new->sgid = new->fsgid = kgid;
499 else if (gid_eq(left: kgid, right: old->gid) || gid_eq(left: kgid, right: old->sgid))
500 new->egid = new->fsgid = kgid;
501 else
502 goto error;
503
504 retval = security_task_fix_setgid(new, old, LSM_SETID_ID);
505 if (retval < 0)
506 goto error;
507
508 return commit_creds(new);
509
510error:
511 abort_creds(new);
512 return retval;
513}
514
515SYSCALL_DEFINE1(setgid, gid_t, gid)
516{
517 return __sys_setgid(gid);
518}
519
520/*
521 * change the user struct in a credentials set to match the new UID
522 */
523static int set_user(struct cred *new)
524{
525 struct user_struct *new_user;
526
527 new_user = alloc_uid(new->uid);
528 if (!new_user)
529 return -EAGAIN;
530
531 free_uid(new->user);
532 new->user = new_user;
533 return 0;
534}
535
536static void flag_nproc_exceeded(struct cred *new)
537{
538 if (new->ucounts == current_ucounts())
539 return;
540
541 /*
542 * We don't fail in case of NPROC limit excess here because too many
543 * poorly written programs don't check set*uid() return code, assuming
544 * it never fails if called by root. We may still enforce NPROC limit
545 * for programs doing set*uid()+execve() by harmlessly deferring the
546 * failure to the execve() stage.
547 */
548 if (is_rlimit_overlimit(ucounts: new->ucounts, type: UCOUNT_RLIMIT_NPROC, max: rlimit(RLIMIT_NPROC)) &&
549 new->user != INIT_USER)
550 current->flags |= PF_NPROC_EXCEEDED;
551 else
552 current->flags &= ~PF_NPROC_EXCEEDED;
553}
554
555/*
556 * Unprivileged users may change the real uid to the effective uid
557 * or vice versa. (BSD-style)
558 *
559 * If you set the real uid at all, or set the effective uid to a value not
560 * equal to the real uid, then the saved uid is set to the new effective uid.
561 *
562 * This makes it possible for a setuid program to completely drop its
563 * privileges, which is often a useful assertion to make when you are doing
564 * a security audit over a program.
565 *
566 * The general idea is that a program which uses just setreuid() will be
567 * 100% compatible with BSD. A program which uses just setuid() will be
568 * 100% compatible with POSIX with saved IDs.
569 */
570long __sys_setreuid(uid_t ruid, uid_t euid)
571{
572 struct user_namespace *ns = current_user_ns();
573 const struct cred *old;
574 struct cred *new;
575 int retval;
576 kuid_t kruid, keuid;
577
578 kruid = make_kuid(from: ns, uid: ruid);
579 keuid = make_kuid(from: ns, uid: euid);
580
581 if ((ruid != (uid_t) -1) && !uid_valid(uid: kruid))
582 return -EINVAL;
583 if ((euid != (uid_t) -1) && !uid_valid(uid: keuid))
584 return -EINVAL;
585
586 new = prepare_creds();
587 if (!new)
588 return -ENOMEM;
589 old = current_cred();
590
591 retval = -EPERM;
592 if (ruid != (uid_t) -1) {
593 new->uid = kruid;
594 if (!uid_eq(left: old->uid, right: kruid) &&
595 !uid_eq(left: old->euid, right: kruid) &&
596 !ns_capable_setid(ns: old->user_ns, CAP_SETUID))
597 goto error;
598 }
599
600 if (euid != (uid_t) -1) {
601 new->euid = keuid;
602 if (!uid_eq(left: old->uid, right: keuid) &&
603 !uid_eq(left: old->euid, right: keuid) &&
604 !uid_eq(left: old->suid, right: keuid) &&
605 !ns_capable_setid(ns: old->user_ns, CAP_SETUID))
606 goto error;
607 }
608
609 if (!uid_eq(left: new->uid, right: old->uid)) {
610 retval = set_user(new);
611 if (retval < 0)
612 goto error;
613 }
614 if (ruid != (uid_t) -1 ||
615 (euid != (uid_t) -1 && !uid_eq(left: keuid, right: old->uid)))
616 new->suid = new->euid;
617 new->fsuid = new->euid;
618
619 retval = security_task_fix_setuid(new, old, LSM_SETID_RE);
620 if (retval < 0)
621 goto error;
622
623 retval = set_cred_ucounts(new);
624 if (retval < 0)
625 goto error;
626
627 flag_nproc_exceeded(new);
628 return commit_creds(new);
629
630error:
631 abort_creds(new);
632 return retval;
633}
634
635SYSCALL_DEFINE2(setreuid, uid_t, ruid, uid_t, euid)
636{
637 return __sys_setreuid(ruid, euid);
638}
639
640/*
641 * setuid() is implemented like SysV with SAVED_IDS
642 *
643 * Note that SAVED_ID's is deficient in that a setuid root program
644 * like sendmail, for example, cannot set its uid to be a normal
645 * user and then switch back, because if you're root, setuid() sets
646 * the saved uid too. If you don't like this, blame the bright people
647 * in the POSIX committee and/or USG. Note that the BSD-style setreuid()
648 * will allow a root program to temporarily drop privileges and be able to
649 * regain them by swapping the real and effective uid.
650 */
651long __sys_setuid(uid_t uid)
652{
653 struct user_namespace *ns = current_user_ns();
654 const struct cred *old;
655 struct cred *new;
656 int retval;
657 kuid_t kuid;
658
659 kuid = make_kuid(from: ns, uid);
660 if (!uid_valid(uid: kuid))
661 return -EINVAL;
662
663 new = prepare_creds();
664 if (!new)
665 return -ENOMEM;
666 old = current_cred();
667
668 retval = -EPERM;
669 if (ns_capable_setid(ns: old->user_ns, CAP_SETUID)) {
670 new->suid = new->uid = kuid;
671 if (!uid_eq(left: kuid, right: old->uid)) {
672 retval = set_user(new);
673 if (retval < 0)
674 goto error;
675 }
676 } else if (!uid_eq(left: kuid, right: old->uid) && !uid_eq(left: kuid, right: new->suid)) {
677 goto error;
678 }
679
680 new->fsuid = new->euid = kuid;
681
682 retval = security_task_fix_setuid(new, old, LSM_SETID_ID);
683 if (retval < 0)
684 goto error;
685
686 retval = set_cred_ucounts(new);
687 if (retval < 0)
688 goto error;
689
690 flag_nproc_exceeded(new);
691 return commit_creds(new);
692
693error:
694 abort_creds(new);
695 return retval;
696}
697
698SYSCALL_DEFINE1(setuid, uid_t, uid)
699{
700 return __sys_setuid(uid);
701}
702
703
704/*
705 * This function implements a generic ability to update ruid, euid,
706 * and suid. This allows you to implement the 4.4 compatible seteuid().
707 */
708long __sys_setresuid(uid_t ruid, uid_t euid, uid_t suid)
709{
710 struct user_namespace *ns = current_user_ns();
711 const struct cred *old;
712 struct cred *new;
713 int retval;
714 kuid_t kruid, keuid, ksuid;
715 bool ruid_new, euid_new, suid_new;
716
717 kruid = make_kuid(from: ns, uid: ruid);
718 keuid = make_kuid(from: ns, uid: euid);
719 ksuid = make_kuid(from: ns, uid: suid);
720
721 if ((ruid != (uid_t) -1) && !uid_valid(uid: kruid))
722 return -EINVAL;
723
724 if ((euid != (uid_t) -1) && !uid_valid(uid: keuid))
725 return -EINVAL;
726
727 if ((suid != (uid_t) -1) && !uid_valid(uid: ksuid))
728 return -EINVAL;
729
730 old = current_cred();
731
732 /* check for no-op */
733 if ((ruid == (uid_t) -1 || uid_eq(left: kruid, right: old->uid)) &&
734 (euid == (uid_t) -1 || (uid_eq(left: keuid, right: old->euid) &&
735 uid_eq(left: keuid, right: old->fsuid))) &&
736 (suid == (uid_t) -1 || uid_eq(left: ksuid, right: old->suid)))
737 return 0;
738
739 ruid_new = ruid != (uid_t) -1 && !uid_eq(left: kruid, right: old->uid) &&
740 !uid_eq(left: kruid, right: old->euid) && !uid_eq(left: kruid, right: old->suid);
741 euid_new = euid != (uid_t) -1 && !uid_eq(left: keuid, right: old->uid) &&
742 !uid_eq(left: keuid, right: old->euid) && !uid_eq(left: keuid, right: old->suid);
743 suid_new = suid != (uid_t) -1 && !uid_eq(left: ksuid, right: old->uid) &&
744 !uid_eq(left: ksuid, right: old->euid) && !uid_eq(left: ksuid, right: old->suid);
745 if ((ruid_new || euid_new || suid_new) &&
746 !ns_capable_setid(ns: old->user_ns, CAP_SETUID))
747 return -EPERM;
748
749 new = prepare_creds();
750 if (!new)
751 return -ENOMEM;
752
753 if (ruid != (uid_t) -1) {
754 new->uid = kruid;
755 if (!uid_eq(left: kruid, right: old->uid)) {
756 retval = set_user(new);
757 if (retval < 0)
758 goto error;
759 }
760 }
761 if (euid != (uid_t) -1)
762 new->euid = keuid;
763 if (suid != (uid_t) -1)
764 new->suid = ksuid;
765 new->fsuid = new->euid;
766
767 retval = security_task_fix_setuid(new, old, LSM_SETID_RES);
768 if (retval < 0)
769 goto error;
770
771 retval = set_cred_ucounts(new);
772 if (retval < 0)
773 goto error;
774
775 flag_nproc_exceeded(new);
776 return commit_creds(new);
777
778error:
779 abort_creds(new);
780 return retval;
781}
782
783SYSCALL_DEFINE3(setresuid, uid_t, ruid, uid_t, euid, uid_t, suid)
784{
785 return __sys_setresuid(ruid, euid, suid);
786}
787
788SYSCALL_DEFINE3(getresuid, uid_t __user *, ruidp, uid_t __user *, euidp, uid_t __user *, suidp)
789{
790 const struct cred *cred = current_cred();
791 int retval;
792 uid_t ruid, euid, suid;
793
794 ruid = from_kuid_munged(to: cred->user_ns, uid: cred->uid);
795 euid = from_kuid_munged(to: cred->user_ns, uid: cred->euid);
796 suid = from_kuid_munged(to: cred->user_ns, uid: cred->suid);
797
798 retval = put_user(ruid, ruidp);
799 if (!retval) {
800 retval = put_user(euid, euidp);
801 if (!retval)
802 return put_user(suid, suidp);
803 }
804 return retval;
805}
806
807/*
808 * Same as above, but for rgid, egid, sgid.
809 */
810long __sys_setresgid(gid_t rgid, gid_t egid, gid_t sgid)
811{
812 struct user_namespace *ns = current_user_ns();
813 const struct cred *old;
814 struct cred *new;
815 int retval;
816 kgid_t krgid, kegid, ksgid;
817 bool rgid_new, egid_new, sgid_new;
818
819 krgid = make_kgid(from: ns, gid: rgid);
820 kegid = make_kgid(from: ns, gid: egid);
821 ksgid = make_kgid(from: ns, gid: sgid);
822
823 if ((rgid != (gid_t) -1) && !gid_valid(gid: krgid))
824 return -EINVAL;
825 if ((egid != (gid_t) -1) && !gid_valid(gid: kegid))
826 return -EINVAL;
827 if ((sgid != (gid_t) -1) && !gid_valid(gid: ksgid))
828 return -EINVAL;
829
830 old = current_cred();
831
832 /* check for no-op */
833 if ((rgid == (gid_t) -1 || gid_eq(left: krgid, right: old->gid)) &&
834 (egid == (gid_t) -1 || (gid_eq(left: kegid, right: old->egid) &&
835 gid_eq(left: kegid, right: old->fsgid))) &&
836 (sgid == (gid_t) -1 || gid_eq(left: ksgid, right: old->sgid)))
837 return 0;
838
839 rgid_new = rgid != (gid_t) -1 && !gid_eq(left: krgid, right: old->gid) &&
840 !gid_eq(left: krgid, right: old->egid) && !gid_eq(left: krgid, right: old->sgid);
841 egid_new = egid != (gid_t) -1 && !gid_eq(left: kegid, right: old->gid) &&
842 !gid_eq(left: kegid, right: old->egid) && !gid_eq(left: kegid, right: old->sgid);
843 sgid_new = sgid != (gid_t) -1 && !gid_eq(left: ksgid, right: old->gid) &&
844 !gid_eq(left: ksgid, right: old->egid) && !gid_eq(left: ksgid, right: old->sgid);
845 if ((rgid_new || egid_new || sgid_new) &&
846 !ns_capable_setid(ns: old->user_ns, CAP_SETGID))
847 return -EPERM;
848
849 new = prepare_creds();
850 if (!new)
851 return -ENOMEM;
852
853 if (rgid != (gid_t) -1)
854 new->gid = krgid;
855 if (egid != (gid_t) -1)
856 new->egid = kegid;
857 if (sgid != (gid_t) -1)
858 new->sgid = ksgid;
859 new->fsgid = new->egid;
860
861 retval = security_task_fix_setgid(new, old, LSM_SETID_RES);
862 if (retval < 0)
863 goto error;
864
865 return commit_creds(new);
866
867error:
868 abort_creds(new);
869 return retval;
870}
871
872SYSCALL_DEFINE3(setresgid, gid_t, rgid, gid_t, egid, gid_t, sgid)
873{
874 return __sys_setresgid(rgid, egid, sgid);
875}
876
877SYSCALL_DEFINE3(getresgid, gid_t __user *, rgidp, gid_t __user *, egidp, gid_t __user *, sgidp)
878{
879 const struct cred *cred = current_cred();
880 int retval;
881 gid_t rgid, egid, sgid;
882
883 rgid = from_kgid_munged(to: cred->user_ns, gid: cred->gid);
884 egid = from_kgid_munged(to: cred->user_ns, gid: cred->egid);
885 sgid = from_kgid_munged(to: cred->user_ns, gid: cred->sgid);
886
887 retval = put_user(rgid, rgidp);
888 if (!retval) {
889 retval = put_user(egid, egidp);
890 if (!retval)
891 retval = put_user(sgid, sgidp);
892 }
893
894 return retval;
895}
896
897
898/*
899 * "setfsuid()" sets the fsuid - the uid used for filesystem checks. This
900 * is used for "access()" and for the NFS daemon (letting nfsd stay at
901 * whatever uid it wants to). It normally shadows "euid", except when
902 * explicitly set by setfsuid() or for access..
903 */
904long __sys_setfsuid(uid_t uid)
905{
906 const struct cred *old;
907 struct cred *new;
908 uid_t old_fsuid;
909 kuid_t kuid;
910
911 old = current_cred();
912 old_fsuid = from_kuid_munged(to: old->user_ns, uid: old->fsuid);
913
914 kuid = make_kuid(from: old->user_ns, uid);
915 if (!uid_valid(uid: kuid))
916 return old_fsuid;
917
918 new = prepare_creds();
919 if (!new)
920 return old_fsuid;
921
922 if (uid_eq(left: kuid, right: old->uid) || uid_eq(left: kuid, right: old->euid) ||
923 uid_eq(left: kuid, right: old->suid) || uid_eq(left: kuid, right: old->fsuid) ||
924 ns_capable_setid(ns: old->user_ns, CAP_SETUID)) {
925 if (!uid_eq(left: kuid, right: old->fsuid)) {
926 new->fsuid = kuid;
927 if (security_task_fix_setuid(new, old, LSM_SETID_FS) == 0)
928 goto change_okay;
929 }
930 }
931
932 abort_creds(new);
933 return old_fsuid;
934
935change_okay:
936 commit_creds(new);
937 return old_fsuid;
938}
939
940SYSCALL_DEFINE1(setfsuid, uid_t, uid)
941{
942 return __sys_setfsuid(uid);
943}
944
945/*
946 * Samma på svenska..
947 */
948long __sys_setfsgid(gid_t gid)
949{
950 const struct cred *old;
951 struct cred *new;
952 gid_t old_fsgid;
953 kgid_t kgid;
954
955 old = current_cred();
956 old_fsgid = from_kgid_munged(to: old->user_ns, gid: old->fsgid);
957
958 kgid = make_kgid(from: old->user_ns, gid);
959 if (!gid_valid(gid: kgid))
960 return old_fsgid;
961
962 new = prepare_creds();
963 if (!new)
964 return old_fsgid;
965
966 if (gid_eq(left: kgid, right: old->gid) || gid_eq(left: kgid, right: old->egid) ||
967 gid_eq(left: kgid, right: old->sgid) || gid_eq(left: kgid, right: old->fsgid) ||
968 ns_capable_setid(ns: old->user_ns, CAP_SETGID)) {
969 if (!gid_eq(left: kgid, right: old->fsgid)) {
970 new->fsgid = kgid;
971 if (security_task_fix_setgid(new,old,LSM_SETID_FS) == 0)
972 goto change_okay;
973 }
974 }
975
976 abort_creds(new);
977 return old_fsgid;
978
979change_okay:
980 commit_creds(new);
981 return old_fsgid;
982}
983
984SYSCALL_DEFINE1(setfsgid, gid_t, gid)
985{
986 return __sys_setfsgid(gid);
987}
988#endif /* CONFIG_MULTIUSER */
989
990/**
991 * sys_getpid - return the thread group id of the current process
992 *
993 * Note, despite the name, this returns the tgid not the pid. The tgid and
994 * the pid are identical unless CLONE_THREAD was specified on clone() in
995 * which case the tgid is the same in all threads of the same group.
996 *
997 * This is SMP safe as current->tgid does not change.
998 */
999SYSCALL_DEFINE0(getpid)
1000{
1001 return task_tgid_vnr(current);
1002}
1003
1004/* Thread ID - the internal kernel "pid" */
1005SYSCALL_DEFINE0(gettid)
1006{
1007 return task_pid_vnr(current);
1008}
1009
1010/*
1011 * Accessing ->real_parent is not SMP-safe, it could
1012 * change from under us. However, we can use a stale
1013 * value of ->real_parent under rcu_read_lock(), see
1014 * release_task()->call_rcu(delayed_put_task_struct).
1015 */
1016SYSCALL_DEFINE0(getppid)
1017{
1018 int pid;
1019
1020 rcu_read_lock();
1021 pid = task_tgid_vnr(rcu_dereference(current->real_parent));
1022 rcu_read_unlock();
1023
1024 return pid;
1025}
1026
1027SYSCALL_DEFINE0(getuid)
1028{
1029 /* Only we change this so SMP safe */
1030 return from_kuid_munged(current_user_ns(), current_uid());
1031}
1032
1033SYSCALL_DEFINE0(geteuid)
1034{
1035 /* Only we change this so SMP safe */
1036 return from_kuid_munged(current_user_ns(), current_euid());
1037}
1038
1039SYSCALL_DEFINE0(getgid)
1040{
1041 /* Only we change this so SMP safe */
1042 return from_kgid_munged(current_user_ns(), current_gid());
1043}
1044
1045SYSCALL_DEFINE0(getegid)
1046{
1047 /* Only we change this so SMP safe */
1048 return from_kgid_munged(current_user_ns(), current_egid());
1049}
1050
1051static void do_sys_times(struct tms *tms)
1052{
1053 u64 tgutime, tgstime, cutime, cstime;
1054
1055 thread_group_cputime_adjusted(current, ut: &tgutime, st: &tgstime);
1056 cutime = current->signal->cutime;
1057 cstime = current->signal->cstime;
1058 tms->tms_utime = nsec_to_clock_t(x: tgutime);
1059 tms->tms_stime = nsec_to_clock_t(x: tgstime);
1060 tms->tms_cutime = nsec_to_clock_t(x: cutime);
1061 tms->tms_cstime = nsec_to_clock_t(x: cstime);
1062}
1063
1064SYSCALL_DEFINE1(times, struct tms __user *, tbuf)
1065{
1066 if (tbuf) {
1067 struct tms tmp;
1068
1069 do_sys_times(tms: &tmp);
1070 if (copy_to_user(to: tbuf, from: &tmp, n: sizeof(struct tms)))
1071 return -EFAULT;
1072 }
1073 force_successful_syscall_return();
1074 return (long) jiffies_64_to_clock_t(x: get_jiffies_64());
1075}
1076
1077#ifdef CONFIG_COMPAT
1078static compat_clock_t clock_t_to_compat_clock_t(clock_t x)
1079{
1080 return compat_jiffies_to_clock_t(clock_t_to_jiffies(x));
1081}
1082
1083COMPAT_SYSCALL_DEFINE1(times, struct compat_tms __user *, tbuf)
1084{
1085 if (tbuf) {
1086 struct tms tms;
1087 struct compat_tms tmp;
1088
1089 do_sys_times(tms: &tms);
1090 /* Convert our struct tms to the compat version. */
1091 tmp.tms_utime = clock_t_to_compat_clock_t(x: tms.tms_utime);
1092 tmp.tms_stime = clock_t_to_compat_clock_t(x: tms.tms_stime);
1093 tmp.tms_cutime = clock_t_to_compat_clock_t(x: tms.tms_cutime);
1094 tmp.tms_cstime = clock_t_to_compat_clock_t(x: tms.tms_cstime);
1095 if (copy_to_user(to: tbuf, from: &tmp, n: sizeof(tmp)))
1096 return -EFAULT;
1097 }
1098 force_successful_syscall_return();
1099 return compat_jiffies_to_clock_t(jiffies);
1100}
1101#endif
1102
1103/*
1104 * This needs some heavy checking ...
1105 * I just haven't the stomach for it. I also don't fully
1106 * understand sessions/pgrp etc. Let somebody who does explain it.
1107 *
1108 * OK, I think I have the protection semantics right.... this is really
1109 * only important on a multi-user system anyway, to make sure one user
1110 * can't send a signal to a process owned by another. -TYT, 12/12/91
1111 *
1112 * !PF_FORKNOEXEC check to conform completely to POSIX.
1113 */
1114SYSCALL_DEFINE2(setpgid, pid_t, pid, pid_t, pgid)
1115{
1116 struct task_struct *p;
1117 struct task_struct *group_leader = current->group_leader;
1118 struct pid *pids[PIDTYPE_MAX] = { 0 };
1119 struct pid *pgrp;
1120 int err;
1121
1122 if (!pid)
1123 pid = task_pid_vnr(tsk: group_leader);
1124 if (!pgid)
1125 pgid = pid;
1126 if (pgid < 0)
1127 return -EINVAL;
1128 rcu_read_lock();
1129
1130 /* From this point forward we keep holding onto the tasklist lock
1131 * so that our parent does not change from under us. -DaveM
1132 */
1133 write_lock_irq(&tasklist_lock);
1134
1135 err = -ESRCH;
1136 p = find_task_by_vpid(nr: pid);
1137 if (!p)
1138 goto out;
1139
1140 err = -EINVAL;
1141 if (!thread_group_leader(p))
1142 goto out;
1143
1144 if (same_thread_group(p1: p->real_parent, p2: group_leader)) {
1145 err = -EPERM;
1146 if (task_session(task: p) != task_session(task: group_leader))
1147 goto out;
1148 err = -EACCES;
1149 if (!(p->flags & PF_FORKNOEXEC))
1150 goto out;
1151 } else {
1152 err = -ESRCH;
1153 if (p != group_leader)
1154 goto out;
1155 }
1156
1157 err = -EPERM;
1158 if (p->signal->leader)
1159 goto out;
1160
1161 pgrp = task_pid(task: p);
1162 if (pgid != pid) {
1163 struct task_struct *g;
1164
1165 pgrp = find_vpid(nr: pgid);
1166 g = pid_task(pid: pgrp, PIDTYPE_PGID);
1167 if (!g || task_session(task: g) != task_session(task: group_leader))
1168 goto out;
1169 }
1170
1171 err = security_task_setpgid(p, pgid);
1172 if (err)
1173 goto out;
1174
1175 if (task_pgrp(task: p) != pgrp)
1176 change_pid(pids, task: p, PIDTYPE_PGID, pid: pgrp);
1177
1178 err = 0;
1179out:
1180 /* All paths lead to here, thus we are safe. -DaveM */
1181 write_unlock_irq(&tasklist_lock);
1182 rcu_read_unlock();
1183 free_pids(pids);
1184 return err;
1185}
1186
1187static int do_getpgid(pid_t pid)
1188{
1189 struct task_struct *p;
1190 struct pid *grp;
1191 int retval;
1192
1193 rcu_read_lock();
1194 if (!pid)
1195 grp = task_pgrp(current);
1196 else {
1197 retval = -ESRCH;
1198 p = find_task_by_vpid(nr: pid);
1199 if (!p)
1200 goto out;
1201 grp = task_pgrp(task: p);
1202 if (!grp)
1203 goto out;
1204
1205 retval = security_task_getpgid(p);
1206 if (retval)
1207 goto out;
1208 }
1209 retval = pid_vnr(pid: grp);
1210out:
1211 rcu_read_unlock();
1212 return retval;
1213}
1214
1215SYSCALL_DEFINE1(getpgid, pid_t, pid)
1216{
1217 return do_getpgid(pid);
1218}
1219
1220#ifdef __ARCH_WANT_SYS_GETPGRP
1221
1222SYSCALL_DEFINE0(getpgrp)
1223{
1224 return do_getpgid(pid: 0);
1225}
1226
1227#endif
1228
1229SYSCALL_DEFINE1(getsid, pid_t, pid)
1230{
1231 struct task_struct *p;
1232 struct pid *sid;
1233 int retval;
1234
1235 rcu_read_lock();
1236 if (!pid)
1237 sid = task_session(current);
1238 else {
1239 retval = -ESRCH;
1240 p = find_task_by_vpid(nr: pid);
1241 if (!p)
1242 goto out;
1243 sid = task_session(task: p);
1244 if (!sid)
1245 goto out;
1246
1247 retval = security_task_getsid(p);
1248 if (retval)
1249 goto out;
1250 }
1251 retval = pid_vnr(pid: sid);
1252out:
1253 rcu_read_unlock();
1254 return retval;
1255}
1256
1257static void set_special_pids(struct pid **pids, struct pid *pid)
1258{
1259 struct task_struct *curr = current->group_leader;
1260
1261 if (task_session(task: curr) != pid)
1262 change_pid(pids, task: curr, PIDTYPE_SID, pid);
1263
1264 if (task_pgrp(task: curr) != pid)
1265 change_pid(pids, task: curr, PIDTYPE_PGID, pid);
1266}
1267
1268int ksys_setsid(void)
1269{
1270 struct task_struct *group_leader = current->group_leader;
1271 struct pid *sid = task_pid(task: group_leader);
1272 struct pid *pids[PIDTYPE_MAX] = { 0 };
1273 pid_t session = pid_vnr(pid: sid);
1274 int err = -EPERM;
1275
1276 write_lock_irq(&tasklist_lock);
1277 /* Fail if I am already a session leader */
1278 if (group_leader->signal->leader)
1279 goto out;
1280
1281 /* Fail if a process group id already exists that equals the
1282 * proposed session id.
1283 */
1284 if (pid_task(pid: sid, PIDTYPE_PGID))
1285 goto out;
1286
1287 group_leader->signal->leader = 1;
1288 set_special_pids(pids, pid: sid);
1289
1290 proc_clear_tty(p: group_leader);
1291
1292 err = session;
1293out:
1294 write_unlock_irq(&tasklist_lock);
1295 free_pids(pids);
1296 if (err > 0) {
1297 proc_sid_connector(task: group_leader);
1298 sched_autogroup_create_attach(p: group_leader);
1299 }
1300 return err;
1301}
1302
1303SYSCALL_DEFINE0(setsid)
1304{
1305 return ksys_setsid();
1306}
1307
1308DECLARE_RWSEM(uts_sem);
1309
1310#ifdef COMPAT_UTS_MACHINE
1311#define override_architecture(name) \
1312 (personality(current->personality) == PER_LINUX32 && \
1313 copy_to_user(name->machine, COMPAT_UTS_MACHINE, \
1314 sizeof(COMPAT_UTS_MACHINE)))
1315#else
1316#define override_architecture(name) 0
1317#endif
1318
1319/*
1320 * Work around broken programs that cannot handle "Linux 3.0".
1321 * Instead we map 3.x to 2.6.40+x, so e.g. 3.0 would be 2.6.40
1322 * And we map 4.x and later versions to 2.6.60+x, so 4.0/5.0/6.0/... would be
1323 * 2.6.60.
1324 */
1325static int override_release(char __user *release, size_t len)
1326{
1327 int ret = 0;
1328
1329 if (current->personality & UNAME26) {
1330 const char *rest = UTS_RELEASE;
1331 char buf[65] = { 0 };
1332 int ndots = 0;
1333 unsigned v;
1334 size_t copy;
1335
1336 while (*rest) {
1337 if (*rest == '.' && ++ndots >= 3)
1338 break;
1339 if (!isdigit(c: *rest) && *rest != '.')
1340 break;
1341 rest++;
1342 }
1343 v = LINUX_VERSION_PATCHLEVEL + 60;
1344 copy = clamp_t(size_t, len, 1, sizeof(buf));
1345 copy = scnprintf(buf, size: copy, fmt: "2.6.%u%s", v, rest);
1346 ret = copy_to_user(to: release, from: buf, n: copy + 1);
1347 }
1348 return ret;
1349}
1350
1351SYSCALL_DEFINE1(newuname, struct new_utsname __user *, name)
1352{
1353 struct new_utsname tmp;
1354
1355 down_read(sem: &uts_sem);
1356 memcpy(&tmp, utsname(), sizeof(tmp));
1357 up_read(sem: &uts_sem);
1358 if (copy_to_user(to: name, from: &tmp, n: sizeof(tmp)))
1359 return -EFAULT;
1360
1361 if (override_release(release: name->release, len: sizeof(name->release)))
1362 return -EFAULT;
1363 if (override_architecture(name))
1364 return -EFAULT;
1365 return 0;
1366}
1367
1368#ifdef __ARCH_WANT_SYS_OLD_UNAME
1369/*
1370 * Old cruft
1371 */
1372SYSCALL_DEFINE1(uname, struct old_utsname __user *, name)
1373{
1374 struct old_utsname tmp;
1375
1376 if (!name)
1377 return -EFAULT;
1378
1379 down_read(sem: &uts_sem);
1380 memcpy(&tmp, utsname(), sizeof(tmp));
1381 up_read(sem: &uts_sem);
1382 if (copy_to_user(to: name, from: &tmp, n: sizeof(tmp)))
1383 return -EFAULT;
1384
1385 if (override_release(release: name->release, len: sizeof(name->release)))
1386 return -EFAULT;
1387 if (override_architecture(name))
1388 return -EFAULT;
1389 return 0;
1390}
1391
1392SYSCALL_DEFINE1(olduname, struct oldold_utsname __user *, name)
1393{
1394 struct oldold_utsname tmp;
1395
1396 if (!name)
1397 return -EFAULT;
1398
1399 memset(&tmp, 0, sizeof(tmp));
1400
1401 down_read(sem: &uts_sem);
1402 memcpy(&tmp.sysname, &utsname()->sysname, __OLD_UTS_LEN);
1403 memcpy(&tmp.nodename, &utsname()->nodename, __OLD_UTS_LEN);
1404 memcpy(&tmp.release, &utsname()->release, __OLD_UTS_LEN);
1405 You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.