LCOV - code coverage report
Current view: top level - kernel - utsname_sysctl.c (source / functions) Hit Total Coverage
Test: landlock.info Lines: 7 29 24.1 %
Date: 2021-04-22 12:43:58 Functions: 2 3 66.7 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-only
       2             : /*
       3             :  *  Copyright (C) 2007
       4             :  *
       5             :  *  Author: Eric Biederman <ebiederm@xmision.com>
       6             :  */
       7             : 
       8             : #include <linux/export.h>
       9             : #include <linux/uts.h>
      10             : #include <linux/utsname.h>
      11             : #include <linux/sysctl.h>
      12             : #include <linux/wait.h>
      13             : #include <linux/rwsem.h>
      14             : 
      15             : #ifdef CONFIG_PROC_SYSCTL
      16             : 
      17           0 : static void *get_uts(struct ctl_table *table)
      18             : {
      19           0 :         char *which = table->data;
      20           0 :         struct uts_namespace *uts_ns;
      21             : 
      22           0 :         uts_ns = current->nsproxy->uts_ns;
      23           0 :         which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
      24             : 
      25           0 :         return which;
      26             : }
      27             : 
      28             : /*
      29             :  *      Special case of dostring for the UTS structure. This has locks
      30             :  *      to observe. Should this be in kernel/sys.c ????
      31             :  */
      32           0 : static int proc_do_uts_string(struct ctl_table *table, int write,
      33             :                   void *buffer, size_t *lenp, loff_t *ppos)
      34             : {
      35           0 :         struct ctl_table uts_table;
      36           0 :         int r;
      37           0 :         char tmp_data[__NEW_UTS_LEN + 1];
      38             : 
      39           0 :         memcpy(&uts_table, table, sizeof(uts_table));
      40           0 :         uts_table.data = tmp_data;
      41             : 
      42             :         /*
      43             :          * Buffer the value in tmp_data so that proc_dostring() can be called
      44             :          * without holding any locks.
      45             :          * We also need to read the original value in the write==1 case to
      46             :          * support partial writes.
      47             :          */
      48           0 :         down_read(&uts_sem);
      49           0 :         memcpy(tmp_data, get_uts(table), sizeof(tmp_data));
      50           0 :         up_read(&uts_sem);
      51           0 :         r = proc_dostring(&uts_table, write, buffer, lenp, ppos);
      52             : 
      53           0 :         if (write) {
      54             :                 /*
      55             :                  * Write back the new value.
      56             :                  * Note that, since we dropped uts_sem, the result can
      57             :                  * theoretically be incorrect if there are two parallel writes
      58             :                  * at non-zero offsets to the same sysctl.
      59             :                  */
      60           0 :                 down_write(&uts_sem);
      61           0 :                 memcpy(get_uts(table), tmp_data, sizeof(tmp_data));
      62           0 :                 up_write(&uts_sem);
      63           0 :                 proc_sys_poll_notify(table->poll);
      64             :         }
      65             : 
      66           0 :         return r;
      67             : }
      68             : #else
      69             : #define proc_do_uts_string NULL
      70             : #endif
      71             : 
      72             : static DEFINE_CTL_TABLE_POLL(hostname_poll);
      73             : static DEFINE_CTL_TABLE_POLL(domainname_poll);
      74             : 
      75             : static struct ctl_table uts_kern_table[] = {
      76             :         {
      77             :                 .procname       = "ostype",
      78             :                 .data           = init_uts_ns.name.sysname,
      79             :                 .maxlen         = sizeof(init_uts_ns.name.sysname),
      80             :                 .mode           = 0444,
      81             :                 .proc_handler   = proc_do_uts_string,
      82             :         },
      83             :         {
      84             :                 .procname       = "osrelease",
      85             :                 .data           = init_uts_ns.name.release,
      86             :                 .maxlen         = sizeof(init_uts_ns.name.release),
      87             :                 .mode           = 0444,
      88             :                 .proc_handler   = proc_do_uts_string,
      89             :         },
      90             :         {
      91             :                 .procname       = "version",
      92             :                 .data           = init_uts_ns.name.version,
      93             :                 .maxlen         = sizeof(init_uts_ns.name.version),
      94             :                 .mode           = 0444,
      95             :                 .proc_handler   = proc_do_uts_string,
      96             :         },
      97             :         {
      98             :                 .procname       = "hostname",
      99             :                 .data           = init_uts_ns.name.nodename,
     100             :                 .maxlen         = sizeof(init_uts_ns.name.nodename),
     101             :                 .mode           = 0644,
     102             :                 .proc_handler   = proc_do_uts_string,
     103             :                 .poll           = &hostname_poll,
     104             :         },
     105             :         {
     106             :                 .procname       = "domainname",
     107             :                 .data           = init_uts_ns.name.domainname,
     108             :                 .maxlen         = sizeof(init_uts_ns.name.domainname),
     109             :                 .mode           = 0644,
     110             :                 .proc_handler   = proc_do_uts_string,
     111             :                 .poll           = &domainname_poll,
     112             :         },
     113             :         {}
     114             : };
     115             : 
     116             : static struct ctl_table uts_root_table[] = {
     117             :         {
     118             :                 .procname       = "kernel",
     119             :                 .mode           = 0555,
     120             :                 .child          = uts_kern_table,
     121             :         },
     122             :         {}
     123             : };
     124             : 
     125             : #ifdef CONFIG_PROC_SYSCTL
     126             : /*
     127             :  * Notify userspace about a change in a certain entry of uts_kern_table,
     128             :  * identified by the parameter proc.
     129             :  */
     130           1 : void uts_proc_notify(enum uts_proc proc)
     131             : {
     132           1 :         struct ctl_table *table = &uts_kern_table[proc];
     133             : 
     134           1 :         proc_sys_poll_notify(table->poll);
     135           1 : }
     136             : #endif
     137             : 
     138           1 : static int __init utsname_sysctl_init(void)
     139             : {
     140           1 :         register_sysctl_table(uts_root_table);
     141           1 :         return 0;
     142             : }
     143             : 
     144             : device_initcall(utsname_sysctl_init);

Generated by: LCOV version 1.14