root/kernel/utsname_sysctl.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. get_uts
  2. proc_do_uts_string
  3. uts_proc_notify
  4. utsname_sysctl_init

   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 static void *get_uts(struct ctl_table *table)
  18 {
  19         char *which = table->data;
  20         struct uts_namespace *uts_ns;
  21 
  22         uts_ns = current->nsproxy->uts_ns;
  23         which = (which - (char *)&init_uts_ns) + (char *)uts_ns;
  24 
  25         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 static int proc_do_uts_string(struct ctl_table *table, int write,
  33                   void __user *buffer, size_t *lenp, loff_t *ppos)
  34 {
  35         struct ctl_table uts_table;
  36         int r;
  37         char tmp_data[__NEW_UTS_LEN + 1];
  38 
  39         memcpy(&uts_table, table, sizeof(uts_table));
  40         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         down_read(&uts_sem);
  49         memcpy(tmp_data, get_uts(table), sizeof(tmp_data));
  50         up_read(&uts_sem);
  51         r = proc_dostring(&uts_table, write, buffer, lenp, ppos);
  52 
  53         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                 down_write(&uts_sem);
  61                 memcpy(get_uts(table), tmp_data, sizeof(tmp_data));
  62                 up_write(&uts_sem);
  63                 proc_sys_poll_notify(table->poll);
  64         }
  65 
  66         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 void uts_proc_notify(enum uts_proc proc)
 131 {
 132         struct ctl_table *table = &uts_kern_table[proc];
 133 
 134         proc_sys_poll_notify(table->poll);
 135 }
 136 #endif
 137 
 138 static int __init utsname_sysctl_init(void)
 139 {
 140         register_sysctl_table(uts_root_table);
 141         return 0;
 142 }
 143 
 144 device_initcall(utsname_sysctl_init);

/* [<][>][^][v][top][bottom][index][help] */