139732acdSEric W. Biederman /* 239732acdSEric W. Biederman * Copyright (C) 2007 339732acdSEric W. Biederman * 439732acdSEric W. Biederman * Author: Eric Biederman <ebiederm@xmision.com> 539732acdSEric W. Biederman * 639732acdSEric W. Biederman * This program is free software; you can redistribute it and/or 739732acdSEric W. Biederman * modify it under the terms of the GNU General Public License as 839732acdSEric W. Biederman * published by the Free Software Foundation, version 2 of the 939732acdSEric W. Biederman * License. 1039732acdSEric W. Biederman */ 1139732acdSEric W. Biederman 129984de1aSPaul Gortmaker #include <linux/export.h> 1339732acdSEric W. Biederman #include <linux/uts.h> 1439732acdSEric W. Biederman #include <linux/utsname.h> 1539732acdSEric W. Biederman #include <linux/sysctl.h> 16f1ecf068SLucas De Marchi #include <linux/wait.h> 17*cd9c513bSIngo Molnar #include <linux/rwsem.h> 1839732acdSEric W. Biederman 19cd89f46bSYuanhan Liu #ifdef CONFIG_PROC_SYSCTL 20cd89f46bSYuanhan Liu 216f8fd1d7SJoe Perches static void *get_uts(struct ctl_table *table, int write) 2239732acdSEric W. Biederman { 2339732acdSEric W. Biederman char *which = table->data; 2432df81cbSPavel Emelyanov struct uts_namespace *uts_ns; 2532df81cbSPavel Emelyanov 2632df81cbSPavel Emelyanov uts_ns = current->nsproxy->uts_ns; 2732df81cbSPavel Emelyanov which = (which - (char *)&init_uts_ns) + (char *)uts_ns; 287d69a1f4SCedric Le Goater 2939732acdSEric W. Biederman if (!write) 3039732acdSEric W. Biederman down_read(&uts_sem); 3139732acdSEric W. Biederman else 3239732acdSEric W. Biederman down_write(&uts_sem); 3339732acdSEric W. Biederman return which; 3439732acdSEric W. Biederman } 3539732acdSEric W. Biederman 366f8fd1d7SJoe Perches static void put_uts(struct ctl_table *table, int write, void *which) 3739732acdSEric W. Biederman { 3839732acdSEric W. Biederman if (!write) 3939732acdSEric W. Biederman up_read(&uts_sem); 4039732acdSEric W. Biederman else 4139732acdSEric W. Biederman up_write(&uts_sem); 4239732acdSEric W. Biederman } 4339732acdSEric W. Biederman 4439732acdSEric W. Biederman /* 4539732acdSEric W. Biederman * Special case of dostring for the UTS structure. This has locks 4639732acdSEric W. Biederman * to observe. Should this be in kernel/sys.c ???? 4739732acdSEric W. Biederman */ 486f8fd1d7SJoe Perches static int proc_do_uts_string(struct ctl_table *table, int write, 4939732acdSEric W. Biederman void __user *buffer, size_t *lenp, loff_t *ppos) 5039732acdSEric W. Biederman { 5139732acdSEric W. Biederman struct ctl_table uts_table; 5239732acdSEric W. Biederman int r; 5339732acdSEric W. Biederman memcpy(&uts_table, table, sizeof(uts_table)); 5439732acdSEric W. Biederman uts_table.data = get_uts(table, write); 558d65af78SAlexey Dobriyan r = proc_dostring(&uts_table, write, buffer, lenp, ppos); 5639732acdSEric W. Biederman put_uts(table, write, uts_table.data); 57f1ecf068SLucas De Marchi 58f1ecf068SLucas De Marchi if (write) 59f1ecf068SLucas De Marchi proc_sys_poll_notify(table->poll); 60f1ecf068SLucas De Marchi 6139732acdSEric W. Biederman return r; 6239732acdSEric W. Biederman } 6339732acdSEric W. Biederman #else 6439732acdSEric W. Biederman #define proc_do_uts_string NULL 6539732acdSEric W. Biederman #endif 6639732acdSEric W. Biederman 67f1ecf068SLucas De Marchi static DEFINE_CTL_TABLE_POLL(hostname_poll); 68f1ecf068SLucas De Marchi static DEFINE_CTL_TABLE_POLL(domainname_poll); 69f1ecf068SLucas De Marchi 7039732acdSEric W. Biederman static struct ctl_table uts_kern_table[] = { 7139732acdSEric W. Biederman { 7239732acdSEric W. Biederman .procname = "ostype", 7339732acdSEric W. Biederman .data = init_uts_ns.name.sysname, 7439732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.sysname), 7539732acdSEric W. Biederman .mode = 0444, 7639732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 7739732acdSEric W. Biederman }, 7839732acdSEric W. Biederman { 7939732acdSEric W. Biederman .procname = "osrelease", 8039732acdSEric W. Biederman .data = init_uts_ns.name.release, 8139732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.release), 8239732acdSEric W. Biederman .mode = 0444, 8339732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 8439732acdSEric W. Biederman }, 8539732acdSEric W. Biederman { 8639732acdSEric W. Biederman .procname = "version", 8739732acdSEric W. Biederman .data = init_uts_ns.name.version, 8839732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.version), 8939732acdSEric W. Biederman .mode = 0444, 9039732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 9139732acdSEric W. Biederman }, 9239732acdSEric W. Biederman { 9339732acdSEric W. Biederman .procname = "hostname", 9439732acdSEric W. Biederman .data = init_uts_ns.name.nodename, 9539732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.nodename), 9639732acdSEric W. Biederman .mode = 0644, 9739732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 98f1ecf068SLucas De Marchi .poll = &hostname_poll, 9939732acdSEric W. Biederman }, 10039732acdSEric W. Biederman { 10139732acdSEric W. Biederman .procname = "domainname", 10239732acdSEric W. Biederman .data = init_uts_ns.name.domainname, 10339732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.domainname), 10439732acdSEric W. Biederman .mode = 0644, 10539732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 106f1ecf068SLucas De Marchi .poll = &domainname_poll, 10739732acdSEric W. Biederman }, 10839732acdSEric W. Biederman {} 10939732acdSEric W. Biederman }; 11039732acdSEric W. Biederman 11139732acdSEric W. Biederman static struct ctl_table uts_root_table[] = { 11239732acdSEric W. Biederman { 11339732acdSEric W. Biederman .procname = "kernel", 11439732acdSEric W. Biederman .mode = 0555, 11539732acdSEric W. Biederman .child = uts_kern_table, 11639732acdSEric W. Biederman }, 11739732acdSEric W. Biederman {} 11839732acdSEric W. Biederman }; 11939732acdSEric W. Biederman 120f1ecf068SLucas De Marchi #ifdef CONFIG_PROC_SYSCTL 121f1ecf068SLucas De Marchi /* 122f1ecf068SLucas De Marchi * Notify userspace about a change in a certain entry of uts_kern_table, 123f1ecf068SLucas De Marchi * identified by the parameter proc. 124f1ecf068SLucas De Marchi */ 125f1ecf068SLucas De Marchi void uts_proc_notify(enum uts_proc proc) 126f1ecf068SLucas De Marchi { 127f1ecf068SLucas De Marchi struct ctl_table *table = &uts_kern_table[proc]; 128f1ecf068SLucas De Marchi 129f1ecf068SLucas De Marchi proc_sys_poll_notify(table->poll); 130f1ecf068SLucas De Marchi } 131f1ecf068SLucas De Marchi #endif 132f1ecf068SLucas De Marchi 13339732acdSEric W. Biederman static int __init utsname_sysctl_init(void) 13439732acdSEric W. Biederman { 1350b4d4147SEric W. Biederman register_sysctl_table(uts_root_table); 13639732acdSEric W. Biederman return 0; 13739732acdSEric W. Biederman } 13839732acdSEric W. Biederman 13995583e4aSFabian Frederick device_initcall(utsname_sysctl_init); 140