/* * Ugh. To avoid negative return values, "getpriority()" will * not return the normal nice-value, but a negated value that * has been offset by 20 (ie it returns 40..1 instead of -20..19) * to stay compatible. */ asmlinkage long sys_getpriority(int which, int who) { struct task_struct *g, *p; struct user_struct *user; long niceval, retval = -ESRCH; struct pid *pgrp; if (which > PRIO_USER || which < PRIO_PROCESS) return -EINVAL; read_lock(&tasklist_lock); switch (which) { case PRIO_PROCESS: if (who) p = find_task_by_vpid(who); else p = current; if (p) { niceval = 20 - task_nice(p); if (niceval > retval) retval = niceval; } break; case PRIO_PGRP: if (who) pgrp = find_vpid(who); else pgrp = task_pgrp(current); do_each_pid_task(pgrp, PIDTYPE_PGID, p) { niceval = 20 - task_nice(p); if (niceval > retval) retval = niceval; } while_each_pid_task(pgrp, PIDTYPE_PGID, p); break; case PRIO_USER: user = current->user; if (!who) who = current->uid; else if ((who != current->uid) && !(user = find_user(who))) goto out_unlock; /* No processes for this user */ do_each_thread(g, p) if (p->uid == who) { niceval = 20 - task_nice(p); if (niceval > retval) retval = niceval; } while_each_thread(g, p); if (who != current->uid) free_uid(user); /* for find_user() */ break; }
asmlinkage long sys_setpriority(int which, int who, int niceval) { struct task_struct *g, *p; struct user_struct *user; int error = -EINVAL; struct pid *pgrp; if (which > PRIO_USER || which < PRIO_PROCESS) goto out; /* normalize: avoid signed division (rounding problems) */ error = -ESRCH; if (niceval < -20) niceval = -20; if (niceval > 19) niceval = 19; read_lock(&tasklist_lock); switch (which) { case PRIO_PROCESS: if (who) p = find_task_by_vpid(who); else p = current; if (p) error = set_one_prio(p, niceval, error); break; case PRIO_PGRP: if (who) pgrp = find_vpid(who); else pgrp = task_pgrp(current); do_each_pid_task(pgrp, PIDTYPE_PGID, p) { error = set_one_prio(p, niceval, error); } while_each_pid_task(pgrp, PIDTYPE_PGID, p); break; case PRIO_USER: user = current->user; if (!who) who = current->uid; else if ((who != current->uid) && !(user = find_user(who))) goto out_unlock; /* No processes for this user */ do_each_thread(g, p) if (p->uid == who) error = set_one_prio(p, niceval, error); while_each_thread(g, p); if (who != current->uid) free_uid(user); /* For find_user() */ break; }
int gr_handle_chroot_fowner(struct pid *pid, enum pid_type type) { #ifdef CONFIG_GRKERNSEC_CHROOT_FINDTASK struct task_struct *p; int ret = 0; if (!grsec_enable_chroot_findtask || !proc_is_chrooted(current) || !pid) return ret; read_lock(&tasklist_lock); do_each_pid_task(pid, type, p) { if (!have_same_root(current, p)) { ret = 1; goto out; } } while_each_pid_task(pid, type, p); out: read_unlock(&tasklist_lock); return ret; #endif return 0; }