lkml.org 
[lkml]   [2012]   [Feb]   [29]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    From
    Subject[RFC] c/r: prctl: Add ability to set new mm_struct::exe_file
    Hi guys,

    at restore time we would like to have a way for /proc/pid/exe
    symlink recovering. So I thought extending prctl might be
    a good idea.

    Still maybe there some other good and 'right' way to do it,
    so I would like to gather opinions.

    Please review, thanks!

    Cyrill
    ---
    From: Cyrill Gorcunov <gorcunov@openvz.org>
    Subject: [RFC] c/r: prctl: Add ability to set new mm_struct::exe_file

    When we do restore we would like to have a way to setup
    a former mm_struct::exe_file so that /proc/pid/exe would
    point to the original executable file a process had at
    checkpoint time.

    For this sake PR_SET_MM_EXE_FILE code is introduced.

    Note, if mm_struct::exe_file already mapped more than once
    we refuse to change anything (which prevents kernel from
    potential problems).

    Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
    ---
    include/linux/prctl.h | 1
    kernel/sys.c | 73 +++++++++++++++++++++++++++++++++++++++++++++++++-
    2 files changed, 73 insertions(+), 1 deletion(-)

    Index: linux-2.6.git/include/linux/prctl.h
    ===================================================================
    --- linux-2.6.git.orig/include/linux/prctl.h
    +++ linux-2.6.git/include/linux/prctl.h
    @@ -118,5 +118,6 @@
    # define PR_SET_MM_ENV_START 10
    # define PR_SET_MM_ENV_END 11
    # define PR_SET_MM_AUXV 12
    +# define PR_SET_MM_EXE_FILE 13

    #endif /* _LINUX_PRCTL_H */
    Index: linux-2.6.git/kernel/sys.c
    ===================================================================
    --- linux-2.6.git.orig/kernel/sys.c
    +++ linux-2.6.git/kernel/sys.c
    @@ -1701,6 +1701,66 @@ static bool vma_flags_mismatch(struct vm
    (vma->vm_flags & banned);
    }

    +/* Expects mm->mmap_sem is read-taken */
    +static int prctl_set_mm_exe_file(struct mm_struct *mm,
    + const void __user *path,
    + size_t size)
    +{
    + struct file *new_exe_file;
    + char *pathbuf;
    + int ret = 0;
    +
    + if (size >= PATH_MAX)
    + return -EINVAL;
    +
    + /*
    + * We allow to change only those exe's which
    + * are not mapped several times. This one
    + * is early test while mmap_sem is taken.
    + */
    + if (mm->num_exe_file_vmas > 1)
    + return -EBUSY;
    +
    + up_read(&mm->mmap_sem);
    +
    + pathbuf = kmalloc(size, GFP_TEMPORARY);
    + if (!pathbuf) {
    + ret = -ENOMEM;
    + goto err_down;
    + }
    +
    + if (copy_from_user(pathbuf, path, size)) {
    + kfree(pathbuf);
    + ret = -EFAULT;
    + goto err_down;
    + }
    + pathbuf[size-1] = '\0';
    +
    + new_exe_file = open_exec(pathbuf);
    + kfree(pathbuf);
    +
    + down_read(&mm->mmap_sem);
    +
    + if (IS_ERR(new_exe_file))
    + return PTR_ERR(new_exe_file);
    +
    + /*
    + * We allow to change only those exe's which
    + * are not mapped several times.
    + */
    + if (mm->num_exe_file_vmas < 2) {
    + set_mm_exe_file(mm, new_exe_file);
    + ret = 0;
    + } else
    + ret = -EBUSY;
    +
    + return ret;
    +
    +err_down:
    + down_read(&mm->mmap_sem);
    + return ret;
    +}
    +
    static int prctl_set_mm(int opt, unsigned long addr,
    unsigned long arg4, unsigned long arg5)
    {
    @@ -1709,7 +1769,9 @@ static int prctl_set_mm(int opt, unsigne
    struct vm_area_struct *vma;
    int error = 0;

    - if (arg5 || (arg4 && opt != PR_SET_MM_AUXV))
    + if (arg5 || (arg4 &&
    + opt != PR_SET_MM_AUXV &&
    + opt != PR_SET_MM_EXE_FILE))
    return -EINVAL;

    if (!capable(CAP_SYS_ADMIN))
    @@ -1837,6 +1899,15 @@ static int prctl_set_mm(int opt, unsigne

    return 0;
    }
    +
    + /*
    + * This to restore /proc/self/exe link.
    + */
    + case PR_SET_MM_EXE_FILE:
    + error = prctl_set_mm_exe_file(mm, (const void __user *)addr, arg4);
    + if (error)
    + goto out;
    + break;
    default:
    error = -EINVAL;
    goto out;

    \
     
     \ /
      Last update: 2012-02-29 16:19    [W:0.026 / U:119.828 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site