1.\" Copyright (c) 2018 Mariusz Zaborski <oshogbo@FreeBSD.org> 2.\" All rights reserved. 3.\" 4.\" Redistribution and use in source and binary forms, with or without 5.\" modification, are permitted provided that the following conditions 6.\" are met: 7.\" 1. Redistributions of source code must retain the above copyright 8.\" notice, this list of conditions and the following disclaimer. 9.\" 2. Redistributions in binary form must reproduce the above copyright 10.\" notice, this list of conditions and the following disclaimer in the 11.\" documentation and/or other materials provided with the distribution. 12.\" 13.\" THIS SOFTWARE IS PROVIDED BY THE AUTHORS AND CONTRIBUTORS ``AS IS'' AND 14.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE 17.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 18.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 19.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 20.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 21.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 22.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 23.\" SUCH DAMAGE. 24.\" 25.Dd December 6, 2023 26.Dt CAP_SYSCTL 3 27.Os 28.Sh NAME 29.Nm cap_sysctl 30.Nd "library for getting or setting system information in capability mode" 31.Sh LIBRARY 32.Lb libcap_sysctl 33.Sh SYNOPSIS 34.In libcasper.h 35.In casper/cap_sysctl.h 36.Ft int 37.Fn cap_sysctl "cap_channel_t *chan" "const int *name" "u_int namelen" "void *oldp" "size_t *oldlenp" "const void *newp" "size_t newlen" 38.Ft int 39.Fn cap_sysctlbyname "cap_channel_t *chan" "const char *name" "void *oldp" "size_t *oldlenp" "const void *newp" "size_t newlen" 40.Ft int 41.Fn cap_sysctlnametomib "cap_channel_t *chan" "const char *name" "int *mibp" "size_t *sizep" 42.Ft cap_sysctl_limit_t * 43.Fn cap_sysctl_limit_init "cap_channel_t *chan" 44.Ft cap_sysctl_limit_t * 45.Fn cap_sysctl_limit_name "cap_sysctl_limit_t *limit" "const char *name" "int flags" 46.Ft cap_sysctl_limit_t * 47.Fn cap_sysctl_limit_mib "cap_sysctl_limit_t *limit" "const int *mibp" "u_int miblen" "int flags" 48.Ft int 49.Fn cap_sysctl_limit "cap_sysctl_limit_t *limit" 50.Sh DESCRIPTION 51The 52.Fn cap_sysctl , 53.Fn cap_sysctlbyname 54and 55.Fn cap_sysctlnametomib 56functions are equivalent to 57.Xr sysctl 3 , 58.Xr sysctlbyname 3 59and 60.Xr sysctlnametomib 3 , 61except that they are implemented by the 62.Ql system.sysctl 63.Xr libcasper 3 64service and require a corresponding 65.Xr libcasper 3 66capability. 67.Pp 68All of these functions, with the exceptions of 69.Fn cap_sysctl_limit_init 70and 71.Fn cap_sysctl_limit_mib , 72are reentrant but not thread-safe. 73That is, they may be called from separate threads only with different 74.Vt cap_channel_t 75arguments or with synchronization. 76.Sh LIMITS 77By default, the 78.Nm 79capability provides unrestricted access to the sysctl namespace. 80Applications typically only require access to a small number of sysctl 81variables; the 82.Fn cap_sysctl_limit 83interface can be used to restrict the sysctls that can be accessed using 84the 85.Nm 86capability. 87.Fn cap_sysctl_limit_init 88returns an opaque limit handle used to store a list of permitted sysctls 89and access rights. 90Rights are encoded using the following flags: 91.Pp 92.Bd -literal -offset indent -compact 93CAP_SYSCTL_READ allow reads of the sysctl variable 94CAP_SYSCTL_WRITE allow writes of the sysctl variable 95CAP_SYSCTL_RDWR allow reads and writes of the sysctl variable 96CAP_RECURSIVE permit access to any child of the sysctl variable 97.Ed 98.Pp 99The 100.Fn cap_sysctl_limit_name 101function adds the sysctl identified by 102.Ar name 103to the limit list, and 104.Fn cap_sysctl_limit_mib 105function adds the sysctl identified by 106.Ar mibp 107to the limit list. 108The access rights for the sysctl are specified in the 109.Ar flags 110parameter; at least one of 111.Dv CAP_SYSCTL_READ , 112.Dv CAP_SYSCTL_WRITE 113and 114.Dv CAP_SYSCTL_RDWR 115must be specified. 116.Fn cap_sysctl_limit 117applies a set of sysctl limits to the capability, denying access to sysctl 118variables not belonging to the set. 119It consumes the limit handle. 120After either success or failure, the user must not access the handle again. 121.Pp 122Once a set of limits is applied, subsequent calls to 123.Fn cap_sysctl_limit 124will fail unless the new set is a subset of the current set. 125.Pp 126.Fn cap_sysctlnametomib 127will succeed so long as the named sysctl variable is present in the limit set, 128regardless of its access rights. 129When a sysctl variable name is added to a limit set, its MIB identifier is 130automatically added to the set. 131.Sh EXAMPLES 132The following example first opens a capability to casper, uses this 133capability to create the 134.Nm system.sysctl 135casper service, and then uses the 136.Nm 137capability to get the value of 138.Dv kern.trap_enotcap . 139.Bd -literal 140cap_channel_t *capcas, *capsysctl; 141const char *name = "kern.trap_enotcap"; 142void *limit; 143size_t size; 144bool value; 145 146/* Open capability to Casper. */ 147capcas = cap_init(); 148if (capcas == NULL) 149 err(1, "Unable to contact Casper"); 150 151/* Enter capability mode sandbox. */ 152if (cap_enter() < 0 && errno != ENOSYS) 153 err(1, "Unable to enter capability mode"); 154 155/* Use Casper capability to create capability to the system.sysctl service. */ 156capsysctl = cap_service_open(capcas, "system.sysctl"); 157if (capsysctl == NULL) 158 err(1, "Unable to open system.sysctl service"); 159 160/* Close Casper capability, we don't need it anymore. */ 161cap_close(capcas); 162 163/* Create limit for one MIB with read access only. */ 164limit = cap_sysctl_limit_init(capsysctl); 165(void)cap_sysctl_limit_name(limit, name, CAP_SYSCTL_READ); 166 167/* Limit system.sysctl. */ 168if (cap_sysctl_limit(limit) < 0) 169 err(1, "Unable to set limits"); 170 171/* Fetch value. */ 172size = sizeof(value); 173if (cap_sysctlbyname(capsysctl, name, &value, &size, NULL, 0) < 0) 174 err(1, "Unable to get value of sysctl"); 175 176printf("The value of %s is %d.\\n", name, value); 177 178cap_close(capsysctl); 179.Ed 180.Sh RETURN VALUES 181.Fn cap_sysctl_limit_init 182will return a new limit handle on success or 183.Dv NULL 184on failure, and set 185.Va errno . 186.Fn cap_sysctl_limit_mib 187and 188.Fn cap_sysctl_limit_name 189will return the modified limit handle on success or 190.Dv NULL 191on failure and set 192.Va errno . 193After failure, the caller must not access the limit handle again. 194.Fn cap_sysctl_limit 195will return 196.Dv -1 197on failure and set 198.Va errno . 199.Fn cap_sysctl , 200.Fn cap_sysctlbyname , 201and 202.Fn cap_sysctlnametomib 203have the same return values as their non-capability-mode equivalents as 204documented in 205.Xr sysctl 3 . 206.Sh SEE ALSO 207.Xr cap_enter 2 , 208.Xr err 3 , 209.Xr sysctl 3 , 210.Xr sysctlbyname 3 , 211.Xr sysctlnametomib 3 , 212.Xr capsicum 4 , 213.Xr nv 9 214.Sh HISTORY 215The 216.Nm cap_sysctl 217service first appeared in 218.Fx 10.3 . 219.Sh AUTHORS 220The 221.Nm cap_sysctl 222service was implemented by 223.An Pawel Jakub Dawidek Aq Mt pawel@dawidek.net 224under sponsorship from the FreeBSD Foundation. 225.Pp 226This manual page was written by 227.An Mariusz Zaborski Aq Mt oshogbo@FreeBSD.org . 228