Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F144977071
D17282.1777063970.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
17 KB
Referenced Files
None
Subscribers
None
D17282.1777063970.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 2018 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,18 @@
#include <sys/types.h>
#include <sys/sysctl.h>
+#include <string.h>
+
+extern int __sysctlbyname(const char *name, u_int 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];
- size_t oidlen;
+ u_int namelen;
- 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);
+ return (__sysctlbyname(name, namelen, oldp, oldlenp, newp, newlen));
}
+
Index: lib/libc/sys/Symbol.map
===================================================================
--- lib/libc/sys/Symbol.map
+++ lib/libc/sys/Symbol.map
@@ -399,6 +399,7 @@
statfs;
cpuset_getdomain;
cpuset_setdomain;
+ __sysctlbyname;
};
FBSDprivate_1.0 {
@@ -456,6 +457,8 @@
__sys___syscall;
___sysctl;
__sys___sysctl;
+ ___sysctlbyname;
+ __sys___sysctlbyname;
__umtx_op;
__sys__umtx_op;
_abort2;
Index: sys/compat/freebsd32/capabilities.conf
===================================================================
--- sys/compat/freebsd32/capabilities.conf
+++ sys/compat/freebsd32/capabilities.conf
@@ -48,6 +48,7 @@
__mac_set_fd
__mac_set_proc
freebsd32_sysctl
+freebsd32_sysctlbyname
freebsd32_umtx_op
abort2
accept
Index: sys/compat/freebsd32/freebsd32_misc.c
===================================================================
--- sys/compat/freebsd32/freebsd32_misc.c
+++ sys/compat/freebsd32/freebsd32_misc.c
@@ -118,6 +118,8 @@
FEATURE(compat_freebsd_32bit, "Compatible with 32-bit FreeBSD");
+MALLOC_DECLARE(M_SYSCTL);
+
#ifdef __amd64__
CTASSERT(sizeof(struct timeval32) == 8);
CTASSERT(sizeof(struct timespec32) == 8);
@@ -2289,6 +2291,59 @@
return (0);
}
+int
+freebsd32_sysctlbyname(struct thread *td, struct
+ freebsd32_sysctlbyname_args *uap)
+{
+ int oid[CTL_MAXNAME];
+#define NAMEBUFLEN 16
+ char namebuf[NAMEBUFLEN];
+ char *name;
+ size_t namelen, oidlen, oldlen, rv;
+ int error;
+ uint32_t tmp;
+
+ namelen = uap->namelen;
+ if (namelen > MAXPATHLEN || namelen == 0)
+ return (EINVAL);
+
+ name = namebuf;
+ if (namelen > NAMEBUFLEN)
+ name = malloc(namelen, M_SYSCTL, M_WAITOK);
+ error = copyin(uap->name, name, namelen);
+ if (error)
+ goto out;
+
+ oid[0] = 0;
+ oid[1] = 3;
+ oidlen = sizeof(oid);
+ error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen,
+ &rv, 0);
+ if (error)
+ goto out;
+
+ if (uap->oldlenp) {
+ error = fueword32(uap->oldlenp, &tmp);
+ oldlen = tmp;
+ } else {
+ oldlen = 0;
+ }
+ if (error)
+ goto out;
+ error = userland_sysctl(td, oid, rv / sizeof(int), uap->old,
+ &oldlen, 1, (void *)uap->new, uap->newlen, &rv, 0);
+ if (error)
+ goto out;
+ if (uap->oldlenp)
+ suword32(uap->oldlenp, rv);
+
+out:
+ if (namelen > NAMEBUFLEN)
+ free(name, M_SYSCTL);
+ return (error);
+#undef NAMEBUF
+}
+
int
freebsd32_jail(struct thread *td, struct freebsd32_jail_args *uap)
{
Index: sys/compat/freebsd32/freebsd32_proto.h
===================================================================
--- sys/compat/freebsd32/freebsd32_proto.h
+++ sys/compat/freebsd32/freebsd32_proto.h
@@ -710,6 +710,14 @@
char mask_l_[PADL_(domainset_t *)]; domainset_t * mask; char mask_r_[PADR_(domainset_t *)];
char policy_l_[PADL_(int)]; int policy; char policy_r_[PADR_(int)];
};
+struct freebsd32_sysctlbyname_args {
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char namelen_l_[PADL_(u_int)]; u_int namelen; char namelen_r_[PADR_(u_int)];
+ char old_l_[PADL_(void *)]; void * old; char old_r_[PADR_(void *)];
+ char oldlenp_l_[PADL_(uint32_t *)]; uint32_t * oldlenp; char oldlenp_r_[PADR_(uint32_t *)];
+ char new_l_[PADL_(void *)]; void * new; char new_r_[PADR_(void *)];
+ char newlen_l_[PADL_(uint32_t)]; uint32_t newlen; char newlen_r_[PADR_(uint32_t)];
+};
#if !defined(PAD64_REQUIRED) && (defined(__powerpc__) || defined(__mips__))
#define PAD64_REQUIRED
#endif
@@ -842,6 +850,7 @@
int freebsd32_kevent(struct thread *, struct freebsd32_kevent_args *);
int freebsd32_cpuset_getdomain(struct thread *, struct freebsd32_cpuset_getdomain_args *);
int freebsd32_cpuset_setdomain(struct thread *, struct freebsd32_cpuset_setdomain_args *);
+int freebsd32_sysctlbyname(struct thread *, struct freebsd32_sysctlbyname_args *);
#ifdef COMPAT_43
@@ -1391,6 +1400,7 @@
#define FREEBSD32_SYS_AUE_freebsd32_kevent AUE_KEVENT
#define FREEBSD32_SYS_AUE_freebsd32_cpuset_getdomain AUE_NULL
#define FREEBSD32_SYS_AUE_freebsd32_cpuset_setdomain AUE_NULL
+#define FREEBSD32_SYS_AUE_freebsd32_sysctlbyname AUE_SYSCTL
#undef PAD_
#undef PADL_
Index: sys/compat/freebsd32/freebsd32_syscall.h
===================================================================
--- sys/compat/freebsd32/freebsd32_syscall.h
+++ sys/compat/freebsd32/freebsd32_syscall.h
@@ -469,4 +469,5 @@
#define FREEBSD32_SYS_freebsd32_cpuset_getdomain 561
#define FREEBSD32_SYS_freebsd32_cpuset_setdomain 562
#define FREEBSD32_SYS_getrandom 563
-#define FREEBSD32_SYS_MAXSYSCALL 564
+#define FREEBSD32_SYS_freebsd32_sysctlbyname 564
+#define FREEBSD32_SYS_MAXSYSCALL 565
Index: sys/compat/freebsd32/freebsd32_syscalls.c
===================================================================
--- sys/compat/freebsd32/freebsd32_syscalls.c
+++ sys/compat/freebsd32/freebsd32_syscalls.c
@@ -596,4 +596,5 @@
"freebsd32_cpuset_getdomain", /* 561 = freebsd32_cpuset_getdomain */
"freebsd32_cpuset_setdomain", /* 562 = freebsd32_cpuset_setdomain */
"getrandom", /* 563 = getrandom */
+ "freebsd32_sysctlbyname", /* 564 = freebsd32_sysctlbyname */
};
Index: sys/compat/freebsd32/freebsd32_sysent.c
===================================================================
--- sys/compat/freebsd32/freebsd32_sysent.c
+++ sys/compat/freebsd32/freebsd32_sysent.c
@@ -643,4 +643,5 @@
{ AS(freebsd32_cpuset_getdomain_args), (sy_call_t *)freebsd32_cpuset_getdomain, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 561 = freebsd32_cpuset_getdomain */
{ AS(freebsd32_cpuset_setdomain_args), (sy_call_t *)freebsd32_cpuset_setdomain, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 562 = freebsd32_cpuset_setdomain */
{ AS(getrandom_args), (sy_call_t *)sys_getrandom, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 563 = getrandom */
+ { AS(freebsd32_sysctlbyname_args), (sy_call_t *)freebsd32_sysctlbyname, AUE_SYSCTL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 564 = freebsd32_sysctlbyname */
};
Index: sys/compat/freebsd32/freebsd32_systrace_args.c
===================================================================
--- sys/compat/freebsd32/freebsd32_systrace_args.c
+++ sys/compat/freebsd32/freebsd32_systrace_args.c
@@ -3258,6 +3258,18 @@
*n_args = 3;
break;
}
+ /* freebsd32_sysctlbyname */
+ case 564: {
+ struct freebsd32_sysctlbyname_args *p = params;
+ uarg[0] = (intptr_t) p->name; /* const char * */
+ uarg[1] = p->namelen; /* u_int */
+ uarg[2] = (intptr_t) p->old; /* void * */
+ uarg[3] = (intptr_t) p->oldlenp; /* uint32_t * */
+ uarg[4] = (intptr_t) p->new; /* void * */
+ uarg[5] = p->newlen; /* uint32_t */
+ *n_args = 6;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8758,6 +8770,31 @@
break;
};
break;
+ /* freebsd32_sysctlbyname */
+ case 564:
+ switch(ndx) {
+ case 0:
+ p = "userland const char *";
+ break;
+ case 1:
+ p = "u_int";
+ break;
+ case 2:
+ p = "userland void *";
+ break;
+ case 3:
+ p = "userland uint32_t *";
+ break;
+ case 4:
+ p = "userland void *";
+ break;
+ case 5:
+ p = "uint32_t";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -10599,6 +10636,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* freebsd32_sysctlbyname */
+ case 564:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
Index: sys/compat/freebsd32/syscalls.master
===================================================================
--- sys/compat/freebsd32/syscalls.master
+++ sys/compat/freebsd32/syscalls.master
@@ -1113,5 +1113,8 @@
int policy); }
563 AUE_NULL NOPROTO { int getrandom(void *buf, size_t buflen, \
unsigned int flags); }
+564 AUE_SYSCTL STD { int freebsd32_sysctlbyname(const char *name, \
+ u_int namelen, void *old, uint32_t *oldlenp, \
+ void *new, uint32_t newlen); }
; vim: syntax=off
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/init_sysent.c
===================================================================
--- sys/kern/init_sysent.c
+++ sys/kern/init_sysent.c
@@ -613,4 +613,5 @@
{ AS(cpuset_getdomain_args), (sy_call_t *)sys_cpuset_getdomain, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 561 = cpuset_getdomain */
{ AS(cpuset_setdomain_args), (sy_call_t *)sys_cpuset_setdomain, AUE_NULL, NULL, 0, 0, 0, SY_THR_STATIC }, /* 562 = cpuset_setdomain */
{ AS(getrandom_args), (sy_call_t *)sys_getrandom, AUE_NULL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 563 = getrandom */
+ { AS(sysctlbyname_args), (sy_call_t *)sys___sysctlbyname, AUE_SYSCTL, NULL, 0, 0, SYF_CAPENABLED, SY_THR_STATIC }, /* 564 = __sysctlbyname */
};
Index: sys/kern/kern_sysctl.c
===================================================================
--- sys/kern/kern_sysctl.c
+++ sys/kern/kern_sysctl.c
@@ -71,7 +71,8 @@
#include <vm/vm.h>
#include <vm/vm_extern.h>
-static MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic");
+/* Can't be static, used by freebsd32 compat. */
+MALLOC_DEFINE(M_SYSCTL, "sysctl", "sysctl internal magic");
static MALLOC_DEFINE(M_SYSCTLOID, "sysctloid", "sysctl dynamic oids");
static MALLOC_DEFINE(M_SYSCTLTMP, "sysctltmp", "sysctl temp output buffer");
@@ -2071,6 +2072,59 @@
return (error);
}
+#ifndef _SYS_SYSPROTO_H_
+struct sysctlbyname_args {
+ const char *name;
+ u_int namelen;
+ void *old;
+ size_t *oldlenp;
+ void *new;
+ size_t newlen;
+};
+#endif
+int
+sys___sysctlbyname(struct thread *td, struct sysctlbyname_args *uap)
+{
+ int oid[CTL_MAXNAME];
+#define NAMEBUFLEN 16
+ char namebuf[NAMEBUFLEN];
+ char *name;
+ size_t namelen, oidlen, rv;
+ int error;
+
+ namelen = uap->namelen;
+ if (namelen > MAXPATHLEN || namelen == 0)
+ return (EINVAL);
+
+ name = namebuf;
+ if (namelen > NAMEBUFLEN)
+ name = malloc(namelen, M_SYSCTL, M_WAITOK);
+ error = copyin(uap->name, name, namelen);
+ if (error)
+ goto out;
+
+ oid[0] = 0;
+ oid[1] = 3;
+ oidlen = sizeof(oid);
+ error = kernel_sysctl(td, oid, 2, oid, &oidlen, (void *)name, namelen,
+ &rv, 0);
+ if (error)
+ goto out;
+
+ error = userland_sysctl(td, oid, rv / sizeof(int), uap->old, uap->oldlenp,
+ 0, (void *)uap->new, uap->newlen, &rv, 0);
+ if (error)
+ goto out;
+ if (uap->oldlenp)
+ error = copyout(&rv, uap->oldlenp, sizeof(rv));
+
+out:
+ if (namelen > NAMEBUFLEN)
+ free(name, M_SYSCTL);
+ return (error);
+#undef NAMEBUFLEN
+}
+
/*
* This is used from various compatibility syscalls too. That's why name
* must be in kernel space.
Index: sys/kern/syscalls.c
===================================================================
--- sys/kern/syscalls.c
+++ sys/kern/syscalls.c
@@ -570,4 +570,5 @@
"cpuset_getdomain", /* 561 = cpuset_getdomain */
"cpuset_setdomain", /* 562 = cpuset_setdomain */
"getrandom", /* 563 = getrandom */
+ "__sysctlbyname", /* 564 = __sysctlbyname */
};
Index: sys/kern/syscalls.master
===================================================================
--- sys/kern/syscalls.master
+++ sys/kern/syscalls.master
@@ -1340,6 +1340,16 @@
563 AUE_NULL STD { int getrandom( \
_Out_writes_bytes_(buflen) void *buf, \
size_t buflen, unsigned int flags); }
+564 AUE_SYSCTL STD { int __sysctlbyname( \
+ _In_reads_(namelen) const char *name, \
+ u_int namelen, \
+ _Out_writes_bytes_opt_(*oldlenp) \
+ void *old, \
+ _Inout_opt_ size_t *oldlenp, \
+ _In_reads_bytes_opt_(newlen) \
+ void *new, \
+ size_t newlen); } \
+ __sysctlbyname sysctlbyname_args int
; Please copy any additions and changes to the following compatability tables:
; sys/compat/freebsd32/syscalls.master
Index: sys/kern/systrace_args.c
===================================================================
--- sys/kern/systrace_args.c
+++ sys/kern/systrace_args.c
@@ -3266,6 +3266,18 @@
*n_args = 3;
break;
}
+ /* __sysctlbyname */
+ case 564: {
+ struct sysctlbyname_args *p = params;
+ uarg[0] = (intptr_t) p->name; /* const char * */
+ uarg[1] = p->namelen; /* u_int */
+ uarg[2] = (intptr_t) p->old; /* void * */
+ uarg[3] = (intptr_t) p->oldlenp; /* size_t * */
+ uarg[4] = (intptr_t) p->new; /* void * */
+ uarg[5] = p->newlen; /* size_t */
+ *n_args = 6;
+ break;
+ }
default:
*n_args = 0;
break;
@@ -8710,6 +8722,31 @@
break;
};
break;
+ /* __sysctlbyname */
+ case 564:
+ switch(ndx) {
+ case 0:
+ p = "userland const char *";
+ break;
+ case 1:
+ p = "u_int";
+ break;
+ case 2:
+ p = "userland void *";
+ break;
+ case 3:
+ p = "userland size_t *";
+ break;
+ case 4:
+ p = "userland void *";
+ break;
+ case 5:
+ p = "size_t";
+ break;
+ default:
+ break;
+ };
+ break;
default:
break;
};
@@ -10586,6 +10623,11 @@
if (ndx == 0 || ndx == 1)
p = "int";
break;
+ /* __sysctlbyname */
+ case 564:
+ if (ndx == 0 || ndx == 1)
+ p = "int";
+ break;
default:
break;
};
Index: sys/sys/syscall.h
===================================================================
--- sys/sys/syscall.h
+++ sys/sys/syscall.h
@@ -479,4 +479,5 @@
#define SYS_cpuset_getdomain 561
#define SYS_cpuset_setdomain 562
#define SYS_getrandom 563
-#define SYS_MAXSYSCALL 564
+#define SYS___sysctlbyname 564
+#define SYS_MAXSYSCALL 565
Index: sys/sys/syscall.mk
===================================================================
--- sys/sys/syscall.mk
+++ sys/sys/syscall.mk
@@ -404,4 +404,5 @@
kevent.o \
cpuset_getdomain.o \
cpuset_setdomain.o \
- getrandom.o
+ getrandom.o \
+ __sysctlbyname.o
Index: sys/sys/sysproto.h
===================================================================
--- sys/sys/sysproto.h
+++ sys/sys/sysproto.h
@@ -1770,6 +1770,14 @@
char buflen_l_[PADL_(size_t)]; size_t buflen; char buflen_r_[PADR_(size_t)];
char flags_l_[PADL_(unsigned int)]; unsigned int flags; char flags_r_[PADR_(unsigned int)];
};
+struct sysctlbyname_args {
+ char name_l_[PADL_(const char *)]; const char * name; char name_r_[PADR_(const char *)];
+ char namelen_l_[PADL_(u_int)]; u_int namelen; char namelen_r_[PADR_(u_int)];
+ char old_l_[PADL_(void *)]; void * old; char old_r_[PADR_(void *)];
+ char oldlenp_l_[PADL_(size_t *)]; size_t * oldlenp; char oldlenp_r_[PADR_(size_t *)];
+ char new_l_[PADL_(void *)]; void * new; char new_r_[PADR_(void *)];
+ char newlen_l_[PADL_(size_t)]; size_t newlen; char newlen_r_[PADR_(size_t)];
+};
int nosys(struct thread *, struct nosys_args *);
void sys_sys_exit(struct thread *, struct sys_exit_args *);
int sys_fork(struct thread *, struct fork_args *);
@@ -2150,6 +2158,7 @@
int sys_cpuset_getdomain(struct thread *, struct cpuset_getdomain_args *);
int sys_cpuset_setdomain(struct thread *, struct cpuset_setdomain_args *);
int sys_getrandom(struct thread *, struct getrandom_args *);
+int sys___sysctlbyname(struct thread *, struct sysctlbyname_args *);
#ifdef COMPAT_43
@@ -3047,6 +3056,7 @@
#define SYS_AUE_cpuset_getdomain AUE_NULL
#define SYS_AUE_cpuset_setdomain AUE_NULL
#define SYS_AUE_getrandom AUE_NULL
+#define SYS_AUE___sysctlbyname AUE_SYSCTL
#undef PAD_
#undef PADL_
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 24, 8:52 PM (18 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28425034
Default Alt Text
D17282.1777063970.diff (17 KB)
Attached To
Mode
D17282: new syscall: __sysctlbyname
Attached
Detach File
Event Timeline
Log In to Comment