5 #include <linux/sysctl.h>
6 #include <linux/poll.h>
9 #include <linux/sched.h>
12 #include <linux/module.h>
38 .default_set.dir.header = {
41 .ctl_table = root_table }},
42 .ctl_table_arg = root_table,
43 .root = &sysctl_table_root,
56 static void sysctl_print_dir(
struct ctl_dir *dir)
59 sysctl_print_dir(dir->
header.parent);
63 static int namecmp(
const char *name1,
int len1,
const char *name2,
int len2)
72 cmp =
memcmp(name1, name2, minlen);
92 ctl_node =
rb_entry(node,
struct ctl_node, node);
97 cmp = namecmp(name, namelen, procname,
strlen(procname));
116 int namelen =
strlen(name);
122 const char *parent_name;
126 parent_node =
rb_entry(parent,
struct ctl_node, node);
127 parent_head = parent_node->
header;
128 parent_entry = &parent_head->
ctl_table[parent_node - parent_head->
node];
129 parent_name = parent_entry->
procname;
131 cmp = namecmp(name, namelen, parent_name,
strlen(parent_name));
138 sysctl_print_dir(head->
parent);
144 rb_link_node(node, parent, p);
172 for (entry = table; entry->
procname; entry++, node++)
181 erase_entry(head, entry);
191 err = insert_links(header);
195 err = insert_entry(header, entry);
201 erase_header(header);
205 drop_sysctl_table(&dir->
header);
235 init_completion(&
wait);
237 spin_unlock(&sysctl_lock);
239 spin_lock(&sysctl_lock);
253 spin_lock(&sysctl_lock);
255 spin_unlock(&sysctl_lock);
260 spin_lock(&sysctl_lock);
263 spin_unlock(&sysctl_lock);
269 spin_lock(&sysctl_lock);
270 if (!use_table(head))
272 spin_unlock(&sysctl_lock);
280 spin_lock(&sysctl_lock);
282 spin_unlock(&sysctl_lock);
290 set = root->
lookup(root, namespaces);
296 const char *name,
int namelen)
301 spin_lock(&sysctl_lock);
302 entry = find_entry(&head, dir, name, namelen);
303 if (entry && use_table(head))
307 spin_unlock(&sysctl_lock);
311 static struct ctl_node *first_usable_entry(
struct rb_node *node)
313 struct ctl_node *ctl_node;
316 ctl_node =
rb_entry(node,
struct ctl_node, node);
317 if (use_table(ctl_node->
header))
323 static void first_entry(
struct ctl_dir *dir,
328 struct ctl_node *ctl_node;
330 spin_lock(&sysctl_lock);
332 spin_unlock(&sysctl_lock);
345 struct ctl_node *ctl_node = &head->
node[entry - head->
ctl_table];
347 spin_lock(&sysctl_lock);
350 ctl_node = first_usable_entry(
rb_next(&ctl_node->
node));
351 spin_unlock(&sysctl_lock);
370 static int test_perm(
int mode,
int op)
390 return test_perm(mode, op);
405 sysctl_head_get(head);
414 inode->
i_op = &proc_sys_inode_operations;
415 inode->
i_fop = &proc_sys_file_operations;
418 inode->
i_op = &proc_sys_dir_operations;
419 inode->
i_fop = &proc_sys_dir_file_operations;
430 return sysctl_head_grab(head);
441 struct dentry *err = ERR_PTR(-
ENOENT);
446 return ERR_CAST(head);
450 p = lookup_entry(&h, ctl_dir, name->
name, name->len);
455 ret = sysctl_follow_link(&h, &p,
current->nsproxy);
462 inode = proc_sys_make_inode(dir->
i_sb, h ? h : head, p);
467 d_set_d_op(dentry, &proc_sys_dentry_operations);
468 d_add(dentry, inode);
472 sysctl_head_finish(h);
473 sysctl_head_finish(head);
477 static ssize_t proc_sys_call_handler(
struct file *filp,
void __user *
buf,
480 struct inode *inode = filp->
f_path.dentry->d_inode;
482 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
487 return PTR_ERR(head);
504 error = table->
proc_handler(table, write, buf, &res, ppos);
508 sysctl_head_finish(head);
513 static ssize_t proc_sys_read(
struct file *filp,
char __user *buf,
514 size_t count, loff_t *ppos)
516 return proc_sys_call_handler(filp, (
void __user *)buf, count, ppos, 0);
519 static ssize_t proc_sys_write(
struct file *filp,
const char __user *buf,
520 size_t count, loff_t *ppos)
522 return proc_sys_call_handler(filp, (
void __user *)buf, count, ppos, 1);
525 static int proc_sys_open(
struct inode *inode,
struct file *filp)
528 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
532 return PTR_ERR(head);
537 sysctl_head_finish(head);
544 struct inode *inode = filp->
f_path.dentry->d_inode;
546 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
561 poll_wait(filp, &table->
poll->wait, wait);
569 sysctl_head_finish(head);
574 static int proc_sys_fill_cache(
struct file *filp,
void *
dirent,
593 inode = proc_sys_make_inode(dir->
d_sb, head, table);
598 d_set_d_op(child, &proc_sys_dentry_operations);
607 type = inode->
i_mode >> 12;
609 return !!filldir(dirent, qname.name, qname.len, filp->
f_pos, ino, type);
612 static int proc_sys_link_fill_cache(
struct file *filp,
void *dirent,
618 head = sysctl_head_grab(head);
622 err = sysctl_follow_link(&head, &table,
current->nsproxy);
627 ret = proc_sys_fill_cache(filp, dirent, filldir, head, table);
629 sysctl_head_finish(head);
639 if ((*pos)++ < file->
f_pos)
643 res = proc_sys_link_fill_cache(file, dirent, filldir, head, table);
645 res = proc_sys_fill_cache(file, dirent, filldir, head, table);
653 static int proc_sys_readdir(
struct file *filp,
void *dirent,
filldir_t filldir)
655 struct dentry *dentry = filp->
f_path.dentry;
656 struct inode *inode = dentry->
d_inode;
660 struct ctl_dir *ctl_dir;
665 return PTR_ERR(head);
671 if (filp->
f_pos == 0) {
672 if (filldir(dirent,
".", 1, filp->
f_pos,
677 if (filp->
f_pos == 1) {
678 if (filldir(dirent,
"..", 2, filp->
f_pos,
685 for (first_entry(ctl_dir, &h, &entry);
h; next_entry(&h, &entry)) {
686 ret =
scan(h, entry, &pos, filp, dirent, filldir);
688 sysctl_head_finish(h);
694 sysctl_head_finish(head);
698 static int proc_sys_permission(
struct inode *inode,
int mask)
712 head = grab_header(inode);
714 return PTR_ERR(head);
716 table = PROC_I(inode)->sysctl_entry;
722 sysctl_head_finish(head);
726 static int proc_sys_setattr(
struct dentry *dentry,
struct iattr *
attr)
728 struct inode *inode = dentry->
d_inode;
739 attr->
ia_size != i_size_read(inode)) {
746 mark_inode_dirty(inode);
750 static int proc_sys_getattr(
struct vfsmount *mnt,
struct dentry *dentry,
struct kstat *
stat)
752 struct inode *inode = dentry->
d_inode;
754 struct ctl_table *table = PROC_I(inode)->sysctl_entry;
757 return PTR_ERR(head);
763 sysctl_head_finish(head);
768 .open = proc_sys_open,
769 .poll = proc_sys_poll,
770 .read = proc_sys_read,
771 .write = proc_sys_write,
777 .readdir = proc_sys_readdir,
782 .permission = proc_sys_permission,
783 .setattr = proc_sys_setattr,
784 .getattr = proc_sys_getattr,
788 .lookup = proc_sys_lookup,
789 .permission = proc_sys_permission,
790 .setattr = proc_sys_setattr,
791 .getattr = proc_sys_getattr,
794 static int proc_sys_revalidate(
struct dentry *dentry,
unsigned int flags)
798 return !PROC_I(dentry->
d_inode)->sysctl->unregistering;
801 static int proc_sys_delete(
const struct dentry *dentry)
803 return !!PROC_I(dentry->
d_inode)->sysctl->unregistering;
810 spin_lock(&sysctl_lock);
813 else if (!
set->is_seen)
816 res =
set->is_seen(
set);
817 spin_unlock(&sysctl_lock);
821 static int proc_sys_compare(
const struct dentry *parent,
822 const struct inode *pinode,
823 const struct dentry *dentry,
const struct inode *inode,
824 unsigned int len,
const char *
str,
const struct qstr *name)
832 if (name->len != len)
837 return !head || !sysctl_is_seen(head);
841 .d_revalidate = proc_sys_revalidate,
842 .d_delete = proc_sys_delete,
843 .d_compare = proc_sys_compare,
846 static struct ctl_dir *find_subdir(
struct ctl_dir *dir,
847 const char *name,
int namelen)
852 entry = find_entry(&head, dir, name, namelen);
861 const char *name,
int namelen)
865 struct ctl_node *
node;
868 new = kzalloc(
sizeof(*
new) +
sizeof(
struct ctl_node) +
869 sizeof(
struct ctl_table)*2 + namelen + 1,
874 node = (
struct ctl_node *)(
new + 1);
876 new_name = (
char *)(table + 2);
877 memcpy(new_name, name, namelen);
881 init_header(&new->header,
set->dir.header.root,
set, node, table);
898 static struct ctl_dir *get_subdir(
struct ctl_dir *dir,
899 const char *name,
int namelen)
902 struct ctl_dir *subdir, *
new =
NULL;
905 spin_lock(&sysctl_lock);
906 subdir = find_subdir(dir, name, namelen);
909 if (PTR_ERR(subdir) != -
ENOENT)
912 spin_unlock(&sysctl_lock);
913 new = new_dir(
set, name, namelen);
914 spin_lock(&sysctl_lock);
915 subdir = ERR_PTR(-
ENOMEM);
920 subdir = find_subdir(dir, name, namelen);
923 if (PTR_ERR(subdir) != -
ENOENT)
927 err = insert_header(dir, &new->
header);
928 subdir = ERR_PTR(err);
937 sysctl_print_dir(dir);
939 namelen, namelen, name, PTR_ERR(subdir));
941 drop_sysctl_table(&dir->
header);
943 drop_sysctl_table(&new->header);
944 spin_unlock(&sysctl_lock);
948 static struct ctl_dir *xlate_dir(
struct ctl_table_set *
set,
struct ctl_dir *dir)
950 struct ctl_dir *parent;
951 const char *procname;
954 parent = xlate_dir(
set, dir->
header.parent);
957 procname = dir->
header.ctl_table[0].procname;
958 return find_subdir(parent, procname,
strlen(procname));
972 spin_lock(&sysctl_lock);
973 root = (*pentry)->data;
974 set = lookup_header_set(root, namespaces);
975 dir = xlate_dir(
set, (*phead)->parent);
979 const char *procname = (*pentry)->procname;
981 entry = find_entry(&head, dir, procname,
strlen(procname));
983 if (entry && use_table(head)) {
991 spin_unlock(&sysctl_lock);
995 static int sysctl_err(
const char *
path,
struct ctl_table *table,
char *
fmt, ...)
1011 static int sysctl_check_table(
const char *
path,
struct ctl_table *table)
1016 err = sysctl_err(path, table,
"Not a file");
1027 err = sysctl_err(path, table,
"No data");
1029 err = sysctl_err(path, table,
"No maxlen");
1032 err = sysctl_err(path, table,
"No proc_handler");
1035 err = sysctl_err(path, table,
"bogus .mode 0%o",
1046 struct ctl_node *
node;
1048 int nr_entries, name_bytes;
1052 for (entry = table; entry->
procname; entry++) {
1058 sizeof(
struct ctl_node)*nr_entries +
1059 sizeof(
struct ctl_table)*(nr_entries + 1) +
1066 node = (
struct ctl_node *)(links + 1);
1067 link_table = (
struct ctl_table *)(node + nr_entries);
1068 link_name = (
char *)&link_table[nr_entries + 1];
1070 for (link = link_table, entry = table; entry->
procname; link++, entry++) {
1075 link->
data = link_root;
1078 init_header(links, dir->
header.root, dir->
header.set, node, link_table);
1079 links->
nreg = nr_entries;
1084 static bool get_links(
struct ctl_dir *dir,
1091 for (entry = table; entry->
procname; entry++) {
1092 const char *procname = entry->
procname;
1093 link = find_entry(&head, dir, procname,
strlen(procname));
1104 for (entry = table; entry->
procname; entry++) {
1105 const char *procname = entry->
procname;
1106 link = find_entry(&head, dir, procname,
strlen(procname));
1115 struct ctl_dir *core_parent =
NULL;
1119 if (head->
set == root_set)
1122 core_parent = xlate_dir(root_set, head->
parent);
1123 if (IS_ERR(core_parent))
1129 core_parent->
header.nreg++;
1130 spin_unlock(&sysctl_lock);
1132 links = new_links(core_parent, head->
ctl_table, head->
root);
1134 spin_lock(&sysctl_lock);
1145 err = insert_header(core_parent, links);
1149 drop_sysctl_table(&core_parent->
header);
1197 const char *path,
struct ctl_table *table)
1201 const char *
name, *nextname;
1202 struct ctl_dir *dir;
1204 struct ctl_node *
node;
1207 for (entry = table; entry->
procname; entry++)
1211 sizeof(
struct ctl_node)*nr_entries,
GFP_KERNEL);
1215 node = (
struct ctl_node *)(header + 1);
1216 init_header(header, root,
set, node, table);
1217 if (sysctl_check_table(path, table))
1220 spin_lock(&sysctl_lock);
1224 spin_unlock(&sysctl_lock);
1227 for (name = path;
name; name = nextname) {
1229 nextname =
strchr(name,
'/');
1231 namelen = nextname -
name;
1239 dir = get_subdir(dir, name, namelen);
1244 spin_lock(&sysctl_lock);
1245 if (insert_header(dir, header))
1246 goto fail_put_dir_locked;
1248 drop_sysctl_table(&dir->
header);
1249 spin_unlock(&sysctl_lock);
1253 fail_put_dir_locked:
1254 drop_sysctl_table(&dir->
header);
1255 spin_unlock(&sysctl_lock);
1279 static char *append_path(
const char *path,
char *pos,
const char *name)
1283 if (((pos - path) + namelen + 2) >=
PATH_MAX)
1285 memcpy(pos, name, namelen);
1287 pos[namelen + 1] =
'\0';
1292 static int count_subheaders(
struct ctl_table *table)
1295 int nr_subheaders = 0;
1302 for (entry = table; entry->
procname; entry++) {
1304 nr_subheaders += count_subheaders(entry->
child);
1308 return nr_subheaders + has_files;
1311 static int register_leaf_sysctl_tables(
const char *path,
char *pos,
1321 for (entry = table; entry->
procname; entry++) {
1330 if (nr_dirs && nr_files) {
1332 files = kzalloc(
sizeof(
struct ctl_table) * (nr_files + 1),
1337 ctl_table_arg =
files;
1338 for (
new = files, entry = table; entry->
procname; entry++) {
1347 if (nr_files || !nr_dirs) {
1351 kfree(ctl_table_arg);
1357 **subheader = header;
1362 for (entry = table; entry->
procname; entry++) {
1369 child_pos = append_path(path, pos, entry->
procname);
1373 err = register_leaf_sysctl_tables(path, child_pos, subheader,
1401 int nr_subheaders = count_subheaders(table);
1404 char *new_path, *
pos;
1411 for (component = path; component->
procname; component++) {
1412 pos = append_path(new_path, pos, component->
procname);
1417 pos = append_path(new_path, pos, table->
procname);
1420 table = table->
child;
1422 if (nr_subheaders == 1) {
1427 header = kzalloc(
sizeof(*header) +
1428 sizeof(*subheaders)*nr_subheaders,
GFP_KERNEL);
1433 subheader = subheaders;
1436 if (register_leaf_sysctl_tables(new_path, pos, &subheader,
1438 goto err_register_leaves;
1445 err_register_leaves:
1446 while (subheader > subheaders) {
1486 static const struct ctl_path null_path[] = { {} };
1496 struct ctl_dir *parent = header->
parent;
1497 struct ctl_dir *core_parent;
1500 if (header->
set == root_set)
1503 core_parent = xlate_dir(root_set, parent);
1504 if (IS_ERR(core_parent))
1510 const char *name = entry->
procname;
1512 link = find_entry(&link_head, core_parent, name,
strlen(name));
1516 drop_sysctl_table(link_head);
1520 sysctl_print_dir(parent);
1528 struct ctl_dir *parent = header->
parent;
1534 start_unregistering(header);
1535 if (!--header->
count)
1539 drop_sysctl_table(&parent->
header);
1563 for (i = nr_subheaders -1; i >= 0; i--) {
1573 spin_lock(&sysctl_lock);
1574 drop_sysctl_table(header);
1575 spin_unlock(&sysctl_lock);
1583 memset(
set, 0,
sizeof(*
set));
1584 set->is_seen = is_seen;
1585 init_header(&
set->dir.header, root,
set,
NULL, root_table);
1598 proc_sys_root->
proc_iops = &proc_sys_dir_operations;
1599 proc_sys_root->
proc_fops = &proc_sys_dir_file_operations;
1600 proc_sys_root->
nlink = 0;
1602 return sysctl_init();