The patch titled Subject: proc: save 2 atomic ops on write to "/proc/*/attr/*" has been added to the -mm tree. Its filename is proc-save-2-atomic-ops-on-write-to-proc-attr.patch This patch should soon appear at http://ozlabs.org/~akpm/mmots/broken-out/proc-save-2-atomic-ops-on-write-to-proc-attr.patch and later at http://ozlabs.org/~akpm/mmotm/broken-out/proc-save-2-atomic-ops-on-write-to-proc-attr.patch Before you just go and hit "reply", please: a) Consider who else should be cc'ed b) Prefer to cc a suitable mailing list as well c) Ideally: find the original patch on the mailing list and do a reply-to-all to that, adding suitable additional cc's *** Remember to use Documentation/process/submit-checklist.rst when testing your code *** The -mm tree is included into linux-next and is updated there every 3-4 working days ------------------------------------------------------ From: Alexey Dobriyan <adobriyan@xxxxxxxxx> Subject: proc: save 2 atomic ops on write to "/proc/*/attr/*" Code checks if write is done by current to its own attributes. For that get/put pair is unnecessary as it can be done under RCU. Note: rcu_read_unlock() can be done even earlier since pointer to a task is not dereferenced. It depends if /proc code should look scary or not: rcu_read_lock(); task = pid_task(...); rcu_read_unlock(); if (!task) return -ESRCH; if (task != current) return -EACCESS: P.S.: rename "length" variable. Code like this length = -EINVAL; should not exist. Link: http://lkml.kernel.org/r/20180627200218.GF18113@avx2 Signed-off-by: Alexey Dobriyan <adobriyan@xxxxxxxxx> Reviewed-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> Signed-off-by: Andrew Morton <akpm@xxxxxxxxxxxxxxxxxxxx> --- diff -puN fs/proc/base.c~proc-save-2-atomic-ops-on-write-to-proc-attr fs/proc/base.c --- a/fs/proc/base.c~proc-save-2-atomic-ops-on-write-to-proc-attr +++ a/fs/proc/base.c @@ -2517,47 +2517,47 @@ static ssize_t proc_pid_attr_write(struc size_t count, loff_t *ppos) { struct inode * inode = file_inode(file); + struct task_struct *task; void *page; - ssize_t length; - struct task_struct *task = get_proc_task(inode); - - length = -ESRCH; - if (!task) - goto out_no_task; + int rv; + rcu_read_lock(); + task = pid_task(proc_pid(inode), PIDTYPE_PID); + if (!task) { + rcu_read_unlock(); + return -ESRCH; + } /* A task may only write its own attributes. */ - length = -EACCES; - if (current != task) - goto out; + if (current != task) { + rcu_read_unlock(); + return -EACCES; + } + rcu_read_unlock(); if (count > PAGE_SIZE) count = PAGE_SIZE; /* No partial writes. */ - length = -EINVAL; if (*ppos != 0) - goto out; + return -EINVAL; page = memdup_user(buf, count); if (IS_ERR(page)) { - length = PTR_ERR(page); + rv = PTR_ERR(page); goto out; } /* Guard against adverse ptrace interaction */ - length = mutex_lock_interruptible(¤t->signal->cred_guard_mutex); - if (length < 0) + rv = mutex_lock_interruptible(¤t->signal->cred_guard_mutex); + if (rv < 0) goto out_free; - length = security_setprocattr(file->f_path.dentry->d_name.name, - page, count); + rv = security_setprocattr(file->f_path.dentry->d_name.name, page, count); mutex_unlock(¤t->signal->cred_guard_mutex); out_free: kfree(page); out: - put_task_struct(task); -out_no_task: - return length; + return rv; } static const struct file_operations proc_pid_attr_operations = { _ Patches currently in -mm which might be from adobriyan@xxxxxxxxx are proc-condemn-myself-to-maintainers.patch proc-fixup-pde-allocation-bloat.patch proc-test-proc-self-symlink.patch proc-test-proc-thread-self-symlink.patch proc-smaller-readlock-section-in-readdir-proc.patch proc-put-task-earlier-in-proc-fail-nth.patch proc-save-2-atomic-ops-on-write-to-proc-attr.patch proc-use-macro-in-proc-latency-hook.patch proc-spread-const-a-bit.patch proc-use-unsigned-int-in-proc-stat-hook.patch proc-use-%02u-format.patch -- To unsubscribe from this list: send the line "unsubscribe mm-commits" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html