diff options
author | Akinobu Mita <akinobu.mita@gmail.com> | 2006-12-08 05:39:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.osdl.org> | 2006-12-08 11:29:02 -0500 |
commit | f4f154fd920b2178382a6a24a236348e4429ebc1 (patch) | |
tree | 0bba747eb50b5d7e18d2b828f8c707b2781d7544 /fs/proc/base.c | |
parent | c17bb4951752d3e0f49cd1ea9d2e868422f9e0d6 (diff) |
[PATCH] fault injection: process filtering for fault-injection capabilities
This patch provides process filtering feature.
The process filter allows failing only permitted processes
by /proc/<pid>/make-it-fail
Please see the example that demostrates how to inject slab allocation
failures into module init/cleanup code
in Documentation/fault-injection/fault-injection.txt
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs/proc/base.c')
-rw-r--r-- | fs/proc/base.c | 65 |
1 files changed, 65 insertions, 0 deletions
diff --git a/fs/proc/base.c b/fs/proc/base.c index a3b5074118a7..fd959d5b5a80 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c | |||
@@ -853,6 +853,65 @@ static struct file_operations proc_seccomp_operations = { | |||
853 | }; | 853 | }; |
854 | #endif /* CONFIG_SECCOMP */ | 854 | #endif /* CONFIG_SECCOMP */ |
855 | 855 | ||
856 | #ifdef CONFIG_FAULT_INJECTION | ||
857 | static ssize_t proc_fault_inject_read(struct file * file, char __user * buf, | ||
858 | size_t count, loff_t *ppos) | ||
859 | { | ||
860 | struct task_struct *task = get_proc_task(file->f_dentry->d_inode); | ||
861 | char buffer[PROC_NUMBUF]; | ||
862 | size_t len; | ||
863 | int make_it_fail; | ||
864 | loff_t __ppos = *ppos; | ||
865 | |||
866 | if (!task) | ||
867 | return -ESRCH; | ||
868 | make_it_fail = task->make_it_fail; | ||
869 | put_task_struct(task); | ||
870 | |||
871 | len = snprintf(buffer, sizeof(buffer), "%i\n", make_it_fail); | ||
872 | if (__ppos >= len) | ||
873 | return 0; | ||
874 | if (count > len-__ppos) | ||
875 | count = len-__ppos; | ||
876 | if (copy_to_user(buf, buffer + __ppos, count)) | ||
877 | return -EFAULT; | ||
878 | *ppos = __ppos + count; | ||
879 | return count; | ||
880 | } | ||
881 | |||
882 | static ssize_t proc_fault_inject_write(struct file * file, | ||
883 | const char __user * buf, size_t count, loff_t *ppos) | ||
884 | { | ||
885 | struct task_struct *task; | ||
886 | char buffer[PROC_NUMBUF], *end; | ||
887 | int make_it_fail; | ||
888 | |||
889 | if (!capable(CAP_SYS_RESOURCE)) | ||
890 | return -EPERM; | ||
891 | memset(buffer, 0, sizeof(buffer)); | ||
892 | if (count > sizeof(buffer) - 1) | ||
893 | count = sizeof(buffer) - 1; | ||
894 | if (copy_from_user(buffer, buf, count)) | ||
895 | return -EFAULT; | ||
896 | make_it_fail = simple_strtol(buffer, &end, 0); | ||
897 | if (*end == '\n') | ||
898 | end++; | ||
899 | task = get_proc_task(file->f_dentry->d_inode); | ||
900 | if (!task) | ||
901 | return -ESRCH; | ||
902 | task->make_it_fail = make_it_fail; | ||
903 | put_task_struct(task); | ||
904 | if (end - buffer == 0) | ||
905 | return -EIO; | ||
906 | return end - buffer; | ||
907 | } | ||
908 | |||
909 | static struct file_operations proc_fault_inject_operations = { | ||
910 | .read = proc_fault_inject_read, | ||
911 | .write = proc_fault_inject_write, | ||
912 | }; | ||
913 | #endif | ||
914 | |||
856 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) | 915 | static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) |
857 | { | 916 | { |
858 | struct inode *inode = dentry->d_inode; | 917 | struct inode *inode = dentry->d_inode; |
@@ -1793,6 +1852,9 @@ static struct pid_entry tgid_base_stuff[] = { | |||
1793 | #ifdef CONFIG_AUDITSYSCALL | 1852 | #ifdef CONFIG_AUDITSYSCALL |
1794 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 1853 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
1795 | #endif | 1854 | #endif |
1855 | #ifdef CONFIG_FAULT_INJECTION | ||
1856 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | ||
1857 | #endif | ||
1796 | }; | 1858 | }; |
1797 | 1859 | ||
1798 | static int proc_tgid_base_readdir(struct file * filp, | 1860 | static int proc_tgid_base_readdir(struct file * filp, |
@@ -2068,6 +2130,9 @@ static struct pid_entry tid_base_stuff[] = { | |||
2068 | #ifdef CONFIG_AUDITSYSCALL | 2130 | #ifdef CONFIG_AUDITSYSCALL |
2069 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), | 2131 | REG("loginuid", S_IWUSR|S_IRUGO, loginuid), |
2070 | #endif | 2132 | #endif |
2133 | #ifdef CONFIG_FAULT_INJECTION | ||
2134 | REG("make-it-fail", S_IRUGO|S_IWUSR, fault_inject), | ||
2135 | #endif | ||
2071 | }; | 2136 | }; |
2072 | 2137 | ||
2073 | static int proc_tid_base_readdir(struct file * filp, | 2138 | static int proc_tid_base_readdir(struct file * filp, |