Commit 1203c8e6 authored by Akinobu Mita's avatar Akinobu Mita Committed by Linus Torvalds

fault-inject: simplify access check for fail-nth

The fail-nth file is created with 0666 and the access is permitted if
and only if the task is current.

This file is owned by the currnet user.  So we can create it with 0644
and allow the owner to write it.  This enables to watch the status of
task->fail_nth from another processes.

[akinobu.mita@gmail.com: don't convert unsigned type value as signed int]
  Link: http://lkml.kernel.org/r/1492444483-9239-1-git-send-email-akinobu.mita@gmail.com
[akinobu.mita@gmail.com: avoid unwanted data race to task->fail_nth]
  Link: http://lkml.kernel.org/r/1499962492-8931-1-git-send-email-akinobu.mita@gmail.com
Link: http://lkml.kernel.org/r/1491490561-10485-5-git-send-email-akinobu.mita@gmail.comSigned-off-by: default avatarAkinobu Mita <akinobu.mita@gmail.com>
Acked-by: default avatarDmitry Vyukov <dvyukov@google.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bfc74093
...@@ -1363,16 +1363,16 @@ static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf, ...@@ -1363,16 +1363,16 @@ static ssize_t proc_fail_nth_write(struct file *file, const char __user *buf,
int err; int err;
unsigned int n; unsigned int n;
err = kstrtouint_from_user(buf, count, 0, &n);
if (err)
return err;
task = get_proc_task(file_inode(file)); task = get_proc_task(file_inode(file));
if (!task) if (!task)
return -ESRCH; return -ESRCH;
WRITE_ONCE(task->fail_nth, n);
put_task_struct(task); put_task_struct(task);
if (task != current)
return -EPERM;
err = kstrtouint_from_user(buf, count, 0, &n);
if (err)
return err;
current->fail_nth = n;
return count; return count;
} }
...@@ -1386,11 +1386,10 @@ static ssize_t proc_fail_nth_read(struct file *file, char __user *buf, ...@@ -1386,11 +1386,10 @@ static ssize_t proc_fail_nth_read(struct file *file, char __user *buf,
task = get_proc_task(file_inode(file)); task = get_proc_task(file_inode(file));
if (!task) if (!task)
return -ESRCH; return -ESRCH;
put_task_struct(task); len = snprintf(numbuf, sizeof(numbuf), "%u\n",
if (task != current) READ_ONCE(task->fail_nth));
return -EPERM;
len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
len = simple_read_from_buffer(buf, count, ppos, numbuf, len); len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
put_task_struct(task);
return len; return len;
} }
...@@ -3355,11 +3354,7 @@ static const struct pid_entry tid_base_stuff[] = { ...@@ -3355,11 +3354,7 @@ static const struct pid_entry tid_base_stuff[] = {
#endif #endif
#ifdef CONFIG_FAULT_INJECTION #ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations), REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_operations),
/* REG("fail-nth", 0644, proc_fail_nth_operations),
* Operations on the file check that the task is current,
* so we create it with 0666 to support testing under unprivileged user.
*/
REG("fail-nth", 0666, proc_fail_nth_operations),
#endif #endif
#ifdef CONFIG_TASK_IO_ACCOUNTING #ifdef CONFIG_TASK_IO_ACCOUNTING
ONE("io", S_IRUSR, proc_tid_io_accounting), ONE("io", S_IRUSR, proc_tid_io_accounting),
......
...@@ -107,9 +107,12 @@ static inline bool fail_stacktrace(struct fault_attr *attr) ...@@ -107,9 +107,12 @@ static inline bool fail_stacktrace(struct fault_attr *attr)
bool should_fail(struct fault_attr *attr, ssize_t size) bool should_fail(struct fault_attr *attr, ssize_t size)
{ {
if (in_task() && current->fail_nth) { if (in_task()) {
if (--current->fail_nth == 0) unsigned int fail_nth = READ_ONCE(current->fail_nth);
if (fail_nth && !WRITE_ONCE(current->fail_nth, fail_nth - 1))
goto fail; goto fail;
return false; return false;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment