Re: [PATCH 2.6.13-rc6 1/2] New Syscall: get rlimits of any process

From: Andrew Morton
Date: Sat Aug 20 2005 - 20:13:08 EST


Wieland Gmeiner <e8607062@xxxxxxxxxxxxxxxxxxxx> wrote:
>
> +asmlinkage long sys_getprlimit(pid_t pid, unsigned int resource, struct rlimit __user *rlim)
> +{
> + struct rlimit value;
> + task_t *p;
> + int retval = -EINVAL;
> +
> + if (resource >= RLIM_NLIMITS)
> + goto out_nounlock;
> +
> + if (pid < 0)
> + goto out_nounlock;
> +
> + retval = -ESRCH;
> + if (pid == 0) {
> + p = current;
> + } else {
> + read_lock(&tasklist_lock);
> + p = find_task_by_pid(pid);
> + }
> + if (p) {
> + retval = -EPERM;
> + if ((current->euid ^ p->suid) && (current->euid ^ p->uid) &&
> + (current->uid ^ p->suid) && (current->uid ^ p->uid) &&
> + !capable(CAP_SYS_RESOURCE))
> + goto out_unlock;
> +
> + task_lock(p->group_leader);
> + value = p->signal->rlim[resource];
> + task_unlock(p->group_leader);

There isn't much point in taking task_lock() here. The value can change
after the lock has been dropped anyway.

> + retval = copy_to_user(rlim, &value, sizeof(*rlim)) ? -EFAULT : 0;

It's not legal to perform copy_*_user() (which sleeps) inside read_lock(),
write_lock(), spin_lock(), preempt_diable() or, really,
local_irq_disable().

> + }
> + if (pid == 0)
> + goto out_nounlock;
> +
> +out_unlock:
> + read_unlock(&tasklist_lock);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/