Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F147861163
D17282.id61275.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D17282.id61275.diff
View Options
Index: lib/libc/gen/sysctlbyname.c
===================================================================
--- lib/libc/gen/sysctlbyname.c
+++ lib/libc/gen/sysctlbyname.c
@@ -1,11 +1,29 @@
-/*
- * ----------------------------------------------------------------------------
- * "THE BEER-WARE LICENSE" (Revision 42):
- * <phk@FreeBSD.org> wrote this file. As long as you retain this notice you
- * can do whatever you want with this stuff. If we meet some day, and you think
- * this stuff is worth it, you can buy me a beer in return. Poul-Henning Kamp
- * ----------------------------------------------------------------------------
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright 2019 Pawel Biernacki, Mysterious Code Ltd.
*
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
*/
#include <sys/cdefs.h>
@@ -13,16 +31,43 @@
#include <sys/types.h>
#include <sys/sysctl.h>
+#ifndef HAVE___SYSCTLBYNAME
+#include <signal.h>
+#endif
+#include <string.h>
+extern int __sysctlbyname(const char *name, size_t namelen, void *oldp,
+ size_t *oldlenp, const void *newp, size_t newlen);
+
int
sysctlbyname(const char *name, void *oldp, size_t *oldlenp,
const void *newp, size_t newlen)
{
- int real_oid[CTL_MAXNAME+2];
+#ifndef HAVE___SYSCTLBYNAME
+ struct sigaction sa, osa;
+ int oid[CTL_MAXNAME];
size_t oidlen;
+#endif
+ size_t namelen;
+ int error;
- oidlen = sizeof(real_oid) / sizeof(int);
- if (sysctlnametomib(name, real_oid, &oidlen) < 0)
- return (-1);
- return (sysctl(real_oid, oidlen, oldp, oldlenp, newp, newlen));
+ namelen = strlen(name);
+#ifndef HAVE___SYSCTLBYNAME
+ memset(&sa, 0, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sigfillset(&sa.sa_mask);
+ sigaction(SIGSYS, &sa, &osa);
+#endif
+ error = __sysctlbyname(name, namelen, oldp, oldlenp, newp, newlen);
+#ifndef HAVE___SYSCTLBYNAME
+ sigaction(SIGSYS, &osa, NULL);
+ if (error != 0) {
+ oidlen = sizeof(oid) / sizeof(int);
+ if (sysctlnametomib(name, oid, &oidlen) == -1)
+ return (-1);
+ error = sysctl(oid, oidlen, oldp, oldlenp, newp, newlen);
+ }
+#endif
+
+ return error;
}
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -402,6 +402,7 @@
};
FBSD_1.6 {
+ __sysctlbyname;
copy_file_range;
fhlink;
fhlinkat;
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -2256,6 +2256,32 @@
}
int
+freebsd32___sysctlbyname(struct thread *td,
+ struct freebsd32___sysctlbyname_args *uap)
+{
+ size_t oldlen, rv;
+ int error = 0;
+ uint32_t tmp;
+
+ if (uap->oldlenp != NULL) {
+ error = fueword32(uap->oldlenp, &tmp);
+ oldlen = tmp;
+ } else {
+ oldlen = 0;
+ }
+ if (error != 0)
+ return (EFAULT);
+ error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
+ &oldlen, uap->new, uap->newlen, &rv, SCTL_MASK32, 1);
+ if (error != 0)
+ return (error);
+ if (uap->oldlenp != NULL)
+ suword32(uap->oldlenp, rv);
+
+ return (0);
+}
+
+int
freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
{
uint32_t version;
Index: sys/kern/capabilities.conf
===================================================================
--- sys/kern/capabilities.conf
+++ sys/kern/capabilities.conf
@@ -58,6 +58,7 @@
## proxying daemon in userspace.
##
__sysctl
+__sysctlbyname
##
## Allow umtx operations as these are scoped by address space.
Index: sys/kern/kern_sysctl.c
===================================================================
--- sys/kern/kern_sysctl.c
+++ sys/kern/kern_sysctl.c
@@ -2145,6 +2145,68 @@
return (error);
}
+int
+kern___sysctlbyname(struct thread *td, const char *oname, size_t namelen,
+ void *old, size_t *oldlenp, void *new, size_t newlen, size_t *retval,
+ int flags, bool inkernel)
+{
+ int oid[CTL_MAXNAME];
+ char namebuf[16];
+ char *name;
+ size_t oidlen;
+ int error;
+
+ if (namelen > MAXPATHLEN || namelen == 0)
+ return (EINVAL);
+ name = namebuf;
+ if (namelen > sizeof(namebuf))
+ name = malloc(namelen, M_SYSCTL, M_WAITOK);
+ error = copyin(oname, name, namelen);
+ if (error != 0)
+ goto out;
+
+ oid[0] = 0;
+ oid[1] = 3;
+ oidlen = sizeof(oid);
+ error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen,
+ retval, flags);
+ if (error != 0)
+ goto out;
+ error = userland_sysctl(td, oid, *retval / sizeof(int), old, oldlenp,
+ inkernel, new, newlen, retval, flags);
+
+out:
+ if (namelen > sizeof(namebuf))
+ free(name, M_SYSCTL);
+ return (error);
+}
+
+#ifndef _SYS_SYSPROTO_H_
+struct __sysctlbyname_args {
+ const char *name;
+ size_t namelen;
+ void *old;
+ size_t *oldlenp;
+ void *new;
+ size_t newlen;
+};
+#endif
+int
+sys___sysctlbyname(struct thread *td, struct __sysctlbyname_args *uap)
+{
+ size_t rv;
+ int error;
+
+ error = kern___sysctlbyname(td, uap->name, uap->namelen, uap->old,
+ uap->oldlenp, uap->new, uap->newlen, &rv, 0, 0);
+ if (error != 0)
+ return (error);
+ if (uap->oldlenp != NULL)
+ error = copyout(&rv, uap->oldlenp, sizeof(rv));
+
+ return (error);
+}
+
/*
* This is used from various compatibility syscalls too. That's why name
* must be in kernel space.
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -3185,6 +3185,15 @@
unsigned int flags
);
}
+570 AUE_SYSCTL STD {
+ int __sysctlbyname(
+ _In_reads_(namelen) const char *name,
+ size_t namelen,
+ _Out_writes_bytes_opt_(*oldlenp) void *old,
+ _Inout_opt_ size_t *oldlenp,
+ _In_reads_bytes_opt_(newlen) void *new,
+ size_t newlen);
+ }
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/sys/sysctl.h
===================================================================
--- sys/sys/sysctl.h
+++ sys/sys/sysctl.h
@@ -1128,6 +1128,9 @@
void sysctl_wlock(void);
void sysctl_wunlock(void);
int sysctl_wire_old_buffer(struct sysctl_req *req, size_t len);
+int kern___sysctlbyname(struct thread *td, const char *name,
+ size_t namelen, void *old, size_t *oldlenp, void *new,
+ size_t newlen, size_t *retval, int flags, bool inkernel);
struct sbuf;
struct sbuf *sbuf_new_for_sysctl(struct sbuf *, char *, int,
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sun, Mar 15, 6:19 AM (5 h, 45 s)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
29705241
Default Alt Text
D17282.id61275.diff (7 KB)
Attached To
Mode
D17282: new syscall: __sysctlbyname
Attached
Detach File
Event Timeline
Log In to Comment