diff options
author | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-15 08:54:06 -0400 |
---|---|---|
committer | Al Viro <viro@zeniv.linux.org.uk> | 2008-07-26 20:53:12 -0400 |
commit | 9043476f726802f4b00c96d0c4f418dde48d1304 (patch) | |
tree | 9ead0294bc75e219c12b44fc7eb8996248400f2a /kernel | |
parent | ae7edecc9b8810770a8e5cb9a466ea4bdcfa8401 (diff) |
[PATCH] sanitize proc_sysctl
* keep references to ctl_table_head and ctl_table in /proc/sys inodes
* grab the former during operations, use the latter for access to
entry if that succeeds
* have ->d_compare() check if table should be seen for one who does lookup;
that allows us to avoid flipping inodes - if we have the same name resolve
to different things, we'll just keep several dentries and ->d_compare()
will reject the wrong ones.
* have ->lookup() and ->readdir() scan the table of our inode first, then
walk all ctl_table_header and scan ->attached_by for those that are
attached to our directory.
* implement ->getattr().
* get rid of insane amounts of tree-walking
* get rid of the need to know dentry in ->permission() and of the contortions
induced by that.
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/sysctl.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/kernel/sysctl.c b/kernel/sysctl.c index c9a0af887033..ff5abcca5ddf 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c | |||
@@ -1932,6 +1932,21 @@ void unregister_sysctl_table(struct ctl_table_header * header) | |||
1932 | spin_unlock(&sysctl_lock); | 1932 | spin_unlock(&sysctl_lock); |
1933 | } | 1933 | } |
1934 | 1934 | ||
1935 | int sysctl_is_seen(struct ctl_table_header *p) | ||
1936 | { | ||
1937 | struct ctl_table_set *set = p->set; | ||
1938 | int res; | ||
1939 | spin_lock(&sysctl_lock); | ||
1940 | if (p->unregistering) | ||
1941 | res = 0; | ||
1942 | else if (!set->is_seen) | ||
1943 | res = 1; | ||
1944 | else | ||
1945 | res = set->is_seen(set); | ||
1946 | spin_unlock(&sysctl_lock); | ||
1947 | return res; | ||
1948 | } | ||
1949 | |||
1935 | void setup_sysctl_set(struct ctl_table_set *p, | 1950 | void setup_sysctl_set(struct ctl_table_set *p, |
1936 | struct ctl_table_set *parent, | 1951 | struct ctl_table_set *parent, |
1937 | int (*is_seen)(struct ctl_table_set *)) | 1952 | int (*is_seen)(struct ctl_table_set *)) |