]> granicus.if.org Git - strace/blob - sysctl.c
rtnl_neightbl: always decode struct ndt_config and struct ndt_stats
[strace] / sysctl.c
1 /*
2  * Copyright (c) 1999 Ulrich Drepper <drepper@cygnus.com>
3  * Copyright (c) 2005 Roland McGrath <roland@redhat.com>
4  * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
5  * Copyright (c) 2014-2018 The strace developers.
6  * All rights reserved.
7  *
8  * SPDX-License-Identifier: LGPL-2.1-or-later
9  */
10
11 #include "defs.h"
12
13 #include <linux/sysctl.h>
14
15 #include "xlat/sysctl_root.h"
16 #include "xlat/sysctl_kern.h"
17 #include "xlat/sysctl_vm.h"
18 #include "xlat/sysctl_net.h"
19 #include "xlat/sysctl_net_core.h"
20 #include "xlat/sysctl_net_unix.h"
21 #include "xlat/sysctl_net_ipv4.h"
22 #include "xlat/sysctl_net_ipv4_route.h"
23 #include "xlat/sysctl_net_ipv4_conf.h"
24 #include "xlat/sysctl_net_ipv6.h"
25 #include "xlat/sysctl_net_ipv6_route.h"
26
27 SYS_FUNC(sysctl)
28 {
29         struct __sysctl_args info;
30         int *name;
31         unsigned long size;
32
33         if (umove_or_printaddr(tcp, tcp->u_arg[0], &info))
34                 return RVAL_DECODED;
35
36         size = sizeof(int) * (unsigned long) info.nlen;
37         name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size);
38         if (name == NULL ||
39             umoven(tcp, (unsigned long) info.name, size, name) < 0) {
40                 free(name);
41                 if (entering(tcp))
42                         tprintf("{%p, %d, %p, %p, %p, %lu}",
43                                 info.name, info.nlen, info.oldval,
44                                 info.oldlenp, info.newval, (unsigned long)info.newlen);
45                 return RVAL_DECODED;
46         }
47
48         if (entering(tcp)) {
49                 unsigned int cnt = 0, max_cnt;
50
51                 tprints("{{");
52
53                 if (info.nlen == 0)
54                         goto out;
55                 printxval(sysctl_root, name[0], "CTL_???");
56                 ++cnt;
57
58                 if (info.nlen == 1)
59                         goto out;
60                 switch (name[0]) {
61                 case CTL_KERN:
62                         tprints(", ");
63                         printxval(sysctl_kern, name[1], "KERN_???");
64                         ++cnt;
65                         break;
66                 case CTL_VM:
67                         tprints(", ");
68                         printxval(sysctl_vm, name[1], "VM_???");
69                         ++cnt;
70                         break;
71                 case CTL_NET:
72                         tprints(", ");
73                         printxval(sysctl_net, name[1], "NET_???");
74                         ++cnt;
75
76                         if (info.nlen == 2)
77                                 goto out;
78                         switch (name[1]) {
79                         case NET_CORE:
80                                 tprints(", ");
81                                 printxval(sysctl_net_core, name[2],
82                                           "NET_CORE_???");
83                                 break;
84                         case NET_UNIX:
85                                 tprints(", ");
86                                 printxval(sysctl_net_unix, name[2],
87                                           "NET_UNIX_???");
88                                 break;
89                         case NET_IPV4:
90                                 tprints(", ");
91                                 printxval(sysctl_net_ipv4, name[2],
92                                           "NET_IPV4_???");
93
94                                 if (info.nlen == 3)
95                                         goto out;
96                                 switch (name[2]) {
97                                 case NET_IPV4_ROUTE:
98                                         tprints(", ");
99                                         printxval(sysctl_net_ipv4_route,
100                                                   name[3],
101                                                   "NET_IPV4_ROUTE_???");
102                                         break;
103                                 case NET_IPV4_CONF:
104                                         tprints(", ");
105                                         printxval(sysctl_net_ipv4_conf,
106                                                   name[3],
107                                                   "NET_IPV4_CONF_???");
108                                         break;
109                                 default:
110                                         goto out;
111                                 }
112                                 break;
113                         case NET_IPV6:
114                                 tprints(", ");
115                                 printxval(sysctl_net_ipv6, name[2],
116                                           "NET_IPV6_???");
117
118                                 if (info.nlen == 3)
119                                         goto out;
120                                 switch (name[2]) {
121                                 case NET_IPV6_ROUTE:
122                                         tprints(", ");
123                                         printxval(sysctl_net_ipv6_route,
124                                                   name[3],
125                                                   "NET_IPV6_ROUTE_???");
126                                         break;
127                                 default:
128                                         goto out;
129                                 }
130                                 break;
131                         default:
132                                 goto out;
133                         }
134                         break;
135                 default:
136                         goto out;
137                 }
138 out:
139                 max_cnt = info.nlen;
140                 if (abbrev(tcp) && max_cnt > max_strlen)
141                         max_cnt = max_strlen;
142                 while (cnt < max_cnt)
143                         tprintf(", %x", name[cnt++]);
144                 if (cnt < (unsigned) info.nlen)
145                         tprints(", ...");
146                 tprintf("}, %d, ", info.nlen);
147         } else {
148                 size_t oldlen = 0;
149                 if (info.oldval == NULL) {
150                         tprints("NULL");
151                 } else if (umove(tcp, ptr_to_kulong(info.oldlenp), &oldlen) >= 0
152                            && info.nlen >= 2
153                            && ((name[0] == CTL_KERN
154                                 && (name[1] == KERN_OSRELEASE
155                                     || name[1] == KERN_OSTYPE
156                                         )))) {
157                         printpath(tcp, ptr_to_kulong(info.oldval));
158                 } else {
159                         tprintf("%p", info.oldval);
160                 }
161                 tprintf(", %lu, ", (unsigned long)oldlen);
162                 if (info.newval == NULL)
163                         tprints("NULL");
164                 else if (syserror(tcp))
165                         tprintf("%p", info.newval);
166                 else
167                         printpath(tcp, ptr_to_kulong(info.newval));
168                 tprintf(", %lu", (unsigned long)info.newlen);
169         }
170
171         free(name);
172         return 0;
173 }