X-Git-Url: https://err.no/cgi-bin/gitweb.cgi?a=blobdiff_plain;f=fs%2Fproc%2Fproc_sysctl.c;h=5acc001d49f6c72db83216173136701c2169f950;hb=f74d505b58d36ceeef10e459094f0eb760681165;hp=4e57fcf85982f648ec29f7c0962a1cebae990388;hpb=8c56a347c1dfbe384b1ffb65d8828faa36dbaea4;p=linux-2.6 diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index 4e57fcf859..5acc001d49 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c @@ -9,7 +9,7 @@ static struct dentry_operations proc_sys_dentry_operations; static const struct file_operations proc_sys_file_operations; -static struct inode_operations proc_sys_inode_operations; +static const struct inode_operations proc_sys_inode_operations; static void proc_sys_refresh_inode(struct inode *inode, struct ctl_table *table) { @@ -165,8 +165,8 @@ out: return err; } -static ssize_t proc_sys_read(struct file *filp, char __user *buf, - size_t count, loff_t *ppos) +static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, + size_t count, loff_t *ppos, int write) { struct dentry *dentry = filp->f_dentry; struct ctl_table_header *head; @@ -190,12 +190,12 @@ static ssize_t proc_sys_read(struct file *filp, char __user *buf, * and won't be until we finish. */ error = -EPERM; - if (sysctl_perm(table, MAY_READ)) + if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ)) goto out; /* careful: calling conventions are nasty here */ res = count; - error = table->proc_handler(table, 0, filp, buf, &res, ppos); + error = table->proc_handler(table, write, filp, buf, &res, ppos); if (!error) error = res; out: @@ -204,44 +204,16 @@ out: return error; } -static ssize_t proc_sys_write(struct file *filp, const char __user *buf, +static ssize_t proc_sys_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { - struct dentry *dentry = filp->f_dentry; - struct ctl_table_header *head; - struct ctl_table *table; - ssize_t error; - size_t res; - - table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); - /* Has the sysctl entry disappeared on us? */ - error = -ENOENT; - if (!table) - goto out; - - /* Has the sysctl entry been replaced by a directory? */ - error = -EISDIR; - if (!table->proc_handler) - goto out; - - /* - * At this point we know that the sysctl was not unregistered - * and won't be until we finish. - */ - error = -EPERM; - if (sysctl_perm(table, MAY_WRITE)) - goto out; - - /* careful: calling conventions are nasty here */ - res = count; - error = table->proc_handler(table, 1, filp, (char __user *)buf, - &res, ppos); - if (!error) - error = res; -out: - sysctl_head_finish(head); + return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 0); +} - return error; +static ssize_t proc_sys_write(struct file *filp, const char __user *buf, + size_t count, loff_t *ppos) +{ + return proc_sys_call_handler(filp, (void __user *)buf, count, ppos, 1); } @@ -407,7 +379,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata * if (!nd || !depth) goto out; - dentry = nd->dentry; + dentry = nd->path.dentry; table = do_proc_sys_lookup(dentry->d_parent, &dentry->d_name, &head); /* If the entry does not exist deny permission */ @@ -416,7 +388,7 @@ static int proc_sys_permission(struct inode *inode, int mask, struct nameidata * goto out; /* Use the permissions on the sysctl table entry */ - error = sysctl_perm(table, mask); + error = sysctl_perm(head->root, table, mask); out: sysctl_head_finish(head); return error; @@ -446,7 +418,7 @@ static const struct file_operations proc_sys_file_operations = { .readdir = proc_sys_readdir, }; -static struct inode_operations proc_sys_inode_operations = { +static const struct inode_operations proc_sys_inode_operations = { .lookup = proc_sys_lookup, .permission = proc_sys_permission, .setattr = proc_sys_setattr,