cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

utsname_sysctl.c (3317B)


      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
     17static 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 */
     32static int proc_do_uts_string(struct ctl_table *table, int write,
     33		  void *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
     72static DEFINE_CTL_TABLE_POLL(hostname_poll);
     73static DEFINE_CTL_TABLE_POLL(domainname_poll);
     74
     75static 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
    116static 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 */
    130void 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
    138static int __init utsname_sysctl_init(void)
    139{
    140	register_sysctl_table(uts_root_table);
    141	return 0;
    142}
    143
    144device_initcall(utsname_sysctl_init);