138a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin/*
238a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * Copyright (c) 1999 Ulrich Drepper <drepper@cygnus.com>
338a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * Copyright (c) 2005 Roland McGrath <roland@redhat.com>
438a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * Copyright (c) 2005-2015 Dmitry V. Levin <ldv@altlinux.org>
538a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * All rights reserved.
638a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin *
738a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * Redistribution and use in source and binary forms, with or without
838a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * modification, are permitted provided that the following conditions
938a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * are met:
1038a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * 1. Redistributions of source code must retain the above copyright
1138a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin *    notice, this list of conditions and the following disclaimer.
1238a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * 2. Redistributions in binary form must reproduce the above copyright
1338a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin *    notice, this list of conditions and the following disclaimer in the
1438a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin *    documentation and/or other materials provided with the distribution.
1538a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * 3. The name of the author may not be used to endorse or promote products
1638a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin *    derived from this software without specific prior written permission.
1738a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin *
1838a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
1938a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
2038a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
2138a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
2238a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
2338a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2438a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2538a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2638a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2738a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2838a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin */
2938a34c9349267c99ce1ddbd0b6e985147415d355Dmitry V. Levin
30172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "defs.h"
31172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
32172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include <linux/sysctl.h>
33172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
34172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_root.h"
35172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_kern.h"
36172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_vm.h"
37172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net.h"
38172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_core.h"
39172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_unix.h"
40172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_ipv4.h"
41172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_ipv4_route.h"
42172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_ipv4_conf.h"
43172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_ipv6.h"
44172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin#include "xlat/sysctl_net_ipv6_route.h"
45172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
46a0bd3749fc6fdf6364c1e269a4c02e8c153eb84bDmitry V. LevinSYS_FUNC(sysctl)
47172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin{
48172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	struct __sysctl_args info;
49172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	int *name;
50172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	unsigned long size;
51172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
525717e7af0dd1b8d80b4d624ce49b3799ec2ae760Dmitry V. Levin	if (umove_or_printaddr(tcp, tcp->u_arg[0], &info))
535717e7af0dd1b8d80b4d624ce49b3799ec2ae760Dmitry V. Levin		return RVAL_DECODED;
54172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
55172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	size = sizeof(int) * (unsigned long) info.nlen;
56172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size);
57172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	if (name == NULL ||
587e69ed98cdd3c8ee0bba783927bc95b895c60160Denys Vlasenko	    umoven(tcp, (unsigned long) info.name, size, name) < 0) {
59172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		free(name);
60172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (entering(tcp))
61172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprintf("{%p, %d, %p, %p, %p, %lu}",
62172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				info.name, info.nlen, info.oldval,
63172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				info.oldlenp, info.newval, (unsigned long)info.newlen);
645717e7af0dd1b8d80b4d624ce49b3799ec2ae760Dmitry V. Levin		return RVAL_DECODED;
65172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	}
66172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
67172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	if (entering(tcp)) {
68172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		unsigned int cnt = 0, max_cnt;
69172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
70172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		tprints("{{");
71172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
72172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (info.nlen == 0)
73172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			goto out;
74172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		printxval(sysctl_root, name[0], "CTL_???");
75172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		++cnt;
76172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
77172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (info.nlen == 1)
78172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			goto out;
79172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		switch (name[0]) {
80172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		case CTL_KERN:
81172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprints(", ");
82172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			printxval(sysctl_kern, name[1], "KERN_???");
83172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			++cnt;
84172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			break;
85172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		case CTL_VM:
86172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprints(", ");
87172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			printxval(sysctl_vm, name[1], "VM_???");
88172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			++cnt;
89172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			break;
90172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		case CTL_NET:
91172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprints(", ");
92172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			printxval(sysctl_net, name[1], "NET_???");
93172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			++cnt;
94172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
95172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			if (info.nlen == 2)
96172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				goto out;
97172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			switch (name[1]) {
98172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			case NET_CORE:
99172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				tprints(", ");
100172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				printxval(sysctl_net_core, name[2],
101172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					  "NET_CORE_???");
102172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				break;
103172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			case NET_UNIX:
104172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				tprints(", ");
105172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				printxval(sysctl_net_unix, name[2],
106172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					  "NET_UNIX_???");
107172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				break;
108172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			case NET_IPV4:
109172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				tprints(", ");
110172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				printxval(sysctl_net_ipv4, name[2],
111172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					  "NET_IPV4_???");
112172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
113172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				if (info.nlen == 3)
114172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					goto out;
115172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				switch (name[2]) {
116172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				case NET_IPV4_ROUTE:
117172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					tprints(", ");
118172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					printxval(sysctl_net_ipv4_route,
119172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin						  name[3],
120172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin						  "NET_IPV4_ROUTE_???");
121172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					break;
122172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				case NET_IPV4_CONF:
123172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					tprints(", ");
124172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					printxval(sysctl_net_ipv4_conf,
125172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin						  name[3],
126172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin						  "NET_IPV4_CONF_???");
127172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					break;
128172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				default:
129172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					goto out;
130172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				}
131172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				break;
132172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			case NET_IPV6:
133172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				tprints(", ");
134172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				printxval(sysctl_net_ipv6, name[2],
135172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					  "NET_IPV6_???");
136172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
137172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				if (info.nlen == 3)
138172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					goto out;
139172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				switch (name[2]) {
140172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				case NET_IPV6_ROUTE:
141172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					tprints(", ");
142172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					printxval(sysctl_net_ipv6_route,
143172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin						  name[3],
144172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin						  "NET_IPV6_ROUTE_???");
145172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					break;
146172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				default:
147172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					goto out;
148172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				}
149172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				break;
150172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			default:
151172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				goto out;
152172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			}
153172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			break;
154172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		default:
155172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			goto out;
156172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		}
157172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	out:
158172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		max_cnt = info.nlen;
159172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (abbrev(tcp) && max_cnt > max_strlen)
160172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			max_cnt = max_strlen;
161172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		while (cnt < max_cnt)
162172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprintf(", %x", name[cnt++]);
163172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (cnt < (unsigned) info.nlen)
164172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprints(", ...");
165172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		tprintf("}, %d, ", info.nlen);
166172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	} else {
167172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		size_t oldlen = 0;
168172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (info.oldval == NULL) {
169172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprints("NULL");
170172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		} else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0
171172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			   && info.nlen >= 2
172172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			   && ((name[0] == CTL_KERN
173172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				&& (name[1] == KERN_OSRELEASE
174172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin				    || name[1] == KERN_OSTYPE
175172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin					)))) {
176172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			printpath(tcp, (size_t)info.oldval);
177172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		} else {
178172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprintf("%p", info.oldval);
179172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		}
180172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		tprintf(", %lu, ", (unsigned long)oldlen);
181172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		if (info.newval == NULL)
182172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprints("NULL");
183172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		else if (syserror(tcp))
184172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			tprintf("%p", info.newval);
185172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		else
186172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin			printpath(tcp, (size_t)info.newval);
187172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin		tprintf(", %lu", (unsigned long)info.newlen);
188172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	}
189172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin
190172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	free(name);
191172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin	return 0;
192172241be48acd731aee0116acabb72e59632f753Dmitry V. Levin}
193