LCOV - code coverage report
Current view: top level - fs/proc - proc_sysctl.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 644 1001 64.3 %
Date: 2021-04-22 12:43:58 Functions: 47 65 72.3 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0
       2             : /*
       3             :  * /proc/sys support
       4             :  */
       5             : #include <linux/init.h>
       6             : #include <linux/sysctl.h>
       7             : #include <linux/poll.h>
       8             : #include <linux/proc_fs.h>
       9             : #include <linux/printk.h>
      10             : #include <linux/security.h>
      11             : #include <linux/sched.h>
      12             : #include <linux/cred.h>
      13             : #include <linux/namei.h>
      14             : #include <linux/mm.h>
      15             : #include <linux/uio.h>
      16             : #include <linux/module.h>
      17             : #include <linux/bpf-cgroup.h>
      18             : #include <linux/mount.h>
      19             : #include "internal.h"
      20             : 
      21             : static const struct dentry_operations proc_sys_dentry_operations;
      22             : static const struct file_operations proc_sys_file_operations;
      23             : static const struct inode_operations proc_sys_inode_operations;
      24             : static const struct file_operations proc_sys_dir_file_operations;
      25             : static const struct inode_operations proc_sys_dir_operations;
      26             : 
      27             : /* shared constants to be used in various sysctls */
      28             : const int sysctl_vals[] = { 0, 1, INT_MAX };
      29             : EXPORT_SYMBOL(sysctl_vals);
      30             : 
      31             : /* Support for permanently empty directories */
      32             : 
      33             : struct ctl_table sysctl_mount_point[] = {
      34             :         { }
      35             : };
      36             : 
      37          84 : static bool is_empty_dir(struct ctl_table_header *head)
      38             : {
      39          84 :         return head->ctl_table[0].child == sysctl_mount_point;
      40             : }
      41             : 
      42           0 : static void set_empty_dir(struct ctl_dir *dir)
      43             : {
      44           0 :         dir->header.ctl_table[0].child = sysctl_mount_point;
      45           0 : }
      46             : 
      47           0 : static void clear_empty_dir(struct ctl_dir *dir)
      48             : 
      49             : {
      50           0 :         dir->header.ctl_table[0].child = NULL;
      51           0 : }
      52             : 
      53           1 : void proc_sys_poll_notify(struct ctl_table_poll *poll)
      54             : {
      55           1 :         if (!poll)
      56             :                 return;
      57             : 
      58           1 :         atomic_inc(&poll->event);
      59           1 :         wake_up_interruptible(&poll->wait);
      60             : }
      61             : 
      62             : static struct ctl_table root_table[] = {
      63             :         {
      64             :                 .procname = "",
      65             :                 .mode = S_IFDIR|S_IRUGO|S_IXUGO,
      66             :         },
      67             :         { }
      68             : };
      69             : static struct ctl_table_root sysctl_table_root = {
      70             :         .default_set.dir.header = {
      71             :                 {{.count = 1,
      72             :                   .nreg = 1,
      73             :                   .ctl_table = root_table }},
      74             :                 .ctl_table_arg = root_table,
      75             :                 .root = &sysctl_table_root,
      76             :                 .set = &sysctl_table_root.default_set,
      77             :         },
      78             : };
      79             : 
      80             : static DEFINE_SPINLOCK(sysctl_lock);
      81             : 
      82             : static void drop_sysctl_table(struct ctl_table_header *header);
      83             : static int sysctl_follow_link(struct ctl_table_header **phead,
      84             :         struct ctl_table **pentry);
      85             : static int insert_links(struct ctl_table_header *head);
      86             : static void put_links(struct ctl_table_header *header);
      87             : 
      88           0 : static void sysctl_print_dir(struct ctl_dir *dir)
      89             : {
      90           0 :         if (dir->header.parent)
      91           0 :                 sysctl_print_dir(dir->header.parent);
      92           0 :         pr_cont("%s/", dir->header.ctl_table[0].procname);
      93           0 : }
      94             : 
      95        2692 : static int namecmp(const char *name1, int len1, const char *name2, int len2)
      96             : {
      97        2692 :         int minlen;
      98        2692 :         int cmp;
      99             : 
     100        2692 :         minlen = len1;
     101        2692 :         if (minlen > len2)
     102             :                 minlen = len2;
     103             : 
     104        2692 :         cmp = memcmp(name1, name2, minlen);
     105        2692 :         if (cmp == 0)
     106         183 :                 cmp = len1 - len2;
     107        2692 :         return cmp;
     108             : }
     109             : 
     110             : /* Called under sysctl_lock */
     111         222 : static struct ctl_table *find_entry(struct ctl_table_header **phead,
     112             :         struct ctl_dir *dir, const char *name, int namelen)
     113             : {
     114         222 :         struct ctl_table_header *head;
     115         222 :         struct ctl_table *entry;
     116         222 :         struct rb_node *node = dir->root.rb_node;
     117             : 
     118         521 :         while (node)
     119             :         {
     120         440 :                 struct ctl_node *ctl_node;
     121         440 :                 const char *procname;
     122         440 :                 int cmp;
     123             : 
     124         440 :                 ctl_node = rb_entry(node, struct ctl_node, node);
     125         440 :                 head = ctl_node->header;
     126         440 :                 entry = &head->ctl_table[ctl_node - head->node];
     127         440 :                 procname = entry->procname;
     128             : 
     129         440 :                 cmp = namecmp(name, namelen, procname, strlen(procname));
     130         440 :                 if (cmp < 0)
     131         153 :                         node = node->rb_left;
     132         287 :                 else if (cmp > 0)
     133         146 :                         node = node->rb_right;
     134             :                 else {
     135         141 :                         *phead = head;
     136         141 :                         return entry;
     137             :                 }
     138             :         }
     139             :         return NULL;
     140             : }
     141             : 
     142         571 : static int insert_entry(struct ctl_table_header *head, struct ctl_table *entry)
     143             : {
     144         571 :         struct rb_node *node = &head->node[entry - head->ctl_table].node;
     145         571 :         struct rb_node **p = &head->parent->root.rb_node;
     146         571 :         struct rb_node *parent = NULL;
     147         571 :         const char *name = entry->procname;
     148         571 :         int namelen = strlen(name);
     149             : 
     150        2823 :         while (*p) {
     151        2252 :                 struct ctl_table_header *parent_head;
     152        2252 :                 struct ctl_table *parent_entry;
     153        2252 :                 struct ctl_node *parent_node;
     154        2252 :                 const char *parent_name;
     155        2252 :                 int cmp;
     156             : 
     157        2252 :                 parent = *p;
     158        2252 :                 parent_node = rb_entry(parent, struct ctl_node, node);
     159        2252 :                 parent_head = parent_node->header;
     160        2252 :                 parent_entry = &parent_head->ctl_table[parent_node - parent_head->node];
     161        2252 :                 parent_name = parent_entry->procname;
     162             : 
     163        2252 :                 cmp = namecmp(name, namelen, parent_name, strlen(parent_name));
     164        2252 :                 if (cmp < 0)
     165        1083 :                         p = &(*p)->rb_left;
     166        1169 :                 else if (cmp > 0)
     167        1169 :                         p = &(*p)->rb_right;
     168             :                 else {
     169           0 :                         pr_err("sysctl duplicate entry: ");
     170           0 :                         sysctl_print_dir(head->parent);
     171           0 :                         pr_cont("/%s\n", entry->procname);
     172           0 :                         return -EEXIST;
     173             :                 }
     174             :         }
     175             : 
     176         571 :         rb_link_node(node, parent, p);
     177         571 :         rb_insert_color(node, &head->parent->root);
     178         571 :         return 0;
     179             : }
     180             : 
     181           0 : static void erase_entry(struct ctl_table_header *head, struct ctl_table *entry)
     182             : {
     183           0 :         struct rb_node *node = &head->node[entry - head->ctl_table].node;
     184             : 
     185           0 :         rb_erase(node, &head->parent->root);
     186           0 : }
     187             : 
     188          80 : static void init_header(struct ctl_table_header *head,
     189             :         struct ctl_table_root *root, struct ctl_table_set *set,
     190             :         struct ctl_node *node, struct ctl_table *table)
     191             : {
     192          80 :         head->ctl_table = table;
     193          80 :         head->ctl_table_arg = table;
     194          80 :         head->used = 0;
     195          80 :         head->count = 1;
     196          80 :         head->nreg = 1;
     197          80 :         head->unregistering = NULL;
     198          80 :         head->root = root;
     199          80 :         head->set = set;
     200          80 :         head->parent = NULL;
     201          80 :         head->node = node;
     202          80 :         INIT_HLIST_HEAD(&head->inodes);
     203          78 :         if (node) {
     204             :                 struct ctl_table *entry;
     205         649 :                 for (entry = table; entry->procname; entry++, node++)
     206         571 :                         node->header = head;
     207             :         }
     208          78 : }
     209             : 
     210           0 : static void erase_header(struct ctl_table_header *head)
     211             : {
     212           0 :         struct ctl_table *entry;
     213           0 :         for (entry = head->ctl_table; entry->procname; entry++)
     214           0 :                 erase_entry(head, entry);
     215           0 : }
     216             : 
     217          78 : static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
     218             : {
     219          78 :         struct ctl_table *entry;
     220          78 :         int err;
     221             : 
     222             :         /* Is this a permanently empty directory? */
     223          78 :         if (is_empty_dir(&dir->header))
     224             :                 return -EROFS;
     225             : 
     226             :         /* Am I creating a permanently empty directory? */
     227          78 :         if (header->ctl_table == sysctl_mount_point) {
     228           0 :                 if (!RB_EMPTY_ROOT(&dir->root))
     229             :                         return -EINVAL;
     230           0 :                 set_empty_dir(dir);
     231             :         }
     232             : 
     233          78 :         dir->header.nreg++;
     234          78 :         header->parent = dir;
     235          78 :         err = insert_links(header);
     236          78 :         if (err)
     237           0 :                 goto fail_links;
     238         649 :         for (entry = header->ctl_table; entry->procname; entry++) {
     239         571 :                 err = insert_entry(header, entry);
     240         571 :                 if (err)
     241           0 :                         goto fail;
     242             :         }
     243             :         return 0;
     244           0 : fail:
     245           0 :         erase_header(header);
     246           0 :         put_links(header);
     247           0 : fail_links:
     248           0 :         if (header->ctl_table == sysctl_mount_point)
     249           0 :                 clear_empty_dir(dir);
     250           0 :         header->parent = NULL;
     251           0 :         drop_sysctl_table(&dir->header);
     252           0 :         return err;
     253             : }
     254             : 
     255             : /* called under sysctl_lock */
     256         321 : static int use_table(struct ctl_table_header *p)
     257             : {
     258         321 :         if (unlikely(p->unregistering))
     259             :                 return 0;
     260         321 :         p->used++;
     261         321 :         return 1;
     262             : }
     263             : 
     264             : /* called under sysctl_lock */
     265         321 : static void unuse_table(struct ctl_table_header *p)
     266             : {
     267         321 :         if (!--p->used)
     268         321 :                 if (unlikely(p->unregistering))
     269           0 :                         complete(p->unregistering);
     270         321 : }
     271             : 
     272           0 : static void proc_sys_invalidate_dcache(struct ctl_table_header *head)
     273             : {
     274           0 :         proc_invalidate_siblings_dcache(&head->inodes, &sysctl_lock);
     275             : }
     276             : 
     277             : /* called under sysctl_lock, will reacquire if has to wait */
     278           0 : static void start_unregistering(struct ctl_table_header *p)
     279             : {
     280             :         /*
     281             :          * if p->used is 0, nobody will ever touch that entry again;
     282             :          * we'll eliminate all paths to it before dropping sysctl_lock
     283             :          */
     284           0 :         if (unlikely(p->used)) {
     285           0 :                 struct completion wait;
     286           0 :                 init_completion(&wait);
     287           0 :                 p->unregistering = &wait;
     288           0 :                 spin_unlock(&sysctl_lock);
     289           0 :                 wait_for_completion(&wait);
     290             :         } else {
     291             :                 /* anything non-NULL; we'll never dereference it */
     292           0 :                 p->unregistering = ERR_PTR(-EINVAL);
     293           0 :                 spin_unlock(&sysctl_lock);
     294             :         }
     295             :         /*
     296             :          * Invalidate dentries for unregistered sysctls: namespaced sysctls
     297             :          * can have duplicate names and contaminate dcache very badly.
     298             :          */
     299           0 :         proc_sys_invalidate_dcache(p);
     300             :         /*
     301             :          * do not remove from the list until nobody holds it; walking the
     302             :          * list in do_sysctl() relies on that.
     303             :          */
     304           0 :         spin_lock(&sysctl_lock);
     305           0 :         erase_header(p);
     306           0 : }
     307             : 
     308         300 : static struct ctl_table_header *sysctl_head_grab(struct ctl_table_header *head)
     309             : {
     310         300 :         BUG_ON(!head);
     311         300 :         spin_lock(&sysctl_lock);
     312         300 :         if (!use_table(head))
     313         300 :                 head = ERR_PTR(-ENOENT);
     314         300 :         spin_unlock(&sysctl_lock);
     315         300 :         return head;
     316             : }
     317             : 
     318         320 : static void sysctl_head_finish(struct ctl_table_header *head)
     319             : {
     320         320 :         if (!head)
     321             :                 return;
     322         320 :         spin_lock(&sysctl_lock);
     323         320 :         unuse_table(head);
     324         320 :         spin_unlock(&sysctl_lock);
     325             : }
     326             : 
     327             : static struct ctl_table_set *
     328           1 : lookup_header_set(struct ctl_table_root *root)
     329             : {
     330           1 :         struct ctl_table_set *set = &root->default_set;
     331           1 :         if (root->lookup)
     332           1 :                 set = root->lookup(root);
     333           1 :         return set;
     334             : }
     335             : 
     336          23 : static struct ctl_table *lookup_entry(struct ctl_table_header **phead,
     337             :                                       struct ctl_dir *dir,
     338             :                                       const char *name, int namelen)
     339             : {
     340          23 :         struct ctl_table_header *head;
     341          23 :         struct ctl_table *entry;
     342             : 
     343          23 :         spin_lock(&sysctl_lock);
     344          23 :         entry = find_entry(&head, dir, name, namelen);
     345          23 :         if (entry && use_table(head))
     346          20 :                 *phead = head;
     347             :         else
     348             :                 entry = NULL;
     349          23 :         spin_unlock(&sysctl_lock);
     350          23 :         return entry;
     351             : }
     352             : 
     353           0 : static struct ctl_node *first_usable_entry(struct rb_node *node)
     354             : {
     355           0 :         struct ctl_node *ctl_node;
     356             : 
     357           0 :         for (;node; node = rb_next(node)) {
     358           0 :                 ctl_node = rb_entry(node, struct ctl_node, node);
     359           0 :                 if (use_table(ctl_node->header))
     360           0 :                         return ctl_node;
     361             :         }
     362             :         return NULL;
     363             : }
     364             : 
     365           0 : static void first_entry(struct ctl_dir *dir,
     366             :         struct ctl_table_header **phead, struct ctl_table **pentry)
     367             : {
     368           0 :         struct ctl_table_header *head = NULL;
     369           0 :         struct ctl_table *entry = NULL;
     370           0 :         struct ctl_node *ctl_node;
     371             : 
     372           0 :         spin_lock(&sysctl_lock);
     373           0 :         ctl_node = first_usable_entry(rb_first(&dir->root));
     374           0 :         spin_unlock(&sysctl_lock);
     375           0 :         if (ctl_node) {
     376           0 :                 head = ctl_node->header;
     377           0 :                 entry = &head->ctl_table[ctl_node - head->node];
     378             :         }
     379           0 :         *phead = head;
     380           0 :         *pentry = entry;
     381           0 : }
     382             : 
     383           0 : static void next_entry(struct ctl_table_header **phead, struct ctl_table **pentry)
     384             : {
     385           0 :         struct ctl_table_header *head = *phead;
     386           0 :         struct ctl_table *entry = *pentry;
     387           0 :         struct ctl_node *ctl_node = &head->node[entry - head->ctl_table];
     388             : 
     389           0 :         spin_lock(&sysctl_lock);
     390           0 :         unuse_table(head);
     391             : 
     392           0 :         ctl_node = first_usable_entry(rb_next(&ctl_node->node));
     393           0 :         spin_unlock(&sysctl_lock);
     394           0 :         head = NULL;
     395           0 :         if (ctl_node) {
     396           0 :                 head = ctl_node->header;
     397           0 :                 entry = &head->ctl_table[ctl_node - head->node];
     398             :         }
     399           0 :         *phead = head;
     400           0 :         *pentry = entry;
     401           0 : }
     402             : 
     403             : /*
     404             :  * sysctl_perm does NOT grant the superuser all rights automatically, because
     405             :  * some sysctl variables are readonly even to root.
     406             :  */
     407             : 
     408         165 : static int test_perm(int mode, int op)
     409             : {
     410         165 :         if (uid_eq(current_euid(), GLOBAL_ROOT_UID))
     411         160 :                 mode >>= 6;
     412           5 :         else if (in_egroup_p(GLOBAL_ROOT_GID))
     413           0 :                 mode >>= 3;
     414         165 :         if ((op & ~mode & (MAY_READ|MAY_WRITE|MAY_EXEC)) == 0)
     415         164 :                 return 0;
     416             :         return -EACCES;
     417             : }
     418             : 
     419         165 : static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, int op)
     420             : {
     421         165 :         struct ctl_table_root *root = head->root;
     422         165 :         int mode;
     423             : 
     424         165 :         if (root->permissions)
     425           7 :                 mode = root->permissions(head, table);
     426             :         else
     427         158 :                 mode = table->mode;
     428             : 
     429         165 :         return test_perm(mode, op);
     430             : }
     431             : 
     432          20 : static struct inode *proc_sys_make_inode(struct super_block *sb,
     433             :                 struct ctl_table_header *head, struct ctl_table *table)
     434             : {
     435          20 :         struct ctl_table_root *root = head->root;
     436          20 :         struct inode *inode;
     437          20 :         struct proc_inode *ei;
     438             : 
     439          20 :         inode = new_inode(sb);
     440          20 :         if (!inode)
     441          20 :                 return ERR_PTR(-ENOMEM);
     442             : 
     443          20 :         inode->i_ino = get_next_ino();
     444             : 
     445          20 :         ei = PROC_I(inode);
     446             : 
     447          20 :         spin_lock(&sysctl_lock);
     448          20 :         if (unlikely(head->unregistering)) {
     449           0 :                 spin_unlock(&sysctl_lock);
     450           0 :                 iput(inode);
     451           0 :                 return ERR_PTR(-ENOENT);
     452             :         }
     453          20 :         ei->sysctl = head;
     454          20 :         ei->sysctl_entry = table;
     455          20 :         hlist_add_head_rcu(&ei->sibling_inodes, &head->inodes);
     456          20 :         head->count++;
     457          20 :         spin_unlock(&sysctl_lock);
     458             : 
     459          20 :         inode->i_mtime = inode->i_atime = inode->i_ctime = current_time(inode);
     460          20 :         inode->i_mode = table->mode;
     461          20 :         if (!S_ISDIR(table->mode)) {
     462          14 :                 inode->i_mode |= S_IFREG;
     463          14 :                 inode->i_op = &proc_sys_inode_operations;
     464          14 :                 inode->i_fop = &proc_sys_file_operations;
     465             :         } else {
     466           6 :                 inode->i_mode |= S_IFDIR;
     467           6 :                 inode->i_op = &proc_sys_dir_operations;
     468           6 :                 inode->i_fop = &proc_sys_dir_file_operations;
     469           6 :                 if (is_empty_dir(head))
     470           0 :                         make_empty_dir_inode(inode);
     471             :         }
     472             : 
     473          20 :         if (root->set_ownership)
     474           2 :                 root->set_ownership(head, table, &inode->i_uid, &inode->i_gid);
     475             :         else {
     476          18 :                 inode->i_uid = GLOBAL_ROOT_UID;
     477          18 :                 inode->i_gid = GLOBAL_ROOT_GID;
     478             :         }
     479             : 
     480             :         return inode;
     481             : }
     482             : 
     483           0 : void proc_sys_evict_inode(struct inode *inode, struct ctl_table_header *head)
     484             : {
     485           0 :         spin_lock(&sysctl_lock);
     486           0 :         hlist_del_init_rcu(&PROC_I(inode)->sibling_inodes);
     487           0 :         if (!--head->count)
     488           0 :                 kfree_rcu(head, rcu);
     489           0 :         spin_unlock(&sysctl_lock);
     490           0 : }
     491             : 
     492         300 : static struct ctl_table_header *grab_header(struct inode *inode)
     493             : {
     494           0 :         struct ctl_table_header *head = PROC_I(inode)->sysctl;
     495         300 :         if (!head)
     496          58 :                 head = &sysctl_table_root.default_set.dir.header;
     497         300 :         return sysctl_head_grab(head);
     498             : }
     499             : 
     500          23 : static struct dentry *proc_sys_lookup(struct inode *dir, struct dentry *dentry,
     501             :                                         unsigned int flags)
     502             : {
     503          23 :         struct ctl_table_header *head = grab_header(dir);
     504          23 :         struct ctl_table_header *h = NULL;
     505          23 :         const struct qstr *name = &dentry->d_name;
     506          23 :         struct ctl_table *p;
     507          23 :         struct inode *inode;
     508          23 :         struct dentry *err = ERR_PTR(-ENOENT);
     509          23 :         struct ctl_dir *ctl_dir;
     510          23 :         int ret;
     511             : 
     512          23 :         if (IS_ERR(head))
     513          23 :                 return ERR_CAST(head);
     514             : 
     515          23 :         ctl_dir = container_of(head, struct ctl_dir, header);
     516             : 
     517          23 :         p = lookup_entry(&h, ctl_dir, name->name, name->len);
     518          23 :         if (!p)
     519           3 :                 goto out;
     520             : 
     521          20 :         if (S_ISLNK(p->mode)) {
     522           1 :                 ret = sysctl_follow_link(&h, &p);
     523           1 :                 err = ERR_PTR(ret);
     524           1 :                 if (ret)
     525           0 :                         goto out;
     526             :         }
     527             : 
     528          40 :         inode = proc_sys_make_inode(dir->i_sb, h ? h : head, p);
     529          20 :         if (IS_ERR(inode)) {
     530           0 :                 err = ERR_CAST(inode);
     531           0 :                 goto out;
     532             :         }
     533             : 
     534          20 :         d_set_d_op(dentry, &proc_sys_dentry_operations);
     535          20 :         err = d_splice_alias(inode, dentry);
     536             : 
     537          23 : out:
     538          23 :         if (h)
     539          20 :                 sysctl_head_finish(h);
     540          23 :         sysctl_head_finish(head);
     541          23 :         return err;
     542             : }
     543             : 
     544          64 : static ssize_t proc_sys_call_handler(struct kiocb *iocb, struct iov_iter *iter,
     545             :                 int write)
     546             : {
     547          64 :         struct inode *inode = file_inode(iocb->ki_filp);
     548          64 :         struct ctl_table_header *head = grab_header(inode);
     549          64 :         struct ctl_table *table = PROC_I(inode)->sysctl_entry;
     550          64 :         size_t count = iov_iter_count(iter);
     551          64 :         char *kbuf;
     552          64 :         ssize_t error;
     553             : 
     554          64 :         if (IS_ERR(head))
     555           0 :                 return PTR_ERR(head);
     556             : 
     557             :         /*
     558             :          * At this point we know that the sysctl was not unregistered
     559             :          * and won't be until we finish.
     560             :          */
     561          64 :         error = -EPERM;
     562         124 :         if (sysctl_perm(head, table, write ? MAY_WRITE : MAY_READ))
     563           0 :                 goto out;
     564             : 
     565             :         /* if that can happen at all, it should be -EINVAL, not -EISDIR */
     566          64 :         error = -EINVAL;
     567          64 :         if (!table->proc_handler)
     568           0 :                 goto out;
     569             : 
     570             :         /* don't even try if the size is too large */
     571          64 :         error = -ENOMEM;
     572          64 :         if (count >= KMALLOC_MAX_SIZE)
     573           0 :                 goto out;
     574          64 :         kbuf = kvzalloc(count + 1, GFP_KERNEL);
     575          64 :         if (!kbuf)
     576           0 :                 goto out;
     577             : 
     578          64 :         if (write) {
     579           4 :                 error = -EFAULT;
     580           8 :                 if (!copy_from_iter_full(kbuf, count, iter))
     581           0 :                         goto out_free_buf;
     582           4 :                 kbuf[count] = '\0';
     583             :         }
     584             : 
     585          64 :         error = BPF_CGROUP_RUN_PROG_SYSCTL(head, table, write, &kbuf, &count,
     586             :                                            &iocb->ki_pos);
     587          64 :         if (error)
     588             :                 goto out_free_buf;
     589             : 
     590             :         /* careful: calling conventions are nasty here */
     591          64 :         error = table->proc_handler(table, write, kbuf, &count, &iocb->ki_pos);
     592          64 :         if (error)
     593           1 :                 goto out_free_buf;
     594             : 
     595          63 :         if (!write) {
     596          60 :                 error = -EFAULT;
     597         120 :                 if (copy_to_iter(kbuf, count, iter) < count)
     598           0 :                         goto out_free_buf;
     599             :         }
     600             : 
     601          63 :         error = count;
     602          64 : out_free_buf:
     603          64 :         kvfree(kbuf);
     604          64 : out:
     605          64 :         sysctl_head_finish(head);
     606             : 
     607          64 :         return error;
     608             : }
     609             : 
     610          60 : static ssize_t proc_sys_read(struct kiocb *iocb, struct iov_iter *iter)
     611             : {
     612          60 :         return proc_sys_call_handler(iocb, iter, 0);
     613             : }
     614             : 
     615           4 : static ssize_t proc_sys_write(struct kiocb *iocb, struct iov_iter *iter)
     616             : {
     617           4 :         return proc_sys_call_handler(iocb, iter, 1);
     618             : }
     619             : 
     620          43 : static int proc_sys_open(struct inode *inode, struct file *filp)
     621             : {
     622          43 :         struct ctl_table_header *head = grab_header(inode);
     623          43 :         struct ctl_table *table = PROC_I(inode)->sysctl_entry;
     624             : 
     625             :         /* sysctl was unregistered */
     626          43 :         if (IS_ERR(head))
     627           0 :                 return PTR_ERR(head);
     628             : 
     629          43 :         if (table->poll)
     630           1 :                 filp->private_data = proc_sys_poll_event(table->poll);
     631             : 
     632          43 :         sysctl_head_finish(head);
     633             : 
     634          43 :         return 0;
     635             : }
     636             : 
     637           1 : static __poll_t proc_sys_poll(struct file *filp, poll_table *wait)
     638             : {
     639           1 :         struct inode *inode = file_inode(filp);
     640           1 :         struct ctl_table_header *head = grab_header(inode);
     641           1 :         struct ctl_table *table = PROC_I(inode)->sysctl_entry;
     642           1 :         __poll_t ret = DEFAULT_POLLMASK;
     643           1 :         unsigned long event;
     644             : 
     645             :         /* sysctl was unregistered */
     646           1 :         if (IS_ERR(head))
     647             :                 return EPOLLERR | EPOLLHUP;
     648             : 
     649           1 :         if (!table->proc_handler)
     650           0 :                 goto out;
     651             : 
     652           1 :         if (!table->poll)
     653           0 :                 goto out;
     654             : 
     655           1 :         event = (unsigned long)filp->private_data;
     656           1 :         poll_wait(filp, &table->poll->wait, wait);
     657             : 
     658           1 :         if (event != atomic_read(&table->poll->event)) {
     659           0 :                 filp->private_data = proc_sys_poll_event(table->poll);
     660           0 :                 ret = EPOLLIN | EPOLLRDNORM | EPOLLERR | EPOLLPRI;
     661             :         }
     662             : 
     663           1 : out:
     664           1 :         sysctl_head_finish(head);
     665             : 
     666           1 :         return ret;
     667             : }
     668             : 
     669           0 : static bool proc_sys_fill_cache(struct file *file,
     670             :                                 struct dir_context *ctx,
     671             :                                 struct ctl_table_header *head,
     672             :                                 struct ctl_table *table)
     673             : {
     674           0 :         struct dentry *child, *dir = file->f_path.dentry;
     675           0 :         struct inode *inode;
     676           0 :         struct qstr qname;
     677           0 :         ino_t ino = 0;
     678           0 :         unsigned type = DT_UNKNOWN;
     679             : 
     680           0 :         qname.name = table->procname;
     681           0 :         qname.len  = strlen(table->procname);
     682           0 :         qname.hash = full_name_hash(dir, qname.name, qname.len);
     683             : 
     684           0 :         child = d_lookup(dir, &qname);
     685           0 :         if (!child) {
     686           0 :                 DECLARE_WAIT_QUEUE_HEAD_ONSTACK(wq);
     687           0 :                 child = d_alloc_parallel(dir, &qname, &wq);
     688           0 :                 if (IS_ERR(child))
     689           0 :                         return false;
     690           0 :                 if (d_in_lookup(child)) {
     691           0 :                         struct dentry *res;
     692           0 :                         inode = proc_sys_make_inode(dir->d_sb, head, table);
     693           0 :                         if (IS_ERR(inode)) {
     694           0 :                                 d_lookup_done(child);
     695           0 :                                 dput(child);
     696           0 :                                 return false;
     697             :                         }
     698           0 :                         d_set_d_op(child, &proc_sys_dentry_operations);
     699           0 :                         res = d_splice_alias(inode, child);
     700           0 :                         d_lookup_done(child);
     701           0 :                         if (unlikely(res)) {
     702           0 :                                 if (IS_ERR(res)) {
     703           0 :                                         dput(child);
     704           0 :                                         return false;
     705             :                                 }
     706           0 :                                 dput(child);
     707           0 :                                 child = res;
     708             :                         }
     709             :                 }
     710             :         }
     711           0 :         inode = d_inode(child);
     712           0 :         ino  = inode->i_ino;
     713           0 :         type = inode->i_mode >> 12;
     714           0 :         dput(child);
     715           0 :         return dir_emit(ctx, qname.name, qname.len, ino, type);
     716             : }
     717             : 
     718           0 : static bool proc_sys_link_fill_cache(struct file *file,
     719             :                                     struct dir_context *ctx,
     720             :                                     struct ctl_table_header *head,
     721             :                                     struct ctl_table *table)
     722             : {
     723           0 :         bool ret = true;
     724             : 
     725           0 :         head = sysctl_head_grab(head);
     726           0 :         if (IS_ERR(head))
     727             :                 return false;
     728             : 
     729             :         /* It is not an error if we can not follow the link ignore it */
     730           0 :         if (sysctl_follow_link(&head, &table))
     731           0 :                 goto out;
     732             : 
     733           0 :         ret = proc_sys_fill_cache(file, ctx, head, table);
     734           0 : out:
     735           0 :         sysctl_head_finish(head);
     736           0 :         return ret;
     737             : }
     738             : 
     739           0 : static int scan(struct ctl_table_header *head, struct ctl_table *table,
     740             :                 unsigned long *pos, struct file *file,
     741             :                 struct dir_context *ctx)
     742             : {
     743           0 :         bool res;
     744             : 
     745           0 :         if ((*pos)++ < ctx->pos)
     746             :                 return true;
     747             : 
     748           0 :         if (unlikely(S_ISLNK(table->mode)))
     749           0 :                 res = proc_sys_link_fill_cache(file, ctx, head, table);
     750             :         else
     751           0 :                 res = proc_sys_fill_cache(file, ctx, head, table);
     752             : 
     753           0 :         if (res)
     754           0 :                 ctx->pos = *pos;
     755             : 
     756           0 :         return res;
     757             : }
     758             : 
     759           0 : static int proc_sys_readdir(struct file *file, struct dir_context *ctx)
     760             : {
     761           0 :         struct ctl_table_header *head = grab_header(file_inode(file));
     762           0 :         struct ctl_table_header *h = NULL;
     763           0 :         struct ctl_table *entry;
     764           0 :         struct ctl_dir *ctl_dir;
     765           0 :         unsigned long pos;
     766             : 
     767           0 :         if (IS_ERR(head))
     768           0 :                 return PTR_ERR(head);
     769             : 
     770           0 :         ctl_dir = container_of(head, struct ctl_dir, header);
     771             : 
     772           0 :         if (!dir_emit_dots(file, ctx))
     773           0 :                 goto out;
     774             : 
     775           0 :         pos = 2;
     776             : 
     777           0 :         for (first_entry(ctl_dir, &h, &entry); h; next_entry(&h, &entry)) {
     778           0 :                 if (!scan(h, entry, &pos, file, ctx)) {
     779           0 :                         sysctl_head_finish(h);
     780           0 :                         break;
     781             :                 }
     782             :         }
     783           0 : out:
     784           0 :         sysctl_head_finish(head);
     785           0 :         return 0;
     786             : }
     787             : 
     788         152 : static int proc_sys_permission(struct user_namespace *mnt_userns,
     789             :                                struct inode *inode, int mask)
     790             : {
     791             :         /*
     792             :          * sysctl entries that are not writeable,
     793             :          * are _NOT_ writeable, capabilities or not.
     794             :          */
     795         152 :         struct ctl_table_header *head;
     796         152 :         struct ctl_table *table;
     797         152 :         int error;
     798             : 
     799             :         /* Executable files are not allowed under /proc/sys/ */
     800         152 :         if ((mask & MAY_EXEC) && S_ISREG(inode->i_mode))
     801             :                 return -EACCES;
     802             : 
     803         152 :         head = grab_header(inode);
     804         152 :         if (IS_ERR(head))
     805           0 :                 return PTR_ERR(head);
     806             : 
     807         152 :         table = PROC_I(inode)->sysctl_entry;
     808         152 :         if (!table) /* global root - r-xr-xr-x */
     809          51 :                 error = mask & MAY_WRITE ? -EACCES : 0;
     810             :         else /* Use the permissions on the sysctl table entry */
     811         101 :                 error = sysctl_perm(head, table, mask & ~MAY_NOT_BLOCK);
     812             : 
     813         152 :         sysctl_head_finish(head);
     814         152 :         return error;
     815             : }
     816             : 
     817           0 : static int proc_sys_setattr(struct user_namespace *mnt_userns,
     818             :                             struct dentry *dentry, struct iattr *attr)
     819             : {
     820           0 :         struct inode *inode = d_inode(dentry);
     821           0 :         int error;
     822             : 
     823           0 :         if (attr->ia_valid & (ATTR_MODE | ATTR_UID | ATTR_GID))
     824             :                 return -EPERM;
     825             : 
     826           0 :         error = setattr_prepare(&init_user_ns, dentry, attr);
     827           0 :         if (error)
     828             :                 return error;
     829             : 
     830           0 :         setattr_copy(&init_user_ns, inode, attr);
     831           0 :         mark_inode_dirty(inode);
     832           0 :         return 0;
     833             : }
     834             : 
     835          17 : static int proc_sys_getattr(struct user_namespace *mnt_userns,
     836             :                             const struct path *path, struct kstat *stat,
     837             :                             u32 request_mask, unsigned int query_flags)
     838             : {
     839          17 :         struct inode *inode = d_inode(path->dentry);
     840          17 :         struct ctl_table_header *head = grab_header(inode);
     841          17 :         struct ctl_table *table = PROC_I(inode)->sysctl_entry;
     842             : 
     843          17 :         if (IS_ERR(head))
     844           0 :                 return PTR_ERR(head);
     845             : 
     846          17 :         generic_fillattr(&init_user_ns, inode, stat);
     847          17 :         if (table)
     848          15 :                 stat->mode = (stat->mode & S_IFMT) | table->mode;
     849             : 
     850          17 :         sysctl_head_finish(head);
     851          17 :         return 0;
     852             : }
     853             : 
     854             : static const struct file_operations proc_sys_file_operations = {
     855             :         .open           = proc_sys_open,
     856             :         .poll           = proc_sys_poll,
     857             :         .read_iter      = proc_sys_read,
     858             :         .write_iter     = proc_sys_write,
     859             :         .splice_read    = generic_file_splice_read,
     860             :         .splice_write   = iter_file_splice_write,
     861             :         .llseek         = default_llseek,
     862             : };
     863             : 
     864             : static const struct file_operations proc_sys_dir_file_operations = {
     865             :         .read           = generic_read_dir,
     866             :         .iterate_shared = proc_sys_readdir,
     867             :         .llseek         = generic_file_llseek,
     868             : };
     869             : 
     870             : static const struct inode_operations proc_sys_inode_operations = {
     871             :         .permission     = proc_sys_permission,
     872             :         .setattr        = proc_sys_setattr,
     873             :         .getattr        = proc_sys_getattr,
     874             : };
     875             : 
     876             : static const struct inode_operations proc_sys_dir_operations = {
     877             :         .lookup         = proc_sys_lookup,
     878             :         .permission     = proc_sys_permission,
     879             :         .setattr        = proc_sys_setattr,
     880             :         .getattr        = proc_sys_getattr,
     881             : };
     882             : 
     883          82 : static int proc_sys_revalidate(struct dentry *dentry, unsigned int flags)
     884             : {
     885          82 :         if (flags & LOOKUP_RCU)
     886             :                 return -ECHILD;
     887          82 :         return !PROC_I(d_inode(dentry))->sysctl->unregistering;
     888             : }
     889             : 
     890          43 : static int proc_sys_delete(const struct dentry *dentry)
     891             : {
     892          43 :         return !!PROC_I(d_inode(dentry))->sysctl->unregistering;
     893             : }
     894             : 
     895          38 : static int sysctl_is_seen(struct ctl_table_header *p)
     896             : {
     897          38 :         struct ctl_table_set *set = p->set;
     898          38 :         int res;
     899          38 :         spin_lock(&sysctl_lock);
     900          38 :         if (p->unregistering)
     901             :                 res = 0;
     902          38 :         else if (!set->is_seen)
     903             :                 res = 1;
     904             :         else
     905           2 :                 res = set->is_seen(set);
     906          38 :         spin_unlock(&sysctl_lock);
     907          38 :         return res;
     908             : }
     909             : 
     910          38 : static int proc_sys_compare(const struct dentry *dentry,
     911             :                 unsigned int len, const char *str, const struct qstr *name)
     912             : {
     913          38 :         struct ctl_table_header *head;
     914          38 :         struct inode *inode;
     915             : 
     916             :         /* Although proc doesn't have negative dentries, rcu-walk means
     917             :          * that inode here can be NULL */
     918             :         /* AV: can it, indeed? */
     919          38 :         inode = d_inode_rcu(dentry);
     920          38 :         if (!inode)
     921             :                 return 1;
     922          38 :         if (name->len != len)
     923             :                 return 1;
     924          38 :         if (memcmp(name->name, str, len))
     925             :                 return 1;
     926          38 :         head = rcu_dereference(PROC_I(inode)->sysctl);
     927          38 :         return !head || !sysctl_is_seen(head);
     928             : }
     929             : 
     930             : static const struct dentry_operations proc_sys_dentry_operations = {
     931             :         .d_revalidate   = proc_sys_revalidate,
     932             :         .d_delete       = proc_sys_delete,
     933             :         .d_compare      = proc_sys_compare,
     934             : };
     935             : 
     936         184 : static struct ctl_dir *find_subdir(struct ctl_dir *dir,
     937             :                                    const char *name, int namelen)
     938             : {
     939         184 :         struct ctl_table_header *head;
     940         184 :         struct ctl_table *entry;
     941             : 
     942         184 :         entry = find_entry(&head, dir, name, namelen);
     943         184 :         if (!entry)
     944         184 :                 return ERR_PTR(-ENOENT);
     945         116 :         if (!S_ISDIR(entry->mode))
     946         184 :                 return ERR_PTR(-ENOTDIR);
     947          86 :         return container_of(head, struct ctl_dir, header);
     948             : }
     949             : 
     950          34 : static struct ctl_dir *new_dir(struct ctl_table_set *set,
     951             :                                const char *name, int namelen)
     952             : {
     953          34 :         struct ctl_table *table;
     954          34 :         struct ctl_dir *new;
     955          34 :         struct ctl_node *node;
     956          34 :         char *new_name;
     957             : 
     958          34 :         new = kzalloc(sizeof(*new) + sizeof(struct ctl_node) +
     959             :                       sizeof(struct ctl_table)*2 +  namelen + 1,
     960             :                       GFP_KERNEL);
     961          34 :         if (!new)
     962             :                 return NULL;
     963             : 
     964          34 :         node = (struct ctl_node *)(new + 1);
     965          34 :         table = (struct ctl_table *)(node + 1);
     966          34 :         new_name = (char *)(table + 2);
     967          34 :         memcpy(new_name, name, namelen);
     968          34 :         new_name[namelen] = '\0';
     969          34 :         table[0].procname = new_name;
     970          34 :         table[0].mode = S_IFDIR|S_IRUGO|S_IXUGO;
     971          34 :         init_header(&new->header, set->dir.header.root, set, node, table);
     972             : 
     973          34 :         return new;
     974             : }
     975             : 
     976             : /**
     977             :  * get_subdir - find or create a subdir with the specified name.
     978             :  * @dir:  Directory to create the subdirectory in
     979             :  * @name: The name of the subdirectory to find or create
     980             :  * @namelen: The length of name
     981             :  *
     982             :  * Takes a directory with an elevated reference count so we know that
     983             :  * if we drop the lock the directory will not go away.  Upon success
     984             :  * the reference is moved from @dir to the returned subdirectory.
     985             :  * Upon error an error code is returned and the reference on @dir is
     986             :  * simply dropped.
     987             :  */
     988          84 : static struct ctl_dir *get_subdir(struct ctl_dir *dir,
     989             :                                   const char *name, int namelen)
     990             : {
     991          84 :         struct ctl_table_set *set = dir->header.set;
     992          84 :         struct ctl_dir *subdir, *new = NULL;
     993          84 :         int err;
     994             : 
     995          84 :         spin_lock(&sysctl_lock);
     996          84 :         subdir = find_subdir(dir, name, namelen);
     997          84 :         if (!IS_ERR(subdir))
     998          50 :                 goto found;
     999          34 :         if (PTR_ERR(subdir) != -ENOENT)
    1000           0 :                 goto failed;
    1001             : 
    1002          34 :         spin_unlock(&sysctl_lock);
    1003          34 :         new = new_dir(set, name, namelen);
    1004          34 :         spin_lock(&sysctl_lock);
    1005          34 :         subdir = ERR_PTR(-ENOMEM);
    1006          34 :         if (!new)
    1007           0 :                 goto failed;
    1008             : 
    1009             :         /* Was the subdir added while we dropped the lock? */
    1010          34 :         subdir = find_subdir(dir, name, namelen);
    1011          34 :         if (!IS_ERR(subdir))
    1012           0 :                 goto found;
    1013          34 :         if (PTR_ERR(subdir) != -ENOENT)
    1014           0 :                 goto failed;
    1015             : 
    1016             :         /* Nope.  Use the our freshly made directory entry. */
    1017          34 :         err = insert_header(dir, &new->header);
    1018          34 :         subdir = ERR_PTR(err);
    1019          34 :         if (err)
    1020           0 :                 goto failed;
    1021             :         subdir = new;
    1022          84 : found:
    1023          84 :         subdir->header.nreg++;
    1024          84 : failed:
    1025          84 :         if (IS_ERR(subdir)) {
    1026           0 :                 pr_err("sysctl could not get directory: ");
    1027           0 :                 sysctl_print_dir(dir);
    1028           0 :                 pr_cont("/%*.*s %ld\n",
    1029             :                         namelen, namelen, name, PTR_ERR(subdir));
    1030             :         }
    1031          84 :         drop_sysctl_table(&dir->header);
    1032          84 :         if (new)
    1033          34 :                 drop_sysctl_table(&new->header);
    1034          84 :         spin_unlock(&sysctl_lock);
    1035          84 :         return subdir;
    1036             : }
    1037             : 
    1038         128 : static struct ctl_dir *xlate_dir(struct ctl_table_set *set, struct ctl_dir *dir)
    1039             : {
    1040         128 :         struct ctl_dir *parent;
    1041         128 :         const char *procname;
    1042         128 :         if (!dir->header.parent)
    1043          38 :                 return &set->dir;
    1044          90 :         parent = xlate_dir(set, dir->header.parent);
    1045          90 :         if (IS_ERR(parent))
    1046             :                 return parent;
    1047          66 :         procname = dir->header.ctl_table[0].procname;
    1048          66 :         return find_subdir(parent, procname, strlen(procname));
    1049             : }
    1050             : 
    1051           1 : static int sysctl_follow_link(struct ctl_table_header **phead,
    1052             :         struct ctl_table **pentry)
    1053             : {
    1054           1 :         struct ctl_table_header *head;
    1055           1 :         struct ctl_table_root *root;
    1056           1 :         struct ctl_table_set *set;
    1057           1 :         struct ctl_table *entry;
    1058           1 :         struct ctl_dir *dir;
    1059           1 :         int ret;
    1060             : 
    1061           1 :         ret = 0;
    1062           1 :         spin_lock(&sysctl_lock);
    1063           1 :         root = (*pentry)->data;
    1064           1 :         set = lookup_header_set(root);
    1065           1 :         dir = xlate_dir(set, (*phead)->parent);
    1066           1 :         if (IS_ERR(dir))
    1067           0 :                 ret = PTR_ERR(dir);
    1068             :         else {
    1069           1 :                 const char *procname = (*pentry)->procname;
    1070           1 :                 head = NULL;
    1071           1 :                 entry = find_entry(&head, dir, procname, strlen(procname));
    1072           1 :                 ret = -ENOENT;
    1073           1 :                 if (entry && use_table(head)) {
    1074           1 :                         unuse_table(*phead);
    1075           1 :                         *phead = head;
    1076           1 :                         *pentry = entry;
    1077           1 :                         ret = 0;
    1078             :                 }
    1079             :         }
    1080             : 
    1081           1 :         spin_unlock(&sysctl_lock);
    1082           1 :         return ret;
    1083             : }
    1084             : 
    1085           0 : static int sysctl_err(const char *path, struct ctl_table *table, char *fmt, ...)
    1086             : {
    1087           0 :         struct va_format vaf;
    1088           0 :         va_list args;
    1089             : 
    1090           0 :         va_start(args, fmt);
    1091           0 :         vaf.fmt = fmt;
    1092           0 :         vaf.va = &args;
    1093             : 
    1094           0 :         pr_err("sysctl table check failed: %s/%s %pV\n",
    1095             :                path, table->procname, &vaf);
    1096             : 
    1097           0 :         va_end(args);
    1098           0 :         return -EINVAL;
    1099             : }
    1100             : 
    1101         235 : static int sysctl_check_table_array(const char *path, struct ctl_table *table)
    1102             : {
    1103         235 :         int err = 0;
    1104             : 
    1105         235 :         if ((table->proc_handler == proc_douintvec) ||
    1106             :             (table->proc_handler == proc_douintvec_minmax)) {
    1107           3 :                 if (table->maxlen != sizeof(unsigned int))
    1108           0 :                         err |= sysctl_err(path, table, "array not allowed");
    1109             :         }
    1110             : 
    1111         235 :         return err;
    1112             : }
    1113             : 
    1114          39 : static int sysctl_check_table(const char *path, struct ctl_table *table)
    1115             : {
    1116          39 :         int err = 0;
    1117         562 :         for (; table->procname; table++) {
    1118         523 :                 if (table->child)
    1119           0 :                         err |= sysctl_err(path, table, "Not a file");
    1120             : 
    1121         523 :                 if ((table->proc_handler == proc_dostring) ||
    1122         415 :                     (table->proc_handler == proc_dointvec) ||
    1123         414 :                     (table->proc_handler == proc_douintvec) ||
    1124         412 :                     (table->proc_handler == proc_douintvec_minmax) ||
    1125         320 :                     (table->proc_handler == proc_dointvec_minmax) ||
    1126         304 :                     (table->proc_handler == proc_dointvec_jiffies) ||
    1127         304 :                     (table->proc_handler == proc_dointvec_userhz_jiffies) ||
    1128         301 :                     (table->proc_handler == proc_dointvec_ms_jiffies) ||
    1129         288 :                     (table->proc_handler == proc_doulongvec_minmax) ||
    1130             :                     (table->proc_handler == proc_doulongvec_ms_jiffies_minmax)) {
    1131         235 :                         if (!table->data)
    1132           0 :                                 err |= sysctl_err(path, table, "No data");
    1133         235 :                         if (!table->maxlen)
    1134           0 :                                 err |= sysctl_err(path, table, "No maxlen");
    1135             :                         else
    1136         235 :                                 err |= sysctl_check_table_array(path, table);
    1137             :                 }
    1138         523 :                 if (!table->proc_handler)
    1139           0 :                         err |= sysctl_err(path, table, "No proc_handler");
    1140             : 
    1141         523 :                 if ((table->mode & (S_IRUGO|S_IWUGO)) != table->mode)
    1142           0 :                         err |= sysctl_err(path, table, "bogus .mode 0%o",
    1143             :                                 table->mode);
    1144             :         }
    1145          39 :         return err;
    1146             : }
    1147             : 
    1148           5 : static struct ctl_table_header *new_links(struct ctl_dir *dir, struct ctl_table *table,
    1149             :         struct ctl_table_root *link_root)
    1150             : {
    1151           5 :         struct ctl_table *link_table, *entry, *link;
    1152           5 :         struct ctl_table_header *links;
    1153           5 :         struct ctl_node *node;
    1154           5 :         char *link_name;
    1155           5 :         int nr_entries, name_bytes;
    1156             : 
    1157           5 :         name_bytes = 0;
    1158           5 :         nr_entries = 0;
    1159          19 :         for (entry = table; entry->procname; entry++) {
    1160          14 :                 nr_entries++;
    1161          14 :                 name_bytes += strlen(entry->procname) + 1;
    1162             :         }
    1163             : 
    1164          10 :         links = kzalloc(sizeof(struct ctl_table_header) +
    1165           5 :                         sizeof(struct ctl_node)*nr_entries +
    1166           5 :                         sizeof(struct ctl_table)*(nr_entries + 1) +
    1167             :                         name_bytes,
    1168             :                         GFP_KERNEL);
    1169             : 
    1170           5 :         if (!links)
    1171             :                 return NULL;
    1172             : 
    1173           5 :         node = (struct ctl_node *)(links + 1);
    1174           5 :         link_table = (struct ctl_table *)(node + nr_entries);
    1175           5 :         link_name = (char *)&link_table[nr_entries + 1];
    1176             : 
    1177          19 :         for (link = link_table, entry = table; entry->procname; link++, entry++) {
    1178          14 :                 int len = strlen(entry->procname) + 1;
    1179          14 :                 memcpy(link_name, entry->procname, len);
    1180          14 :                 link->procname = link_name;
    1181          14 :                 link->mode = S_IFLNK|S_IRWXUGO;
    1182          14 :                 link->data = link_root;
    1183          14 :                 link_name += len;
    1184             :         }
    1185           5 :         init_header(links, dir->header.root, dir->header.set, node, link_table);
    1186           5 :         links->nreg = nr_entries;
    1187             : 
    1188           5 :         return links;
    1189             : }
    1190             : 
    1191          12 : static bool get_links(struct ctl_dir *dir,
    1192             :         struct ctl_table *table, struct ctl_table_root *link_root)
    1193             : {
    1194          12 :         struct ctl_table_header *head;
    1195          12 :         struct ctl_table *entry, *link;
    1196             : 
    1197             :         /* Are there links available for every entry in table? */
    1198          14 :         for (entry = table; entry->procname; entry++) {
    1199          12 :                 const char *procname = entry->procname;
    1200          12 :                 link = find_entry(&head, dir, procname, strlen(procname));
    1201          12 :                 if (!link)
    1202             :                         return false;
    1203           2 :                 if (S_ISDIR(link->mode) && S_ISDIR(entry->mode))
    1204           2 :                         continue;
    1205           0 :                 if (S_ISLNK(link->mode) && (link->data == link_root))
    1206           0 :                         continue;
    1207             :                 return false;
    1208             :         }
    1209             : 
    1210             :         /* The checks passed.  Increase the registration count on the links */
    1211           4 :         for (entry = table; entry->procname; entry++) {
    1212           2 :                 const char *procname = entry->procname;
    1213           2 :                 link = find_entry(&head, dir, procname, strlen(procname));
    1214           2 :                 head->nreg++;
    1215             :         }
    1216             :         return true;
    1217             : }
    1218             : 
    1219          78 : static int insert_links(struct ctl_table_header *head)
    1220             : {
    1221          78 :         struct ctl_table_set *root_set = &sysctl_table_root.default_set;
    1222          78 :         struct ctl_dir *core_parent = NULL;
    1223          78 :         struct ctl_table_header *links;
    1224          78 :         int err;
    1225             : 
    1226          78 :         if (head->set == root_set)
    1227             :                 return 0;
    1228             : 
    1229          37 :         core_parent = xlate_dir(root_set, head->parent);
    1230          37 :         if (IS_ERR(core_parent))
    1231             :                 return 0;
    1232             : 
    1233           7 :         if (get_links(core_parent, head->ctl_table, head->root))
    1234             :                 return 0;
    1235             : 
    1236           5 :         core_parent->header.nreg++;
    1237           5 :         spin_unlock(&sysctl_lock);
    1238             : 
    1239           5 :         links = new_links(core_parent, head->ctl_table, head->root);
    1240             : 
    1241           5 :         spin_lock(&sysctl_lock);
    1242           5 :         err = -ENOMEM;
    1243           5 :         if (!links)
    1244           0 :                 goto out;
    1245             : 
    1246           5 :         err = 0;
    1247           5 :         if (get_links(core_parent, head->ctl_table, head->root)) {
    1248           0 :                 kfree(links);
    1249           0 :                 goto out;
    1250             :         }
    1251             : 
    1252           5 :         err = insert_header(core_parent, links);
    1253           5 :         if (err)
    1254           0 :                 kfree(links);
    1255           5 : out:
    1256           5 :         drop_sysctl_table(&core_parent->header);
    1257           5 :         return err;
    1258             : }
    1259             : 
    1260             : /**
    1261             :  * __register_sysctl_table - register a leaf sysctl table
    1262             :  * @set: Sysctl tree to register on
    1263             :  * @path: The path to the directory the sysctl table is in.
    1264             :  * @table: the top-level table structure
    1265             :  *
    1266             :  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
    1267             :  * array. A completely 0 filled entry terminates the table.
    1268             :  *
    1269             :  * The members of the &struct ctl_table structure are used as follows:
    1270             :  *
    1271             :  * procname - the name of the sysctl file under /proc/sys. Set to %NULL to not
    1272             :  *            enter a sysctl file
    1273             :  *
    1274             :  * data - a pointer to data for use by proc_handler
    1275             :  *
    1276             :  * maxlen - the maximum size in bytes of the data
    1277             :  *
    1278             :  * mode - the file permissions for the /proc/sys file
    1279             :  *
    1280             :  * child - must be %NULL.
    1281             :  *
    1282             :  * proc_handler - the text handler routine (described below)
    1283             :  *
    1284             :  * extra1, extra2 - extra pointers usable by the proc handler routines
    1285             :  *
    1286             :  * Leaf nodes in the sysctl tree will be represented by a single file
    1287             :  * under /proc; non-leaf nodes will be represented by directories.
    1288             :  *
    1289             :  * There must be a proc_handler routine for any terminal nodes.
    1290             :  * Several default handlers are available to cover common cases -
    1291             :  *
    1292             :  * proc_dostring(), proc_dointvec(), proc_dointvec_jiffies(),
    1293             :  * proc_dointvec_userhz_jiffies(), proc_dointvec_minmax(),
    1294             :  * proc_doulongvec_ms_jiffies_minmax(), proc_doulongvec_minmax()
    1295             :  *
    1296             :  * It is the handler's job to read the input buffer from user memory
    1297             :  * and process it. The handler should return 0 on success.
    1298             :  *
    1299             :  * This routine returns %NULL on a failure to register, and a pointer
    1300             :  * to the table header on success.
    1301             :  */
    1302          39 : struct ctl_table_header *__register_sysctl_table(
    1303             :         struct ctl_table_set *set,
    1304             :         const char *path, struct ctl_table *table)
    1305             : {
    1306          39 :         struct ctl_table_root *root = set->dir.header.root;
    1307          39 :         struct ctl_table_header *header;
    1308          39 :         const char *name, *nextname;
    1309          39 :         struct ctl_dir *dir;
    1310          39 :         struct ctl_table *entry;
    1311          39 :         struct ctl_node *node;
    1312          39 :         int nr_entries = 0;
    1313             : 
    1314         562 :         for (entry = table; entry->procname; entry++)
    1315         523 :                 nr_entries++;
    1316             : 
    1317          78 :         header = kzalloc(sizeof(struct ctl_table_header) +
    1318          39 :                          sizeof(struct ctl_node)*nr_entries, GFP_KERNEL);
    1319          39 :         if (!header)
    1320             :                 return NULL;
    1321             : 
    1322          39 :         node = (struct ctl_node *)(header + 1);
    1323          39 :         init_header(header, root, set, node, table);
    1324          39 :         if (sysctl_check_table(path, table))
    1325           0 :                 goto fail;
    1326             : 
    1327          39 :         spin_lock(&sysctl_lock);
    1328          39 :         dir = &set->dir;
    1329             :         /* Reference moved down the diretory tree get_subdir */
    1330          39 :         dir->header.nreg++;
    1331          39 :         spin_unlock(&sysctl_lock);
    1332             : 
    1333             :         /* Find the directory for the ctl_table */
    1334         179 :         for (name = path; name; name = nextname) {
    1335         101 :                 int namelen;
    1336         101 :                 nextname = strchr(name, '/');
    1337         101 :                 if (nextname) {
    1338          62 :                         namelen = nextname - name;
    1339          62 :                         nextname++;
    1340             :                 } else {
    1341          39 :                         namelen = strlen(name);
    1342             :                 }
    1343         101 :                 if (namelen == 0)
    1344          17 :                         continue;
    1345             : 
    1346          84 :                 dir = get_subdir(dir, name, namelen);
    1347          84 :                 if (IS_ERR(dir))
    1348           0 :                         goto fail;
    1349             :         }
    1350             : 
    1351          39 :         spin_lock(&sysctl_lock);
    1352          39 :         if (insert_header(dir, header))
    1353           0 :                 goto fail_put_dir_locked;
    1354             : 
    1355          39 :         drop_sysctl_table(&dir->header);
    1356          39 :         spin_unlock(&sysctl_lock);
    1357             : 
    1358          39 :         return header;
    1359             : 
    1360           0 : fail_put_dir_locked:
    1361           0 :         drop_sysctl_table(&dir->header);
    1362           0 :         spin_unlock(&sysctl_lock);
    1363           0 : fail:
    1364           0 :         kfree(header);
    1365           0 :         dump_stack();
    1366           0 :         return NULL;
    1367             : }
    1368             : 
    1369             : /**
    1370             :  * register_sysctl - register a sysctl table
    1371             :  * @path: The path to the directory the sysctl table is in.
    1372             :  * @table: the table structure
    1373             :  *
    1374             :  * Register a sysctl table. @table should be a filled in ctl_table
    1375             :  * array. A completely 0 filled entry terminates the table.
    1376             :  *
    1377             :  * See __register_sysctl_table for more details.
    1378             :  */
    1379           2 : struct ctl_table_header *register_sysctl(const char *path, struct ctl_table *table)
    1380             : {
    1381           2 :         return __register_sysctl_table(&sysctl_table_root.default_set,
    1382             :                                         path, table);
    1383             : }
    1384             : EXPORT_SYMBOL(register_sysctl);
    1385             : 
    1386          22 : static char *append_path(const char *path, char *pos, const char *name)
    1387             : {
    1388          22 :         int namelen;
    1389          22 :         namelen = strlen(name);
    1390          22 :         if (((pos - path) + namelen + 2) >= PATH_MAX)
    1391             :                 return NULL;
    1392          22 :         memcpy(pos, name, namelen);
    1393          22 :         pos[namelen] = '/';
    1394          22 :         pos[namelen + 1] = '\0';
    1395          22 :         pos += namelen + 1;
    1396          22 :         return pos;
    1397             : }
    1398             : 
    1399          31 : static int count_subheaders(struct ctl_table *table)
    1400             : {
    1401          31 :         int has_files = 0;
    1402          31 :         int nr_subheaders = 0;
    1403          31 :         struct ctl_table *entry;
    1404             : 
    1405             :         /* special case: no directory and empty directory */
    1406          31 :         if (!table || !table->procname)
    1407             :                 return 1;
    1408             : 
    1409         214 :         for (entry = table; entry->procname; entry++) {
    1410         184 :                 if (entry->child)
    1411          22 :                         nr_subheaders += count_subheaders(entry->child);
    1412             :                 else
    1413             :                         has_files = 1;
    1414             :         }
    1415          30 :         return nr_subheaders + has_files;
    1416             : }
    1417             : 
    1418          10 : static int register_leaf_sysctl_tables(const char *path, char *pos,
    1419             :         struct ctl_table_header ***subheader, struct ctl_table_set *set,
    1420             :         struct ctl_table *table)
    1421             : {
    1422          10 :         struct ctl_table *ctl_table_arg = NULL;
    1423          10 :         struct ctl_table *entry, *files;
    1424          10 :         int nr_files = 0;
    1425          10 :         int nr_dirs = 0;
    1426          10 :         int err = -ENOMEM;
    1427             : 
    1428         150 :         for (entry = table; entry->procname; entry++) {
    1429         140 :                 if (entry->child)
    1430           9 :                         nr_dirs++;
    1431             :                 else
    1432         131 :                         nr_files++;
    1433             :         }
    1434             : 
    1435          10 :         files = table;
    1436             :         /* If there are mixed files and directories we need a new table */
    1437          10 :         if (nr_dirs && nr_files) {
    1438           2 :                 struct ctl_table *new;
    1439           2 :                 files = kcalloc(nr_files + 1, sizeof(struct ctl_table),
    1440             :                                 GFP_KERNEL);
    1441           2 :                 if (!files)
    1442           0 :                         goto out;
    1443             : 
    1444          82 :                 ctl_table_arg = files;
    1445          82 :                 for (new = files, entry = table; entry->procname; entry++) {
    1446          80 :                         if (entry->child)
    1447           4 :                                 continue;
    1448          76 :                         *new = *entry;
    1449          76 :                         new++;
    1450             :                 }
    1451             :         }
    1452             : 
    1453             :         /* Register everything except a directory full of subdirectories */
    1454          10 :         if (nr_files || !nr_dirs) {
    1455           9 :                 struct ctl_table_header *header;
    1456           9 :                 header = __register_sysctl_table(set, path, files);
    1457           9 :                 if (!header) {
    1458           0 :                         kfree(ctl_table_arg);
    1459           0 :                         goto out;
    1460             :                 }
    1461             : 
    1462             :                 /* Remember if we need to free the file table */
    1463           9 :                 header->ctl_table_arg = ctl_table_arg;
    1464           9 :                 **subheader = header;
    1465           9 :                 (*subheader)++;
    1466             :         }
    1467             : 
    1468             :         /* Recurse into the subdirectories. */
    1469         150 :         for (entry = table; entry->procname; entry++) {
    1470         140 :                 char *child_pos;
    1471             : 
    1472         140 :                 if (!entry->child)
    1473         131 :                         continue;
    1474             : 
    1475           9 :                 err = -ENAMETOOLONG;
    1476           9 :                 child_pos = append_path(path, pos, entry->procname);
    1477           9 :                 if (!child_pos)
    1478           0 :                         goto out;
    1479             : 
    1480           9 :                 err = register_leaf_sysctl_tables(path, child_pos, subheader,
    1481             :                                                   set, entry->child);
    1482           9 :                 pos[0] = '\0';
    1483           9 :                 if (err)
    1484           0 :                         goto out;
    1485             :         }
    1486             :         err = 0;
    1487          10 : out:
    1488             :         /* On failure our caller will unregister all registered subheaders */
    1489          10 :         return err;
    1490             : }
    1491             : 
    1492             : /**
    1493             :  * __register_sysctl_paths - register a sysctl table hierarchy
    1494             :  * @set: Sysctl tree to register on
    1495             :  * @path: The path to the directory the sysctl table is in.
    1496             :  * @table: the top-level table structure
    1497             :  *
    1498             :  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
    1499             :  * array. A completely 0 filled entry terminates the table.
    1500             :  *
    1501             :  * See __register_sysctl_table for more details.
    1502             :  */
    1503           9 : struct ctl_table_header *__register_sysctl_paths(
    1504             :         struct ctl_table_set *set,
    1505             :         const struct ctl_path *path, struct ctl_table *table)
    1506             : {
    1507           9 :         struct ctl_table *ctl_table_arg = table;
    1508           9 :         int nr_subheaders = count_subheaders(table);
    1509           9 :         struct ctl_table_header *header = NULL, **subheaders, **subheader;
    1510           9 :         const struct ctl_path *component;
    1511           9 :         char *new_path, *pos;
    1512             : 
    1513           9 :         pos = new_path = kmalloc(PATH_MAX, GFP_KERNEL);
    1514           9 :         if (!new_path)
    1515             :                 return NULL;
    1516             : 
    1517           9 :         pos[0] = '\0';
    1518           9 :         for (component = path; component->procname; component++) {
    1519           0 :                 pos = append_path(new_path, pos, component->procname);
    1520           0 :                 if (!pos)
    1521           0 :                         goto out;
    1522             :         }
    1523          22 :         while (table->procname && table->child && !table[1].procname) {
    1524          13 :                 pos = append_path(new_path, pos, table->procname);
    1525          13 :                 if (!pos)
    1526           0 :                         goto out;
    1527          13 :                 table = table->child;
    1528             :         }
    1529           9 :         if (nr_subheaders == 1) {
    1530           8 :                 header = __register_sysctl_table(set, new_path, table);
    1531           8 :                 if (header)
    1532           8 :                         header->ctl_table_arg = ctl_table_arg;
    1533             :         } else {
    1534           1 :                 header = kzalloc(sizeof(*header) +
    1535             :                                  sizeof(*subheaders)*nr_subheaders, GFP_KERNEL);
    1536           1 :                 if (!header)
    1537           0 :                         goto out;
    1538             : 
    1539           1 :                 subheaders = (struct ctl_table_header **) (header + 1);
    1540           1 :                 subheader = subheaders;
    1541           1 :                 header->ctl_table_arg = ctl_table_arg;
    1542             : 
    1543           1 :                 if (register_leaf_sysctl_tables(new_path, pos, &subheader,
    1544             :                                                 set, table))
    1545           0 :                         goto err_register_leaves;
    1546             :         }
    1547             : 
    1548           1 : out:
    1549           9 :         kfree(new_path);
    1550           9 :         return header;
    1551             : 
    1552           0 : err_register_leaves:
    1553           0 :         while (subheader > subheaders) {
    1554           0 :                 struct ctl_table_header *subh = *(--subheader);
    1555           0 :                 struct ctl_table *table = subh->ctl_table_arg;
    1556           0 :                 unregister_sysctl_table(subh);
    1557           0 :                 kfree(table);
    1558             :         }
    1559           0 :         kfree(header);
    1560           0 :         header = NULL;
    1561           0 :         goto out;
    1562             : }
    1563             : 
    1564             : /**
    1565             :  * register_sysctl_table_path - register a sysctl table hierarchy
    1566             :  * @path: The path to the directory the sysctl table is in.
    1567             :  * @table: the top-level table structure
    1568             :  *
    1569             :  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
    1570             :  * array. A completely 0 filled entry terminates the table.
    1571             :  *
    1572             :  * See __register_sysctl_paths for more details.
    1573             :  */
    1574           9 : struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
    1575             :                                                 struct ctl_table *table)
    1576             : {
    1577           0 :         return __register_sysctl_paths(&sysctl_table_root.default_set,
    1578             :                                         path, table);
    1579             : }
    1580             : EXPORT_SYMBOL(register_sysctl_paths);
    1581             : 
    1582             : /**
    1583             :  * register_sysctl_table - register a sysctl table hierarchy
    1584             :  * @table: the top-level table structure
    1585             :  *
    1586             :  * Register a sysctl table hierarchy. @table should be a filled in ctl_table
    1587             :  * array. A completely 0 filled entry terminates the table.
    1588             :  *
    1589             :  * See register_sysctl_paths for more details.
    1590             :  */
    1591           9 : struct ctl_table_header *register_sysctl_table(struct ctl_table *table)
    1592             : {
    1593           9 :         static const struct ctl_path null_path[] = { {} };
    1594             : 
    1595           9 :         return register_sysctl_paths(null_path, table);
    1596             : }
    1597             : EXPORT_SYMBOL(register_sysctl_table);
    1598             : 
    1599           0 : static void put_links(struct ctl_table_header *header)
    1600             : {
    1601           0 :         struct ctl_table_set *root_set = &sysctl_table_root.default_set;
    1602           0 :         struct ctl_table_root *root = header->root;
    1603           0 :         struct ctl_dir *parent = header->parent;
    1604           0 :         struct ctl_dir *core_parent;
    1605           0 :         struct ctl_table *entry;
    1606             : 
    1607           0 :         if (header->set == root_set)
    1608             :                 return;
    1609             : 
    1610           0 :         core_parent = xlate_dir(root_set, parent);
    1611           0 :         if (IS_ERR(core_parent))
    1612             :                 return;
    1613             : 
    1614           0 :         for (entry = header->ctl_table; entry->procname; entry++) {
    1615           0 :                 struct ctl_table_header *link_head;
    1616           0 :                 struct ctl_table *link;
    1617           0 :                 const char *name = entry->procname;
    1618             : 
    1619           0 :                 link = find_entry(&link_head, core_parent, name, strlen(name));
    1620           0 :                 if (link &&
    1621           0 :                     ((S_ISDIR(link->mode) && S_ISDIR(entry->mode)) ||
    1622           0 :                      (S_ISLNK(link->mode) && (link->data == root)))) {
    1623           0 :                         drop_sysctl_table(link_head);
    1624             :                 }
    1625             :                 else {
    1626           0 :                         pr_err("sysctl link missing during unregister: ");
    1627           0 :                         sysctl_print_dir(parent);
    1628           0 :                         pr_cont("/%s\n", name);
    1629             :                 }
    1630             :         }
    1631             : }
    1632             : 
    1633         162 : static void drop_sysctl_table(struct ctl_table_header *header)
    1634             : {
    1635         162 :         struct ctl_dir *parent = header->parent;
    1636             : 
    1637         162 :         if (--header->nreg)
    1638             :                 return;
    1639             : 
    1640           0 :         if (parent) {
    1641           0 :                 put_links(header);
    1642           0 :                 start_unregistering(header);
    1643             :         }
    1644             : 
    1645           0 :         if (!--header->count)
    1646           0 :                 kfree_rcu(header, rcu);
    1647             : 
    1648           0 :         if (parent)
    1649           0 :                 drop_sysctl_table(&parent->header);
    1650             : }
    1651             : 
    1652             : /**
    1653             :  * unregister_sysctl_table - unregister a sysctl table hierarchy
    1654             :  * @header: the header returned from register_sysctl_table
    1655             :  *
    1656             :  * Unregisters the sysctl table and all children. proc entries may not
    1657             :  * actually be removed until they are no longer used by anyone.
    1658             :  */
    1659           0 : void unregister_sysctl_table(struct ctl_table_header * header)
    1660             : {
    1661           0 :         int nr_subheaders;
    1662           0 :         might_sleep();
    1663             : 
    1664           0 :         if (header == NULL)
    1665             :                 return;
    1666             : 
    1667           0 :         nr_subheaders = count_subheaders(header->ctl_table_arg);
    1668           0 :         if (unlikely(nr_subheaders > 1)) {
    1669           0 :                 struct ctl_table_header **subheaders;
    1670           0 :                 int i;
    1671             : 
    1672           0 :                 subheaders = (struct ctl_table_header **)(header + 1);
    1673           0 :                 for (i = nr_subheaders -1; i >= 0; i--) {
    1674           0 :                         struct ctl_table_header *subh = subheaders[i];
    1675           0 :                         struct ctl_table *table = subh->ctl_table_arg;
    1676           0 :                         unregister_sysctl_table(subh);
    1677           0 :                         kfree(table);
    1678             :                 }
    1679           0 :                 kfree(header);
    1680           0 :                 return;
    1681             :         }
    1682             : 
    1683           0 :         spin_lock(&sysctl_lock);
    1684           0 :         drop_sysctl_table(header);
    1685           0 :         spin_unlock(&sysctl_lock);
    1686             : }
    1687             : EXPORT_SYMBOL(unregister_sysctl_table);
    1688             : 
    1689           2 : void setup_sysctl_set(struct ctl_table_set *set,
    1690             :         struct ctl_table_root *root,
    1691             :         int (*is_seen)(struct ctl_table_set *))
    1692             : {
    1693           2 :         memset(set, 0, sizeof(*set));
    1694           2 :         set->is_seen = is_seen;
    1695           2 :         init_header(&set->dir.header, root, set, NULL, root_table);
    1696           2 : }
    1697             : 
    1698           0 : void retire_sysctl_set(struct ctl_table_set *set)
    1699             : {
    1700           0 :         WARN_ON(!RB_EMPTY_ROOT(&set->dir.root));
    1701           0 : }
    1702             : 
    1703           1 : int __init proc_sys_init(void)
    1704             : {
    1705           1 :         struct proc_dir_entry *proc_sys_root;
    1706             : 
    1707           1 :         proc_sys_root = proc_mkdir("sys", NULL);
    1708           1 :         proc_sys_root->proc_iops = &proc_sys_dir_operations;
    1709           1 :         proc_sys_root->proc_dir_ops = &proc_sys_dir_file_operations;
    1710           1 :         proc_sys_root->nlink = 0;
    1711             : 
    1712           1 :         return sysctl_init();
    1713             : }
    1714             : 
    1715             : struct sysctl_alias {
    1716             :         const char *kernel_param;
    1717             :         const char *sysctl_param;
    1718             : };
    1719             : 
    1720             : /*
    1721             :  * Historically some settings had both sysctl and a command line parameter.
    1722             :  * With the generic sysctl. parameter support, we can handle them at a single
    1723             :  * place and only keep the historical name for compatibility. This is not meant
    1724             :  * to add brand new aliases. When adding existing aliases, consider whether
    1725             :  * the possibly different moment of changing the value (e.g. from early_param
    1726             :  * to the moment do_sysctl_args() is called) is an issue for the specific
    1727             :  * parameter.
    1728             :  */
    1729             : static const struct sysctl_alias sysctl_aliases[] = {
    1730             :         {"hardlockup_all_cpu_backtrace",      "kernel.hardlockup_all_cpu_backtrace" },
    1731             :         {"hung_task_panic",                   "kernel.hung_task_panic" },
    1732             :         {"numa_zonelist_order",                       "vm.numa_zonelist_order" },
    1733             :         {"softlockup_all_cpu_backtrace",      "kernel.softlockup_all_cpu_backtrace" },
    1734             :         {"softlockup_panic",                  "kernel.softlockup_panic" },
    1735             :         { }
    1736             : };
    1737             : 
    1738           6 : static const char *sysctl_find_alias(char *param)
    1739             : {
    1740           6 :         const struct sysctl_alias *alias;
    1741             : 
    1742          36 :         for (alias = &sysctl_aliases[0]; alias->kernel_param != NULL; alias++) {
    1743          30 :                 if (strcmp(alias->kernel_param, param) == 0)
    1744           0 :                         return alias->sysctl_param;
    1745             :         }
    1746             : 
    1747             :         return NULL;
    1748             : }
    1749             : 
    1750             : /* Set sysctl value passed on kernel command line. */
    1751           6 : static int process_sysctl_arg(char *param, char *val,
    1752             :                                const char *unused, void *arg)
    1753             : {
    1754           6 :         char *path;
    1755           6 :         struct vfsmount **proc_mnt = arg;
    1756           6 :         struct file_system_type *proc_fs_type;
    1757           6 :         struct file *file;
    1758           6 :         int len;
    1759           6 :         int err;
    1760           6 :         loff_t pos = 0;
    1761           6 :         ssize_t wret;
    1762             : 
    1763           6 :         if (strncmp(param, "sysctl", sizeof("sysctl") - 1) == 0) {
    1764           0 :                 param += sizeof("sysctl") - 1;
    1765             : 
    1766           0 :                 if (param[0] != '/' && param[0] != '.')
    1767             :                         return 0;
    1768             : 
    1769           0 :                 param++;
    1770             :         } else {
    1771           6 :                 param = (char *) sysctl_find_alias(param);
    1772           6 :                 if (!param)
    1773             :                         return 0;
    1774             :         }
    1775             : 
    1776           0 :         if (!val)
    1777             :                 return -EINVAL;
    1778           0 :         len = strlen(val);
    1779           0 :         if (len == 0)
    1780             :                 return -EINVAL;
    1781             : 
    1782             :         /*
    1783             :          * To set sysctl options, we use a temporary mount of proc, look up the
    1784             :          * respective sys/ file and write to it. To avoid mounting it when no
    1785             :          * options were given, we mount it only when the first sysctl option is
    1786             :          * found. Why not a persistent mount? There are problems with a
    1787             :          * persistent mount of proc in that it forces userspace not to use any
    1788             :          * proc mount options.
    1789             :          */
    1790           0 :         if (!*proc_mnt) {
    1791           0 :                 proc_fs_type = get_fs_type("proc");
    1792           0 :                 if (!proc_fs_type) {
    1793           0 :                         pr_err("Failed to find procfs to set sysctl from command line\n");
    1794           0 :                         return 0;
    1795             :                 }
    1796           0 :                 *proc_mnt = kern_mount(proc_fs_type);
    1797           0 :                 put_filesystem(proc_fs_type);
    1798           0 :                 if (IS_ERR(*proc_mnt)) {
    1799           0 :                         pr_err("Failed to mount procfs to set sysctl from command line\n");
    1800           0 :                         return 0;
    1801             :                 }
    1802             :         }
    1803             : 
    1804           0 :         path = kasprintf(GFP_KERNEL, "sys/%s", param);
    1805           0 :         if (!path)
    1806           0 :                 panic("%s: Failed to allocate path for %s\n", __func__, param);
    1807           0 :         strreplace(path, '.', '/');
    1808             : 
    1809           0 :         file = file_open_root((*proc_mnt)->mnt_root, *proc_mnt, path, O_WRONLY, 0);
    1810           0 :         if (IS_ERR(file)) {
    1811           0 :                 err = PTR_ERR(file);
    1812           0 :                 if (err == -ENOENT)
    1813           0 :                         pr_err("Failed to set sysctl parameter '%s=%s': parameter not found\n",
    1814             :                                 param, val);
    1815           0 :                 else if (err == -EACCES)
    1816           0 :                         pr_err("Failed to set sysctl parameter '%s=%s': permission denied (read-only?)\n",
    1817             :                                 param, val);
    1818             :                 else
    1819           0 :                         pr_err("Error %pe opening proc file to set sysctl parameter '%s=%s'\n",
    1820             :                                 file, param, val);
    1821           0 :                 goto out;
    1822             :         }
    1823           0 :         wret = kernel_write(file, val, len, &pos);
    1824           0 :         if (wret < 0) {
    1825           0 :                 err = wret;
    1826           0 :                 if (err == -EINVAL)
    1827           0 :                         pr_err("Failed to set sysctl parameter '%s=%s': invalid value\n",
    1828             :                                 param, val);
    1829             :                 else
    1830           0 :                         pr_err("Error %pe writing to proc file to set sysctl parameter '%s=%s'\n",
    1831             :                                 ERR_PTR(err), param, val);
    1832           0 :         } else if (wret != len) {
    1833           0 :                 pr_err("Wrote only %zd bytes of %d writing to proc file %s to set sysctl parameter '%s=%s\n",
    1834             :                         wret, len, path, param, val);
    1835             :         }
    1836             : 
    1837           0 :         err = filp_close(file, NULL);
    1838           0 :         if (err)
    1839           0 :                 pr_err("Error %pe closing proc file to set sysctl parameter '%s=%s\n",
    1840             :                         ERR_PTR(err), param, val);
    1841           0 : out:
    1842           0 :         kfree(path);
    1843           0 :         return 0;
    1844             : }
    1845             : 
    1846           1 : void do_sysctl_args(void)
    1847             : {
    1848           1 :         char *command_line;
    1849           1 :         struct vfsmount *proc_mnt = NULL;
    1850             : 
    1851           1 :         command_line = kstrdup(saved_command_line, GFP_KERNEL);
    1852           1 :         if (!command_line)
    1853           0 :                 panic("%s: Failed to allocate copy of command line\n", __func__);
    1854             : 
    1855           1 :         parse_args("Setting sysctl args", command_line,
    1856             :                    NULL, 0, -1, -1, &proc_mnt, process_sysctl_arg);
    1857             : 
    1858           1 :         if (proc_mnt)
    1859           0 :                 kern_unmount(proc_mnt);
    1860             : 
    1861           1 :         kfree(command_line);
    1862           1 : }

Generated by: LCOV version 1.14