1*dbec2846SEric W. Biederman /* 2*dbec2846SEric W. Biederman * This program is free software; you can redistribute it and/or 3*dbec2846SEric W. Biederman * modify it under the terms of the GNU General Public License as 4*dbec2846SEric W. Biederman * published by the Free Software Foundation, version 2 of the 5*dbec2846SEric W. Biederman * License. 6*dbec2846SEric W. Biederman */ 7*dbec2846SEric W. Biederman 8*dbec2846SEric W. Biederman #include <linux/stat.h> 9*dbec2846SEric W. Biederman #include <linux/sysctl.h> 10*dbec2846SEric W. Biederman #include <linux/slab.h> 11*dbec2846SEric W. Biederman #include <linux/user_namespace.h> 12*dbec2846SEric W. Biederman 13*dbec2846SEric W. Biederman #ifdef CONFIG_SYSCTL 14*dbec2846SEric W. Biederman static struct ctl_table_set * 15*dbec2846SEric W. Biederman set_lookup(struct ctl_table_root *root) 16*dbec2846SEric W. Biederman { 17*dbec2846SEric W. Biederman return ¤t_user_ns()->set; 18*dbec2846SEric W. Biederman } 19*dbec2846SEric W. Biederman 20*dbec2846SEric W. Biederman static int set_is_seen(struct ctl_table_set *set) 21*dbec2846SEric W. Biederman { 22*dbec2846SEric W. Biederman return ¤t_user_ns()->set == set; 23*dbec2846SEric W. Biederman } 24*dbec2846SEric W. Biederman 25*dbec2846SEric W. Biederman static int set_permissions(struct ctl_table_header *head, 26*dbec2846SEric W. Biederman struct ctl_table *table) 27*dbec2846SEric W. Biederman { 28*dbec2846SEric W. Biederman struct user_namespace *user_ns = 29*dbec2846SEric W. Biederman container_of(head->set, struct user_namespace, set); 30*dbec2846SEric W. Biederman int mode; 31*dbec2846SEric W. Biederman 32*dbec2846SEric W. Biederman /* Allow users with CAP_SYS_RESOURCE unrestrained access */ 33*dbec2846SEric W. Biederman if (ns_capable(user_ns, CAP_SYS_RESOURCE)) 34*dbec2846SEric W. Biederman mode = (table->mode & S_IRWXU) >> 6; 35*dbec2846SEric W. Biederman else 36*dbec2846SEric W. Biederman /* Allow all others at most read-only access */ 37*dbec2846SEric W. Biederman mode = table->mode & S_IROTH; 38*dbec2846SEric W. Biederman return (mode << 6) | (mode << 3) | mode; 39*dbec2846SEric W. Biederman } 40*dbec2846SEric W. Biederman 41*dbec2846SEric W. Biederman static struct ctl_table_root set_root = { 42*dbec2846SEric W. Biederman .lookup = set_lookup, 43*dbec2846SEric W. Biederman .permissions = set_permissions, 44*dbec2846SEric W. Biederman }; 45*dbec2846SEric W. Biederman 46*dbec2846SEric W. Biederman static struct ctl_table userns_table[] = { 47*dbec2846SEric W. Biederman { } 48*dbec2846SEric W. Biederman }; 49*dbec2846SEric W. Biederman #endif /* CONFIG_SYSCTL */ 50*dbec2846SEric W. Biederman 51*dbec2846SEric W. Biederman bool setup_userns_sysctls(struct user_namespace *ns) 52*dbec2846SEric W. Biederman { 53*dbec2846SEric W. Biederman #ifdef CONFIG_SYSCTL 54*dbec2846SEric W. Biederman struct ctl_table *tbl; 55*dbec2846SEric W. Biederman setup_sysctl_set(&ns->set, &set_root, set_is_seen); 56*dbec2846SEric W. Biederman tbl = kmemdup(userns_table, sizeof(userns_table), GFP_KERNEL); 57*dbec2846SEric W. Biederman if (tbl) { 58*dbec2846SEric W. Biederman ns->sysctls = __register_sysctl_table(&ns->set, "userns", tbl); 59*dbec2846SEric W. Biederman } 60*dbec2846SEric W. Biederman if (!ns->sysctls) { 61*dbec2846SEric W. Biederman kfree(tbl); 62*dbec2846SEric W. Biederman retire_sysctl_set(&ns->set); 63*dbec2846SEric W. Biederman return false; 64*dbec2846SEric W. Biederman } 65*dbec2846SEric W. Biederman #endif 66*dbec2846SEric W. Biederman return true; 67*dbec2846SEric W. Biederman } 68*dbec2846SEric W. Biederman 69*dbec2846SEric W. Biederman void retire_userns_sysctls(struct user_namespace *ns) 70*dbec2846SEric W. Biederman { 71*dbec2846SEric W. Biederman #ifdef CONFIG_SYSCTL 72*dbec2846SEric W. Biederman struct ctl_table *tbl; 73*dbec2846SEric W. Biederman 74*dbec2846SEric W. Biederman tbl = ns->sysctls->ctl_table_arg; 75*dbec2846SEric W. Biederman unregister_sysctl_table(ns->sysctls); 76*dbec2846SEric W. Biederman retire_sysctl_set(&ns->set); 77*dbec2846SEric W. Biederman kfree(tbl); 78*dbec2846SEric W. Biederman #endif 79*dbec2846SEric W. Biederman } 80*dbec2846SEric W. Biederman 81*dbec2846SEric W. Biederman static __init int user_namespace_sysctl_init(void) 82*dbec2846SEric W. Biederman { 83*dbec2846SEric W. Biederman #ifdef CONFIG_SYSCTL 84*dbec2846SEric W. Biederman static struct ctl_table_header *userns_header; 85*dbec2846SEric W. Biederman static struct ctl_table empty[1]; 86*dbec2846SEric W. Biederman /* 87*dbec2846SEric W. Biederman * It is necessary to register the userns directory in the 88*dbec2846SEric W. Biederman * default set so that registrations in the child sets work 89*dbec2846SEric W. Biederman * properly. 90*dbec2846SEric W. Biederman */ 91*dbec2846SEric W. Biederman userns_header = register_sysctl("userns", empty); 92*dbec2846SEric W. Biederman BUG_ON(!userns_header); 93*dbec2846SEric W. Biederman BUG_ON(!setup_userns_sysctls(&init_user_ns)); 94*dbec2846SEric W. Biederman #endif 95*dbec2846SEric W. Biederman return 0; 96*dbec2846SEric W. Biederman } 97*dbec2846SEric W. Biederman subsys_initcall(user_namespace_sysctl_init); 98*dbec2846SEric W. Biederman 99*dbec2846SEric W. Biederman 100