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 1239732acdSEric W. Biederman #include <linux/module.h> 1339732acdSEric W. Biederman #include <linux/uts.h> 1439732acdSEric W. Biederman #include <linux/utsname.h> 1539732acdSEric W. Biederman #include <linux/version.h> 1639732acdSEric W. Biederman #include <linux/sysctl.h> 1739732acdSEric W. Biederman 1839732acdSEric W. Biederman static void *get_uts(ctl_table *table, int write) 1939732acdSEric W. Biederman { 2039732acdSEric W. Biederman char *which = table->data; 21*32df81cbSPavel Emelyanov struct uts_namespace *uts_ns; 22*32df81cbSPavel Emelyanov 23*32df81cbSPavel Emelyanov uts_ns = current->nsproxy->uts_ns; 24*32df81cbSPavel Emelyanov which = (which - (char *)&init_uts_ns) + (char *)uts_ns; 257d69a1f4SCedric Le Goater 2639732acdSEric W. Biederman if (!write) 2739732acdSEric W. Biederman down_read(&uts_sem); 2839732acdSEric W. Biederman else 2939732acdSEric W. Biederman down_write(&uts_sem); 3039732acdSEric W. Biederman return which; 3139732acdSEric W. Biederman } 3239732acdSEric W. Biederman 3339732acdSEric W. Biederman static void put_uts(ctl_table *table, int write, void *which) 3439732acdSEric W. Biederman { 3539732acdSEric W. Biederman if (!write) 3639732acdSEric W. Biederman up_read(&uts_sem); 3739732acdSEric W. Biederman else 3839732acdSEric W. Biederman up_write(&uts_sem); 3939732acdSEric W. Biederman } 4039732acdSEric W. Biederman 4139732acdSEric W. Biederman #ifdef CONFIG_PROC_FS 4239732acdSEric W. Biederman /* 4339732acdSEric W. Biederman * Special case of dostring for the UTS structure. This has locks 4439732acdSEric W. Biederman * to observe. Should this be in kernel/sys.c ???? 4539732acdSEric W. Biederman */ 4639732acdSEric W. Biederman static int proc_do_uts_string(ctl_table *table, int write, struct file *filp, 4739732acdSEric W. Biederman void __user *buffer, size_t *lenp, loff_t *ppos) 4839732acdSEric W. Biederman { 4939732acdSEric W. Biederman struct ctl_table uts_table; 5039732acdSEric W. Biederman int r; 5139732acdSEric W. Biederman memcpy(&uts_table, table, sizeof(uts_table)); 5239732acdSEric W. Biederman uts_table.data = get_uts(table, write); 5339732acdSEric W. Biederman r = proc_dostring(&uts_table,write,filp,buffer,lenp, ppos); 5439732acdSEric W. Biederman put_uts(table, write, uts_table.data); 5539732acdSEric W. Biederman return r; 5639732acdSEric W. Biederman } 5739732acdSEric W. Biederman #else 5839732acdSEric W. Biederman #define proc_do_uts_string NULL 5939732acdSEric W. Biederman #endif 6039732acdSEric W. Biederman 6139732acdSEric W. Biederman 6239732acdSEric W. Biederman #ifdef CONFIG_SYSCTL_SYSCALL 6339732acdSEric W. Biederman /* The generic string strategy routine: */ 6439732acdSEric W. Biederman static int sysctl_uts_string(ctl_table *table, int __user *name, int nlen, 6539732acdSEric W. Biederman void __user *oldval, size_t __user *oldlenp, 6639732acdSEric W. Biederman void __user *newval, size_t newlen) 6739732acdSEric W. Biederman { 6839732acdSEric W. Biederman struct ctl_table uts_table; 6939732acdSEric W. Biederman int r, write; 7039732acdSEric W. Biederman write = newval && newlen; 7139732acdSEric W. Biederman memcpy(&uts_table, table, sizeof(uts_table)); 7239732acdSEric W. Biederman uts_table.data = get_uts(table, write); 7339732acdSEric W. Biederman r = sysctl_string(&uts_table, name, nlen, 7439732acdSEric W. Biederman oldval, oldlenp, newval, newlen); 7539732acdSEric W. Biederman put_uts(table, write, uts_table.data); 7639732acdSEric W. Biederman return r; 7739732acdSEric W. Biederman } 7839732acdSEric W. Biederman #else 7939732acdSEric W. Biederman #define sysctl_uts_string NULL 8039732acdSEric W. Biederman #endif 8139732acdSEric W. Biederman 8239732acdSEric W. Biederman static struct ctl_table uts_kern_table[] = { 8339732acdSEric W. Biederman { 8439732acdSEric W. Biederman .ctl_name = KERN_OSTYPE, 8539732acdSEric W. Biederman .procname = "ostype", 8639732acdSEric W. Biederman .data = init_uts_ns.name.sysname, 8739732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.sysname), 8839732acdSEric W. Biederman .mode = 0444, 8939732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 9039732acdSEric W. Biederman .strategy = sysctl_uts_string, 9139732acdSEric W. Biederman }, 9239732acdSEric W. Biederman { 9339732acdSEric W. Biederman .ctl_name = KERN_OSRELEASE, 9439732acdSEric W. Biederman .procname = "osrelease", 9539732acdSEric W. Biederman .data = init_uts_ns.name.release, 9639732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.release), 9739732acdSEric W. Biederman .mode = 0444, 9839732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 9939732acdSEric W. Biederman .strategy = sysctl_uts_string, 10039732acdSEric W. Biederman }, 10139732acdSEric W. Biederman { 10239732acdSEric W. Biederman .ctl_name = KERN_VERSION, 10339732acdSEric W. Biederman .procname = "version", 10439732acdSEric W. Biederman .data = init_uts_ns.name.version, 10539732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.version), 10639732acdSEric W. Biederman .mode = 0444, 10739732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 10839732acdSEric W. Biederman .strategy = sysctl_uts_string, 10939732acdSEric W. Biederman }, 11039732acdSEric W. Biederman { 11139732acdSEric W. Biederman .ctl_name = KERN_NODENAME, 11239732acdSEric W. Biederman .procname = "hostname", 11339732acdSEric W. Biederman .data = init_uts_ns.name.nodename, 11439732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.nodename), 11539732acdSEric W. Biederman .mode = 0644, 11639732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 11739732acdSEric W. Biederman .strategy = sysctl_uts_string, 11839732acdSEric W. Biederman }, 11939732acdSEric W. Biederman { 12039732acdSEric W. Biederman .ctl_name = KERN_DOMAINNAME, 12139732acdSEric W. Biederman .procname = "domainname", 12239732acdSEric W. Biederman .data = init_uts_ns.name.domainname, 12339732acdSEric W. Biederman .maxlen = sizeof(init_uts_ns.name.domainname), 12439732acdSEric W. Biederman .mode = 0644, 12539732acdSEric W. Biederman .proc_handler = proc_do_uts_string, 12639732acdSEric W. Biederman .strategy = sysctl_uts_string, 12739732acdSEric W. Biederman }, 12839732acdSEric W. Biederman {} 12939732acdSEric W. Biederman }; 13039732acdSEric W. Biederman 13139732acdSEric W. Biederman static struct ctl_table uts_root_table[] = { 13239732acdSEric W. Biederman { 13339732acdSEric W. Biederman .ctl_name = CTL_KERN, 13439732acdSEric W. Biederman .procname = "kernel", 13539732acdSEric W. Biederman .mode = 0555, 13639732acdSEric W. Biederman .child = uts_kern_table, 13739732acdSEric W. Biederman }, 13839732acdSEric W. Biederman {} 13939732acdSEric W. Biederman }; 14039732acdSEric W. Biederman 14139732acdSEric W. Biederman static int __init utsname_sysctl_init(void) 14239732acdSEric W. Biederman { 1430b4d4147SEric W. Biederman register_sysctl_table(uts_root_table); 14439732acdSEric W. Biederman return 0; 14539732acdSEric W. Biederman } 14639732acdSEric W. Biederman 14739732acdSEric W. Biederman __initcall(utsname_sysctl_init); 148