1 /* 2 * Copyright (c) 1999 Ulrich Drepper <drepper (at) cygnus.com> 3 * Copyright (c) 2005 Roland McGrath <roland (at) redhat.com> 4 * Copyright (c) 2005-2015 Dmitry V. Levin <ldv (at) altlinux.org> 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. The name of the author may not be used to endorse or promote products 16 * derived from this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 19 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 20 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 21 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 23 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 27 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "defs.h" 31 32 #include <linux/sysctl.h> 33 34 #include "xlat/sysctl_root.h" 35 #include "xlat/sysctl_kern.h" 36 #include "xlat/sysctl_vm.h" 37 #include "xlat/sysctl_net.h" 38 #include "xlat/sysctl_net_core.h" 39 #include "xlat/sysctl_net_unix.h" 40 #include "xlat/sysctl_net_ipv4.h" 41 #include "xlat/sysctl_net_ipv4_route.h" 42 #include "xlat/sysctl_net_ipv4_conf.h" 43 #include "xlat/sysctl_net_ipv6.h" 44 #include "xlat/sysctl_net_ipv6_route.h" 45 46 SYS_FUNC(sysctl) 47 { 48 struct __sysctl_args info; 49 int *name; 50 unsigned long size; 51 52 if (umove_or_printaddr(tcp, tcp->u_arg[0], &info)) 53 return RVAL_DECODED; 54 55 size = sizeof(int) * (unsigned long) info.nlen; 56 name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size); 57 if (name == NULL || 58 umoven(tcp, (unsigned long) info.name, size, name) < 0) { 59 free(name); 60 if (entering(tcp)) 61 tprintf("{%p, %d, %p, %p, %p, %lu}", 62 info.name, info.nlen, info.oldval, 63 info.oldlenp, info.newval, (unsigned long)info.newlen); 64 return RVAL_DECODED; 65 } 66 67 if (entering(tcp)) { 68 unsigned int cnt = 0, max_cnt; 69 70 tprints("{{"); 71 72 if (info.nlen == 0) 73 goto out; 74 printxval(sysctl_root, name[0], "CTL_???"); 75 ++cnt; 76 77 if (info.nlen == 1) 78 goto out; 79 switch (name[0]) { 80 case CTL_KERN: 81 tprints(", "); 82 printxval(sysctl_kern, name[1], "KERN_???"); 83 ++cnt; 84 break; 85 case CTL_VM: 86 tprints(", "); 87 printxval(sysctl_vm, name[1], "VM_???"); 88 ++cnt; 89 break; 90 case CTL_NET: 91 tprints(", "); 92 printxval(sysctl_net, name[1], "NET_???"); 93 ++cnt; 94 95 if (info.nlen == 2) 96 goto out; 97 switch (name[1]) { 98 case NET_CORE: 99 tprints(", "); 100 printxval(sysctl_net_core, name[2], 101 "NET_CORE_???"); 102 break; 103 case NET_UNIX: 104 tprints(", "); 105 printxval(sysctl_net_unix, name[2], 106 "NET_UNIX_???"); 107 break; 108 case NET_IPV4: 109 tprints(", "); 110 printxval(sysctl_net_ipv4, name[2], 111 "NET_IPV4_???"); 112 113 if (info.nlen == 3) 114 goto out; 115 switch (name[2]) { 116 case NET_IPV4_ROUTE: 117 tprints(", "); 118 printxval(sysctl_net_ipv4_route, 119 name[3], 120 "NET_IPV4_ROUTE_???"); 121 break; 122 case NET_IPV4_CONF: 123 tprints(", "); 124 printxval(sysctl_net_ipv4_conf, 125 name[3], 126 "NET_IPV4_CONF_???"); 127 break; 128 default: 129 goto out; 130 } 131 break; 132 case NET_IPV6: 133 tprints(", "); 134 printxval(sysctl_net_ipv6, name[2], 135 "NET_IPV6_???"); 136 137 if (info.nlen == 3) 138 goto out; 139 switch (name[2]) { 140 case NET_IPV6_ROUTE: 141 tprints(", "); 142 printxval(sysctl_net_ipv6_route, 143 name[3], 144 "NET_IPV6_ROUTE_???"); 145 break; 146 default: 147 goto out; 148 } 149 break; 150 default: 151 goto out; 152 } 153 break; 154 default: 155 goto out; 156 } 157 out: 158 max_cnt = info.nlen; 159 if (abbrev(tcp) && max_cnt > max_strlen) 160 max_cnt = max_strlen; 161 while (cnt < max_cnt) 162 tprintf(", %x", name[cnt++]); 163 if (cnt < (unsigned) info.nlen) 164 tprints(", ..."); 165 tprintf("}, %d, ", info.nlen); 166 } else { 167 size_t oldlen = 0; 168 if (info.oldval == NULL) { 169 tprints("NULL"); 170 } else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0 171 && info.nlen >= 2 172 && ((name[0] == CTL_KERN 173 && (name[1] == KERN_OSRELEASE 174 || name[1] == KERN_OSTYPE 175 )))) { 176 printpath(tcp, (size_t)info.oldval); 177 } else { 178 tprintf("%p", info.oldval); 179 } 180 tprintf(", %lu, ", (unsigned long)oldlen); 181 if (info.newval == NULL) 182 tprints("NULL"); 183 else if (syserror(tcp)) 184 tprintf("%p", info.newval); 185 else 186 printpath(tcp, (size_t)info.newval); 187 tprintf(", %lu", (unsigned long)info.newlen); 188 } 189 190 free(name); 191 return 0; 192 } 193