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