1*39732acdSEric W. Biederman /* 2*39732acdSEric W. Biederman * Copyright (C) 2007 3*39732acdSEric W. Biederman * 4*39732acdSEric W. Biederman * Author: Eric Biederman <ebiederm@xmision.com> 5*39732acdSEric W. Biederman * 6*39732acdSEric W. Biederman * This program is free software; you can redistribute it and/or 7*39732acdSEric W. Biederman * modify it under the terms of the GNU General Public License as 8*39732acdSEric W. Biederman * published by the Free Software Foundation, version 2 of the 9*39732acdSEric W. Biederman * License. 10*39732acdSEric W. Biederman */ 11*39732acdSEric W. Biederman 12*39732acdSEric W. Biederman #include <linux/module.h> 13*39732acdSEric W. Biederman #include <linux/uts.h> 14*39732acdSEric W. Biederman #include <linux/utsname.h> 15*39732acdSEric W. Biederman #include <linux/version.h> 16*39732acdSEric W. Biederman #include <linux/sysctl.h> 17*39732acdSEric W. Biederman 18*39732acdSEric W. Biederman static void *get_uts(ctl_table *table, int write) 19*39732acdSEric W. Biederman { 20*39732acdSEric W. Biederman char *which = table->data; 21*39732acdSEric W. Biederman #ifdef CONFIG_UTS_NS 22*39732acdSEric W. Biederman struct uts_namespace *uts_ns = current->nsproxy->uts_ns; 23*39732acdSEric W. Biederman which = (which - (char *)&init_uts_ns) + (char *)uts_ns; 24*39732acdSEric W. Biederman #endif 25*39732acdSEric W. Biederman if (!write) 26*39732acdSEric W. Biederman down_read(&uts_sem); 27*39732acdSEric W. Biederman else 28*39732acdSEric W. Biederman down_write(&uts_sem); 29*39732acdSEric W. Biederman return which; 30*39732acdSEric W. Biederman } 31*39732acdSEric W. Biederman 32*39732acdSEric W. Biederman static void put_uts(ctl_table *table, int write, void *which) 33*39732acdSEric W. Biederman { 34*39732acdSEric W. Biederman if (!write) 35*39732acdSEric W. Biederman up_read(&uts_sem); 36*39732acdSEric W. Biederman else 37*39732acdSEric W. Biederman up_write(&uts_sem); 38*39732acdSEric W. Biederman } 39*39732acdSEric W. Biederman 40*39732acdSEric W. Biederman #ifdef CONFIG_PROC_FS 41*39732acdSEric W. Biederman /* 42*39732acdSEric W. Biederman * Special case of dostring for the UTS structure. This has locks 43*39732acdSEric W. Biederman * to observe. Should this be in kernel/sys.c ???? 44*39732acdSEric W. Biederman */ 45*39732acdSEric W. Biederman static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, 46*39732acdSEric W. Biederman void __user *buffer, size_t *lenp, loff_t *ppos) 47*39732acdSEric W. Biederman { 48*39732acdSEric W. Biederman struct ctl_table uts_table; 49*39732acdSEric W. Biederman int r; 50*39732acdSEric W. Biederman memcpy(&uts_table, table, sizeof(uts_table)); 51*39732acdSEric W. Biederman uts_table.data = get_uts(table, write); 52*39732acdSEric W. Biederman r = proc_dostring(&uts_table,write,filp,buffer,lenp, ppos); 53*39732acdSEric W. Biederman put_uts(table, write, uts_table.data); 54*39732acdSEric W. Biederman return r; 55*39732acdSEric W. Biederman } 56*39732acdSEric W. Biederman #else 57*39732acdSEric W. Biederman #define proc_do_uts_string NULL 58*39732acdSEric W. Biederman #endif 59*39732acdSEric W. Biederman 60*39732acdSEric W. Biederman 61*39732acdSEric W. Biederman #ifdef CONFIG_SYSCTL_SYSCALL 62*39732acdSEric W. Biederman /* The generic string strategy routine: */ 63*39732acdSEric W. Biederman static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, 64*39732acdSEric W. Biederman void __user *oldval, size_t __user *oldlenp, 65*39732acdSEric W. Biederman void __user *newval, size_t newlen) 66*39732acdSEric W. Biederman { 67*39732acdSEric W. Biederman struct ctl_table uts_table; 68*39732acdSEric W. Biederman int r, write; 69*39732acdSEric W. Biederman write = newval && newlen; 70*39732acdSEric W. Biederman memcpy(&uts_table, table, sizeof(uts_table)); 71*39732acdSEric W. Biederman uts_table.data = get_uts(table, write); 72*39732acdSEric W. Biederman r = sysctl_string(&uts_table, name, nlen, 73*39732acdSEric W. Biederman oldval, oldlenp, newval, newlen); 74*39732acdSEric W. Biederman put_uts(table, write, uts_table.data); 75*39732acdSEric W. Biederman return r; 76*39732acdSEric W. Biederman } 77*39732acdSEric W. Biederman #else 78*39732acdSEric W. Biederman #define sysctl_uts_string NULL 79*39732acdSEric W. Biederman #endif 80*39732acdSEric W. Biederman 81*39732acdSEric W. Biederman static struct ctl_table uts_kern_table[] = { 82*39732acdSEric W. Biederman { 83*39732acdSEric W. Biederman .ctl_name = KERN_OSTYPE, 84*39732acdSEric W. Biederman .procname = "ostype", 85*39732acdSEric W. Biederman .data = init_uts_ns.name.sysname, 86*39732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.sysname), 87*39732acdSEric W. Biederman .mode = 0444, 88*39732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 89*39732acdSEric W. Biederman .strategy = sysctl_uts_string, 90*39732acdSEric W. Biederman }, 91*39732acdSEric W. Biederman { 92*39732acdSEric W. Biederman .ctl_name = KERN_OSRELEASE, 93*39732acdSEric W. Biederman .procname = "osrelease", 94*39732acdSEric W. Biederman .data = init_uts_ns.name.release, 95*39732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.release), 96*39732acdSEric W. Biederman .mode = 0444, 97*39732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 98*39732acdSEric W. Biederman .strategy = sysctl_uts_string, 99*39732acdSEric W. Biederman }, 100*39732acdSEric W. Biederman { 101*39732acdSEric W. Biederman .ctl_name = KERN_VERSION, 102*39732acdSEric W. Biederman .procname = "version", 103*39732acdSEric W. Biederman .data = init_uts_ns.name.version, 104*39732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.version), 105*39732acdSEric W. Biederman .mode = 0444, 106*39732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 107*39732acdSEric W. Biederman .strategy = sysctl_uts_string, 108*39732acdSEric W. Biederman }, 109*39732acdSEric W. Biederman { 110*39732acdSEric W. Biederman .ctl_name = KERN_NODENAME, 111*39732acdSEric W. Biederman .procname = "hostname", 112*39732acdSEric W. Biederman .data = init_uts_ns.name.nodename, 113*39732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.nodename), 114*39732acdSEric W. Biederman .mode = 0644, 115*39732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 116*39732acdSEric W. Biederman .strategy = sysctl_uts_string, 117*39732acdSEric W. Biederman }, 118*39732acdSEric W. Biederman { 119*39732acdSEric W. Biederman .ctl_name = KERN_DOMAINNAME, 120*39732acdSEric W. Biederman .procname = "domainname", 121*39732acdSEric W. Biederman .data = init_uts_ns.name.domainname, 122*39732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.domainname), 123*39732acdSEric W. Biederman .mode = 0644, 124*39732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 125*39732acdSEric W. Biederman .strategy = sysctl_uts_string, 126*39732acdSEric W. Biederman }, 127*39732acdSEric W. Biederman {} 128*39732acdSEric W. Biederman }; 129*39732acdSEric W. Biederman 130*39732acdSEric W. Biederman static struct ctl_table uts_root_table[] = { 131*39732acdSEric W. Biederman { 132*39732acdSEric W. Biederman .ctl_name = CTL_KERN, 133*39732acdSEric W. Biederman .procname = "kernel", 134*39732acdSEric W. Biederman .mode = 0555, 135*39732acdSEric W. Biederman .child = uts_kern_table, 136*39732acdSEric W. Biederman }, 137*39732acdSEric W. Biederman {} 138*39732acdSEric W. Biederman }; 139*39732acdSEric W. Biederman 140*39732acdSEric W. Biederman static int __init utsname_sysctl_init(void) 141*39732acdSEric W. Biederman { 142*39732acdSEric W. Biederman register_sysctl_table(uts_root_table, 0); 143*39732acdSEric W. Biederman return 0; 144*39732acdSEric W. Biederman } 145*39732acdSEric W. Biederman 146*39732acdSEric W. Biederman __initcall(utsname_sysctl_init); 147