lkml.org 
[lkml]   [2009]   [Oct]   [12]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    SubjectRe: [PATCH 2/3] extend get/setrlimit to support setting rlimits external to a process (v6)
    Add syscall infrastructure for getprlimit/setprlimit

    This patch adds the definitions for the get/setprlimit syscalls. They are
    identical to the get/setlimit calls, except that they allow the caller to
    manipulate limits for processes other than themselves.

    Signed-off-by: Neil Horman <nhorman@tuxdriver.com>


    include/linux/syscalls.h | 4 ++
    kernel/sys.c | 84 +++++++++++++++++++++++++++++++++++++++++++++++
    2 files changed, 88 insertions(+)

    diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
    index a990ace..9f357ab 100644
    --- a/include/linux/syscalls.h
    +++ b/include/linux/syscalls.h
    @@ -702,11 +702,15 @@ asmlinkage long sys_newuname(struct new_utsname __user *name);

    asmlinkage long sys_getrlimit(unsigned int resource,
    struct rlimit __user *rlim);
    +asmlinkage long sys_getprlimit(pid_t pid, unsigned int resource,
    + struct rlimit __user *rlim);
    #if defined(COMPAT_RLIM_OLD_INFINITY) || !(defined(CONFIG_IA64))
    asmlinkage long sys_old_getrlimit(unsigned int resource, struct rlimit __user *rlim);
    #endif
    asmlinkage long sys_setrlimit(unsigned int resource,
    struct rlimit __user *rlim);
    +asmlinkage long sys_setprlimit(pid_t pid, unsigned int resource,
    + struct rlimit __user *rlim);
    asmlinkage long sys_getrusage(int who, struct rusage __user *ru);
    asmlinkage long sys_umask(int mask);

    diff --git a/kernel/sys.c b/kernel/sys.c
    index 0e210a4..6ca9e7f 100644
    --- a/kernel/sys.c
    +++ b/kernel/sys.c
    @@ -1213,6 +1213,50 @@ SYSCALL_DEFINE2(getrlimit, unsigned int, resource, struct rlimit __user *, rlim)
    }
    }

    +SYSCALL_DEFINE3(getprlimit, pid_t, pid, unsigned int, resource,
    + struct rlimit __user *, rlim)
    +{
    + unsigned long flags;
    + struct task_struct *tsk;
    + struct pid *ppid;
    + int retval = -EINVAL;
    +
    + ppid = find_get_pid(pid);
    + if (!ppid)
    + goto out;
    +
    + tsk = get_pid_task(ppid, PIDTYPE_PID);
    +
    + if (!tsk)
    + goto out_put_pid;
    +
    + if (resource >= RLIM_NLIMITS)
    + goto out_put_all;
    +
    + retval = -EBUSY;
    + if (!lock_task_sighand(tsk, &flags))
    + goto out_put_all;
    +
    + else {
    + struct rlimit val;
    +
    + task_lock(tsk->group_leader);
    + val = current->signal->rlim[resource];
    + task_unlock(tsk->group_leader);
    + retval = copy_to_user(rlim, &val, sizeof(*rlim)) ? -EFAULT : 0;
    + }
    +
    + unlock_task_sighand(tsk, &flags);
    +
    +out_put_all:
    + put_task_struct(tsk);
    +out_put_pid:
    + put_pid(ppid);
    +out:
    + return retval;
    +}
    +
    +
    #ifdef __ARCH_WANT_SYS_OLD_GETRLIMIT

    /*
    @@ -1303,6 +1347,46 @@ SYSCALL_DEFINE2(setrlimit, unsigned int, resource, struct rlimit __user *, rlim)
    return do_setrlimit(resource, &new_rlim, current);
    }

    +SYSCALL_DEFINE3(setprlimit, pid_t, pid, unsigned int, resource,
    + struct rlimit __user *, rlim)
    +{
    + struct task_struct *tsk;
    + struct pid *ppid;
    + unsigned long flags;
    + struct rlimit new_rlim;
    + int retval = -EINVAL;
    +
    + ppid = find_get_pid(pid);
    + if (!ppid)
    + goto out;
    +
    + tsk = get_pid_task(ppid, PIDTYPE_PID);
    +
    + if (!tsk)
    + goto out_put_pid;
    +
    + if (resource >= RLIM_NLIMITS)
    + goto out_put_all;
    +
    + retval = -EFAULT;
    + if (copy_from_user(&new_rlim, rlim, sizeof(*rlim)))
    + goto out_put_all;
    +
    + if (!lock_task_sighand(tsk, &flags))
    + goto out_put_all;
    +
    + retval = do_setrlimit(resource, &new_rlim, tsk);
    +
    + unlock_task_sighand(tsk, &flags);
    +
    +out_put_all:
    + put_task_struct(tsk);
    +out_put_pid:
    + put_pid(ppid);
    +out:
    + return retval;
    +}
    +
    /*
    * It would make sense to put struct rusage in the task_struct,
    * except that would make the task_struct be *really big*. After

    \
     
     \ /
      Last update: 2009-10-12 22:33    [W:0.027 / U:1.804 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site