Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/compat/linux/linux_sysctl.c
39492 views
1
/*-
2
* SPDX-License-Identifier: BSD-2-Clause
3
*
4
* Copyright (c) 2001 Marcel Moolenaar
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
*
16
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
17
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
20
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
21
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
22
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26
* SUCH DAMAGE.
27
*/
28
29
#include <sys/param.h>
30
#include <sys/lock.h>
31
#include <sys/malloc.h>
32
#include <sys/mutex.h>
33
#include <sys/sysctl.h>
34
#include <sys/sbuf.h>
35
#include <sys/vnode.h>
36
37
#ifdef COMPAT_LINUX32
38
#include <machine/../linux32/linux.h>
39
#include <machine/../linux32/linux32_proto.h>
40
#else
41
#include <machine/../linux/linux.h>
42
#include <machine/../linux/linux_proto.h>
43
#endif
44
45
#include <compat/linux/linux_dtrace.h>
46
#include <compat/linux/linux_misc.h>
47
#include <compat/linux/linux_util.h>
48
49
#define LINUX_CTL_KERN 1
50
#define LINUX_CTL_VM 2
51
#define LINUX_CTL_NET 3
52
#define LINUX_CTL_PROC 4
53
#define LINUX_CTL_FS 5
54
#define LINUX_CTL_DEBUG 6
55
#define LINUX_CTL_DEV 7
56
#define LINUX_CTL_BUS 8
57
58
/* CTL_KERN names */
59
#define LINUX_KERN_OSTYPE 1
60
#define LINUX_KERN_OSRELEASE 2
61
#define LINUX_KERN_OSREV 3
62
#define LINUX_KERN_VERSION 4
63
64
/* DTrace init */
65
LIN_SDT_PROVIDER_DECLARE(LINUX_DTRACE);
66
67
/**
68
* DTrace probes in this module.
69
*/
70
LIN_SDT_PROBE_DEFINE1(sysctl, handle_string, copyout_error, "int");
71
LIN_SDT_PROBE_DEFINE1(sysctl, linux_sysctl, copyin_error, "int");
72
LIN_SDT_PROBE_DEFINE2(sysctl, linux_sysctl, wrong_length, "int", "int");
73
LIN_SDT_PROBE_DEFINE1(sysctl, linux_sysctl, unsupported_sysctl, "char *");
74
75
#ifdef LINUX_LEGACY_SYSCALLS
76
static int
77
handle_string(struct l___sysctl_args *la, const char *value)
78
{
79
int error;
80
81
if (la->oldval != 0) {
82
l_int len = strlen(value);
83
error = copyout(value, PTRIN(la->oldval), len + 1);
84
if (!error && la->oldlenp != 0)
85
error = copyout(&len, PTRIN(la->oldlenp), sizeof(len));
86
if (error) {
87
LIN_SDT_PROBE1(sysctl, handle_string, copyout_error,
88
error);
89
return (error);
90
}
91
}
92
93
if (la->newval != 0)
94
return (ENOTDIR);
95
96
return (0);
97
}
98
99
int
100
linux_sysctl(struct thread *td, struct linux_sysctl_args *args)
101
{
102
struct l___sysctl_args la;
103
struct sbuf *sb;
104
l_int *mib;
105
char *sysctl_string;
106
int error, i;
107
108
error = copyin(args->args, &la, sizeof(la));
109
if (error) {
110
LIN_SDT_PROBE1(sysctl, linux_sysctl, copyin_error, error);
111
return (error);
112
}
113
114
if (la.nlen <= 0 || la.nlen > LINUX_CTL_MAXNAME) {
115
LIN_SDT_PROBE2(sysctl, linux_sysctl, wrong_length, la.nlen,
116
LINUX_CTL_MAXNAME);
117
return (ENOTDIR);
118
}
119
120
mib = malloc(la.nlen * sizeof(l_int), M_LINUX, M_WAITOK);
121
error = copyin(PTRIN(la.name), mib, la.nlen * sizeof(l_int));
122
if (error) {
123
LIN_SDT_PROBE1(sysctl, linux_sysctl, copyin_error, error);
124
free(mib, M_LINUX);
125
return (error);
126
}
127
128
switch (mib[0]) {
129
case LINUX_CTL_KERN:
130
if (la.nlen < 2)
131
break;
132
133
switch (mib[1]) {
134
case LINUX_KERN_VERSION:
135
error = handle_string(&la, version);
136
free(mib, M_LINUX);
137
return (error);
138
default:
139
break;
140
}
141
break;
142
default:
143
break;
144
}
145
146
sb = sbuf_new(NULL, NULL, 20 + la.nlen * 5, SBUF_AUTOEXTEND);
147
if (sb == NULL) {
148
linux_msg(td, "sysctl is not implemented");
149
LIN_SDT_PROBE1(sysctl, linux_sysctl, unsupported_sysctl,
150
"unknown sysctl, ENOMEM during lookup");
151
} else {
152
sbuf_printf(sb, "sysctl ");
153
for (i = 0; i < la.nlen; i++)
154
sbuf_printf(sb, "%c%d", (i) ? ',' : '{', mib[i]);
155
sbuf_printf(sb, "} is not implemented");
156
sbuf_finish(sb);
157
sysctl_string = sbuf_data(sb);
158
linux_msg(td, "%s", sysctl_string);
159
LIN_SDT_PROBE1(sysctl, linux_sysctl, unsupported_sysctl,
160
sysctl_string);
161
sbuf_delete(sb);
162
}
163
164
free(mib, M_LINUX);
165
166
return (ENOTDIR);
167
}
168
#endif
169
170