int err;
unsigned int n;
+ err = kstrtouint_from_user(buf, count, 0, &n);
+ if (err)
+ return err;
+
task = get_proc_task(file_inode(file));
if (!task)
return -ESRCH;
+ WRITE_ONCE(task->fail_nth, n);
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;
}
task = get_proc_task(file_inode(file));
if (!task)
return -ESRCH;
- put_task_struct(task);
- if (task != current)
- return -EPERM;
- len = snprintf(numbuf, sizeof(numbuf), "%u\n", task->fail_nth);
+ len = snprintf(numbuf, sizeof(numbuf), "%u\n",
+ READ_ONCE(task->fail_nth));
len = simple_read_from_buffer(buf, count, ppos, numbuf, len);
+ put_task_struct(task);
return len;
}
#endif
#ifdef CONFIG_FAULT_INJECTION
REG("make-it-fail", S_IRUGO|S_IWUSR, proc_fault_inject_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),
+ REG("fail-nth", 0644, proc_fail_nth_operations),
#endif
#ifdef CONFIG_TASK_IO_ACCOUNTING
ONE("io", S_IRUSR, proc_tid_io_accounting),
bool should_fail(struct fault_attr *attr, ssize_t size)
{
- if (in_task() && current->fail_nth) {
- if (--current->fail_nth == 0)
+ if (in_task()) {
+ unsigned int fail_nth = READ_ONCE(current->fail_nth);
+
+ if (fail_nth && !WRITE_ONCE(current->fail_nth, fail_nth - 1))
goto fail;
+
return false;
}