LCOV - code coverage report
Current view: top level - kernel - utsname_sysctl.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 3 24 12.5 %
Date: 2023-08-24 13:40:31 Functions: 1 3 33.3 %

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

Generated by: LCOV version 1.14