diff options
Diffstat (limited to 'lib')
240 files changed, 9857 insertions, 1622 deletions
diff --git a/lib/Makefile b/lib/Makefile index 9447cc4551c0..75a2355aa452 100644 --- a/lib/Makefile +++ b/lib/Makefile @@ -157,11 +157,13 @@ SUBDIR_DEPEND_liblzma= libthr SUBDIR_DEPEND_libpcap= ofed .endif SUBDIR_DEPEND_nss_tacplus= libtacplus +SUBDIR_DEPEND_virtual_oss= libsamplerate # NB: keep these sorted by MK_* knobs SUBDIR.${MK_BEARSSL}+= libbearssl libsecureboot SUBDIR.${MK_BLACKLIST}+=libblacklist +SUBDIR.${MK_BLOCKLIST}+=libblocklist SUBDIR.${MK_BLUETOOTH}+=libbluetooth libsdp SUBDIR.${MK_BSNMP}+= libbsnmp @@ -173,18 +175,19 @@ SUBDIR+= clang .endif SUBDIR.${MK_CUSE}+= libcuse +SUBDIR.${MK_CUSE}+= virtual_oss SUBDIR.${MK_TOOLCHAIN}+=libpe SUBDIR.${MK_DIALOG}+= libdpv libfigpar SUBDIR.${MK_FDT}+= libfdt SUBDIR.${MK_FILE}+= libmagic SUBDIR.${MK_GPIO}+= libgpio .if ${MK_MITKRB5} == "no" -SUBDIR.${MK_GSSAPI}+= libgssapi +SUBDIR.${MK_KERBEROS}+= libgssapi .endif -SUBDIR.${MK_GSSAPI}+= librpcsec_gss +SUBDIR.${MK_KERBEROS}+= librpcsec_gss SUBDIR.${MK_ICONV}+= libiconv_modules .if ${MK_MITKRB5} == "no" -SUBDIR.${MK_KERBEROS_SUPPORT}+= libcom_err +SUBDIR.${MK_KERBEROS}+= libcom_err .endif SUBDIR.${MK_LDNS}+= libldns SUBDIR.${MK_STATS}+= libstats diff --git a/lib/atf/Makefile.inc b/lib/atf/Makefile.inc index f8f329842eb4..bebed0280596 100644 --- a/lib/atf/Makefile.inc +++ b/lib/atf/Makefile.inc @@ -24,6 +24,8 @@ # SUCH DAMAGE. # +PACKAGE= atf +LIB_PACKAGE= CFLAGS+= -DHAVE_CONFIG_H WARNS?= 3 diff --git a/lib/atf/libatf-c++/Makefile b/lib/atf/libatf-c++/Makefile index 985a79b7dc03..4f4f7f12ec05 100644 --- a/lib/atf/libatf-c++/Makefile +++ b/lib/atf/libatf-c++/Makefile @@ -27,7 +27,6 @@ .include <src.opts.mk> .include <bsd.init.mk> -PACKAGE= tests LIB_CXX= atf-c++ PRIVATELIB= true SHLIB_MAJOR= 2 diff --git a/lib/atf/libatf-c++/tests/Makefile b/lib/atf/libatf-c++/tests/Makefile index dc052c19df67..839c6902d6b1 100644 --- a/lib/atf/libatf-c++/tests/Makefile +++ b/lib/atf/libatf-c++/tests/Makefile @@ -1,7 +1,5 @@ .include <bsd.init.mk> -PACKAGE= tests - TESTS_SUBDIRS= detail ATF= ${SRCTOP}/contrib/atf diff --git a/lib/atf/libatf-c/Makefile b/lib/atf/libatf-c/Makefile index 4cfee2ed824f..c0890abc7640 100644 --- a/lib/atf/libatf-c/Makefile +++ b/lib/atf/libatf-c/Makefile @@ -27,7 +27,6 @@ .include <src.opts.mk> .include <bsd.init.mk> -PACKAGE= tests LIB= atf-c PRIVATELIB= true SHLIB_MAJOR= 1 diff --git a/lib/atf/libatf-c/tests/Makefile b/lib/atf/libatf-c/tests/Makefile index c81c18a91f00..5647e7b9fcbe 100644 --- a/lib/atf/libatf-c/tests/Makefile +++ b/lib/atf/libatf-c/tests/Makefile @@ -1,7 +1,5 @@ .include <bsd.init.mk> -PACKAGE= tests - TESTS_SUBDIRS= detail ATF= ${SRCTOP}/contrib/atf diff --git a/lib/clang/freebsd_cc_version.h b/lib/clang/freebsd_cc_version.h index 277744ae8624..b493dc96db5e 100644 --- a/lib/clang/freebsd_cc_version.h +++ b/lib/clang/freebsd_cc_version.h @@ -1 +1 @@ -#define FREEBSD_CC_VERSION 1500000 +#define FREEBSD_CC_VERSION 1600000 diff --git a/lib/clang/include/lld/Common/Version.inc b/lib/clang/include/lld/Common/Version.inc index 0643da4abbf4..0def3da7469c 100644 --- a/lib/clang/include/lld/Common/Version.inc +++ b/lib/clang/include/lld/Common/Version.inc @@ -1,4 +1,4 @@ // Local identifier in __FreeBSD_version style -#define LLD_FREEBSD_VERSION 1500001 +#define LLD_FREEBSD_VERSION 1600000 #define LLD_VERSION_STRING "19.1.7 (FreeBSD llvmorg-19.1.7-0-gcd708029e0b2-" __XSTRING(LLD_FREEBSD_VERSION) ")" diff --git a/lib/geom/Makefile.inc b/lib/geom/Makefile.inc index 35163127538d..75d312a94fe4 100644 --- a/lib/geom/Makefile.inc +++ b/lib/geom/Makefile.inc @@ -1,10 +1,11 @@ .include <src.opts.mk> -SHLIBDIR=${GEOM_CLASS_DIR} -SHLIB_NAME?=geom_${GEOM_CLASS}.so -MAN= g${GEOM_CLASS}.8 -SRCS+= geom_${GEOM_CLASS}.c subr.c -CFLAGS+=-I${SRCTOP}/sbin/geom +SHLIBDIR= ${GEOM_CLASS_DIR} +SHLIB_NAME?= geom_${GEOM_CLASS}.so +MANNODEV= g${GEOM_CLASS}.8 + +SRCS+= geom_${GEOM_CLASS}.c subr.c +CFLAGS+= -I${SRCTOP}/sbin/geom .PATH: ${SRCTOP}/sbin/geom/misc diff --git a/lib/geom/part/gpart.8 b/lib/geom/part/gpart.8 index f76c1d9d5d6c..2e11417f8494 100644 --- a/lib/geom/part/gpart.8 +++ b/lib/geom/part/gpart.8 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd February 11, 2025 +.Dd October 24, 2025 .Dt GPART 8 .Os .Sh NAME @@ -1497,6 +1497,26 @@ and .Bd -literal -offset indent /sbin/gpart backup ada0 | /sbin/gpart restore -F ada1 ada2 .Ed +.Sh DIAGNOSTICS +.Bl -diag +.It gpart: arg0 '%s': Invalid argument +The provided +.Ar geom +argument +is not a GEOM provider. +Not every device in +.Xr devfs 4 +is a GEOM provider. +For example, a +.Xr zfs 4 +zvol will show up as a GEOM provider only if its +.Sy volmode +is set properly +.Po refer to +.Xr zfsprops 8 +for details +.Pc . +.El .Sh SEE ALSO .Xr geom 4 , .Xr boot0cfg 8 , diff --git a/lib/libarchive/Makefile b/lib/libarchive/Makefile index fed73c388318..4e32dcf72341 100644 --- a/lib/libarchive/Makefile +++ b/lib/libarchive/Makefile @@ -184,12 +184,13 @@ MAN= archive_entry.3 \ archive_write_new.3 \ archive_write_open.3 \ archive_write_set_options.3 \ - cpio.5 \ libarchive.3 \ libarchive_changes.3 \ - libarchive_internals.3 \ - libarchive-formats.5 \ - tar.5 + libarchive_internals.3 + +MANNODEV= cpio.5 \ + libarchive-formats.5 \ + tar.5 # Symlink the man pages under each function name. MLINKS+= archive_entry.3 archive_entry_clear.3 diff --git a/lib/libarchive/tests/Makefile b/lib/libarchive/tests/Makefile index 07c5fe24dd30..930250d974c5 100644 --- a/lib/libarchive/tests/Makefile +++ b/lib/libarchive/tests/Makefile @@ -185,6 +185,7 @@ TESTS_SRCS= \ test_read_format_rar_overflow.c \ test_read_format_raw.c \ test_read_format_tar.c \ + test_read_format_tar_V_negative_size.c \ test_read_format_tar_concatenated.c \ test_read_format_tar_empty_filename.c \ test_read_format_tar_empty_pax.c \ @@ -607,6 +608,7 @@ ${PACKAGE}FILES+= test_read_format_rar5_decode_number_out_of_bounds_read.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_different_solid_window_size.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_different_window_size.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_different_winsize_on_merge.rar.uu +${PACKAGE}FILES+= test_read_format_rar5_dirdata.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_distance_overflow.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_encrypted.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_encrypted_filenames.rar.uu @@ -616,6 +618,7 @@ ${PACKAGE}FILES+= test_read_format_rar5_extra_field_version.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_fileattr.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_hardlink.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_invalid_dict_reference.rar.uu +${PACKAGE}FILES+= test_read_format_rar5_invalid_hash_valid_htime_exfld.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_leftshift1.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_leftshift2.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_multiarchive.part01.rar.uu @@ -633,6 +636,7 @@ ${PACKAGE}FILES+= test_read_format_rar5_multiarchive_solid.part04.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_multiple_files.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_multiple_files_solid.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_nonempty_dir_stream.rar.uu +${PACKAGE}FILES+= test_read_format_rar5_only_crypt_exfld.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_owner.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_readtables_overflow.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_sfx.exe.uu @@ -642,12 +646,14 @@ ${PACKAGE}FILES+= test_read_format_rar5_stored_manyfiles.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_symlink.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_truncated_huff.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_unicode.rar.uu +${PACKAGE}FILES+= test_read_format_rar5_unsupported_exfld.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_win32.rar.uu ${PACKAGE}FILES+= test_read_format_rar5_window_buf_and_size_desync.rar.uu ${PACKAGE}FILES+= test_read_format_raw.bufr.uu ${PACKAGE}FILES+= test_read_format_raw.data.Z.uu ${PACKAGE}FILES+= test_read_format_raw.data.gz.uu ${PACKAGE}FILES+= test_read_format_raw.data.uu +${PACKAGE}FILES+= test_read_format_tar_V_negative_size.tar.uu ${PACKAGE}FILES+= test_read_format_tar_concatenated.tar.uu ${PACKAGE}FILES+= test_read_format_tar_empty_filename.tar.uu ${PACKAGE}FILES+= test_read_format_tar_empty_with_gnulabel.tar.uu diff --git a/lib/libbe/Makefile b/lib/libbe/Makefile index b04becc38d74..3ba456aee4b7 100644 --- a/lib/libbe/Makefile +++ b/lib/libbe/Makefile @@ -3,6 +3,7 @@ SHLIBDIR?= /lib .include <src.opts.mk> PACKAGE= zfs +LIB_PACKAGE= LIB= be SHLIB_MAJOR= 1 SHLIB_MINOR= 0 diff --git a/lib/libblacklist/Makefile b/lib/libblacklist/Makefile index bfd9edb9614c..cac023d69bb7 100644 --- a/lib/libblacklist/Makefile +++ b/lib/libblacklist/Makefile @@ -1,6 +1,6 @@ BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist -.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include +.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include ${BLOCKLIST_DIR}/port PACKAGE= blocklist LIB= blacklist @@ -13,9 +13,10 @@ CFLAGS.clang+=-Wno-thread-safety-analysis CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ -D_REENTRANT -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_GETPROGNAME \ - -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRUCT_SOCKADDR_SA_LEN + -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRUCT_SOCKADDR_SA_LEN \ + -DHAVE_SYS_CDEFS_H -SRCS= bl.c blacklist.c +SRCS= old_bl.c blacklist.c vsyslog_r.c INCS= blacklist.h MAN= libblacklist.3 diff --git a/lib/libblocklist/Makefile b/lib/libblocklist/Makefile new file mode 100644 index 000000000000..127abb23f43e --- /dev/null +++ b/lib/libblocklist/Makefile @@ -0,0 +1,30 @@ +BLOCKLIST_DIR=${SRCTOP}/contrib/blocklist + +.PATH: ${BLOCKLIST_DIR}/lib ${BLOCKLIST_DIR}/include ${BLOCKLIST_DIR}/port + +PACKAGE= blocklist +LIB= blocklist +SHLIB_MAJOR= 0 + +LIBADD+= pthread + +CFLAGS.clang+=-Wno-thread-safety-analysis + +CFLAGS+=-I${BLOCKLIST_DIR}/include -I${BLOCKLIST_DIR}/port \ + -D_REENTRANT -DHAVE_CONFIG_H -DHAVE_DB_H -DHAVE_LIBUTIL_H \ + -DHAVE_CLOCK_GETTIME -DHAVE_FGETLN -DHAVE_GETPROGNAME \ + -DHAVE_STRLCAT -DHAVE_STRLCPY -DHAVE_STRUCT_SOCKADDR_SA_LEN \ + -DHAVE_SYS_CDEFS_H + +SRCS= bl.c blocklist.c vsyslog_r.c +INCS= blocklist.h +MAN= libblocklist.3 + +MLINKS= libblocklist.3 blocklist_open.3 \ + libblocklist.3 blocklist_close.3 \ + libblocklist.3 blocklist.3 \ + libblocklist.3 blocklist_r.3 \ + libblocklist.3 blocklist_sa.3 \ + libblocklist.3 blocklist_sa_r.3 + +.include <bsd.lib.mk> diff --git a/lib/libblocklist/Makefile.depend b/lib/libblocklist/Makefile.depend new file mode 100644 index 000000000000..577dc5747f1e --- /dev/null +++ b/lib/libblocklist/Makefile.depend @@ -0,0 +1,16 @@ +# Autogenerated - do NOT edit! + +DIRDEPS = \ + include \ + include/xlocale \ + lib/${CSU_DIR} \ + lib/libc \ + lib/libcompiler_rt \ + lib/libthr \ + + +.include <dirdeps.mk> + +.if ${DEP_RELDIR} == ${_DEP_RELDIR} +# local dependencies - needed for -jN in clean tree +.endif diff --git a/lib/libbluetooth/Makefile b/lib/libbluetooth/Makefile index a6ac291a0bf8..b935bdf3fc78 100644 --- a/lib/libbluetooth/Makefile +++ b/lib/libbluetooth/Makefile @@ -1,6 +1,8 @@ # $Id: Makefile,v 1.5 2003/07/22 18:38:04 max Exp $ PACKAGE= bluetooth +LIB_PACKAGE= + CONFS= hosts protocols CONFSDIR= /etc/bluetooth CONFSMODE_protocols= 444 diff --git a/lib/libbsdstat/bsdstat.h b/lib/libbsdstat/bsdstat.h index 1b0d1f24e93f..b293cd652a72 100644 --- a/lib/libbsdstat/bsdstat.h +++ b/lib/libbsdstat/bsdstat.h @@ -76,7 +76,7 @@ struct fmt { * classes derived from it are useful. */ struct bsdstat { - const char *name; /* statistics name, e.g. wlanstats */ + const char *name; /* statistics name, e.g. wlanstat */ const struct fmt *stats; /* statistics in class */ int nstats; /* number of stats */ #define FMTS_IS_STAT 0x80 /* the following two bytes are the stat id */ diff --git a/lib/libbsm/Makefile b/lib/libbsm/Makefile index 67802eef62ac..4413a5dd79f7 100644 --- a/lib/libbsm/Makefile +++ b/lib/libbsm/Makefile @@ -1,9 +1,8 @@ -# -# +PACKAGE= audit +LIB_PACKAGE= -PACKAGE= lib${LIB} -OPENBSMDIR= ${SRCTOP}/contrib/openbsm -_LIBBSMDIR= ${OPENBSMDIR}/libbsm +OPENBSMDIR= ${SRCTOP}/contrib/openbsm +_LIBBSMDIR= ${OPENBSMDIR}/libbsm LIB= bsm SHLIB_MAJOR= 3 diff --git a/lib/libbz2/Makefile b/lib/libbz2/Makefile index f7ea21b1a085..2aedbaed4328 100644 --- a/lib/libbz2/Makefile +++ b/lib/libbz2/Makefile @@ -1,4 +1,6 @@ -PACKAGE= lib${LIB} +PACKAGE= bzip2 +LIB_PACKAGE= + BZ2DIR= ${SRCTOP}/contrib/bzip2 .PATH: ${BZ2DIR} @@ -11,4 +13,17 @@ CFLAGS+= -I${BZ2DIR} WARNS?= 3 +BZIP2_VERSION!= sed -n '/bzip2\/libbzip2 version /{s/.*version //;s/ of.*//p;q;}' ${BZ2DIR}/bzlib.h + +bzip2.pc: bzip2.pc.in + sed -e 's,@prefix@,/usr,g ; \ + s,@exec_prefix@,$${prefix},g ; \ + s,@libdir@,${LIBDIR},g ; \ + s,@sharedlibdir@,${SHLIBDIR},g ; \ + s,@includedir@,${INCLUDEDIR},g ; \ + s,@VERSION@,${BZIP2_VERSION},g ;' \ + ${.ALLSRC} > ${.TARGET} + +PCFILES= bzip2.pc + .include <bsd.lib.mk> diff --git a/lib/libbz2/bzip2.pc.in b/lib/libbz2/bzip2.pc.in new file mode 100644 index 000000000000..d91c9931a58a --- /dev/null +++ b/lib/libbz2/bzip2.pc.in @@ -0,0 +1,11 @@ +prefix=@prefix@ +exec_prefix=@exec_prefix@ +libdir=@libdir@ +sharedlibdir=@sharedlibdir@ +includedir=@includedir@ + +Name: bzip2 +Description: bzip2 compression library +Version: @VERSION@ +Libs: -L${libdir} -lbz2 +Cflags: -I${includedir} diff --git a/lib/libc/Makefile b/lib/libc/Makefile index d0c254e33396..8705568f6d34 100644 --- a/lib/libc/Makefile +++ b/lib/libc/Makefile @@ -109,7 +109,6 @@ NOASM= .include "${LIBC_SRCTOP}/inet/Makefile.inc" .include "${LIBC_SRCTOP}/isc/Makefile.inc" .include "${LIBC_SRCTOP}/locale/Makefile.inc" -.include "${LIBC_SRCTOP}/md/Makefile.inc" .include "${LIBC_SRCTOP}/nameser/Makefile.inc" .include "${LIBC_SRCTOP}/net/Makefile.inc" .include "${LIBC_SRCTOP}/nls/Makefile.inc" diff --git a/lib/libc/Versions.def b/lib/libc/Versions.def index 184e107d225a..1c7b34bef35b 100644 --- a/lib/libc/Versions.def +++ b/lib/libc/Versions.def @@ -42,6 +42,10 @@ FBSD_1.7 { FBSD_1.8 { } FBSD_1.7; +# This version was first added to 16.0-current. +FBSD_1.9 { +} FBSD_1.8; + # This is our private namespace. Any global interfaces that are # strictly for use only by other FreeBSD applications and libraries # are listed here. We use a separate namespace so we can write @@ -49,4 +53,4 @@ FBSD_1.8 { # # Please do NOT increment the version of this namespace. FBSDprivate_1.0 { -} FBSD_1.8; +} FBSD_1.9; diff --git a/lib/libc/aarch64/string/timingsafe_memcmp.S b/lib/libc/aarch64/string/timingsafe_memcmp.S index 28fdd911a387..4cc10a152aa8 100644 --- a/lib/libc/aarch64/string/timingsafe_memcmp.S +++ b/lib/libc/aarch64/string/timingsafe_memcmp.S @@ -114,4 +114,4 @@ ENTRY(timingsafe_memcmp) csetm w0, lo csinc w0, w0, wzr, ls ret -END(timingsafe_bcmp) +END(timingsafe_memcmp) diff --git a/lib/libc/gdtoa/_hdtoa.c b/lib/libc/gdtoa/_hdtoa.c index 8ae739acf0db..9c42630cd918 100644 --- a/lib/libc/gdtoa/_hdtoa.c +++ b/lib/libc/gdtoa/_hdtoa.c @@ -40,6 +40,7 @@ #define DBL_ADJ (DBL_MAX_EXP - 2) #define SIGFIGS ((DBL_MANT_DIG + 3) / 4 + 1) +#define MAX_HEX_DIGITS ((DBL_MANT_DIG + 3 - 1) / 4 + 1) static const float one[] = { 1.0f, -1.0f }; @@ -111,7 +112,7 @@ __hdtoa(double d, const char *xdigs, int ndigits, int *decpt, int *sign, s0 = rv_alloc(bufsize); /* Round to the desired number of digits. */ - if (SIGFIGS > ndigits && ndigits > 0) { + if (MAX_HEX_DIGITS > ndigits && ndigits > 0) { float redux = one[u.bits.sign]; int offset = 4 * ndigits + DBL_MAX_EXP - 4 - DBL_MANT_DIG; u.bits.exp = offset; diff --git a/lib/libc/gdtoa/_hldtoa.c b/lib/libc/gdtoa/_hldtoa.c index 965d2349d103..5f10d12c5c09 100644 --- a/lib/libc/gdtoa/_hldtoa.c +++ b/lib/libc/gdtoa/_hldtoa.c @@ -65,6 +65,7 @@ typedef uint32_t manl_t; #define LDBL_ADJ (LDBL_MAX_EXP - 2) #define SIGFIGS ((LDBL_MANT_DIG + 3) / 4 + 1) +#define MAX_HEX_DIGITS ((LDBL_MANT_DIG + 3 - 1) / 4 + 1) static const float one[] = { 1.0f, -1.0f }; @@ -125,7 +126,7 @@ __hldtoa(long double e, const char *xdigs, int ndigits, int *decpt, int *sign, s0 = rv_alloc(bufsize); /* Round to the desired number of digits. */ - if (SIGFIGS > ndigits && ndigits > 0) { + if (MAX_HEX_DIGITS > ndigits && ndigits > 0) { float redux = one[u.bits.sign]; int offset = 4 * ndigits + LDBL_MAX_EXP - 4 - LDBL_MANT_DIG; #ifdef __i386__ diff --git a/lib/libc/gen/Symbol.map b/lib/libc/gen/Symbol.map index 26f638568efc..494b65bc5cc1 100644 --- a/lib/libc/gen/Symbol.map +++ b/lib/libc/gen/Symbol.map @@ -193,7 +193,6 @@ FBSD_1.0 { __isinff; __isinfl; isatty; - initgroups; jrand48; lcong48; ldexp; @@ -462,6 +461,7 @@ FBSD_1.8 { fdscandir_b; fts_open_b; glob_b; + initgroups; inotify_add_watch; inotify_init; inotify_init1; diff --git a/lib/libc/gen/_rand48.c b/lib/libc/gen/_rand48.c index 990e2c86949b..114c1595b33d 100644 --- a/lib/libc/gen/_rand48.c +++ b/lib/libc/gen/_rand48.c @@ -13,34 +13,6 @@ #include "rand48.h" -unsigned short _rand48_seed[3] = { - RAND48_SEED_0, - RAND48_SEED_1, - RAND48_SEED_2 -}; -unsigned short _rand48_mult[3] = { - RAND48_MULT_0, - RAND48_MULT_1, - RAND48_MULT_2 -}; -unsigned short _rand48_add = RAND48_ADD; - -void -_dorand48(unsigned short xseed[3]) -{ - unsigned long accu; - unsigned short temp[2]; - - accu = (unsigned long) _rand48_mult[0] * (unsigned long) xseed[0] + - (unsigned long) _rand48_add; - temp[0] = (unsigned short) accu; /* lower 16 bits */ - accu >>= sizeof(unsigned short) * 8; - accu += (unsigned long) _rand48_mult[0] * (unsigned long) xseed[1] + - (unsigned long) _rand48_mult[1] * (unsigned long) xseed[0]; - temp[1] = (unsigned short) accu; /* middle 16 bits */ - accu >>= sizeof(unsigned short) * 8; - accu += _rand48_mult[0] * xseed[2] + _rand48_mult[1] * xseed[1] + _rand48_mult[2] * xseed[0]; - xseed[0] = temp[0]; - xseed[1] = temp[1]; - xseed[2] = (unsigned short) accu; -} +uint48 _rand48_seed = RAND48_SEED; +uint48 _rand48_mult = RAND48_MULT; +uint48 _rand48_add = RAND48_ADD; diff --git a/lib/libc/gen/drand48.c b/lib/libc/gen/drand48.c index cec04a6a2425..f7f43ff20468 100644 --- a/lib/libc/gen/drand48.c +++ b/lib/libc/gen/drand48.c @@ -13,10 +13,10 @@ #include "rand48.h" -extern unsigned short _rand48_seed[3]; - double drand48(void) { - return erand48(_rand48_seed); + ERAND48_BEGIN; + _DORAND48(_rand48_seed); + ERAND48_END(_rand48_seed); } diff --git a/lib/libc/gen/erand48.c b/lib/libc/gen/erand48.c index 286904c27839..38d4774a9fe6 100644 --- a/lib/libc/gen/erand48.c +++ b/lib/libc/gen/erand48.c @@ -16,8 +16,9 @@ double erand48(unsigned short xseed[3]) { - _dorand48(xseed); - return ldexp((double) xseed[0], -48) + - ldexp((double) xseed[1], -32) + - ldexp((double) xseed[2], -16); + uint48 tmp; + + ERAND48_BEGIN; + DORAND48(tmp, xseed); + ERAND48_END(tmp); } diff --git a/lib/libc/gen/fts-compat.c b/lib/libc/gen/fts-compat.c index f87cabf085f7..62a1e0a81f62 100644 --- a/lib/libc/gen/fts-compat.c +++ b/lib/libc/gen/fts-compat.c @@ -44,9 +44,9 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "gen-compat.h" #include "fts-compat.h" #include "un-namespace.h" +#include "gen-compat.h" #include "gen-private.h" diff --git a/lib/libc/gen/fts-compat11.c b/lib/libc/gen/fts-compat11.c index 0351ce5ac690..5abb378f5f08 100644 --- a/lib/libc/gen/fts-compat11.c +++ b/lib/libc/gen/fts-compat11.c @@ -43,9 +43,9 @@ #include <stdlib.h> #include <string.h> #include <unistd.h> -#include "gen-compat.h" #include "fts-compat11.h" #include "un-namespace.h" +#include "gen-compat.h" #include "gen-private.h" diff --git a/lib/libc/gen/fts.3 b/lib/libc/gen/fts.3 index ee558b892c8c..da304e59ee72 100644 --- a/lib/libc/gen/fts.3 +++ b/lib/libc/gen/fts.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd June 30, 2025 +.Dd October 6, 2025 .Dt FTS 3 .Os .Sh NAME @@ -69,14 +69,15 @@ on a file hierarchy, which is then supplied to the other .Nm functions. -The function +The .Fn fts_read -returns a pointer to a structure describing one of the files in the file -hierarchy. -The function +function returns a pointer to a structure describing one of the files +in the file hierarchy. +The .Fn fts_children -returns a pointer to a linked list of structures, each of which describes -one of the files contained in a directory in the hierarchy. +function returns a pointer to a linked list of structures, each of +which describes one of the files contained in a directory in the +hierarchy. In general, directories are visited two distinguishable times; in pre-order (before any of their descendants are visited) and in post-order (after all of their descendants have been visited). @@ -376,7 +377,44 @@ The .Fa fts_name field is always .Dv NUL Ns -terminated . -.Sh FTS_OPEN +.Ss Thread Safety +The +.Nm +functions can safely be used in multi-threaded programs provided no +two threads access the same +.Vt FTS +or +.Vt FTSENT +structure simultaneously. +However, unless the +.Dv FTS_NOCHDIR +flag was passed to +.Fn fts_open +or +.Fn fts_open_b , +calls to +.Fn fts_read +and +.Fn fts_children +may change the current working directory, which will affect all +threads. +Conversely, changing the current working directory either during or +between calls to +.Fn fts_read +or +.Fn fts_children +(even in a single-thread program) may cause +.Nm +to malfunction unless the +.Dv FTS_NOCHDIR +flag was passed to +.Fn fts_open +or +.Fn fts_open_b +and all paths in +.Va path_argv +were absolute. +.Ss Fn fts_open The .Fn fts_open function takes a pointer to an array of character pointers naming one @@ -507,10 +545,10 @@ from descending into directories that have a different device number than the file from which the descent began. .El .Pp -The argument -.Fn compar -specifies a user-defined function which may be used to order the traversal -of the hierarchy. +The +.Fa compar +argument points to a user-defined function which may be used to order +the traversal of the hierarchy. It takes two pointers to pointers to .Vt FTSENT @@ -545,7 +583,7 @@ the directory traversal order is in the order listed in .Fa path_argv for the root paths, and in the order listed in the directory for everything else. -.Sh FTS_OPEN_B +.Ss Fn fts_open_b The .Fn fts_open_b function is identical to @@ -554,7 +592,7 @@ except that it takes a block pointer instead of a function pointer. The block is copied before .Fn fts_open_b returns, so the original can safely go out of scope or be released. -.Sh FTS_READ +.Ss Fn fts_read The .Fn fts_read function returns a pointer to an @@ -588,6 +626,15 @@ structure is returned, and .Va errno may or may not have been set (see .Fa fts_info ) . +Note that +.Fn fts_read +will not set +.Va errno +to 0 if called again with the same +.Fa ftsp +argument after the +.Dv FTS_STOP +flag has been set or the end of the stream has been reached. .Pp The .Vt FTSENT @@ -602,10 +649,10 @@ directory, in which case they will not be overwritten until after a call to .Fn fts_read after the .Vt FTSENT -structure has been returned by the function +structure has been returned by the .Fn fts_read -in post-order. -.Sh FTS_CHILDREN +function in post-order. +.Ss Fn fts_children The .Fn fts_children function returns a pointer to an @@ -679,11 +726,11 @@ and .Fa fts_namelen fields. .El -.Sh FTS_SET -The function +.Ss Fn fts_set +The .Fn fts_set -allows the user application to determine further processing for the -file +function allows the user application to determine further processing +for the file .Fa f of the stream .Fa ftsp . @@ -749,7 +796,40 @@ The file may be one of those most recently returned by either or .Fn fts_read . .El -.Sh FTS_CLOSE +.Ss Fn fts_set_clientptr , Fn fts_get_clientptr +The +.Fn fts_set_clientptr +function sets the client data pointer for the stream +.Fa ftsp +to +.Fa clientdata . +The +.Fn fts_get_clientptr +function returns the client data pointer associated with +.Fa ftsp . +This can be used to pass per-stream data to the comparison function. +.Pp +For performance reasons, +.Fn fts_get_clientptr +may be shadowed by a preprocessor macro. +.Ss Fn fts_get_stream +The +.Fn fts_get_stream +function returns the +.Nm +stream associated with the file entry +.Fa f . +A typical use for this would be for a comparison function to first call +.Fn fts_get_stream +on one of its arguments, then call +.Fn fts_get_clientptr +to obtain the client data pointer, which in turn points to information +necessary to correctly order the two entries. +.Pp +For performance reasons, +.Fn fts_get_stream +may be shadowed by a preprocessor macro. +.Ss Fn fts_close The .Fn fts_close function closes a file hierarchy stream @@ -760,6 +840,75 @@ or .Fn fts_open_b was called to open .Fa ftsp . +.Sh RETURN VALUES +The +.Fn fts_open +and +.Fn fts_open_b +functions return a pointer to the new +.Nm +stream on success and +.Dv NULL +on failure. +.Pp +The +.Fn fts_read +function returns a pointer to the next file entry on success, or if an +error occurs that relates specifically to that file entry. +On reaching the end of the file hierarchy, it returns +.Dv NULL +and sets the external variable +.Va errno +to 0. +On failure, it returns +.Dv NULL +and sets +.Va errno +to an appropriate non-zero value. +If called again after the +.Dv FTS_STOP +flag has been set or the end of the stream has been reached, +.Fn fts_read +returns +.Dv NULL +and leaves +.Va errno +untouched. +.Pp +The +.Fn fts_children +function returns a pointer to a linked list of file entries on +success. +On reaching the end of the file hierarchy, it returns +.Dv NULL +and sets the external variable +.Va errno +to 0. +On failure, it returns +.Dv NULL +and sets +.Va errno +to an appropriate non-zero value. +.Pp +The +.Fn fts_set +function returns 0 on success and \-1 if its +.Fa instr +argument is invalid. +.Pp +The +.Fn fts_get_clientptr +function returns the client data pointer associated with its argument, +or +.Dv NULL +if none has been set. +.Pp +The +.Fn fts_get_stream +function returns a pointer to the +.Nm +stream associated with its argument. +.Pp The .Fn fts_close function @@ -816,7 +965,7 @@ functions may fail and set as follows: .Bl -tag -width Er .It Bq Er EINVAL -The options were invalid, or the list were empty. +The options were invalid, or the list was empty. .El .Sh SEE ALSO .Xr find 1 , diff --git a/lib/libc/gen/fts.c b/lib/libc/gen/fts.c index cce959ba836a..4aa386d777cd 100644 --- a/lib/libc/gen/fts.c +++ b/lib/libc/gen/fts.c @@ -106,7 +106,6 @@ struct _fts_private { * This assumption only holds for UFS-like filesystems that implement * links and directories this way, so we must punt for others. */ - static const char *ufslike_filesystems[] = { "ufs", "zfs", @@ -679,7 +678,6 @@ fts_children(FTS *sp, int instr) void * (fts_get_clientptr)(FTS *sp) { - return (fts_get_clientptr(sp)); } @@ -696,7 +694,6 @@ FTS * void fts_set_clientptr(FTS *sp, void *clientptr) { - sp->fts_clientptr = clientptr; } diff --git a/lib/libc/gen/gen-compat.h b/lib/libc/gen/gen-compat.h index 08e80ede6b6e..19b9addb4321 100644 --- a/lib/libc/gen/gen-compat.h +++ b/lib/libc/gen/gen-compat.h @@ -40,16 +40,50 @@ struct freebsd11_statfs; struct freebsd11_dirent *freebsd11_readdir(DIR *); int freebsd11_readdir_r(DIR *, struct freebsd11_dirent *, struct freebsd11_dirent **); -int freebsd11_stat(const char *, struct freebsd11_stat *); -int freebsd11_lstat(const char *, struct freebsd11_stat *); -int freebsd11_fstat(int, struct freebsd11_stat *); -int freebsd11_fstatat(int, const char *, struct freebsd11_stat *, int); -int freebsd11_statfs(const char *, struct freebsd11_statfs *); -int freebsd11_getfsstat(struct freebsd11_statfs *, long, int); int freebsd11_getmntinfo(struct freebsd11_statfs **, int); char *freebsd11_devname(__uint32_t dev, __mode_t type); -char *freebsd11_devname_r(__uint32_t dev, __mode_t type, char *buf, int len); +char *freebsd11_devname_r(__uint32_t dev, __mode_t type, char *buf, + int len); + +/* + * We want freebsd11_fstat in C source to result in resolution to + * - fstat@FBSD_1.0 for libc.so (but we do not need the _definition_ + * of this fstat, it is provided by libsys.so which we want to use). + * - freebsd11_fstat for libc.a (since if we make it fstat@FBSD_1.0 + * for libc.a, then final linkage into static object ignores version + * and would reference fstat, which is the current syscall, not the + * compat syscall). libc.a provides the freebsd11_fstat implementation. + * Note that freebsd11_fstat from libc.a is not used for anything, but + * we make it correct nonetheless, just in case it would. + * This is arranged by COMPAT_SYSCALL, and libc can just use freebsd11_fstat. + */ +#ifdef PIC +#define COMPAT_SYSCALL(rtype, fun, args, sym, ver) \ + rtype fun args; __sym_compat(sym, fun, ver); +#else +#define COMPAT_SYSCALL(rtype, fun, args, sym, ver) \ + rtype fun args; +#endif + +COMPAT_SYSCALL(int, freebsd11_stat, (const char *, struct freebsd11_stat *), + stat, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_lstat, (const char *, struct freebsd11_stat *), + lstat, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_fstat, (int, struct freebsd11_stat *), + fstat, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_fstatat, (int, const char *, + struct freebsd11_stat *, int), fstatat, FBSD_1.1); + +COMPAT_SYSCALL(int, freebsd11_statfs, (const char *, + struct freebsd11_statfs *), statfs, FBSD_1.0); +COMPAT_SYSCALL(int, freebsd11_getfsstat, (struct freebsd11_statfs *, long, + int), getfsstat, FBSD_1.0); + +COMPAT_SYSCALL(int, freebsd14_setgroups, (int gidsize, const __gid_t *gidset), + setgroups, FBSD_1.0); + +#undef COMPAT_SYSCALL #endif /* _GEN_COMPAT_H_ */ diff --git a/lib/libc/gen/getgrouplist.3 b/lib/libc/gen/getgrouplist.3 index e9a980f99751..9e05ff7e7a29 100644 --- a/lib/libc/gen/getgrouplist.3 +++ b/lib/libc/gen/getgrouplist.3 @@ -1,5 +1,13 @@ +.\"- +.\" SPDX-License-Identifier: BSD-3-Clause +.\" .\" Copyright (c) 1991, 1993 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 2025 The FreeBSD Foundation +.\" +.\" Portions of this documentation were written by Olivier Certner +.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD +.\" Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -25,12 +33,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 26, 2014 +.Dd October 9, 2025 .Dt GETGROUPLIST 3 .Os .Sh NAME .Nm getgrouplist -.Nd calculate group access list +.Nd produce a user's effective group list .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -40,36 +48,44 @@ .Sh DESCRIPTION The .Fn getgrouplist -function reads through the group file and calculates -the group access list for the user specified in -.Fa name . -The +function retrieves from the group database the supplementary groups for the user +specified in +.Fa name +and returns the effective group list, whose first group is the value of +.Fa basegid +and the others are the supplementary groups. .Fa basegid -is automatically included in the groups list. -Typically this value is given as -the group number from the password file. +typically is the user's initial numerical group ID from the password database. .Pp -The resulting group list is returned in the array pointed to by +The effective group list is returned in the array pointed to by .Fa groups . -The caller specifies the size of the +The caller specifies the length of the .Fa groups array in the integer pointed to by -.Fa ngroups ; -the actual number of groups found is returned in +.Fa ngroups . +The number of groups of the effective group list, which may be greater than the +.Fa groups +array's length, is returned through .Fa ngroups . .Sh RETURN VALUES The .Fn getgrouplist -function -returns 0 on success and \-1 if the size of the group list is too small to -hold all the user's groups. -Here, the group array will be filled with as many groups as will fit. +function returns 0 on success and \-1 if the length of the group list is too +small to hold all the user's groups. +In the latter case, the +.Fa groups +array is filled with as many groups as possible from the start of the effective +group list, and the length pointed to by +.Fa ngroups +is set to the full length of the latter, thus to a value strictly greater than +before the call. .Sh FILES .Bl -tag -width /etc/group -compact .It Pa /etc/group group membership list .El .Sh SEE ALSO +.Xr setcred 2 , .Xr setgroups 2 , .Xr initgroups 3 .Sh HISTORY diff --git a/lib/libc/gen/getgrouplist.c b/lib/libc/gen/getgrouplist.c index 5bd06bc5121f..9c57b7031336 100644 --- a/lib/libc/gen/getgrouplist.c +++ b/lib/libc/gen/getgrouplist.c @@ -29,13 +29,8 @@ * SUCH DAMAGE. */ -/* - * get credential - */ #include <sys/types.h> -#include <grp.h> -#include <string.h> #include <unistd.h> #include <ssp/ssp.h> @@ -46,4 +41,3 @@ __ssp_real(getgrouplist)(const char *uname, gid_t agroup, gid_t *groups, int *gr { return __getgroupmembership(uname, agroup, groups, *grpcnt, grpcnt); } - diff --git a/lib/libc/gen/getvfsbyname.3 b/lib/libc/gen/getvfsbyname.3 index 23036429b27e..61fd48624fbd 100644 --- a/lib/libc/gen/getvfsbyname.3 +++ b/lib/libc/gen/getvfsbyname.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 16, 2018 +.Dd October 28, 2025 .Dt GETVFSBYNAME 3 .Os .Sh NAME @@ -102,6 +102,7 @@ argument specifies a file system that is unknown or not configured in the kernel. .El .Sh SEE ALSO +.Xr lsvfs 1 , .Xr jail 2 , .Xr mount 2 , .Xr sysctl 3 , diff --git a/lib/libc/gen/initgroups.3 b/lib/libc/gen/initgroups.3 index 03bd07494fc9..74133e7d7048 100644 --- a/lib/libc/gen/initgroups.3 +++ b/lib/libc/gen/initgroups.3 @@ -1,5 +1,13 @@ +.\"- +.\" SPDX-License-Identifier: BSD-3-Clause +.\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 2025 The FreeBSD Foundation +.\" +.\" Portions of this documentation were written by Olivier Certner +.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD +.\" Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -25,12 +33,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 26, 2014 +.Dd October 9, 2025 .Dt INITGROUPS 3 .Os .Sh NAME .Nm initgroups -.Nd initialize group access list +.Nd initialize supplementary groups as per the group database .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -40,19 +48,18 @@ .Sh DESCRIPTION The .Fn initgroups -function -uses the -.Xr getgrouplist 3 -function to calculate the group access list for the user -specified in +function initializes the current process' supplementary groups as prescribed by +its arguments and the system's group database. +.Pp +It first uses the +.Fn getgrouplist +function to compute a list of groups containing the passed +.Fa basegid , +which typically is the user's initial numerical group ID from the password +database, and the supplementary groups in the group database for the user named .Fa name . -This group list is then setup for the current process using -.Xr setgroups 2 . -The -.Fa basegid -is automatically included in the groups list. -Typically this value is given as -the group number from the password file. +It then installs this list as the current process' supplementary groups using +.Fn setgroups . .Sh RETURN VALUES .Rv -std initgroups .Sh ERRORS @@ -60,9 +67,9 @@ The .Fn initgroups function may fail and set .Va errno -for any of the errors specified for the library function -.Xr setgroups 2 . -It may also return: +to any of the errors specified for the +.Xr setgroups 2 +system call, or to: .Bl -tag -width Er .It Bq Er ENOMEM The @@ -77,3 +84,67 @@ The .Fn initgroups function appeared in .Bx 4.2 . +.Pp +The +.Fn initgroups +function changed semantics in +.Fx 15 , +following that of +.Xr setgroups 2 +in the same release. +Before that, it would also set the effective group ID to +.Fa basegid , +and would not include the latter in the supplementary groups except before +.Fx 8 . +Its current behavior in these respects is known to be compatible with that of +the following systems up to the specified versions that are current at time of +this writing: +.Bl -dash -width "-" -compact +.It +Linux (up to 6.6) with the GNU libc (up to 2.42) +.It +.Nx 1.1 and greater (up to 10) +.It +.Ox (up to 7.7) +.It +Systems based on illumos (up to August 2025 sources) +.El +.Sh SECURITY CONSIDERATIONS +As +.Fa basegid +is typically the user's initial numerical group ID, to which the current +process' effective group ID is generally initialized, processes using functions +to change their effective group ID +.Pq via Xr setgid 2 or similar +or that are spawned from executables with the set-group-ID mode bit set will not +be able to relinquish the access rights deriving from being a member of +.Fa basegid , +as these functions do not change the supplementary groups. +.Pp +This behavior is generally desirable in order to paper over the difference of +treatment between the effective group and supplementary ones in this situation, +as they are all in the end indiscriminately used in traditional UNIX +discretionary access checks. +It blends well with the practice of allocating each user its own private group, +as processes launched from a set-group-ID executable keep the same user and +consistently stay also in the same user's group. +Finally, it was also chosen for compatibility with other systems +.Po +see the +.Sx HISTORY +section +.Pc . +.Pp +This convention of including +.Fa basegid +in the supplementary groups is however only enforced by the +.Fn initgroups +function, and not by the +.Xr setgroups 2 +system call, so applications expressly wanting to include in the supplementary +groups only those specified by the group database can themselves call +.Fn getgrouplist +and then +.Fn setgroups +on the result with the first element skipped +.Pq see Xr getgrouplist 3 . diff --git a/lib/libc/gen/initgroups.c b/lib/libc/gen/initgroups.c index b6697dd7ed8f..a1a7d92250e2 100644 --- a/lib/libc/gen/initgroups.c +++ b/lib/libc/gen/initgroups.c @@ -3,6 +3,11 @@ * * Copyright (c) 1983, 1993 * The Regents of the University of California. All rights reserved. + * Copyright (c) 2025 The FreeBSD Foundation + * + * Portions of this software were developed by Olivier Certner + * <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD + * Foundation. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -29,34 +34,52 @@ * SUCH DAMAGE. */ -#include <sys/param.h> +/* For __sym_compat(). */ +#include <sys/cdefs.h> -#include "namespace.h" -#include <err.h> -#include "un-namespace.h" #include <errno.h> -#include <stdio.h> #include <stdlib.h> #include <unistd.h> -int -initgroups(const char *uname, gid_t agroup) +/* For freebsd14_setgroups(). */ +#include "gen-compat.h" + +static int +initgroups_impl(const char *uname, gid_t agroup, + int (*setgroups)(int, const gid_t *)) { - int ngroups, ret; - long ngroups_max; gid_t *groups; + long ngroups_max; + int ngroups, ret; /* - * Provide space for one group more than possible to allow - * setgroups to fail and set errno. + * Provide space for one group more than possible to allow setgroups() + * to fail and set 'errno' in case we get back more than {NGROUPS_MAX} + + * 1 groups. */ ngroups_max = sysconf(_SC_NGROUPS_MAX) + 2; - if ((groups = malloc(sizeof(*groups) * ngroups_max)) == NULL) - return (ENOMEM); + groups = malloc(sizeof(*groups) * ngroups_max); + if (groups == NULL) + return (-1); /* malloc() set 'errno'. */ ngroups = (int)ngroups_max; - getgrouplist(uname, agroup, groups, &ngroups); - ret = setgroups(ngroups, groups); + (void)getgrouplist(uname, agroup, groups, &ngroups); + ret = (*setgroups)(ngroups, groups); + free(groups); - return (ret); + return (ret); /* setgroups() set 'errno'. */ } + +int +initgroups(const char *uname, gid_t agroup) +{ + return (initgroups_impl(uname, agroup, setgroups)); +} + +int +freebsd14_initgroups(const char *uname, gid_t agroup) +{ + return (initgroups_impl(uname, agroup, freebsd14_setgroups)); +} + +__sym_compat(initgroups, freebsd14_initgroups, FBSD_1.0); diff --git a/lib/libc/gen/jrand48.c b/lib/libc/gen/jrand48.c index 0a9f780a9e5c..93442439d49e 100644 --- a/lib/libc/gen/jrand48.c +++ b/lib/libc/gen/jrand48.c @@ -11,14 +11,13 @@ * to anyone/anything when using this software. */ -#include <stdint.h> - #include "rand48.h" long jrand48(unsigned short xseed[3]) { + uint48 tmp; - _dorand48(xseed); - return ((int32_t)(((uint32_t)xseed[2] << 16) | (uint32_t)xseed[1])); + DORAND48(tmp, xseed); + return ((int)((tmp >> 16) & 0xffffffff)); } diff --git a/lib/libc/gen/lcong48.c b/lib/libc/gen/lcong48.c index f13826b3d3f3..871b2110ed94 100644 --- a/lib/libc/gen/lcong48.c +++ b/lib/libc/gen/lcong48.c @@ -13,18 +13,10 @@ #include "rand48.h" -extern unsigned short _rand48_seed[3]; -extern unsigned short _rand48_mult[3]; -extern unsigned short _rand48_add; - void lcong48(unsigned short p[7]) { - _rand48_seed[0] = p[0]; - _rand48_seed[1] = p[1]; - _rand48_seed[2] = p[2]; - _rand48_mult[0] = p[3]; - _rand48_mult[1] = p[4]; - _rand48_mult[2] = p[5]; + LOADRAND48(_rand48_seed, &p[0]); + LOADRAND48(_rand48_mult, &p[3]); _rand48_add = p[6]; } diff --git a/lib/libc/gen/lrand48.c b/lib/libc/gen/lrand48.c index a3d0111cf4d5..cc07044b8af9 100644 --- a/lib/libc/gen/lrand48.c +++ b/lib/libc/gen/lrand48.c @@ -13,11 +13,9 @@ #include "rand48.h" -extern unsigned short _rand48_seed[3]; - long lrand48(void) { - _dorand48(_rand48_seed); - return ((long) _rand48_seed[2] << 15) + ((long) _rand48_seed[1] >> 1); + _DORAND48(_rand48_seed); + return (_rand48_seed >> 17) & 0x7fffffff; } diff --git a/lib/libc/gen/mrand48.c b/lib/libc/gen/mrand48.c index 15b0bfb1bd6e..f9128a6d4188 100644 --- a/lib/libc/gen/mrand48.c +++ b/lib/libc/gen/mrand48.c @@ -15,13 +15,9 @@ #include "rand48.h" -extern unsigned short _rand48_seed[3]; - long mrand48(void) { - - _dorand48(_rand48_seed); - return ((int32_t)(((uint32_t)_rand48_seed[2] << 16) | - (uint32_t)_rand48_seed[1])); + _DORAND48(_rand48_seed); + return ((int)((_rand48_seed >> 16) & 0xffffffff)); } diff --git a/lib/libc/gen/nrand48.c b/lib/libc/gen/nrand48.c index 6c54065e7e0f..f6f4e231105c 100644 --- a/lib/libc/gen/nrand48.c +++ b/lib/libc/gen/nrand48.c @@ -16,6 +16,8 @@ long nrand48(unsigned short xseed[3]) { - _dorand48(xseed); - return ((long) xseed[2] << 15) + ((long) xseed[1] >> 1); + uint48 tmp; + + DORAND48(tmp, xseed); + return ((tmp >> 17) & 0x7fffffff); } diff --git a/lib/libc/gen/psignal.3 b/lib/libc/gen/psignal.3 index 098b7b02a9b9..bf6a99b4b113 100644 --- a/lib/libc/gen/psignal.3 +++ b/lib/libc/gen/psignal.3 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 10, 2025 +.Dd September 23, 2025 .Dt PSIGNAL 3 .Os .Sh NAME @@ -141,6 +141,13 @@ The name in can be either the name of the signal, with or without the .Dq SIG prefix, or a decimal number. +.Sh RETURN VALUES +The +.Fn sig2str +and +.Fn str2sig +return 0 on success and -1 on translation failure. +In the latter case the memory to store the translation result is left intact. .Sh SEE ALSO .Xr sigaction 2 , .Xr perror 3 , diff --git a/lib/libc/gen/rand48.3 b/lib/libc/gen/rand48.3 index 1e47c843058e..3ea649354270 100644 --- a/lib/libc/gen/rand48.3 +++ b/lib/libc/gen/rand48.3 @@ -9,7 +9,7 @@ .\" of any kind. I shall in no event be liable for anything that happens .\" to anyone/anything when using this software. .\" -.Dd September 4, 2012 +.Dd September 11, 2025 .Dt RAND48 3 .Os .Sh NAME @@ -183,5 +183,8 @@ generator calls. .Xr arc4random 3 , .Xr rand 3 , .Xr random 3 +.Sh STANDARDS +The functions described in this page are expected to conform to +.St -p1003.1-2008 . .Sh AUTHORS .An Martin Birgmeier diff --git a/lib/libc/gen/rand48.h b/lib/libc/gen/rand48.h index 9861e99683cb..d3326e851491 100644 --- a/lib/libc/gen/rand48.h +++ b/lib/libc/gen/rand48.h @@ -14,10 +14,11 @@ #ifndef _RAND48_H_ #define _RAND48_H_ +#include <sys/types.h> #include <math.h> #include <stdlib.h> -void _dorand48(unsigned short[3]); +#include "fpmath.h" #define RAND48_SEED_0 (0x330e) #define RAND48_SEED_1 (0xabcd) @@ -27,4 +28,62 @@ void _dorand48(unsigned short[3]); #define RAND48_MULT_2 (0x0005) #define RAND48_ADD (0x000b) +typedef uint64_t uint48; + +extern uint48 _rand48_seed; +extern uint48 _rand48_mult; +extern uint48 _rand48_add; + +#define TOUINT48(x, y, z) \ + ((uint48)(x) + (((uint48)(y)) << 16) + (((uint48)(z)) << 32)) + +#define RAND48_SEED TOUINT48(RAND48_SEED_0, RAND48_SEED_1, RAND48_SEED_2) +#define RAND48_MULT TOUINT48(RAND48_MULT_0, RAND48_MULT_1, RAND48_MULT_2) + +#define LOADRAND48(l, x) do { \ + (l) = TOUINT48((x)[0], (x)[1], (x)[2]); \ +} while (0) + +#define STORERAND48(l, x) do { \ + (x)[0] = (unsigned short)(l); \ + (x)[1] = (unsigned short)((l) >> 16); \ + (x)[2] = (unsigned short)((l) >> 32); \ +} while (0) + +#define _DORAND48(l) do { \ + (l) = (l) * _rand48_mult + _rand48_add; \ +} while (0) + +#define DORAND48(l, x) do { \ + LOADRAND48(l, x); \ + _DORAND48(l); \ + STORERAND48(l, x); \ +} while (0) + +#define ERAND48_BEGIN \ + union { \ + union IEEEd2bits ieee; \ + uint64_t u64; \ + } u; \ + int s + +/* + * Optimization for speed: assume doubles are IEEE 754 and use bit fiddling + * rather than converting to double. Specifically, clamp the result to 48 bits + * and convert to a double in [0.0, 1.0) via division by 2^48. Normalize by + * shifting the most significant bit into the implicit one position and + * adjusting the exponent accordingly. The store to the exponent field + * overwrites the implicit one. + */ +#define ERAND48_END(x) do { \ + u.u64 = ((x) & 0xffffffffffffULL); \ + if (u.u64 == 0) \ + return (0.0); \ + u.u64 <<= 5; \ + for (s = 0; !(u.u64 & (1LL << 52)); s++, u.u64 <<= 1) \ + ; \ + u.ieee.bits.exp = 1022 - s; \ + return (u.ieee.d); \ +} while (0) + #endif /* _RAND48_H_ */ diff --git a/lib/libc/gen/seed48.c b/lib/libc/gen/seed48.c index 258c4bac3c9f..f57656ce1121 100644 --- a/lib/libc/gen/seed48.c +++ b/lib/libc/gen/seed48.c @@ -13,24 +13,14 @@ #include "rand48.h" -extern unsigned short _rand48_seed[3]; -extern unsigned short _rand48_mult[3]; -extern unsigned short _rand48_add; - unsigned short * seed48(unsigned short xseed[3]) { static unsigned short sseed[3]; - sseed[0] = _rand48_seed[0]; - sseed[1] = _rand48_seed[1]; - sseed[2] = _rand48_seed[2]; - _rand48_seed[0] = xseed[0]; - _rand48_seed[1] = xseed[1]; - _rand48_seed[2] = xseed[2]; - _rand48_mult[0] = RAND48_MULT_0; - _rand48_mult[1] = RAND48_MULT_1; - _rand48_mult[2] = RAND48_MULT_2; + STORERAND48(_rand48_seed, sseed); + LOADRAND48(_rand48_seed, xseed); + _rand48_mult = RAND48_MULT; _rand48_add = RAND48_ADD; - return sseed; + return (sseed); } diff --git a/lib/libc/gen/srand48.c b/lib/libc/gen/srand48.c index fd369a094c51..4b82ece72db8 100644 --- a/lib/libc/gen/srand48.c +++ b/lib/libc/gen/srand48.c @@ -13,18 +13,11 @@ #include "rand48.h" -extern unsigned short _rand48_seed[3]; -extern unsigned short _rand48_mult[3]; -extern unsigned short _rand48_add; - void srand48(long seed) { - _rand48_seed[0] = RAND48_SEED_0; - _rand48_seed[1] = (unsigned short) seed; - _rand48_seed[2] = (unsigned short) (seed >> 16); - _rand48_mult[0] = RAND48_MULT_0; - _rand48_mult[1] = RAND48_MULT_1; - _rand48_mult[2] = RAND48_MULT_2; + _rand48_seed = TOUINT48(RAND48_SEED_0, (unsigned short)seed, + (unsigned short)(seed >> 16)); + _rand48_mult = RAND48_MULT; _rand48_add = RAND48_ADD; } diff --git a/lib/libc/gen/sysconf.c b/lib/libc/gen/sysconf.c index 66562d0e29f0..b5b732eed05d 100644 --- a/lib/libc/gen/sysconf.c +++ b/lib/libc/gen/sysconf.c @@ -51,7 +51,7 @@ #include "un-namespace.h" #include "../stdlib/atexit.h" -#include "tzdir.h" /* from ../../../contrib/tzcode/stdtime */ +#include "tzdir.h" /* from ../../../contrib/tzcode */ #include "libc_private.h" #define _PATH_ZONEINFO TZDIR /* from tzfile.h */ diff --git a/lib/libc/i386/gen/makecontext.c b/lib/libc/i386/gen/makecontext.c index 7b4845ac6bee..9fedd8b99c47 100644 --- a/lib/libc/i386/gen/makecontext.c +++ b/lib/libc/i386/gen/makecontext.c @@ -124,7 +124,7 @@ __makecontext(ucontext_t *ucp, void (*start)(void), int argc, ...) /* * Setup the top of the stack with the user start routine - * followed by all of its aguments and the pointer to the + * followed by all of its arguments and the pointer to the * ucontext. We need to leave a spare spot at the top of * the stack because setcontext will move eip to the top * of the stack before returning. diff --git a/lib/libc/include/compat.h b/lib/libc/include/compat.h index 97f22607ddd7..630ffe7daae3 100644 --- a/lib/libc/include/compat.h +++ b/lib/libc/include/compat.h @@ -80,4 +80,3 @@ __sym_compat(setgroups, freebsd14_setgroups, FBSD_1.0); #undef __weak_reference #endif /* __LIBC_COMPAT_H__ */ - diff --git a/lib/libc/include/port_before.h b/lib/libc/include/port_before.h index cfc43c53f157..aa2cd394104a 100644 --- a/lib/libc/include/port_before.h +++ b/lib/libc/include/port_before.h @@ -5,7 +5,6 @@ #define _LIBC 1 #define DO_PTHREADS 1 #define USE_POLL 1 -#define HAVE_MD5 1 #define ISC_SOCKLEN_T socklen_t #define ISC_FORMAT_PRINTF(fmt, args) \ diff --git a/lib/libc/inet/inet_net_ntop.c b/lib/libc/inet/inet_net_ntop.c index 9d98dbb5ca99..30dd5c0571f2 100644 --- a/lib/libc/inet/inet_net_ntop.c +++ b/lib/libc/inet/inet_net_ntop.c @@ -1,20 +1,23 @@ -/*- - * SPDX-License-Identifier: ISC +/* $OpenBSD: inet_net_ntop.c,v 1.9 2019/07/03 03:24:04 deraadt Exp $ */ + +/* + * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org> + * Copyright (c) 1996 by Internet Software Consortium. * - * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") - * Copyright (c) 1996,1999 by Internet Software Consortium. + * SPDX-License-Identifier: ISC * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT - * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. */ #include "port_before.h" @@ -31,18 +34,10 @@ #include "port_after.h" -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif - -static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, - size_t size); -static char * inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, - size_t size); +static char *inet_net_ntop_ipv4(const u_char *, int, char *, size_t); +static char *inet_net_ntop_ipv6(const u_char *, int, char *, size_t); -/*% +/* * char * * inet_net_ntop(af, src, bits, dst, size) * convert network number from network to presentation format. @@ -66,7 +61,7 @@ inet_net_ntop(int af, const void *src, int bits, char *dst, size_t size) } } -/*% +/* * static char * * inet_net_ntop_ipv4(src, bits, dst, size) * convert IPv4 network number from network to presentation format. @@ -83,53 +78,63 @@ static char * inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) { char *odst = dst; - char *t; u_int m; int b; + char *ep; + int advance; + + ep = dst + size; + if (ep <= dst) + goto emsgsize; if (bits < 0 || bits > 32) { errno = EINVAL; return (NULL); } - if (bits == 0) { - if (size < sizeof "0") + if (ep - dst < sizeof "0") goto emsgsize; *dst++ = '0'; - size--; *dst = '\0'; } /* Format whole octets. */ for (b = bits / 8; b > 0; b--) { - if (size <= sizeof "255.") + if (ep - dst < sizeof "255.") + goto emsgsize; + advance = snprintf(dst, ep - dst, "%u", *src++); + if (advance <= 0 || advance >= ep - dst) goto emsgsize; - t = dst; - dst += SPRINTF((dst, "%u", *src++)); + dst += advance; if (b > 1) { + if (dst + 1 >= ep) + goto emsgsize; *dst++ = '.'; *dst = '\0'; } - size -= (size_t)(dst - t); } /* Format partial octet. */ b = bits % 8; if (b > 0) { - if (size <= sizeof ".255") + if (ep - dst < sizeof ".255") goto emsgsize; - t = dst; if (dst != odst) *dst++ = '.'; m = ((1 << b) - 1) << (8 - b); - dst += SPRINTF((dst, "%u", *src & m)); - size -= (size_t)(dst - t); + advance = snprintf(dst, ep - dst, "%u", *src & m); + if (advance <= 0 || advance >= ep - dst) + goto emsgsize; + dst += advance; } /* Format CIDR /width. */ - if (size <= sizeof "/32") + if (ep - dst < sizeof "/32") + goto emsgsize; + advance = snprintf(dst, ep - dst, "/%u", bits); + if (advance <= 0 || advance >= ep - dst) goto emsgsize; - dst += SPRINTF((dst, "/%u", bits)); + dst += advance; return (odst); emsgsize: @@ -137,132 +142,27 @@ inet_net_ntop_ipv4(const u_char *src, int bits, char *dst, size_t size) return (NULL); } -/*% - * static char * - * inet_net_ntop_ipv6(src, bits, fakebits, dst, size) - * convert IPv6 network number from network to presentation format. - * generates CIDR style result always. Picks the shortest representation - * unless the IP is really IPv4. - * always prints specified number of bits (bits). - * return: - * pointer to dst, or NULL if an error occurred (check errno). - * note: - * network byte order assumed. this means 192.5.5.240/28 has - * 0b11110000 in its fourth octet. - * author: - * Vadim Kogan (UCB), June 2001 - * Original version (IPv4) by Paul Vixie (ISC), July 1996 - */ - static char * -inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) { - u_int m; - int b; - int p; - int zero_s, zero_l, tmp_zero_s, tmp_zero_l; - int i; - int is_ipv4 = 0; - unsigned char inbuf[16]; - char outbuf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255.255.255.255/128")]; - char *cp; - int words; - u_char *s; +inet_net_ntop_ipv6(const u_char *src, int bits, char *dst, size_t size) +{ + int ret; + char buf[sizeof("xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:255:255:255:255/128")]; if (bits < 0 || bits > 128) { errno = EINVAL; return (NULL); } - cp = outbuf; - - if (bits == 0) { - *cp++ = ':'; - *cp++ = ':'; - *cp = '\0'; - } else { - /* Copy src to private buffer. Zero host part. */ - p = (bits + 7) / 8; - memcpy(inbuf, src, p); - memset(inbuf + p, 0, 16 - p); - b = bits % 8; - if (b != 0) { - m = ~0 << (8 - b); - inbuf[p-1] &= m; - } - - s = inbuf; - - /* how many words need to be displayed in output */ - words = (bits + 15) / 16; - if (words == 1) - words = 2; - - /* Find the longest substring of zero's */ - zero_s = zero_l = tmp_zero_s = tmp_zero_l = 0; - for (i = 0; i < (words * 2); i += 2) { - if ((s[i] | s[i+1]) == 0) { - if (tmp_zero_l == 0) - tmp_zero_s = i / 2; - tmp_zero_l++; - } else { - if (tmp_zero_l && zero_l < tmp_zero_l) { - zero_s = tmp_zero_s; - zero_l = tmp_zero_l; - tmp_zero_l = 0; - } - } - } - - if (tmp_zero_l && zero_l < tmp_zero_l) { - zero_s = tmp_zero_s; - zero_l = tmp_zero_l; - } - - if (zero_l != words && zero_s == 0 && ((zero_l == 6) || - ((zero_l == 5 && s[10] == 0xff && s[11] == 0xff) || - ((zero_l == 7 && s[14] != 0 && s[15] != 1))))) - is_ipv4 = 1; - - /* Format whole words. */ - for (p = 0; p < words; p++) { - if (zero_l != 0 && p >= zero_s && p < zero_s + zero_l) { - /* Time to skip some zeros */ - if (p == zero_s) - *cp++ = ':'; - if (p == words - 1) - *cp++ = ':'; - s++; - s++; - continue; - } + if (inet_ntop(AF_INET6, src, buf, size) == NULL) + return (NULL); - if (is_ipv4 && p > 5 ) { - *cp++ = (p == 6) ? ':' : '.'; - cp += SPRINTF((cp, "%u", *s++)); - /* we can potentially drop the last octet */ - if (p != 7 || bits > 120) { - *cp++ = '.'; - cp += SPRINTF((cp, "%u", *s++)); - } - } else { - if (cp != outbuf) - *cp++ = ':'; - cp += SPRINTF((cp, "%x", *s * 256 + s[1])); - s += 2; - } - } + ret = snprintf(dst, size, "%s/%d", buf, bits); + if (ret < 0 || ret >= size) { + errno = EMSGSIZE; + return (NULL); } - /* Format CIDR /width. */ - sprintf(cp, "/%u", bits); - if (strlen(outbuf) + 1 > size) - goto emsgsize; - strcpy(dst, outbuf); return (dst); - -emsgsize: - errno = EMSGSIZE; - return (NULL); } /* @@ -271,5 +171,3 @@ emsgsize: */ #undef inet_net_ntop __weak_reference(__inet_net_ntop, inet_net_ntop); - -/*! \file */ diff --git a/lib/libc/inet/inet_net_pton.c b/lib/libc/inet/inet_net_pton.c index d566a0e1d3c3..14c88eb72014 100644 --- a/lib/libc/inet/inet_net_pton.c +++ b/lib/libc/inet/inet_net_pton.c @@ -1,20 +1,23 @@ -/*- - * SPDX-License-Identifier: ISC +/* $OpenBSD: inet_net_pton.c,v 1.14 2022/12/27 17:10:06 jmc Exp $ */ + +/* + * Copyright (c) 2012 by Gilles Chehade <gilles@openbsd.org> + * Copyright (c) 1996,1999 by Internet Software Consortium. * - * Copyright (C) 2004, 2005, 2008 Internet Systems Consortium, Inc. ("ISC") - * Copyright (C) 1996, 1998, 1999, 2001, 2003 Internet Software Consortium. + * SPDX-License-Identifier: ISC * - * Permission to use, copy, modify, and/or distribute this software for any + * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * - * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH - * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY - * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, - * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM - * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE - * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR - * PERFORMANCE OF THIS SOFTWARE. + * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS + * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE + * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL + * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR + * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS + * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS + * SOFTWARE. */ #include "port_before.h" @@ -22,7 +25,6 @@ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> -#include <arpa/nameser.h> #include <arpa/inet.h> #include <assert.h> @@ -34,13 +36,37 @@ #include "port_after.h" -#ifdef SPRINTF_CHAR -# define SPRINTF(x) strlen(sprintf/**/x) -#else -# define SPRINTF(x) ((size_t)sprintf x) -#endif +static int inet_net_pton_ipv4(const char *, u_char *, size_t); +static int inet_net_pton_ipv6(const char *, u_char *, size_t); -/*% +/* + * static int + * inet_net_pton(af, src, dst, size) + * convert network number from presentation to network format. + * accepts hex octets, hex strings, decimal octets, and /CIDR. + * "size" is in bytes and describes "dst". + * return: + * number of bits, either imputed classfully or specified with /CIDR, + * or -1 if some failure occurred (check errno). ENOENT means it was + * not a valid network specification. + * author: + * Paul Vixie (ISC), June 1996 + */ +int +inet_net_pton(int af, const char *src, void *dst, size_t size) +{ + switch (af) { + case AF_INET: + return (inet_net_pton_ipv4(src, dst, size)); + case AF_INET6: + return (inet_net_pton_ipv6(src, dst, size)); + default: + errno = EAFNOSUPPORT; + return (-1); + } +} + +/* * static int * inet_net_pton_ipv4(src, dst, size) * convert IPv4 network number from presentation to network format. @@ -57,22 +83,24 @@ * Paul Vixie (ISC), June 1996 */ static int -inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { - static const char xdigits[] = "0123456789abcdef"; - static const char digits[] = "0123456789"; - int n, ch, tmp = 0, dirty, bits; +inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) +{ + static const char + xdigits[] = "0123456789abcdef", + digits[] = "0123456789"; + int n, ch, tmp, dirty, bits; const u_char *odst = dst; - ch = *src++; + ch = (unsigned char)*src++; if (ch == '0' && (src[0] == 'x' || src[0] == 'X') - && isascii((unsigned char)(src[1])) - && isxdigit((unsigned char)(src[1]))) { + && isascii((unsigned char)src[1]) && isxdigit((unsigned char)src[1])) { /* Hexadecimal: Eat nybble string. */ - if (size <= 0U) + if (size == 0) goto emsgsize; - dirty = 0; - src++; /*%< skip x or X. */ - while ((ch = *src++) != '\0' && isascii(ch) && isxdigit(ch)) { + tmp = 0, dirty = 0; + src++; /* skip x or X. */ + while ((ch = (unsigned char)*src++) != '\0' && + isascii(ch) && isxdigit(ch)) { if (isupper(ch)) ch = tolower(ch); n = strchr(xdigits, ch) - xdigits; @@ -82,14 +110,14 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { else tmp = (tmp << 4) | n; if (++dirty == 2) { - if (size-- <= 0U) + if (size-- == 0) goto emsgsize; *dst++ = (u_char) tmp; dirty = 0; } } - if (dirty) { /*%< Odd trailing nybble? */ - if (size-- <= 0U) + if (dirty) { /* Odd trailing nybble? */ + if (size-- == 0) goto emsgsize; *dst++ = (u_char) (tmp << 4); } @@ -104,16 +132,16 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { tmp += n; if (tmp > 255) goto enoent; - } while ((ch = *src++) != '\0' && + } while ((ch = (unsigned char)*src++) != '\0' && isascii(ch) && isdigit(ch)); - if (size-- <= 0U) + if (size-- == 0) goto emsgsize; *dst++ = (u_char) tmp; if (ch == '\0' || ch == '/') break; if (ch != '.') goto enoent; - ch = *src++; + ch = (unsigned char)*src++; if (!isascii(ch) || !isdigit(ch)) goto enoent; } @@ -121,10 +149,10 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { goto enoent; bits = -1; - if (ch == '/' && isascii((unsigned char)(src[0])) && - isdigit((unsigned char)(src[0])) && dst > odst) { + if (ch == '/' && isascii((unsigned char)src[0]) && + isdigit((unsigned char)src[0]) && dst > odst) { /* CIDR width specifier. Nothing can follow it. */ - ch = *src++; /*%< Skip over the /. */ + ch = (unsigned char)*src++; /* Skip over the /. */ bits = 0; do { n = strchr(digits, ch) - digits; @@ -132,8 +160,9 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { bits *= 10; bits += n; if (bits > 32) - goto enoent; - } while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch)); + goto emsgsize; + } while ((ch = (unsigned char)*src++) != '\0' && + isascii(ch) && isdigit(ch)); if (ch != '\0') goto enoent; } @@ -147,29 +176,23 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { goto enoent; /* If no CIDR spec was given, infer width from net class. */ if (bits == -1) { - if (*odst >= 240) /*%< Class E */ + if (*odst >= 240) /* Class E */ bits = 32; - else if (*odst >= 224) /*%< Class D */ - bits = 8; - else if (*odst >= 192) /*%< Class C */ + else if (*odst >= 224) /* Class D */ + bits = 4; + else if (*odst >= 192) /* Class C */ bits = 24; - else if (*odst >= 128) /*%< Class B */ + else if (*odst >= 128) /* Class B */ bits = 16; - else /*%< Class A */ + else /* Class A */ bits = 8; /* If imputed mask is narrower than specified octets, widen. */ if (bits < ((dst - odst) * 8)) bits = (dst - odst) * 8; - /* - * If there are no additional bits specified for a class D - * address adjust bits to 4. - */ - if (bits == 8 && *odst == 224) - bits = 4; } /* Extend network to cover the actual mask. */ while (bits > ((dst - odst) * 8)) { - if (size-- <= 0U) + if (size-- == 0) goto emsgsize; *dst++ = '\0'; } @@ -184,222 +207,48 @@ inet_net_pton_ipv4(const char *src, u_char *dst, size_t size) { return (-1); } -static int -getbits(const char *src, int *bitsp) { - static const char digits[] = "0123456789"; - int n; - int val; - char ch; - - val = 0; - n = 0; - while ((ch = *src++) != '\0') { - const char *pch; - - pch = strchr(digits, ch); - if (pch != NULL) { - if (n++ != 0 && val == 0) /*%< no leading zeros */ - return (0); - val *= 10; - val += (pch - digits); - if (val > 128) /*%< range */ - return (0); - continue; - } - return (0); - } - if (n == 0) - return (0); - *bitsp = val; - return (1); -} static int -getv4(const char *src, u_char *dst, int *bitsp) { - static const char digits[] = "0123456789"; - u_char *odst = dst; - int n; - u_int val; - char ch; - - val = 0; - n = 0; - while ((ch = *src++) != '\0') { - const char *pch; +inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) +{ + struct in6_addr in6; + int ret; + int bits; + size_t bytes; + char buf[INET6_ADDRSTRLEN + sizeof("/128")]; + char *sep; + const char *errstr; - pch = strchr(digits, ch); - if (pch != NULL) { - if (n++ != 0 && val == 0) /*%< no leading zeros */ - return (0); - val *= 10; - val += (pch - digits); - if (val > 255) /*%< range */ - return (0); - continue; - } - if (ch == '.' || ch == '/') { - if (dst - odst > 3) /*%< too many octets? */ - return (0); - *dst++ = val; - if (ch == '/') - return (getbits(src, bitsp)); - val = 0; - n = 0; - continue; - } - return (0); + if (strlcpy(buf, src, sizeof buf) >= sizeof buf) { + errno = EMSGSIZE; + return (-1); } - if (n == 0) - return (0); - if (dst - odst > 3) /*%< too many octets? */ - return (0); - *dst++ = val; - return (1); -} -static int -inet_net_pton_ipv6(const char *src, u_char *dst, size_t size) { - static const char xdigits_l[] = "0123456789abcdef", - xdigits_u[] = "0123456789ABCDEF"; - u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp; - const char *xdigits, *curtok; - int ch, saw_xdigit; - u_int val; - int digits; - int bits; - size_t bytes; - int words; - int ipv4; + sep = strchr(buf, '/'); + if (sep != NULL) + *sep++ = '\0'; - memset((tp = tmp), '\0', NS_IN6ADDRSZ); - endp = tp + NS_IN6ADDRSZ; - colonp = NULL; - /* Leading :: requires some special handling. */ - if (*src == ':') - if (*++src != ':') - goto enoent; - curtok = src; - saw_xdigit = 0; - val = 0; - digits = 0; - bits = -1; - ipv4 = 0; - while ((ch = *src++) != '\0') { - const char *pch; + ret = inet_pton(AF_INET6, buf, &in6); + if (ret != 1) + return (-1); - if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL) - pch = strchr((xdigits = xdigits_u), ch); - if (pch != NULL) { - val <<= 4; - val |= (pch - xdigits); - if (++digits > 4) - goto enoent; - saw_xdigit = 1; - continue; - } - if (ch == ':') { - curtok = src; - if (!saw_xdigit) { - if (colonp) - goto enoent; - colonp = tp; - continue; - } else if (*src == '\0') - goto enoent; - if (tp + NS_INT16SZ > endp) - return (0); - *tp++ = (u_char) (val >> 8) & 0xff; - *tp++ = (u_char) val & 0xff; - saw_xdigit = 0; - digits = 0; - val = 0; - continue; - } - if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) && - getv4(curtok, tp, &bits) > 0) { - tp += NS_INADDRSZ; - saw_xdigit = 0; - ipv4 = 1; - break; /*%< '\\0' was seen by inet_pton4(). */ - } - if (ch == '/' && getbits(src, &bits) > 0) - break; - goto enoent; - } - if (saw_xdigit) { - if (tp + NS_INT16SZ > endp) - goto enoent; - *tp++ = (u_char) (val >> 8) & 0xff; - *tp++ = (u_char) val & 0xff; - } - if (bits == -1) + if (sep == NULL) bits = 128; - - words = (bits + 15) / 16; - if (words < 2) - words = 2; - if (ipv4) - words = 8; - endp = tmp + 2 * words; - - if (colonp != NULL) { - /* - * Since some memmove()'s erroneously fail to handle - * overlapping regions, we'll do the shift by hand. - */ - const int n = tp - colonp; - int i; - - if (tp == endp) - goto enoent; - for (i = 1; i <= n; i++) { - endp[- i] = colonp[n - i]; - colonp[n - i] = 0; + else { + bits = strtonum(sep, 0, 128, &errstr); + if (errstr) { + errno = EINVAL; + return (-1); } - tp = endp; } - if (tp != endp) - goto enoent; bytes = (bits + 7) / 8; - if (bytes > size) - goto emsgsize; - memcpy(dst, tmp, bytes); - return (bits); - - enoent: - errno = ENOENT; - return (-1); - - emsgsize: - errno = EMSGSIZE; - return (-1); -} - -/*% - * int - * inet_net_pton(af, src, dst, size) - * convert network number from presentation to network format. - * accepts hex octets, hex strings, decimal octets, and /CIDR. - * "size" is in bytes and describes "dst". - * return: - * number of bits, either imputed classfully or specified with /CIDR, - * or -1 if some failure occurred (check errno). ENOENT means it was - * not a valid network specification. - * author: - * Paul Vixie (ISC), June 1996 - */ -int -inet_net_pton(int af, const char *src, void *dst, size_t size) { - switch (af) { - case AF_INET: - return (inet_net_pton_ipv4(src, dst, size)); - case AF_INET6: - return (inet_net_pton_ipv6(src, dst, size)); - default: - errno = EAFNOSUPPORT; + if (bytes > size) { + errno = EMSGSIZE; return (-1); } + memcpy(dst, &in6.s6_addr, bytes); + return (bits); } /* @@ -408,5 +257,3 @@ inet_net_pton(int af, const char *src, void *dst, size_t size) { */ #undef inet_net_pton __weak_reference(__inet_net_pton, inet_net_pton); - -/*! \file */ diff --git a/lib/libc/locale/Makefile.inc b/lib/libc/locale/Makefile.inc index 33caafc5c10a..127f8fc67abc 100644 --- a/lib/libc/locale/Makefile.inc +++ b/lib/libc/locale/Makefile.inc @@ -46,7 +46,7 @@ MAN+= btowc.3 \ wctrans.3 wctype.3 wcwidth.3 \ duplocale.3 freelocale.3 newlocale.3 querylocale.3 uselocale.3 xlocale.3 -MAN+= big5.5 euc.5 gb18030.5 gb2312.5 gbk.5 mskanji.5 utf8.5 +MANNODEV+= big5.5 euc.5 gb18030.5 gb2312.5 gbk.5 mskanji.5 utf8.5 MLINKS+=btowc.3 wctob.3 MLINKS+=digittoint.3 digittoint_l.3 diff --git a/lib/libc/md/Makefile.inc b/lib/libc/md/Makefile.inc deleted file mode 100644 index 82c5f0670485..000000000000 --- a/lib/libc/md/Makefile.inc +++ /dev/null @@ -1,3 +0,0 @@ -.PATH: ${SRCTOP}/sys/kern - -SRCS+= md5c.c diff --git a/lib/libc/net/gai_strerror.c b/lib/libc/net/gai_strerror.c index 0d4303e76a73..23f58b763573 100644 --- a/lib/libc/net/gai_strerror.c +++ b/lib/libc/net/gai_strerror.c @@ -45,22 +45,22 @@ * Entries EAI_ADDRFAMILY (1) and EAI_NODATA (7) were omitted from RFC 3493, * but are or may be used as extensions or in old code. */ -static const char *ai_errlist[] = { - "Success", /* 0 */ - "Address family for hostname not supported", /* EAI_ADDRFAMILY */ - "Name could not be resolved at this time", /* EAI_AGAIN */ - "Flags parameter had an invalid value", /* EAI_BADFLAGS */ - "Non-recoverable failure in name resolution", /* EAI_FAIL */ - "Address family not recognized", /* EAI_FAMILY */ - "Memory allocation failure", /* EAI_MEMORY */ - "No address associated with hostname", /* EAI_NODATA*/ - "Name does not resolve", /* EAI_NONAME */ - "Service was not recognized for socket type", /* EAI_SERVICE */ - "Intended socket type was not recognized", /* EAI_SOCKTYPE */ - "System error returned in errno", /* EAI_SYSTEM */ - "Invalid value for hints", /* EAI_BADHINTS */ - "Resolved protocol is unknown", /* EAI_PROTOCOL */ - "Argument buffer overflow" /* EAI_OVERFLOW */ +static const char *const ai_errlist[] = { + [0] = "Success", + [EAI_ADDRFAMILY] = "Address family for hostname not supported", + [EAI_AGAIN] = "Name could not be resolved at this time", + [EAI_BADFLAGS] = "Flags parameter had an invalid value", + [EAI_FAIL] = "Non-recoverable failure in name resolution", + [EAI_FAMILY] = "Address family not recognized", + [EAI_MEMORY] = "Memory allocation failure", + [EAI_NODATA] = "No address associated with hostname", + [EAI_NONAME] = "Name does not resolve", + [EAI_SERVICE] = "Service was not recognized for socket type", + [EAI_SOCKTYPE] = "Intended socket type was not recognized", + [EAI_SYSTEM] = "System error returned in errno", + [EAI_BADHINTS] = "Invalid value for hints", + [EAI_PROTOCOL] = "Resolved protocol is unknown", + [EAI_OVERFLOW] = "Argument buffer overflow", }; #if defined(NLS) @@ -72,7 +72,7 @@ static int gai_keycreated = 0; static void gai_keycreate(void) { - gai_keycreated = (thr_keycreate(&gai_key, free) == 0); + gai_keycreated = thr_keycreate(&gai_key, free) == 0; } #endif @@ -82,7 +82,9 @@ gai_strerror(int ecode) #if defined(NLS) nl_catd catd; char *buf; + int saved_errno; + saved_errno = errno; if (thr_main() != 0) buf = gai_buf; else { @@ -110,11 +112,13 @@ gai_strerror(int ecode) strlcpy(buf, catgets(catd, 3, NL_MSGMAX, "Unknown error"), sizeof(gai_buf)); catclose(catd); - return buf; + errno = saved_errno; + return (buf); thr_err: + errno = saved_errno; #endif if (ecode >= 0 && ecode < EAI_MAX) - return ai_errlist[ecode]; - return "Unknown error"; + return (ai_errlist[ecode]); + return ("Unknown error"); } diff --git a/lib/libc/nls/Makefile.inc b/lib/libc/nls/Makefile.inc index f26e04c187a5..c211026aba72 100644 --- a/lib/libc/nls/Makefile.inc +++ b/lib/libc/nls/Makefile.inc @@ -12,6 +12,11 @@ MAN+= catclose.3 catgets.3 catopen.3 # for translators. NLSNAME= libc +# We don't want libc's NLS catalogues to be installed in the clibs package. +# Put them in locales instead, since anyone interested in NLS will have +# that installed. +NLSPACKAGE= locales + NLS+= be_BY.UTF-8 NLS+= ca_ES.ISO8859-1 NLS+= de_DE.ISO8859-1 diff --git a/lib/libc/posix1e/Makefile.inc b/lib/libc/posix1e/Makefile.inc index 934998cdd092..48f6c1ddf884 100644 --- a/lib/libc/posix1e/Makefile.inc +++ b/lib/libc/posix1e/Makefile.inc @@ -84,7 +84,6 @@ MAN+= acl.3 \ acl_valid.3 \ extattr.3 \ mac.3 \ - mac.conf.5 \ mac_free.3 \ mac_is_present.3 \ mac_get.3 \ @@ -134,4 +133,6 @@ MLINKS+=acl_create_entry.3 acl_create_entry_np.3\ mac_text.3 mac_from_text.3 \ mac_text.3 mac_to_text.3 +MANNODEV+= mac.conf.5 + CLEANFILES+= subr_acl_nfs4.c diff --git a/lib/libc/posix1e/mac_free.3 b/lib/libc/posix1e/mac_free.3 index 4ed68b70f3a3..6674ca2e9094 100644 --- a/lib/libc/posix1e/mac_free.3 +++ b/lib/libc/posix1e/mac_free.3 @@ -31,7 +31,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 21, 2023 +.Dd October 26, 2025 .Dt MAC_FREE 3 .Os .Sh NAME @@ -85,7 +85,7 @@ is a complex structure in the implementation, .Fn mac_free is specific to -.Vt mac_3 , +.Vt mac_t , and must not be used to free the character strings returned from .Fn mac_to_text . Doing so may result in undefined behavior. diff --git a/lib/libc/posix1e/mac_text.3 b/lib/libc/posix1e/mac_text.3 index 29c1aacca485..7633f4b0da64 100644 --- a/lib/libc/posix1e/mac_text.3 +++ b/lib/libc/posix1e/mac_text.3 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 21, 2023 +.Dd October 26, 2025 .Dt MAC_TEXT 3 .Os .Sh NAME @@ -52,14 +52,16 @@ into the internal policy label format and places it in .Fa *mac , which must later be freed with -.Xr free 3 . +.Xr mac_free 3 . .Pp The .Fn mac_to_text function allocates storage for .Fa *text , which will be set to the text representation of -.Fa label . +.Fa label +and must later be freed with +.Xr free 3 . .Pp Refer to .Xr maclabel 7 diff --git a/lib/libc/regex/Makefile.inc b/lib/libc/regex/Makefile.inc index 89468f1317f6..e3417a3d9983 100644 --- a/lib/libc/regex/Makefile.inc +++ b/lib/libc/regex/Makefile.inc @@ -9,9 +9,9 @@ SYM_MAPS+=${LIBC_SRCTOP}/regex/Symbol.map # manpages only included in libc version .if ${LIB} == "c" -MAN+= regex.3 -MAN+= re_format.7 +MAN+= regex.3 +MLINKS+= regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3 +MLINKS+= regexec.3 regfree.3 -MLINKS+=regex.3 regcomp.3 regex.3 regexec.3 regex.3 regerror.3 -MLINKS+=regexec.3 regfree.3 +MANNODEV+= re_format.7 .endif diff --git a/lib/libc/resolv/Symbol.map b/lib/libc/resolv/Symbol.map index 6b9c43298fb5..26daecbe2eff 100644 --- a/lib/libc/resolv/Symbol.map +++ b/lib/libc/resolv/Symbol.map @@ -103,6 +103,5 @@ FBSD_1.0 { }; FBSD_1.4 { - __res_rndinit; __res_nrandomid; }; diff --git a/lib/libc/resolv/res_init.c b/lib/libc/resolv/res_init.c index 71ab2dcb7038..5a2fce013c8c 100644 --- a/lib/libc/resolv/res_init.c +++ b/lib/libc/resolv/res_init.c @@ -86,19 +86,6 @@ #include <unistd.h> #include <netdb.h> -#ifndef HAVE_MD5 -# include "../dst/md5.h" -#else -# ifdef SOLARIS2 -# include <sys/md5.h> -# elif _LIBC -# include <md5.h> -# endif -#endif -#ifndef _MD5_H_ -# define _MD5_H_ 1 /*%< make sure we do not include rsaref md5.h file */ -#endif - #include "un-namespace.h" #include "port_after.h" @@ -184,8 +171,6 @@ __res_vinit(res_state statp, int preinit) { statp->options = RES_DEFAULT; } - statp->_rnd = malloc(16); - res_rndinit(statp); statp->id = res_nrandomid(statp); memset(u, 0, sizeof(u)); @@ -733,48 +718,18 @@ net_mask(struct in_addr in) /*!< XXX - should really use system's version of th } #endif -static u_char srnd[16]; - void -res_rndinit(res_state statp) +freebsd15_res_rndinit(res_state statp) { - struct timeval now; - u_int32_t u32; - u_int16_t u16; - u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; - - gettimeofday(&now, NULL); - u32 = now.tv_sec; - memcpy(rnd, &u32, 4); - u32 = now.tv_usec; - memcpy(rnd + 4, &u32, 4); - u32 += now.tv_sec; - memcpy(rnd + 8, &u32, 4); - u16 = getpid(); - memcpy(rnd + 12, &u16, 2); + (void)statp; } +__sym_compat(__res_rndinit, freebsd15_res_rndinit, FBSD_1.4); u_int res_nrandomid(res_state statp) { - struct timeval now; - u_int16_t u16; - MD5_CTX ctx; - u_char *rnd = statp->_rnd == NULL ? srnd : statp->_rnd; - - gettimeofday(&now, NULL); - u16 = (u_int16_t) (now.tv_sec ^ now.tv_usec); - memcpy(rnd + 14, &u16, 2); -#ifndef HAVE_MD5 - MD5_Init(&ctx); - MD5_Update(&ctx, rnd, 16); - MD5_Final(rnd, &ctx); -#else - MD5Init(&ctx); - MD5Update(&ctx, rnd, 16); - MD5Final(rnd, &ctx); -#endif - memcpy(&u16, rnd + 14, 2); - return ((u_int) u16); + (void) statp; + + return ((u_int)(arc4random() & 0xffff)); } /*% @@ -808,10 +763,6 @@ res_ndestroy(res_state statp) { free(statp->_u._ext.ext); statp->_u._ext.ext = NULL; } - if (statp->_rnd != NULL) { - free(statp->_rnd); - statp->_rnd = NULL; - } statp->options &= ~RES_INIT; } diff --git a/lib/libc/rpc/Makefile.inc b/lib/libc/rpc/Makefile.inc index 87963d10eec1..c22fac2c0e16 100644 --- a/lib/libc/rpc/Makefile.inc +++ b/lib/libc/rpc/Makefile.inc @@ -42,12 +42,12 @@ crypt_xdr.c: ${RPCDIR}/crypt.x crypt.h crypt.h: ${RPCDIR}/crypt.x ${RPCGEN} -h -o ${.TARGET} ${RPCDIR}/crypt.x + MAN+= bindresvport.3 des_crypt.3 getnetconfig.3 getnetpath.3 getrpcent.3 \ getrpcport.3 rpc.3 rpc_soc.3 rpc_clnt_auth.3 rpc_clnt_calls.3 \ rpc_clnt_create.3 rpc_svc_calls.3 rpc_svc_create.3 rpc_svc_err.3 \ rpc_svc_reg.3 rpc_xdr.3 rpcbind.3 publickey.3 rpc_secure.3 \ rtime.3 -MAN+= rpc.5 netconfig.5 MLINKS+= bindresvport.3 bindresvport_sa.3 \ des_crypt.3 ecb_crypt.3 \ des_crypt.3 cbc_crypt.3 \ @@ -177,3 +177,5 @@ MLINKS+= bindresvport.3 bindresvport_sa.3 \ rpc_soc.3 xdr_authunix_parms.3 \ rpc_soc.3 xdr_pmap.3 \ rpc_soc.3 xdr_pmaplist.3 + +MANNODEV+= rpc.5 netconfig.5 diff --git a/lib/libc/rpc/Symbol.map b/lib/libc/rpc/Symbol.map index 61e8e084b1e0..105d6fb6b54e 100644 --- a/lib/libc/rpc/Symbol.map +++ b/lib/libc/rpc/Symbol.map @@ -8,9 +8,13 @@ FBSD_1.0 { xdr_desargs; xdr_desresp; + authdes_seccreate; + authdes_pk_seccreate; authnone_create; authunix_create; authunix_create_default; + xdr_authdes_cred; + xdr_authdes_verf; xdr_authunix_parms; bindresvport; bindresvport_sa; @@ -54,6 +58,15 @@ FBSD_1.0 { endrpcent; getrpcent; getrpcport; + key_setsecret; + key_secretkey_is_set; + key_encryptsession_pk; + key_decryptsession_pk; + key_encryptsession; + key_decryptsession; + key_gendes; + key_setnet; + key_get_conv; xdr_keystatus; xdr_keybuf; xdr_netnamestr; @@ -117,6 +130,7 @@ FBSD_1.0 { callrpc; registerrpc; clnt_broadcast; + authdes_create; clntunix_create; svcunix_create; svcunixfd_create; @@ -166,6 +180,8 @@ FBSD_1.0 { _authenticate; _svcauth_null; svc_auth_reg; + _svcauth_des; + authdes_getucred; _svcauth_unix; _svcauth_short; svc_dg_create; @@ -189,6 +205,9 @@ FBSD_1.8 { FBSDprivate_1.0 { __des_crypt_LOCAL; + __key_encryptsession_pk_LOCAL; + __key_decryptsession_pk_LOCAL; + __key_gendes_LOCAL; __svc_clean_idle; __rpc_gss_unwrap; __rpc_gss_unwrap_stub; diff --git a/lib/libc/rpc/auth_des.c b/lib/libc/rpc/auth_des.c index 754d55cbed3e..c9b20de25cda 100644 --- a/lib/libc/rpc/auth_des.c +++ b/lib/libc/rpc/auth_des.c @@ -30,34 +30,463 @@ /* * Copyright (c) 1988 by Sun Microsystems, Inc. */ - /* - * Secure RPC DES authentication was removed in FreeBSD 15.0. - * These symbols are provided for backward compatibility, but provide no - * functionality and will always return an error. + * auth_des.c, client-side implementation of DES authentication */ #include "namespace.h" #include "reentrant.h" +#include <err.h> +#include <errno.h> +#include <string.h> +#include <stdlib.h> +#include <unistd.h> +#include <rpc/des_crypt.h> +#include <syslog.h> #include <rpc/types.h> #include <rpc/auth.h> #include <rpc/auth_des.h> +#include <rpc/clnt.h> +#include <rpc/xdr.h> +#include <sys/socket.h> +#undef NIS #include <rpcsvc/nis.h> #include "un-namespace.h" +#include "mt_misc.h" + +#define USEC_PER_SEC 1000000 +#define RTIME_TIMEOUT 5 /* seconds to wait for sync */ + +#define AUTH_PRIVATE(auth) (struct ad_private *) auth->ah_private +#define ALLOC(object_type) (object_type *) mem_alloc(sizeof(object_type)) +#define FREE(ptr, size) mem_free((char *)(ptr), (int) size) +#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) + +extern bool_t xdr_authdes_cred( XDR *, struct authdes_cred *); +extern bool_t xdr_authdes_verf( XDR *, struct authdes_verf *); +extern int key_encryptsession_pk(char *, netobj *, des_block *); + +extern bool_t __rpc_get_time_offset(struct timeval *, nis_server *, char *, + char **, char **); -static AUTH * -__authdes_seccreate(const char *servername, const u_int win, +/* + * DES authenticator operations vector + */ +static void authdes_nextverf(AUTH *); +static bool_t authdes_marshal(AUTH *, XDR *); +static bool_t authdes_validate(AUTH *, struct opaque_auth *); +static bool_t authdes_refresh(AUTH *, void *); +static void authdes_destroy(AUTH *); + +static struct auth_ops *authdes_ops(void); + +/* + * This struct is pointed to by the ah_private field of an "AUTH *" + */ +struct ad_private { + char *ad_fullname; /* client's full name */ + u_int ad_fullnamelen; /* length of name, rounded up */ + char *ad_servername; /* server's full name */ + u_int ad_servernamelen; /* length of name, rounded up */ + u_int ad_window; /* client specified window */ + bool_t ad_dosync; /* synchronize? */ + struct netbuf ad_syncaddr; /* remote host to synch with */ + char *ad_timehost; /* remote host to synch with */ + struct timeval ad_timediff; /* server's time - client's time */ + u_int ad_nickname; /* server's nickname for client */ + struct authdes_cred ad_cred; /* storage for credential */ + struct authdes_verf ad_verf; /* storage for verifier */ + struct timeval ad_timestamp; /* timestamp sent */ + des_block ad_xkey; /* encrypted conversation key */ + u_char ad_pkey[1024]; /* Server's actual public key */ + char *ad_netid; /* Timehost netid */ + char *ad_uaddr; /* Timehost uaddr */ + nis_server *ad_nis_srvr; /* NIS+ server struct */ +}; + +AUTH *authdes_pk_seccreate(const char *, netobj *, u_int, const char *, + const des_block *, nis_server *); + +/* + * documented version of authdes_seccreate + */ +/* + servername: network name of server + win: time to live + timehost: optional hostname to sync with + ckey: optional conversation key to use +*/ + +AUTH * +authdes_seccreate(const char *servername, const u_int win, const char *timehost, const des_block *ckey) { - return (NULL); + u_char pkey_data[1024]; + netobj pkey; + AUTH *dummy; + + if (! getpublickey(servername, (char *) pkey_data)) { + syslog(LOG_ERR, + "authdes_seccreate: no public key found for %s", + servername); + return (NULL); + } + + pkey.n_bytes = (char *) pkey_data; + pkey.n_len = (u_int)strlen((char *)pkey_data) + 1; + dummy = authdes_pk_seccreate(servername, &pkey, win, timehost, + ckey, NULL); + return (dummy); } -__sym_compat(authdes_seccreate, __authdes_seccreate, FBSD_1.0); -static AUTH * -__authdes_pk_seccreate(const char *servername __unused, netobj *pkey __unused, - u_int window __unused, const char *timehost __unused, - const des_block *ckey __unused, nis_server *srvr __unused) +/* + * Slightly modified version of authdessec_create which takes the public key + * of the server principal as an argument. This spares us a call to + * getpublickey() which in the nameserver context can cause a deadlock. + */ +AUTH * +authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window, + const char *timehost, const des_block *ckey, nis_server *srvr) { + AUTH *auth; + struct ad_private *ad; + char namebuf[MAXNETNAMELEN+1]; + + /* + * Allocate everything now + */ + auth = ALLOC(AUTH); + if (auth == NULL) { + syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); + return (NULL); + } + ad = ALLOC(struct ad_private); + if (ad == NULL) { + syslog(LOG_ERR, "authdes_pk_seccreate: out of memory"); + goto failed; + } + ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */ + ad->ad_timehost = NULL; + ad->ad_netid = NULL; + ad->ad_uaddr = NULL; + ad->ad_nis_srvr = NULL; + ad->ad_timediff.tv_sec = 0; + ad->ad_timediff.tv_usec = 0; + memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len); + if (!getnetname(namebuf)) + goto failed; + ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf)); + ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1); + ad->ad_servernamelen = strlen(servername); + ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1); + + if (ad->ad_fullname == NULL || ad->ad_servername == NULL) { + syslog(LOG_ERR, "authdes_seccreate: out of memory"); + goto failed; + } + if (timehost != NULL) { + ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1); + if (ad->ad_timehost == NULL) { + syslog(LOG_ERR, "authdes_seccreate: out of memory"); + goto failed; + } + memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1); + ad->ad_dosync = TRUE; + } else if (srvr != NULL) { + ad->ad_nis_srvr = srvr; /* transient */ + ad->ad_dosync = TRUE; + } else { + ad->ad_dosync = FALSE; + } + memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1); + memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1); + ad->ad_window = window; + if (ckey == NULL) { + if (key_gendes(&auth->ah_key) < 0) { + syslog(LOG_ERR, + "authdes_seccreate: keyserv(1m) is unable to generate session key"); + goto failed; + } + } else { + auth->ah_key = *ckey; + } + + /* + * Set up auth handle + */ + auth->ah_cred.oa_flavor = AUTH_DES; + auth->ah_verf.oa_flavor = AUTH_DES; + auth->ah_ops = authdes_ops(); + auth->ah_private = (caddr_t)ad; + + if (!authdes_refresh(auth, NULL)) { + goto failed; + } + ad->ad_nis_srvr = NULL; /* not needed any longer */ + return (auth); + +failed: + if (auth) + FREE(auth, sizeof (AUTH)); + if (ad) { + if (ad->ad_fullname) + FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); + if (ad->ad_servername) + FREE(ad->ad_servername, ad->ad_servernamelen + 1); + if (ad->ad_timehost) + FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); + if (ad->ad_netid) + FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); + if (ad->ad_uaddr) + FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); + FREE(ad, sizeof (struct ad_private)); + } return (NULL); } -__sym_compat(authdes_pk_seccreate, __authdes_pk_seccreate, FBSD_1.0); + +/* + * Implement the five authentication operations + */ + + +/* + * 1. Next Verifier + */ +/*ARGSUSED*/ +static void +authdes_nextverf(AUTH *auth __unused) +{ + /* what the heck am I supposed to do??? */ +} + + +/* + * 2. Marshal + */ +static bool_t +authdes_marshal(AUTH *auth, XDR *xdrs) +{ +/* LINTED pointer alignment */ + struct ad_private *ad = AUTH_PRIVATE(auth); + struct authdes_cred *cred = &ad->ad_cred; + struct authdes_verf *verf = &ad->ad_verf; + des_block cryptbuf[2]; + des_block ivec; + int status; + int len; + rpc_inline_t *ixdr; + + /* + * Figure out the "time", accounting for any time difference + * with the server if necessary. + */ + (void)gettimeofday(&ad->ad_timestamp, NULL); + ad->ad_timestamp.tv_sec += ad->ad_timediff.tv_sec; + ad->ad_timestamp.tv_usec += ad->ad_timediff.tv_usec; + while (ad->ad_timestamp.tv_usec >= USEC_PER_SEC) { + ad->ad_timestamp.tv_usec -= USEC_PER_SEC; + ad->ad_timestamp.tv_sec++; + } + + /* + * XDR the timestamp and possibly some other things, then + * encrypt them. + */ + ixdr = (rpc_inline_t *)cryptbuf; + IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_sec); + IXDR_PUT_INT32(ixdr, ad->ad_timestamp.tv_usec); + if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { + IXDR_PUT_U_INT32(ixdr, ad->ad_window); + IXDR_PUT_U_INT32(ixdr, ad->ad_window - 1); + ivec.key.high = ivec.key.low = 0; + status = cbc_crypt((char *)&auth->ah_key, (char *)cryptbuf, + (u_int) 2 * sizeof (des_block), + DES_ENCRYPT | DES_HW, (char *)&ivec); + } else { + status = ecb_crypt((char *)&auth->ah_key, (char *)cryptbuf, + (u_int) sizeof (des_block), + DES_ENCRYPT | DES_HW); + } + if (DES_FAILED(status)) { + syslog(LOG_ERR, "authdes_marshal: DES encryption failure"); + return (FALSE); + } + ad->ad_verf.adv_xtimestamp = cryptbuf[0]; + if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { + ad->ad_cred.adc_fullname.window = cryptbuf[1].key.high; + ad->ad_verf.adv_winverf = cryptbuf[1].key.low; + } else { + ad->ad_cred.adc_nickname = ad->ad_nickname; + ad->ad_verf.adv_winverf = 0; + } + + /* + * Serialize the credential and verifier into opaque + * authentication data. + */ + if (ad->ad_cred.adc_namekind == ADN_FULLNAME) { + len = ((1 + 1 + 2 + 1)*BYTES_PER_XDR_UNIT + ad->ad_fullnamelen); + } else { + len = (1 + 1)*BYTES_PER_XDR_UNIT; + } + + if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { + IXDR_PUT_INT32(ixdr, AUTH_DES); + IXDR_PUT_INT32(ixdr, len); + } else { + ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_cred.oa_flavor)); + ATTEMPT(xdr_putint32(xdrs, &len)); + } + ATTEMPT(xdr_authdes_cred(xdrs, cred)); + + len = (2 + 1)*BYTES_PER_XDR_UNIT; + if ((ixdr = xdr_inline(xdrs, 2*BYTES_PER_XDR_UNIT))) { + IXDR_PUT_INT32(ixdr, AUTH_DES); + IXDR_PUT_INT32(ixdr, len); + } else { + ATTEMPT(xdr_putint32(xdrs, (int *)&auth->ah_verf.oa_flavor)); + ATTEMPT(xdr_putint32(xdrs, &len)); + } + ATTEMPT(xdr_authdes_verf(xdrs, verf)); + return (TRUE); +} + + +/* + * 3. Validate + */ +static bool_t +authdes_validate(AUTH *auth, struct opaque_auth *rverf) +{ +/* LINTED pointer alignment */ + struct ad_private *ad = AUTH_PRIVATE(auth); + struct authdes_verf verf; + int status; + uint32_t *ixdr; + des_block buf; + + if (rverf->oa_length != (2 + 1) * BYTES_PER_XDR_UNIT) { + return (FALSE); + } +/* LINTED pointer alignment */ + ixdr = (uint32_t *)rverf->oa_base; + buf.key.high = (uint32_t)*ixdr++; + buf.key.low = (uint32_t)*ixdr++; + verf.adv_int_u = (uint32_t)*ixdr++; + + /* + * Decrypt the timestamp + */ + status = ecb_crypt((char *)&auth->ah_key, (char *)&buf, + (u_int)sizeof (des_block), DES_DECRYPT | DES_HW); + + if (DES_FAILED(status)) { + syslog(LOG_ERR, "authdes_validate: DES decryption failure"); + return (FALSE); + } + + /* + * xdr the decrypted timestamp + */ +/* LINTED pointer alignment */ + ixdr = (uint32_t *)buf.c; + verf.adv_timestamp.tv_sec = IXDR_GET_INT32(ixdr) + 1; + verf.adv_timestamp.tv_usec = IXDR_GET_INT32(ixdr); + + /* + * validate + */ + if (bcmp((char *)&ad->ad_timestamp, (char *)&verf.adv_timestamp, + sizeof(struct timeval)) != 0) { + syslog(LOG_DEBUG, "authdes_validate: verifier mismatch"); + return (FALSE); + } + + /* + * We have a nickname now, let's use it + */ + ad->ad_nickname = verf.adv_nickname; + ad->ad_cred.adc_namekind = ADN_NICKNAME; + return (TRUE); +} + +/* + * 4. Refresh + */ +/*ARGSUSED*/ +static bool_t +authdes_refresh(AUTH *auth, void *dummy __unused) +{ +/* LINTED pointer alignment */ + struct ad_private *ad = AUTH_PRIVATE(auth); + struct authdes_cred *cred = &ad->ad_cred; + int ok; + netobj pkey; + + if (ad->ad_dosync) { + ok = __rpc_get_time_offset(&ad->ad_timediff, ad->ad_nis_srvr, + ad->ad_timehost, &(ad->ad_uaddr), + &(ad->ad_netid)); + if (! ok) { + /* + * Hope the clocks are synced! + */ + ad->ad_dosync = 0; + syslog(LOG_DEBUG, + "authdes_refresh: unable to synchronize clock"); + } + } + ad->ad_xkey = auth->ah_key; + pkey.n_bytes = (char *)(ad->ad_pkey); + pkey.n_len = (u_int)strlen((char *)ad->ad_pkey) + 1; + if (key_encryptsession_pk(ad->ad_servername, &pkey, &ad->ad_xkey) < 0) { + syslog(LOG_INFO, + "authdes_refresh: keyserv(1m) is unable to encrypt session key"); + return (FALSE); + } + cred->adc_fullname.key = ad->ad_xkey; + cred->adc_namekind = ADN_FULLNAME; + cred->adc_fullname.name = ad->ad_fullname; + return (TRUE); +} + + +/* + * 5. Destroy + */ +static void +authdes_destroy(AUTH *auth) +{ +/* LINTED pointer alignment */ + struct ad_private *ad = AUTH_PRIVATE(auth); + + FREE(ad->ad_fullname, ad->ad_fullnamelen + 1); + FREE(ad->ad_servername, ad->ad_servernamelen + 1); + if (ad->ad_timehost) + FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1); + if (ad->ad_netid) + FREE(ad->ad_netid, strlen(ad->ad_netid) + 1); + if (ad->ad_uaddr) + FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1); + FREE(ad, sizeof (struct ad_private)); + FREE(auth, sizeof(AUTH)); +} + +static struct auth_ops * +authdes_ops(void) +{ + static struct auth_ops ops; + + /* VARIABLES PROTECTED BY ops_lock: ops */ + + mutex_lock(&authdes_ops_lock); + if (ops.ah_nextverf == NULL) { + ops.ah_nextverf = authdes_nextverf; + ops.ah_marshal = authdes_marshal; + ops.ah_validate = authdes_validate; + ops.ah_refresh = authdes_refresh; + ops.ah_destroy = authdes_destroy; + } + mutex_unlock(&authdes_ops_lock); + return (&ops); +} diff --git a/lib/libc/rpc/authdes_prot.c b/lib/libc/rpc/authdes_prot.c index 56b44daafe41..79a0e5baa084 100644 --- a/lib/libc/rpc/authdes_prot.c +++ b/lib/libc/rpc/authdes_prot.c @@ -42,16 +42,44 @@ #include <rpc/auth_des.h> #include "un-namespace.h" -static bool_t -__xdr_authdes_cred(XDR *xdrs, void *cred) +#define ATTEMPT(xdr_op) if (!(xdr_op)) return (FALSE) + +bool_t +xdr_authdes_cred(XDR *xdrs, struct authdes_cred *cred) { - return (FALSE); + enum authdes_namekind *padc_namekind = &cred->adc_namekind; + /* + * Unrolled xdr + */ + ATTEMPT(xdr_enum(xdrs, (enum_t *) padc_namekind)); + switch (cred->adc_namekind) { + case ADN_FULLNAME: + ATTEMPT(xdr_string(xdrs, &cred->adc_fullname.name, + MAXNETNAMELEN)); + ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.key, + sizeof(des_block))); + ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_fullname.window, + sizeof(cred->adc_fullname.window))); + return (TRUE); + case ADN_NICKNAME: + ATTEMPT(xdr_opaque(xdrs, (caddr_t)&cred->adc_nickname, + sizeof(cred->adc_nickname))); + return (TRUE); + default: + return (FALSE); + } } -__sym_compat(xdr_authdes_cred, __xdr_authdes_cred, FBSD_1.0); -static bool_t -__xdr_authdes_verf(XDR *xdrs, void *verf) + +bool_t +xdr_authdes_verf(XDR *xdrs, struct authdes_verf *verf) { - return (FALSE); + /* + * Unrolled xdr + */ + ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_xtimestamp, + sizeof(des_block))); + ATTEMPT(xdr_opaque(xdrs, (caddr_t)&verf->adv_int_u, + sizeof(verf->adv_int_u))); + return (TRUE); } -__sym_compat(xdr_authdes_verf, __xdr_authdes_verf, FBSD_1.0); diff --git a/lib/libc/rpc/key_call.c b/lib/libc/rpc/key_call.c index eb274fcfff36..5c87881c815c 100644 --- a/lib/libc/rpc/key_call.c +++ b/lib/libc/rpc/key_call.c @@ -32,78 +32,426 @@ */ /* - * Secure RPC keyserver support was removed in FreeBSD 15.0. - * These symbols are provided for backward compatibility, but provide no - * functionality and will always return an error. + * key_call.c, Interface to keyserver + * + * setsecretkey(key) - set your secret key + * encryptsessionkey(agent, deskey) - encrypt a session key to talk to agent + * decryptsessionkey(agent, deskey) - decrypt ditto + * gendeskey(deskey) - generate a secure des key */ #include "namespace.h" #include "reentrant.h" +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <errno.h> #include <rpc/rpc.h> -#include <rpc/key_prot.h> #include <rpc/auth.h> +#include <rpc/auth_unix.h> +#include <rpc/key_prot.h> +#include <string.h> +#include <netconfig.h> +#include <sys/utsname.h> +#include <stdlib.h> +#include <signal.h> +#include <sys/wait.h> +#include <sys/fcntl.h> #include "un-namespace.h" #include "mt_misc.h" -static int -__key_setsecret(const char *secretkey) + +#define KEY_TIMEOUT 5 /* per-try timeout in seconds */ +#define KEY_NRETRY 12 /* number of retries */ + +#ifdef DEBUG +#define debug(msg) (void) fprintf(stderr, "%s\n", msg); +#else +#define debug(msg) +#endif /* DEBUG */ + +/* + * Hack to allow the keyserver to use AUTH_DES (for authenticated + * NIS+ calls, for example). The only functions that get called + * are key_encryptsession_pk, key_decryptsession_pk, and key_gendes. + * + * The approach is to have the keyserver fill in pointers to local + * implementations of these functions, and to call those in key_call(). + */ + +cryptkeyres *(*__key_encryptsession_pk_LOCAL)(uid_t, void *arg) = 0; +cryptkeyres *(*__key_decryptsession_pk_LOCAL)(uid_t, void *arg) = 0; +des_block *(*__key_gendes_LOCAL)(uid_t, void *) = 0; + +static int key_call( u_long, xdrproc_t, void *, xdrproc_t, void *); + +int +key_setsecret(const char *secretkey) { - return (-1); + keystatus status; + + if (!key_call((u_long) KEY_SET, (xdrproc_t)xdr_keybuf, + (void *)secretkey, + (xdrproc_t)xdr_keystatus, &status)) { + return (-1); + } + if (status != KEY_SUCCESS) { + debug("set status is nonzero"); + return (-1); + } + return (0); } -__sym_compat(key_setsecret, __key_setsecret, FBSD_1.0); -static int -__key_secretkey_is_set(void) + +/* key_secretkey_is_set() returns 1 if the keyserver has a secret key + * stored for the caller's effective uid; it returns 0 otherwise + * + * N.B.: The KEY_NET_GET key call is undocumented. Applications shouldn't + * be using it, because it allows them to get the user's secret key. + */ + +int +key_secretkey_is_set(void) { + struct key_netstres kres; + + memset((void*)&kres, 0, sizeof (kres)); + if (key_call((u_long) KEY_NET_GET, (xdrproc_t)xdr_void, NULL, + (xdrproc_t)xdr_key_netstres, &kres) && + (kres.status == KEY_SUCCESS) && + (kres.key_netstres_u.knet.st_priv_key[0] != 0)) { + /* avoid leaving secret key in memory */ + memset(kres.key_netstres_u.knet.st_priv_key, 0, HEXKEYBYTES); + return (1); + } return (0); } -__sym_compat(key_secretkey_is_set, __key_secretkey_is_set, FBSD_1.0); -static int -__key_encryptsession_pk(char *remotename, netobj *remotekey, des_block *deskey) +int +key_encryptsession_pk(char *remotename, netobj *remotekey, des_block *deskey) { - return (-1); + cryptkeyarg2 arg; + cryptkeyres res; + + arg.remotename = remotename; + arg.remotekey = *remotekey; + arg.deskey = *deskey; + if (!key_call((u_long)KEY_ENCRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg, + (xdrproc_t)xdr_cryptkeyres, &res)) { + return (-1); + } + if (res.status != KEY_SUCCESS) { + debug("encrypt status is nonzero"); + return (-1); + } + *deskey = res.cryptkeyres_u.deskey; + return (0); } -__sym_compat(key_encryptsession_pk, __key_encryptsession_pk, FBSD_1.0); -static int -__key_decryptsession_pk(char *remotename, netobj *remotekey, des_block *deskey) +int +key_decryptsession_pk(char *remotename, netobj *remotekey, des_block *deskey) { - return (-1); + cryptkeyarg2 arg; + cryptkeyres res; + + arg.remotename = remotename; + arg.remotekey = *remotekey; + arg.deskey = *deskey; + if (!key_call((u_long)KEY_DECRYPT_PK, (xdrproc_t)xdr_cryptkeyarg2, &arg, + (xdrproc_t)xdr_cryptkeyres, &res)) { + return (-1); + } + if (res.status != KEY_SUCCESS) { + debug("decrypt status is nonzero"); + return (-1); + } + *deskey = res.cryptkeyres_u.deskey; + return (0); } -__sym_compat(key_decryptsession_pk, __key_decryptsession_pk, FBSD_1.0); -static int -__key_encryptsession(const char *remotename, des_block *deskey) +int +key_encryptsession(const char *remotename, des_block *deskey) { - return (-1); + cryptkeyarg arg; + cryptkeyres res; + + arg.remotename = (char *) remotename; + arg.deskey = *deskey; + if (!key_call((u_long)KEY_ENCRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg, + (xdrproc_t)xdr_cryptkeyres, &res)) { + return (-1); + } + if (res.status != KEY_SUCCESS) { + debug("encrypt status is nonzero"); + return (-1); + } + *deskey = res.cryptkeyres_u.deskey; + return (0); } -__sym_compat(key_encryptsession, __key_encryptsession, FBSD_1.0); -static int -__key_decryptsession(const char *remotename, des_block *deskey) +int +key_decryptsession(const char *remotename, des_block *deskey) { - return (-1); + cryptkeyarg arg; + cryptkeyres res; + + arg.remotename = (char *) remotename; + arg.deskey = *deskey; + if (!key_call((u_long)KEY_DECRYPT, (xdrproc_t)xdr_cryptkeyarg, &arg, + (xdrproc_t)xdr_cryptkeyres, &res)) { + return (-1); + } + if (res.status != KEY_SUCCESS) { + debug("decrypt status is nonzero"); + return (-1); + } + *deskey = res.cryptkeyres_u.deskey; + return (0); } -__sym_compat(key_decryptsession, __key_decryptsession, FBSD_1.0); -static int -__key_gendes(des_block *key) +int +key_gendes(des_block *key) { - return (-1); + if (!key_call((u_long)KEY_GEN, (xdrproc_t)xdr_void, NULL, + (xdrproc_t)xdr_des_block, key)) { + return (-1); + } + return (0); } -__sym_compat(key_gendes, __key_gendes, FBSD_1.0); -static int -__key_setnet(struct key_netstarg *arg) +int +key_setnet(struct key_netstarg *arg) { - return (-1); + keystatus status; + + + if (!key_call((u_long) KEY_NET_PUT, (xdrproc_t)xdr_key_netstarg, arg, + (xdrproc_t)xdr_keystatus, &status)){ + return (-1); + } + + if (status != KEY_SUCCESS) { + debug("key_setnet status is nonzero"); + return (-1); + } + return (1); +} + + +int +key_get_conv(char *pkey, des_block *deskey) +{ + cryptkeyres res; + + if (!key_call((u_long) KEY_GET_CONV, (xdrproc_t)xdr_keybuf, pkey, + (xdrproc_t)xdr_cryptkeyres, &res)) { + return (-1); + } + if (res.status != KEY_SUCCESS) { + debug("get_conv status is nonzero"); + return (-1); + } + *deskey = res.cryptkeyres_u.deskey; + return (0); +} + +struct key_call_private { + CLIENT *client; /* Client handle */ + pid_t pid; /* process-id at moment of creation */ + uid_t uid; /* user-id at last authorization */ +}; +static struct key_call_private *key_call_private_main = NULL; +static thread_key_t key_call_key; +static once_t key_call_once = ONCE_INITIALIZER; +static int key_call_key_error; + +static void +key_call_destroy(void *vp) +{ + struct key_call_private *kcp = (struct key_call_private *)vp; + + if (kcp) { + if (kcp->client) + clnt_destroy(kcp->client); + free(kcp); + } +} + +static void +key_call_init(void) +{ + + key_call_key_error = thr_keycreate(&key_call_key, key_call_destroy); } -__sym_compat(key_setnet, __key_setnet, FBSD_1.0); + +/* + * Keep the handle cached. This call may be made quite often. + */ +static CLIENT * +getkeyserv_handle(int vers) +{ + void *localhandle; + struct netconfig *nconf; + struct netconfig *tpconf; + struct key_call_private *kcp; + struct timeval wait_time; + struct utsname u; + int main_thread; + int fd; + +#define TOTAL_TIMEOUT 30 /* total timeout talking to keyserver */ +#define TOTAL_TRIES 5 /* Number of tries */ + + if ((main_thread = thr_main())) { + kcp = key_call_private_main; + } else { + if (thr_once(&key_call_once, key_call_init) != 0 || + key_call_key_error != 0) + return ((CLIENT *) NULL); + kcp = (struct key_call_private *)thr_getspecific(key_call_key); + } + if (kcp == (struct key_call_private *)NULL) { + kcp = (struct key_call_private *)malloc(sizeof (*kcp)); + if (kcp == (struct key_call_private *)NULL) { + return ((CLIENT *) NULL); + } + if (main_thread) + key_call_private_main = kcp; + else + thr_setspecific(key_call_key, (void *) kcp); + kcp->client = NULL; + } + + /* if pid has changed, destroy client and rebuild */ + if (kcp->client != NULL && kcp->pid != getpid()) { + clnt_destroy(kcp->client); + kcp->client = NULL; + } + + if (kcp->client != NULL) { + /* if uid has changed, build client handle again */ + if (kcp->uid != geteuid()) { + kcp->uid = geteuid(); + auth_destroy(kcp->client->cl_auth); + kcp->client->cl_auth = + authsys_create("", kcp->uid, 0, 0, NULL); + if (kcp->client->cl_auth == NULL) { + clnt_destroy(kcp->client); + kcp->client = NULL; + return ((CLIENT *) NULL); + } + } + /* Change the version number to the new one */ + clnt_control(kcp->client, CLSET_VERS, (void *)&vers); + return (kcp->client); + } + if (!(localhandle = setnetconfig())) { + return ((CLIENT *) NULL); + } + tpconf = NULL; +#if defined(__FreeBSD__) + if (uname(&u) == -1) +#else +#if defined(i386) + if (_nuname(&u) == -1) +#elif defined(sparc) + if (_uname(&u) == -1) +#else +#error Unknown architecture! +#endif +#endif + { + endnetconfig(localhandle); + return ((CLIENT *) NULL); + } + while ((nconf = getnetconfig(localhandle)) != NULL) { + if (strcmp(nconf->nc_protofmly, NC_LOOPBACK) == 0) { + /* + * We use COTS_ORD here so that the caller can + * find out immediately if the server is dead. + */ + if (nconf->nc_semantics == NC_TPI_COTS_ORD) { + kcp->client = clnt_tp_create(u.nodename, + KEY_PROG, vers, nconf); + if (kcp->client) + break; + } else { + tpconf = nconf; + } + } + } + if ((kcp->client == (CLIENT *) NULL) && (tpconf)) + /* Now, try the CLTS or COTS loopback transport */ + kcp->client = clnt_tp_create(u.nodename, + KEY_PROG, vers, tpconf); + endnetconfig(localhandle); + + if (kcp->client == (CLIENT *) NULL) { + return ((CLIENT *) NULL); + } + kcp->uid = geteuid(); + kcp->pid = getpid(); + kcp->client->cl_auth = authsys_create("", kcp->uid, 0, 0, NULL); + if (kcp->client->cl_auth == NULL) { + clnt_destroy(kcp->client); + kcp->client = NULL; + return ((CLIENT *) NULL); + } + + wait_time.tv_sec = TOTAL_TIMEOUT/TOTAL_TRIES; + wait_time.tv_usec = 0; + (void) clnt_control(kcp->client, CLSET_RETRY_TIMEOUT, + (char *)&wait_time); + if (clnt_control(kcp->client, CLGET_FD, (char *)&fd)) + _fcntl(fd, F_SETFD, 1); /* make it "close on exec" */ + + return (kcp->client); +} + +/* returns 0 on failure, 1 on success */ static int -__key_get_conv(char *pkey, des_block *deskey) +key_call(u_long proc, xdrproc_t xdr_arg, void *arg, xdrproc_t xdr_rslt, + void *rslt) { - return (-1); + CLIENT *clnt; + struct timeval wait_time; + + if (proc == KEY_ENCRYPT_PK && __key_encryptsession_pk_LOCAL) { + cryptkeyres *res; + res = (*__key_encryptsession_pk_LOCAL)(geteuid(), arg); + *(cryptkeyres*)rslt = *res; + return (1); + } else if (proc == KEY_DECRYPT_PK && __key_decryptsession_pk_LOCAL) { + cryptkeyres *res; + res = (*__key_decryptsession_pk_LOCAL)(geteuid(), arg); + *(cryptkeyres*)rslt = *res; + return (1); + } else if (proc == KEY_GEN && __key_gendes_LOCAL) { + des_block *res; + res = (*__key_gendes_LOCAL)(geteuid(), 0); + *(des_block*)rslt = *res; + return (1); + } + + if ((proc == KEY_ENCRYPT_PK) || (proc == KEY_DECRYPT_PK) || + (proc == KEY_NET_GET) || (proc == KEY_NET_PUT) || + (proc == KEY_GET_CONV)) + clnt = getkeyserv_handle(2); /* talk to version 2 */ + else + clnt = getkeyserv_handle(1); /* talk to version 1 */ + + if (clnt == NULL) { + return (0); + } + + wait_time.tv_sec = TOTAL_TIMEOUT; + wait_time.tv_usec = 0; + + if (clnt_call(clnt, proc, xdr_arg, arg, xdr_rslt, rslt, + wait_time) == RPC_SUCCESS) { + return (1); + } else { + return (0); + } } -__sym_compat(key_get_conv, __key_get_conv, FBSD_1.0); diff --git a/lib/libc/rpc/publickey.5 b/lib/libc/rpc/publickey.5 new file mode 100644 index 000000000000..db95c4617b50 --- /dev/null +++ b/lib/libc/rpc/publickey.5 @@ -0,0 +1,40 @@ +.Dd October 19, 1987 +.Dt PUBLICKEY 5 +.Os +.Sh NAME +.Nm publickey +.Nd "public key database" +.Sh SYNOPSIS +.Pa /etc/publickey +.Sh DESCRIPTION +.Pa /etc/publickey +is the public key database used for secure +RPC (Remote Procedure Calls). +Each entry in +the database consists of a network user +name (which may either refer to +a user or a hostname), followed by the user's +public key (in hex +notation), a colon, and then the user's +secret key encrypted with +its login password (also in hex notation). +.Pp +This file is altered either by the user through the +.Xr chkey 1 +command or by the system administrator through the +.Xr newkey 8 +command. +The file +.Pa /etc/publickey +should only contain data on the +.Tn NIS +master machine, where it +is converted into the +.Tn NIS +database +.Pa publickey.byname . +.Sh SEE ALSO +.Xr chkey 1 , +.Xr publickey 3 , +.Xr newkey 8 , +.Xr ypupdated 8 diff --git a/lib/libc/rpc/rpc_generic.c b/lib/libc/rpc/rpc_generic.c index 0e563f6a5996..8019f2d8f236 100644 --- a/lib/libc/rpc/rpc_generic.c +++ b/lib/libc/rpc/rpc_generic.c @@ -610,6 +610,10 @@ __rpc_taddr2uaddr_af(int af, const struct netbuf *nbuf) return NULL; break; #endif + case AF_NETLINK: + if (asprintf(&ret, "%s", (char *)nbuf->buf) < 0) + return NULL; + break; case AF_LOCAL: sun = nbuf->buf; if (asprintf(&ret, "%.*s", (int)(sun->sun_len - diff --git a/lib/libc/rpc/rpc_secure.3 b/lib/libc/rpc/rpc_secure.3 index ca99b06b556d..ce59bba7115f 100644 --- a/lib/libc/rpc/rpc_secure.3 +++ b/lib/libc/rpc/rpc_secure.3 @@ -1,17 +1,34 @@ .\" -.Dd August 10, 2025 -.Dt RPC_SECURE 3 +.Dd February 16, 1988 +.Dt RPC 3 .Os .Sh NAME .Nm rpc_secure .Nd library routines for secure remote procedure calls .Sh SYNOPSIS .In rpc/rpc.h +.Ft AUTH * +.Fo authdes_create +.Fa "char *name" +.Fa "unsigned window" +.Fa "struct sockaddr *addr" +.Fa "des_block *ckey" +.Fc +.Ft int +.Fn authdes_getucred "struct authdes_cred *adc" "uid_t *uid" "gid_t *gid" "int *grouplen" "gid_t *groups" .Ft int .Fn getnetname "char *name" .Ft int .Fn host2netname "char *name" "const char *host" "const char *domain" .Ft int +.Fn key_decryptsession "const char *remotename" "des_block *deskey" +.Ft int +.Fn key_encryptsession "const char *remotename" "des_block *deskey" +.Ft int +.Fn key_gendes "des_block *deskey" +.Ft int +.Fn key_setsecret "const char *key" +.Ft int .Fn netname2host "char *name" "char *host" "int hostlen" .Ft int .Fn netname2user "char *name" "uid_t *uidp" "gid_t *gidp" "int *gidlenp" "gid_t *gidlist" @@ -21,11 +38,101 @@ These routines are part of the .Tn RPC library. +They implement +.Tn DES +Authentication. See .Xr rpc 3 for further details about .Tn RPC . .Pp +The +.Fn authdes_create +is the first of two routines which interface to the +.Tn RPC +secure authentication system, known as +.Tn DES +authentication. +The second is +.Fn authdes_getucred , +below. +.Pp +Note: the keyserver daemon +.Xr keyserv 8 +must be running for the +.Tn DES +authentication system to work. +.Pp +The +.Fn authdes_create +function, +used on the client side, returns an authentication handle that +will enable the use of the secure authentication system. +The first argument +.Fa name +is the network name, or +.Fa netname , +of the owner of the server process. +This field usually +represents a +.Fa hostname +derived from the utility routine +.Fn host2netname , +but could also represent a user name using +.Fn user2netname . +The second field is window on the validity of +the client credential, given in seconds. +A small +window is more secure than a large one, but choosing +too small of a window will increase the frequency of +resynchronizations because of clock drift. +The third +argument +.Fa addr +is optional. +If it is +.Dv NULL , +then the authentication system will assume +that the local clock is always in sync with the server's +clock, and will not attempt resynchronizations. +If an address +is supplied, however, then the system will use the address +for consulting the remote time service whenever +resynchronization +is required. +This argument is usually the +address of the +.Tn RPC +server itself. +The final argument +.Fa ckey +is also optional. +If it is +.Dv NULL , +then the authentication system will +generate a random +.Tn DES +key to be used for the encryption of credentials. +If it is supplied, however, then it will be used instead. +.Pp +The +.Fn authdes_getucred +function, +the second of the two +.Tn DES +authentication routines, +is used on the server side for converting a +.Tn DES +credential, which is +operating system independent, into a +.Ux +credential. +This routine differs from utility routine +.Fn netname2user +in that +.Fn authdes_getucred +pulls its information from a cache, and does not have to do a +Yellow Pages lookup every time it is called to get its information. .Pp The .Fn getnetname @@ -54,6 +161,72 @@ Inverse of .Fn netname2host . .Pp The +.Fn key_decryptsession +function +is an interface to the keyserver daemon, which is associated +with +.Tn RPC Ns 's +secure authentication system +.Tn ( DES +authentication). +User programs rarely need to call it, or its associated routines +.Fn key_encryptsession , +.Fn key_gendes +and +.Fn key_setsecret . +System commands such as +.Xr login 1 +and the +.Tn RPC +library are the main clients of these four routines. +.Pp +The +.Fn key_decryptsession +function +takes a server netname and a +.Tn DES +key, and decrypts the key by +using the public key of the server and the secret key +associated with the effective uid of the calling process. +It +is the inverse of +.Fn key_encryptsession . +.Pp +The +.Fn key_encryptsession +function +is a keyserver interface routine. +It +takes a server netname and a des key, and encrypts +it using the public key of the server and the secret key +associated with the effective uid of the calling process. +It +is the inverse of +.Fn key_decryptsession . +.Pp +The +.Fn key_gendes +function +is a keyserver interface routine. +It +is used to ask the keyserver for a secure conversation key. +Choosing one +.Qq random +is usually not good enough, +because +the common ways of choosing random numbers, such as using the +current time, are very easy to guess. +.Pp +The +.Fn key_setsecret +function +is a keyserver interface routine. +It is used to set the key for +the effective +.Fa uid +of the calling process. +.Pp +The .Fn netname2host function converts from an operating-system independent netname to a diff --git a/lib/libc/rpc/rpc_soc.3 b/lib/libc/rpc/rpc_soc.3 index e6fd8a0da6e4..4abd4b14c475 100644 --- a/lib/libc/rpc/rpc_soc.3 +++ b/lib/libc/rpc/rpc_soc.3 @@ -1,6 +1,6 @@ .\" $NetBSD: rpc_soc.3,v 1.2 2000/06/07 13:39:43 simonb Exp $ .\" -.Dd August 10, 2025 +.Dd February 16, 1988 .Dt RPC_SOC 3 .Os .Sh NAME @@ -100,6 +100,16 @@ to perform the requested service, and then sends back a reply. Finally, the procedure call returns to the client. .Pp +Routines that are used for Secure +.Tn RPC ( DES +authentication) are described in +.Xr rpc_secure 3 . +Secure +.Tn RPC +can be used only if +.Tn DES +encryption is available. +.Pp .Bl -tag -width indent -compact .It Xo .Ft void @@ -1691,6 +1701,7 @@ This routine modifies the global variable Service implementors usually do not need this routine. .El .Sh SEE ALSO +.Xr rpc_secure 3 , .Xr xdr 3 .Rs .%T "Remote Procedure Calls: Protocol Specification" diff --git a/lib/libc/rpc/rpc_soc.c b/lib/libc/rpc/rpc_soc.c index e293a2ccf22f..c63b89594ce6 100644 --- a/lib/libc/rpc/rpc_soc.c +++ b/lib/libc/rpc/rpc_soc.c @@ -379,13 +379,36 @@ clnt_broadcast(u_long prog, u_long vers, u_long proc, xdrproc_t xargs, * Create the client des authentication object. Obsoleted by * authdes_seccreate(). */ -static AUTH * -__authdes_create(char *servername, u_int window, struct sockaddr *syncaddr, +AUTH * +authdes_create(char *servername, u_int window, struct sockaddr *syncaddr, des_block *ckey) +/* + * char *servername; // network name of server + * u_int window; // time to live + * struct sockaddr *syncaddr; // optional hostaddr to sync with + * des_block *ckey; // optional conversation key to use + */ { - return (NULL); + AUTH *dummy; + AUTH *nauth; + char hostname[NI_MAXHOST]; + + if (syncaddr) { + /* + * Change addr to hostname, because that is the way + * new interface takes it. + */ + if (getnameinfo(syncaddr, syncaddr->sa_len, hostname, + sizeof hostname, NULL, 0, 0) != 0) + goto fallback; + + nauth = authdes_seccreate(servername, window, hostname, ckey); + return (nauth); + } +fallback: + dummy = authdes_seccreate(servername, window, NULL, ckey); + return (dummy); } -__sym_compat(authdes_create, __authdes_create, FBSD_1.0); /* * Create a client handle for a unix connection. Obsoleted by clnt_vc_create() diff --git a/lib/libc/rpc/svc_auth.c b/lib/libc/rpc/svc_auth.c index b8a9a8f33ebb..eb61171733d6 100644 --- a/lib/libc/rpc/svc_auth.c +++ b/lib/libc/rpc/svc_auth.c @@ -114,6 +114,11 @@ _authenticate(struct svc_req *rqst, struct rpc_msg *msg) case AUTH_SHORT: dummy = _svcauth_short(rqst, msg); return (dummy); +#ifdef DES_BUILTIN + case AUTH_DES: + dummy = _svcauth_des(rqst, msg); + return (dummy); +#endif default: break; } @@ -181,6 +186,9 @@ svc_auth_reg(int cred_flavor, case AUTH_NULL: case AUTH_SYS: case AUTH_SHORT: +#ifdef DES_BUILTIN + case AUTH_DES: +#endif /* already registered */ return (1); diff --git a/lib/libc/rpc/svc_auth_des.c b/lib/libc/rpc/svc_auth_des.c index 8fde5512e53f..d4736cc851e8 100644 --- a/lib/libc/rpc/svc_auth_des.c +++ b/lib/libc/rpc/svc_auth_des.c @@ -34,8 +34,17 @@ */ /* - * svcauth_des.c, server-side des authentication. - * This functionality was removed in FreeBSD 15.0. + * svcauth_des.c, server-side des authentication + * + * We insure for the service the following: + * (1) The timestamp microseconds do not exceed 1 million. + * (2) The timestamp plus the window is less than the current time. + * (3) The timestamp is not less than the one previously + * seen in the current session. + * + * It is up to the server to determine if the window size is + * too small . + * */ #include "namespace.h" @@ -56,27 +65,458 @@ #include <rpc/svc_auth.h> #include "libc_private.h" +extern int key_decryptsession_pk(const char *, netobj *, des_block *); + +#define debug(msg) printf("svcauth_des: %s\n", msg) + +#define USEC_PER_SEC ((u_long) 1000000L) +#define BEFORE(t1, t2) timercmp(t1, t2, <) + +/* + * LRU cache of conversation keys and some other useful items. + */ +#define AUTHDES_CACHESZ 64 +struct cache_entry { + des_block key; /* conversation key */ + char *rname; /* client's name */ + u_int window; /* credential lifetime window */ + struct timeval laststamp; /* detect replays of creds */ + char *localcred; /* generic local credential */ +}; +static struct cache_entry *authdes_cache/* [AUTHDES_CACHESZ] */; +static short *authdes_lru/* [AUTHDES_CACHESZ] */; + +static void cache_init(void); /* initialize the cache */ +static short cache_spot(des_block *, char *, struct timeval *); /* find an entry in the cache */ +static void cache_ref(short sid); /* note that sid was ref'd */ + +static void invalidate(char *); /* invalidate entry in cache */ + +/* + * cache statistics + */ +static struct { + u_long ncachehits; /* times cache hit, and is not replay */ + u_long ncachereplays; /* times cache hit, and is replay */ + u_long ncachemisses; /* times cache missed */ +} svcauthdes_stats; + /* * Service side authenticator for AUTH_DES */ -static enum auth_stat -__svcauth_des(struct svc_req *rqst, struct rpc_msg *msg) +enum auth_stat +_svcauth_des(struct svc_req *rqst, struct rpc_msg *msg) { - return (AUTH_FAILED); + + long *ixdr; + des_block cryptbuf[2]; + struct authdes_cred *cred; + struct authdes_verf verf; + int status; + struct cache_entry *entry; + short sid = 0; + des_block *sessionkey; + des_block ivec; + u_int window; + struct timeval timestamp; + u_long namelen; + struct area { + struct authdes_cred area_cred; + char area_netname[MAXNETNAMELEN+1]; + } *area; + + if (authdes_cache == NULL) { + cache_init(); + } + + area = (struct area *)rqst->rq_clntcred; + cred = (struct authdes_cred *)&area->area_cred; + + /* + * Get the credential + */ + ixdr = (long *)msg->rm_call.cb_cred.oa_base; + cred->adc_namekind = IXDR_GET_ENUM(ixdr, enum authdes_namekind); + switch (cred->adc_namekind) { + case ADN_FULLNAME: + namelen = IXDR_GET_U_LONG(ixdr); + if (namelen > MAXNETNAMELEN) { + return (AUTH_BADCRED); + } + cred->adc_fullname.name = area->area_netname; + bcopy((char *)ixdr, cred->adc_fullname.name, + (u_int)namelen); + cred->adc_fullname.name[namelen] = 0; + ixdr += (RNDUP(namelen) / BYTES_PER_XDR_UNIT); + cred->adc_fullname.key.key.high = (u_long)*ixdr++; + cred->adc_fullname.key.key.low = (u_long)*ixdr++; + cred->adc_fullname.window = (u_long)*ixdr++; + break; + case ADN_NICKNAME: + cred->adc_nickname = (u_long)*ixdr++; + break; + default: + return (AUTH_BADCRED); + } + + /* + * Get the verifier + */ + ixdr = (long *)msg->rm_call.cb_verf.oa_base; + verf.adv_xtimestamp.key.high = (u_long)*ixdr++; + verf.adv_xtimestamp.key.low = (u_long)*ixdr++; + verf.adv_int_u = (u_long)*ixdr++; + + + /* + * Get the conversation key + */ + if (cred->adc_namekind == ADN_FULLNAME) { + netobj pkey; + char pkey_data[1024]; + + sessionkey = &cred->adc_fullname.key; + if (! getpublickey(cred->adc_fullname.name, pkey_data)) { + debug("getpublickey"); + return(AUTH_BADCRED); + } + pkey.n_bytes = pkey_data; + pkey.n_len = strlen(pkey_data) + 1; + if (key_decryptsession_pk(cred->adc_fullname.name, &pkey, + sessionkey) < 0) { + debug("decryptsessionkey"); + return (AUTH_BADCRED); /* key not found */ + } + } else { /* ADN_NICKNAME */ + sid = (short)cred->adc_nickname; + if (sid < 0 || sid >= AUTHDES_CACHESZ) { + debug("bad nickname"); + return (AUTH_BADCRED); /* garbled credential */ + } + sessionkey = &authdes_cache[sid].key; + } + + + /* + * Decrypt the timestamp + */ + cryptbuf[0] = verf.adv_xtimestamp; + if (cred->adc_namekind == ADN_FULLNAME) { + cryptbuf[1].key.high = cred->adc_fullname.window; + cryptbuf[1].key.low = verf.adv_winverf; + ivec.key.high = ivec.key.low = 0; + status = cbc_crypt((char *)sessionkey, (char *)cryptbuf, + 2*sizeof(des_block), DES_DECRYPT | DES_HW, + (char *)&ivec); + } else { + status = ecb_crypt((char *)sessionkey, (char *)cryptbuf, + sizeof(des_block), DES_DECRYPT | DES_HW); + } + if (DES_FAILED(status)) { + debug("decryption failure"); + return (AUTH_FAILED); /* system error */ + } + + /* + * XDR the decrypted timestamp + */ + ixdr = (long *)cryptbuf; + timestamp.tv_sec = IXDR_GET_LONG(ixdr); + timestamp.tv_usec = IXDR_GET_LONG(ixdr); + + /* + * Check for valid credentials and verifiers. + * They could be invalid because the key was flushed + * out of the cache, and so a new session should begin. + * Be sure and send AUTH_REJECTED{CRED, VERF} if this is the case. + */ + { + struct timeval current; + int nick; + int winverf; + + if (cred->adc_namekind == ADN_FULLNAME) { + window = IXDR_GET_U_LONG(ixdr); + winverf = IXDR_GET_U_LONG(ixdr); + if (winverf != window - 1) { + debug("window verifier mismatch"); + return (AUTH_BADCRED); /* garbled credential */ + } + sid = cache_spot(sessionkey, cred->adc_fullname.name, + ×tamp); + if (sid < 0) { + debug("replayed credential"); + return (AUTH_REJECTEDCRED); /* replay */ + } + nick = 0; + } else { /* ADN_NICKNAME */ + window = authdes_cache[sid].window; + nick = 1; + } + + if ((u_long)timestamp.tv_usec >= USEC_PER_SEC) { + debug("invalid usecs"); + /* cached out (bad key), or garbled verifier */ + return (nick ? AUTH_REJECTEDVERF : AUTH_BADVERF); + } + if (nick && BEFORE(×tamp, + &authdes_cache[sid].laststamp)) { + debug("timestamp before last seen"); + return (AUTH_REJECTEDVERF); /* replay */ + } + (void)gettimeofday(¤t, NULL); + current.tv_sec -= window; /* allow for expiration */ + if (!BEFORE(¤t, ×tamp)) { + debug("timestamp expired"); + /* replay, or garbled credential */ + return (nick ? AUTH_REJECTEDVERF : AUTH_BADCRED); + } + } + + /* + * Set up the reply verifier + */ + verf.adv_nickname = (u_long)sid; + + /* + * xdr the timestamp before encrypting + */ + ixdr = (long *)cryptbuf; + IXDR_PUT_LONG(ixdr, timestamp.tv_sec - 1); + IXDR_PUT_LONG(ixdr, timestamp.tv_usec); + + /* + * encrypt the timestamp + */ + status = ecb_crypt((char *)sessionkey, (char *)cryptbuf, + sizeof(des_block), DES_ENCRYPT | DES_HW); + if (DES_FAILED(status)) { + debug("encryption failure"); + return (AUTH_FAILED); /* system error */ + } + verf.adv_xtimestamp = cryptbuf[0]; + + /* + * Serialize the reply verifier, and update rqst + */ + ixdr = (long *)msg->rm_call.cb_verf.oa_base; + *ixdr++ = (long)verf.adv_xtimestamp.key.high; + *ixdr++ = (long)verf.adv_xtimestamp.key.low; + *ixdr++ = (long)verf.adv_int_u; + + rqst->rq_xprt->xp_verf.oa_flavor = AUTH_DES; + rqst->rq_xprt->xp_verf.oa_base = msg->rm_call.cb_verf.oa_base; + rqst->rq_xprt->xp_verf.oa_length = + (char *)ixdr - msg->rm_call.cb_verf.oa_base; + + /* + * We succeeded, commit the data to the cache now and + * finish cooking the credential. + */ + entry = &authdes_cache[sid]; + entry->laststamp = timestamp; + cache_ref(sid); + if (cred->adc_namekind == ADN_FULLNAME) { + cred->adc_fullname.window = window; + cred->adc_nickname = (u_long)sid; /* save nickname */ + if (entry->rname != NULL) { + mem_free(entry->rname, strlen(entry->rname) + 1); + } + entry->rname = (char *)mem_alloc((u_int)strlen(cred->adc_fullname.name) + + 1); + if (entry->rname != NULL) { + (void) strcpy(entry->rname, cred->adc_fullname.name); + } else { + debug("out of memory"); + } + entry->key = *sessionkey; + entry->window = window; + invalidate(entry->localcred); /* mark any cached cred invalid */ + } else { /* ADN_NICKNAME */ + /* + * nicknames are cooked into fullnames + */ + cred->adc_namekind = ADN_FULLNAME; + cred->adc_fullname.name = entry->rname; + cred->adc_fullname.key = entry->key; + cred->adc_fullname.window = entry->window; + } + return (AUTH_OK); /* we made it!*/ } -__sym_compat(_svcauth_des, __svcauth_des, FBSD_1.0); /* + * Initialize the cache + */ +static void +cache_init(void) +{ + int i; + + authdes_cache = (struct cache_entry *) + mem_alloc(sizeof(struct cache_entry) * AUTHDES_CACHESZ); + bzero((char *)authdes_cache, + sizeof(struct cache_entry) * AUTHDES_CACHESZ); + + authdes_lru = (short *)mem_alloc(sizeof(short) * AUTHDES_CACHESZ); + /* + * Initialize the lru list + */ + for (i = 0; i < AUTHDES_CACHESZ; i++) { + authdes_lru[i] = i; + } +} + + +/* + * Find the lru victim + */ +static short +cache_victim(void) +{ + return (authdes_lru[AUTHDES_CACHESZ-1]); +} + +/* + * Note that sid was referenced + */ +static void +cache_ref(short sid) +{ + int i; + short curr; + short prev; + + prev = authdes_lru[0]; + authdes_lru[0] = sid; + for (i = 1; prev != sid; i++) { + curr = authdes_lru[i]; + authdes_lru[i] = prev; + prev = curr; + } +} + + +/* + * Find a spot in the cache for a credential containing + * the items given. Return -1 if a replay is detected, otherwise + * return the spot in the cache. + */ +static short +cache_spot(des_block *key, char *name, struct timeval *timestamp) +{ + struct cache_entry *cp; + int i; + u_long hi; + + hi = key->key.high; + for (cp = authdes_cache, i = 0; i < AUTHDES_CACHESZ; i++, cp++) { + if (cp->key.key.high == hi && + cp->key.key.low == key->key.low && + cp->rname != NULL && + bcmp(cp->rname, name, strlen(name) + 1) == 0) { + if (BEFORE(timestamp, &cp->laststamp)) { + svcauthdes_stats.ncachereplays++; + return (-1); /* replay */ + } + svcauthdes_stats.ncachehits++; + return (i); /* refresh */ + } + } + svcauthdes_stats.ncachemisses++; + return (cache_victim()); /* new credential */ +} + + +#if (defined(sun) || defined(vax) || defined(__FreeBSD__)) +/* + * Local credential handling stuff. + * NOTE: bsd unix dependent. + * Other operating systems should put something else here. + */ +#define UNKNOWN -2 /* grouplen, if cached cred is unknown user */ +#define INVALID -1 /* grouplen, if cache entry is invalid */ + +struct bsdcred { + uid_t uid; /* cached uid */ + gid_t gid; /* cached gid */ + int grouplen; /* length of cached groups */ + gid_t groups[NGRPS]; /* cached groups */ +}; + +/* * Map a des credential into a unix cred. * We cache the credential here so the application does * not have to make an rpc call every time to interpret * the credential. */ -static int -__authdes_getucred(void *adc, uid_t *uid, gid_t *gid, +int +authdes_getucred(struct authdes_cred *adc, uid_t *uid, gid_t *gid, int *grouplen, gid_t *groups) { - return (0); + unsigned sid; + int i; + uid_t i_uid; + gid_t i_gid; + int i_grouplen; + struct bsdcred *cred; + + sid = adc->adc_nickname; + if (sid >= AUTHDES_CACHESZ) { + debug("invalid nickname"); + return (0); + } + cred = (struct bsdcred *)authdes_cache[sid].localcred; + if (cred == NULL) { + cred = (struct bsdcred *)mem_alloc(sizeof(struct bsdcred)); + authdes_cache[sid].localcred = (char *)cred; + cred->grouplen = INVALID; + } + if (cred->grouplen == INVALID) { + /* + * not in cache: lookup + */ + if (!netname2user(adc->adc_fullname.name, &i_uid, &i_gid, + &i_grouplen, groups)) + { + debug("unknown netname"); + cred->grouplen = UNKNOWN; /* mark as lookup up, but not found */ + return (0); + } + debug("missed ucred cache"); + *uid = cred->uid = i_uid; + *gid = cred->gid = i_gid; + *grouplen = cred->grouplen = i_grouplen; + for (i = i_grouplen - 1; i >= 0; i--) { + cred->groups[i] = groups[i]; /* int to short */ + } + return (1); + } else if (cred->grouplen == UNKNOWN) { + /* + * Already lookup up, but no match found + */ + return (0); + } + + /* + * cached credentials + */ + *uid = cred->uid; + *gid = cred->gid; + *grouplen = cred->grouplen; + for (i = cred->grouplen - 1; i >= 0; i--) { + groups[i] = cred->groups[i]; /* short to int */ + } + return (1); +} + +static void +invalidate(char *cred) +{ + if (cred == NULL) { + return; + } + ((struct bsdcred *)cred)->grouplen = INVALID; } -__sym_compat(authdes_getucred, __authdes_getucred, FBSD_1.0); +#endif + diff --git a/lib/libc/stdlib/Makefile.inc b/lib/libc/stdlib/Makefile.inc index ca199a669be1..e7b9955b9646 100644 --- a/lib/libc/stdlib/Makefile.inc +++ b/lib/libc/stdlib/Makefile.inc @@ -10,7 +10,7 @@ MISRCS+=C99_Exit.c a64l.c abort.c abs.c atexit.c atof.c atoi.c atol.c atoll.c \ insque.c l64a.c labs.c ldiv.c llabs.c lldiv.c lsearch.c \ merge.c mergesort_b.c ptsname.c qsort.c qsort_r.c qsort_r_compat.c \ qsort_s.c quick_exit.c radixsort.c rand.c \ - random.c reallocarray.c reallocf.c realpath.c remque.c \ + random.c reallocarray.c reallocf.c realpath.c recallocarray.c remque.c \ set_constraint_handler_s.c strfmon.c strtoimax.c \ strtol.c strtold.c strtoll.c strtoq.c strtoul.c strtonum.c strtoull.c \ strtoumax.c strtouq.c system.c tdelete.c tfind.c tsearch.c twalk.c @@ -76,6 +76,7 @@ MLINKS+=random.3 initstate.3 \ random.3 srandom.3 \ random.3 srandomdev.3 MLINKS+=radixsort.3 sradixsort.3 +MLINKS+=reallocarray.3 recallocarray.3 MLINKS+=set_constraint_handler_s.3 abort_handler_s.3 MLINKS+=set_constraint_handler_s.3 ignore_handler_s.3 MLINKS+=strfmon.3 strfmon_l.3 diff --git a/lib/libc/stdlib/Symbol.map b/lib/libc/stdlib/Symbol.map index 2b79ca2ece8b..53d71bcafb7d 100644 --- a/lib/libc/stdlib/Symbol.map +++ b/lib/libc/stdlib/Symbol.map @@ -131,6 +131,10 @@ FBSD_1.8 { getenv_r; }; +FBSD_1.9 { + recallocarray; +}; + FBSDprivate_1.0 { __system; _system; diff --git a/lib/libc/stdlib/malloc/jemalloc/Makefile.inc b/lib/libc/stdlib/malloc/jemalloc/Makefile.inc index c10d79dbce6c..7722a7b755f3 100644 --- a/lib/libc/stdlib/malloc/jemalloc/Makefile.inc +++ b/lib/libc/stdlib/malloc/jemalloc/Makefile.inc @@ -1,15 +1,21 @@ .PATH: ${LIBC_SRCTOP}/stdlib/malloc/jemalloc JEMALLOCSRCS:= jemalloc.c arena.c background_thread.c base.c bin.c bitmap.c \ - ckh.c ctl.c div.c extent.c extent_dss.c extent_mmap.c hash.c hook.c \ - large.c log.c malloc_io.c mutex.c mutex_pool.c nstime.c pages.c \ - prng.c prof.c rtree.c safety_check.c sc.c stats.c sz.c tcache.c \ - test_hooks.c ticker.c tsd.c witness.c + ckh.c ctl.c div.c extent.c extent_dss.c extent_mmap.c hook.c \ + large.c log.c malloc_io.c mutex.c nstime.c pages.c \ + prof.c rtree.c safety_check.c sc.c stats.c sz.c tcache.c \ + test_hooks.c ticker.c tsd.c witness.c \ + bin_info.c san.c san_bump.c counter.c prof_data.c prof_log.c prof_recent.c prof_stats.c prof_sys.c \ + emap.c edata.c edata_cache.c pa.c pa_extra.c pac.c decay.c hpa.c hpa_hooks.c fxp.c hpdata.c pai.c \ + ecache.c ehooks.c eset.c sec.c cache_bin.c peak_event.c psset.c inspect.c exp_grow.c thread_event.c \ + buf_writer.c CFLAGS+=-I${SRCTOP}/contrib/jemalloc/include -I${LIBC_SRCTOP}/stdlib/malloc/jemalloc/include .if ${MK_JEMALLOC_LG_VADDR_WIDE} != no CFLAGS+=-D_USE_LG_VADDR_WIDE .endif +CFLAGS.gcc+=-Wno-error=missing-braces + .for src in ${JEMALLOCSRCS} MISRCS+=jemalloc_${src} diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h index 1aedb916976b..900ae867f321 100644 --- a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_internal_defs.h @@ -45,17 +45,17 @@ #define LG_VADDR 48 /* Defined if C11 atomics are available. */ -#define JEMALLOC_C11_ATOMICS 1 +#define JEMALLOC_C11_ATOMICS /* Defined if GCC __atomic atomics are available. */ -#define JEMALLOC_GCC_ATOMIC_ATOMICS 1 +#define JEMALLOC_GCC_ATOMIC_ATOMICS /* and the 8-bit variant support. */ -#define JEMALLOC_GCC_U8_ATOMIC_ATOMICS 1 +#define JEMALLOC_GCC_U8_ATOMIC_ATOMICS /* Defined if GCC __sync atomics are available. */ -#define JEMALLOC_GCC_SYNC_ATOMICS 1 +#define JEMALLOC_GCC_SYNC_ATOMICS /* and the 8-bit variant support. */ -#define JEMALLOC_GCC_U8_SYNC_ATOMICS 1 +#define JEMALLOC_GCC_U8_SYNC_ATOMICS /* * Defined if __builtin_clz() and __builtin_clzl() are available. @@ -73,7 +73,7 @@ /* * Defined if secure_getenv(3) is available. */ -/* #undef JEMALLOC_HAVE_SECURE_GETENV */ +#define JEMALLOC_HAVE_SECURE_GETENV /* * Defined if issetugid(2) is available. @@ -84,17 +84,23 @@ #define JEMALLOC_HAVE_PTHREAD_ATFORK /* Defined if pthread_setname_np(3) is available. */ -/* #undef JEMALLOC_HAVE_PTHREAD_SETNAME_NP */ +#define JEMALLOC_HAVE_PTHREAD_SETNAME_NP + +/* Defined if pthread_getname_np(3) is available. */ +#define JEMALLOC_HAVE_PTHREAD_GETNAME_NP + +/* Defined if pthread_get_name_np(3) is available. */ +#define JEMALLOC_HAVE_PTHREAD_GET_NAME_NP /* * Defined if clock_gettime(CLOCK_MONOTONIC_COARSE, ...) is available. */ -/* #undef JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE */ +#define JEMALLOC_HAVE_CLOCK_MONOTONIC_COARSE /* * Defined if clock_gettime(CLOCK_MONOTONIC, ...) is available. */ -#define JEMALLOC_HAVE_CLOCK_MONOTONIC 1 +#define JEMALLOC_HAVE_CLOCK_MONOTONIC /* * Defined if mach_absolute_time() is available. @@ -102,6 +108,11 @@ /* #undef JEMALLOC_HAVE_MACH_ABSOLUTE_TIME */ /* + * Defined if clock_gettime(CLOCK_REALTIME, ...) is available. + */ +#define JEMALLOC_HAVE_CLOCK_REALTIME + +/* * Defined if _malloc_thread_cleanup() exists. At least in the case of * FreeBSD, pthread_key_create() allocates, which if used during malloc * bootstrapping will cause recursion into the pthreads library. Therefore, if @@ -122,7 +133,7 @@ * _pthread_mutex_init_calloc_cb(), in which case the function is used in order * to avoid recursive allocation during mutex initialization. */ -#define JEMALLOC_MUTEX_INIT_CB 1 +#define JEMALLOC_MUTEX_INIT_CB /* Non-empty if the tls_model attribute is supported. */ #define JEMALLOC_TLS_MODEL __attribute__((tls_model("initial-exec"))) @@ -163,6 +174,9 @@ /* Support utrace(2)-based tracing. */ #define JEMALLOC_UTRACE +/* Support utrace(2)-based tracing (label based signature). */ +/* #undef JEMALLOC_UTRACE_LABEL */ + /* Support optional abort() on OOM. */ #define JEMALLOC_XMALLOC @@ -178,6 +192,9 @@ /* One page is 2^LG_PAGE bytes. */ #define LG_PAGE 12 +/* Maximum number of regions in a slab. */ +/* #undef CONFIG_LG_SLAB_MAXREGS */ + /* * One huge page is 2^LG_HUGEPAGE bytes. Note that this is defined even if the * system does not explicitly support huge pages; system calls that require @@ -292,16 +309,45 @@ /* #undef JEMALLOC_MADVISE_DONTDUMP */ /* + * Defined if MADV_[NO]CORE is supported as an argument to madvise. + */ +#define JEMALLOC_MADVISE_NOCORE + +/* Defined if mprotect(2) is available. */ +#define JEMALLOC_HAVE_MPROTECT + +/* * Defined if transparent huge pages (THPs) are supported via the * MADV_[NO]HUGEPAGE arguments to madvise(2), and THP support is enabled. */ /* #undef JEMALLOC_THP */ +/* Defined if posix_madvise is available. */ +/* #undef JEMALLOC_HAVE_POSIX_MADVISE */ + +/* + * Method for purging unused pages using posix_madvise. + * + * posix_madvise(..., POSIX_MADV_DONTNEED) + */ +/* #undef JEMALLOC_PURGE_POSIX_MADVISE_DONTNEED */ +/* #undef JEMALLOC_PURGE_POSIX_MADVISE_DONTNEED_ZEROS */ + +/* + * Defined if memcntl page admin call is supported + */ +/* #undef JEMALLOC_HAVE_MEMCNTL */ + +/* + * Defined if malloc_size is supported + */ +/* #undef JEMALLOC_HAVE_MALLOC_SIZE */ + /* Define if operating system has alloca.h header. */ /* #undef JEMALLOC_HAS_ALLOCA_H */ /* C99 restrict keyword supported. */ -#define JEMALLOC_HAS_RESTRICT 1 +#define JEMALLOC_HAS_RESTRICT /* For use by hash code. */ /* #undef JEMALLOC_BIG_ENDIAN */ @@ -334,15 +380,15 @@ #define JEMALLOC_HAVE_PTHREAD_MUTEX_ADAPTIVE_NP /* GNU specific sched_getcpu support */ -/* #undef JEMALLOC_HAVE_SCHED_GETCPU */ +#define JEMALLOC_HAVE_SCHED_GETCPU /* GNU specific sched_setaffinity support */ -/* #undef JEMALLOC_HAVE_SCHED_SETAFFINITY */ +#define JEMALLOC_HAVE_SCHED_SETAFFINITY /* * If defined, all the features necessary for background threads are present. */ -#define JEMALLOC_BACKGROUND_THREAD 1 +#define JEMALLOC_BACKGROUND_THREAD /* * If defined, jemalloc symbols are not exported (doesn't work when @@ -354,7 +400,7 @@ #define JEMALLOC_CONFIG_MALLOC_CONF "abort_conf:false" /* If defined, jemalloc takes the malloc/free/etc. symbol names. */ -#define JEMALLOC_IS_MALLOC 1 +#define JEMALLOC_IS_MALLOC /* * Defined if strerror_r returns char * if _GNU_SOURCE is defined. @@ -364,4 +410,19 @@ /* Performs additional safety checks when defined. */ /* #undef JEMALLOC_OPT_SAFETY_CHECKS */ +/* Is C++ support being built? */ +#define JEMALLOC_ENABLE_CXX + +/* Performs additional size checks when defined. */ +/* #undef JEMALLOC_OPT_SIZE_CHECKS */ + +/* Allows sampled junk and stash for checking use-after-free when defined. */ +/* #undef JEMALLOC_UAF_DETECTION */ + +/* Darwin VM_MAKE_TAG support */ +/* #undef JEMALLOC_HAVE_VM_MAKE_TAG */ + +/* If defined, realloc(ptr, 0) defaults to "free" instead of "alloc". */ +/* #undef JEMALLOC_ZERO_REALLOC_DEFAULT_FREE */ + #endif /* JEMALLOC_INTERNAL_DEFS_H_ */ diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_preamble.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_preamble.h index d1dcc50d5a3b..b6cf5864109d 100644 --- a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_preamble.h +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/jemalloc_preamble.h @@ -4,12 +4,20 @@ #include "jemalloc_internal_defs.h" #include "jemalloc/internal/jemalloc_internal_decls.h" -#ifdef JEMALLOC_UTRACE +#if defined(JEMALLOC_UTRACE) || defined(JEMALLOC_UTRACE_LABEL) #include <sys/ktrace.h> +# if defined(JEMALLOC_UTRACE) +# define UTRACE_CALL(p, l) utrace(p, l) +# else +# define UTRACE_CALL(p, l) utrace("jemalloc_process", p, l) +# define JEMALLOC_UTRACE +# endif #endif +#ifndef JEMALLOC_PRIVATE_NAMESPACE #include "un-namespace.h" #include "libc_private.h" +#endif #define JEMALLOC_NO_DEMANGLE #ifdef JEMALLOC_JET @@ -177,6 +185,35 @@ static const bool config_opt_safety_checks = #endif ; +/* + * Extra debugging of sized deallocations too onerous to be included in the + * general safety checks. + */ +static const bool config_opt_size_checks = +#if defined(JEMALLOC_OPT_SIZE_CHECKS) || defined(JEMALLOC_DEBUG) + true +#else + false +#endif + ; + +static const bool config_uaf_detection = +#if defined(JEMALLOC_UAF_DETECTION) || defined(JEMALLOC_DEBUG) + true +#else + false +#endif + ; + +/* Whether or not the C++ extensions are enabled. */ +static const bool config_enable_cxx = +#ifdef JEMALLOC_ENABLE_CXX + true +#else + false +#endif +; + #if defined(_WIN32) || defined(JEMALLOC_HAVE_SCHED_GETCPU) /* Currently percpu_arena depends on sched_getcpu. */ #define JEMALLOC_PERCPU_ARENA @@ -206,5 +243,20 @@ static const bool have_background_thread = false #endif ; +static const bool config_high_res_timer = +#ifdef JEMALLOC_HAVE_CLOCK_REALTIME + true +#else + false +#endif + ; + +static const bool have_memcntl = +#ifdef JEMALLOC_HAVE_MEMCNTL + true +#else + false +#endif + ; #endif /* JEMALLOC_PREAMBLE_H */ diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/private_namespace.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/private_namespace.h index a448ad63fa54..08ce9219cbf8 100644 --- a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/private_namespace.h +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/private_namespace.h @@ -5,10 +5,9 @@ #define arena_init JEMALLOC_N(arena_init) #define arena_migrate JEMALLOC_N(arena_migrate) #define arena_set JEMALLOC_N(arena_set) -#define arena_tdata_get_hard JEMALLOC_N(arena_tdata_get_hard) #define arenas JEMALLOC_N(arenas) #define arenas_lock JEMALLOC_N(arenas_lock) -#define arenas_tdata_cleanup JEMALLOC_N(arenas_tdata_cleanup) +#define batch_alloc JEMALLOC_N(batch_alloc) #define bootstrap_calloc JEMALLOC_N(bootstrap_calloc) #define bootstrap_free JEMALLOC_N(bootstrap_free) #define bootstrap_malloc JEMALLOC_N(bootstrap_malloc) @@ -16,8 +15,10 @@ #define iarena_cleanup JEMALLOC_N(iarena_cleanup) #define je_sdallocx_noflags JEMALLOC_N(je_sdallocx_noflags) #define jemalloc_postfork_child JEMALLOC_N(jemalloc_postfork_child) +#define junk_alloc_callback JEMALLOC_N(junk_alloc_callback) +#define junk_free_callback JEMALLOC_N(junk_free_callback) #define malloc_default JEMALLOC_N(malloc_default) -#define malloc_initialized JEMALLOC_N(malloc_initialized) +#define malloc_init_state JEMALLOC_N(malloc_init_state) #define malloc_slow JEMALLOC_N(malloc_slow) #define manual_arena_base JEMALLOC_N(manual_arena_base) #define narenas_auto JEMALLOC_N(narenas_auto) @@ -25,49 +26,64 @@ #define ncpus JEMALLOC_N(ncpus) #define opt_abort JEMALLOC_N(opt_abort) #define opt_abort_conf JEMALLOC_N(opt_abort_conf) +#define opt_cache_oblivious JEMALLOC_N(opt_cache_oblivious) #define opt_confirm_conf JEMALLOC_N(opt_confirm_conf) +#define opt_experimental_infallible_new JEMALLOC_N(opt_experimental_infallible_new) +#define opt_hpa JEMALLOC_N(opt_hpa) +#define opt_hpa_opts JEMALLOC_N(opt_hpa_opts) +#define opt_hpa_sec_opts JEMALLOC_N(opt_hpa_sec_opts) #define opt_junk JEMALLOC_N(opt_junk) #define opt_junk_alloc JEMALLOC_N(opt_junk_alloc) #define opt_junk_free JEMALLOC_N(opt_junk_free) #define opt_narenas JEMALLOC_N(opt_narenas) +#define opt_narenas_ratio JEMALLOC_N(opt_narenas_ratio) +#define opt_trust_madvise JEMALLOC_N(opt_trust_madvise) #define opt_utrace JEMALLOC_N(opt_utrace) #define opt_xmalloc JEMALLOC_N(opt_xmalloc) #define opt_zero JEMALLOC_N(opt_zero) +#define opt_zero_realloc_action JEMALLOC_N(opt_zero_realloc_action) #define sdallocx_default JEMALLOC_N(sdallocx_default) -#define arena_alloc_junk_small JEMALLOC_N(arena_alloc_junk_small) +#define zero_realloc_count JEMALLOC_N(zero_realloc_count) +#define zero_realloc_mode_names JEMALLOC_N(zero_realloc_mode_names) #define arena_basic_stats_merge JEMALLOC_N(arena_basic_stats_merge) -#define arena_bin_choose_lock JEMALLOC_N(arena_bin_choose_lock) +#define arena_bin_choose JEMALLOC_N(arena_bin_choose) +#define arena_bin_offsets JEMALLOC_N(arena_bin_offsets) +#define arena_binind_div_info JEMALLOC_N(arena_binind_div_info) #define arena_boot JEMALLOC_N(arena_boot) +#define arena_cache_bin_fill_small JEMALLOC_N(arena_cache_bin_fill_small) #define arena_choose_huge JEMALLOC_N(arena_choose_huge) -#define arena_dalloc_bin_junked_locked JEMALLOC_N(arena_dalloc_bin_junked_locked) -#define arena_dalloc_junk_small JEMALLOC_N(arena_dalloc_junk_small) +#define arena_config_default JEMALLOC_N(arena_config_default) +#define arena_dalloc_bin_locked_handle_newly_empty JEMALLOC_N(arena_dalloc_bin_locked_handle_newly_empty) +#define arena_dalloc_bin_locked_handle_newly_nonempty JEMALLOC_N(arena_dalloc_bin_locked_handle_newly_nonempty) #define arena_dalloc_promoted JEMALLOC_N(arena_dalloc_promoted) #define arena_dalloc_small JEMALLOC_N(arena_dalloc_small) #define arena_decay JEMALLOC_N(arena_decay) +#define arena_decay_ms_get JEMALLOC_N(arena_decay_ms_get) +#define arena_decay_ms_set JEMALLOC_N(arena_decay_ms_set) #define arena_destroy JEMALLOC_N(arena_destroy) #define arena_dirty_decay_ms_default_get JEMALLOC_N(arena_dirty_decay_ms_default_get) #define arena_dirty_decay_ms_default_set JEMALLOC_N(arena_dirty_decay_ms_default_set) -#define arena_dirty_decay_ms_get JEMALLOC_N(arena_dirty_decay_ms_get) -#define arena_dirty_decay_ms_set JEMALLOC_N(arena_dirty_decay_ms_set) +#define arena_do_deferred_work JEMALLOC_N(arena_do_deferred_work) #define arena_dss_prec_get JEMALLOC_N(arena_dss_prec_get) #define arena_dss_prec_set JEMALLOC_N(arena_dss_prec_set) +#define arena_emap_global JEMALLOC_N(arena_emap_global) #define arena_extent_alloc_large JEMALLOC_N(arena_extent_alloc_large) #define arena_extent_dalloc_large_prep JEMALLOC_N(arena_extent_dalloc_large_prep) #define arena_extent_ralloc_large_expand JEMALLOC_N(arena_extent_ralloc_large_expand) #define arena_extent_ralloc_large_shrink JEMALLOC_N(arena_extent_ralloc_large_shrink) -#define arena_extent_sn_next JEMALLOC_N(arena_extent_sn_next) -#define arena_extents_dirty_dalloc JEMALLOC_N(arena_extents_dirty_dalloc) +#define arena_fill_small_fresh JEMALLOC_N(arena_fill_small_fresh) +#define arena_get_ehooks JEMALLOC_N(arena_get_ehooks) +#define arena_handle_deferred_work JEMALLOC_N(arena_handle_deferred_work) #define arena_init_huge JEMALLOC_N(arena_init_huge) #define arena_is_huge JEMALLOC_N(arena_is_huge) #define arena_malloc_hard JEMALLOC_N(arena_malloc_hard) #define arena_muzzy_decay_ms_default_get JEMALLOC_N(arena_muzzy_decay_ms_default_get) #define arena_muzzy_decay_ms_default_set JEMALLOC_N(arena_muzzy_decay_ms_default_set) -#define arena_muzzy_decay_ms_get JEMALLOC_N(arena_muzzy_decay_ms_get) -#define arena_muzzy_decay_ms_set JEMALLOC_N(arena_muzzy_decay_ms_set) #define arena_new JEMALLOC_N(arena_new) #define arena_nthreads_dec JEMALLOC_N(arena_nthreads_dec) #define arena_nthreads_get JEMALLOC_N(arena_nthreads_get) #define arena_nthreads_inc JEMALLOC_N(arena_nthreads_inc) +#define arena_pa_central_global JEMALLOC_N(arena_pa_central_global) #define arena_palloc JEMALLOC_N(arena_palloc) #define arena_postfork_child JEMALLOC_N(arena_postfork_child) #define arena_postfork_parent JEMALLOC_N(arena_postfork_parent) @@ -79,14 +95,15 @@ #define arena_prefork5 JEMALLOC_N(arena_prefork5) #define arena_prefork6 JEMALLOC_N(arena_prefork6) #define arena_prefork7 JEMALLOC_N(arena_prefork7) +#define arena_prefork8 JEMALLOC_N(arena_prefork8) #define arena_prof_promote JEMALLOC_N(arena_prof_promote) #define arena_ralloc JEMALLOC_N(arena_ralloc) #define arena_ralloc_no_move JEMALLOC_N(arena_ralloc_no_move) #define arena_reset JEMALLOC_N(arena_reset) #define arena_retain_grow_limit_get_set JEMALLOC_N(arena_retain_grow_limit_get_set) +#define arena_set_extent_hooks JEMALLOC_N(arena_set_extent_hooks) +#define arena_slab_dalloc JEMALLOC_N(arena_slab_dalloc) #define arena_stats_merge JEMALLOC_N(arena_stats_merge) -#define arena_tcache_fill_small JEMALLOC_N(arena_tcache_fill_small) -#define h_steps JEMALLOC_N(h_steps) #define opt_dirty_decay_ms JEMALLOC_N(opt_dirty_decay_ms) #define opt_muzzy_decay_ms JEMALLOC_N(opt_muzzy_decay_ms) #define opt_oversize_threshold JEMALLOC_N(opt_oversize_threshold) @@ -99,13 +116,14 @@ #define background_thread_ctl_init JEMALLOC_N(background_thread_ctl_init) #define background_thread_enabled_state JEMALLOC_N(background_thread_enabled_state) #define background_thread_info JEMALLOC_N(background_thread_info) -#define background_thread_interval_check JEMALLOC_N(background_thread_interval_check) +#define background_thread_is_started JEMALLOC_N(background_thread_is_started) #define background_thread_lock JEMALLOC_N(background_thread_lock) #define background_thread_postfork_child JEMALLOC_N(background_thread_postfork_child) #define background_thread_postfork_parent JEMALLOC_N(background_thread_postfork_parent) #define background_thread_prefork0 JEMALLOC_N(background_thread_prefork0) #define background_thread_prefork1 JEMALLOC_N(background_thread_prefork1) #define background_thread_stats_read JEMALLOC_N(background_thread_stats_read) +#define background_thread_wakeup_early JEMALLOC_N(background_thread_wakeup_early) #define background_threads_disable JEMALLOC_N(background_threads_disable) #define background_threads_enable JEMALLOC_N(background_threads_enable) #define max_background_threads JEMALLOC_N(max_background_threads) @@ -115,10 +133,11 @@ #define pthread_create_wrapper JEMALLOC_N(pthread_create_wrapper) #define b0get JEMALLOC_N(b0get) #define base_alloc JEMALLOC_N(base_alloc) -#define base_alloc_extent JEMALLOC_N(base_alloc_extent) +#define base_alloc_edata JEMALLOC_N(base_alloc_edata) #define base_boot JEMALLOC_N(base_boot) #define base_delete JEMALLOC_N(base_delete) -#define base_extent_hooks_get JEMALLOC_N(base_extent_hooks_get) +#define base_ehooks_get JEMALLOC_N(base_ehooks_get) +#define base_ehooks_get_for_metadata JEMALLOC_N(base_ehooks_get_for_metadata) #define base_extent_hooks_set JEMALLOC_N(base_extent_hooks_set) #define base_new JEMALLOC_N(base_new) #define base_postfork_child JEMALLOC_N(base_postfork_child) @@ -127,17 +146,28 @@ #define base_stats_get JEMALLOC_N(base_stats_get) #define metadata_thp_mode_names JEMALLOC_N(metadata_thp_mode_names) #define opt_metadata_thp JEMALLOC_N(opt_metadata_thp) -#define bin_boot JEMALLOC_N(bin_boot) -#define bin_infos JEMALLOC_N(bin_infos) #define bin_init JEMALLOC_N(bin_init) #define bin_postfork_child JEMALLOC_N(bin_postfork_child) #define bin_postfork_parent JEMALLOC_N(bin_postfork_parent) #define bin_prefork JEMALLOC_N(bin_prefork) #define bin_shard_sizes_boot JEMALLOC_N(bin_shard_sizes_boot) #define bin_update_shard_size JEMALLOC_N(bin_update_shard_size) +#define bin_info_boot JEMALLOC_N(bin_info_boot) +#define bin_infos JEMALLOC_N(bin_infos) #define bitmap_info_init JEMALLOC_N(bitmap_info_init) #define bitmap_init JEMALLOC_N(bitmap_init) #define bitmap_size JEMALLOC_N(bitmap_size) +#define buf_writer_cb JEMALLOC_N(buf_writer_cb) +#define buf_writer_flush JEMALLOC_N(buf_writer_flush) +#define buf_writer_init JEMALLOC_N(buf_writer_init) +#define buf_writer_pipe JEMALLOC_N(buf_writer_pipe) +#define buf_writer_terminate JEMALLOC_N(buf_writer_terminate) +#define cache_bin_info_compute_alloc JEMALLOC_N(cache_bin_info_compute_alloc) +#define cache_bin_info_init JEMALLOC_N(cache_bin_info_init) +#define cache_bin_init JEMALLOC_N(cache_bin_init) +#define cache_bin_postincrement JEMALLOC_N(cache_bin_postincrement) +#define cache_bin_preincrement JEMALLOC_N(cache_bin_preincrement) +#define cache_bin_still_zero_initialized JEMALLOC_N(cache_bin_still_zero_initialized) #define ckh_count JEMALLOC_N(ckh_count) #define ckh_delete JEMALLOC_N(ckh_delete) #define ckh_insert JEMALLOC_N(ckh_insert) @@ -149,61 +179,116 @@ #define ckh_search JEMALLOC_N(ckh_search) #define ckh_string_hash JEMALLOC_N(ckh_string_hash) #define ckh_string_keycomp JEMALLOC_N(ckh_string_keycomp) +#define counter_accum_init JEMALLOC_N(counter_accum_init) +#define counter_postfork_child JEMALLOC_N(counter_postfork_child) +#define counter_postfork_parent JEMALLOC_N(counter_postfork_parent) +#define counter_prefork JEMALLOC_N(counter_prefork) #define ctl_boot JEMALLOC_N(ctl_boot) #define ctl_bymib JEMALLOC_N(ctl_bymib) +#define ctl_bymibname JEMALLOC_N(ctl_bymibname) #define ctl_byname JEMALLOC_N(ctl_byname) +#define ctl_mibnametomib JEMALLOC_N(ctl_mibnametomib) +#define ctl_mtx_assert_held JEMALLOC_N(ctl_mtx_assert_held) #define ctl_nametomib JEMALLOC_N(ctl_nametomib) #define ctl_postfork_child JEMALLOC_N(ctl_postfork_child) #define ctl_postfork_parent JEMALLOC_N(ctl_postfork_parent) #define ctl_prefork JEMALLOC_N(ctl_prefork) +#define decay_deadline_init JEMALLOC_N(decay_deadline_init) +#define decay_init JEMALLOC_N(decay_init) +#define decay_maybe_advance_epoch JEMALLOC_N(decay_maybe_advance_epoch) +#define decay_ms_valid JEMALLOC_N(decay_ms_valid) +#define decay_npages_purge_in JEMALLOC_N(decay_npages_purge_in) +#define decay_ns_until_purge JEMALLOC_N(decay_ns_until_purge) +#define decay_reinit JEMALLOC_N(decay_reinit) #define div_init JEMALLOC_N(div_init) -#define extent_alloc JEMALLOC_N(extent_alloc) +#define ecache_init JEMALLOC_N(ecache_init) +#define ecache_postfork_child JEMALLOC_N(ecache_postfork_child) +#define ecache_postfork_parent JEMALLOC_N(ecache_postfork_parent) +#define ecache_prefork JEMALLOC_N(ecache_prefork) +#define edata_avail_any JEMALLOC_N(edata_avail_any) +#define edata_avail_empty JEMALLOC_N(edata_avail_empty) +#define edata_avail_first JEMALLOC_N(edata_avail_first) +#define edata_avail_insert JEMALLOC_N(edata_avail_insert) +#define edata_avail_new JEMALLOC_N(edata_avail_new) +#define edata_avail_remove JEMALLOC_N(edata_avail_remove) +#define edata_avail_remove_any JEMALLOC_N(edata_avail_remove_any) +#define edata_avail_remove_first JEMALLOC_N(edata_avail_remove_first) +#define edata_heap_any JEMALLOC_N(edata_heap_any) +#define edata_heap_empty JEMALLOC_N(edata_heap_empty) +#define edata_heap_first JEMALLOC_N(edata_heap_first) +#define edata_heap_insert JEMALLOC_N(edata_heap_insert) +#define edata_heap_new JEMALLOC_N(edata_heap_new) +#define edata_heap_remove JEMALLOC_N(edata_heap_remove) +#define edata_heap_remove_any JEMALLOC_N(edata_heap_remove_any) +#define edata_heap_remove_first JEMALLOC_N(edata_heap_remove_first) +#define edata_cache_fast_disable JEMALLOC_N(edata_cache_fast_disable) +#define edata_cache_fast_get JEMALLOC_N(edata_cache_fast_get) +#define edata_cache_fast_init JEMALLOC_N(edata_cache_fast_init) +#define edata_cache_fast_put JEMALLOC_N(edata_cache_fast_put) +#define edata_cache_get JEMALLOC_N(edata_cache_get) +#define edata_cache_init JEMALLOC_N(edata_cache_init) +#define edata_cache_postfork_child JEMALLOC_N(edata_cache_postfork_child) +#define edata_cache_postfork_parent JEMALLOC_N(edata_cache_postfork_parent) +#define edata_cache_prefork JEMALLOC_N(edata_cache_prefork) +#define edata_cache_put JEMALLOC_N(edata_cache_put) +#define ehooks_default_alloc_impl JEMALLOC_N(ehooks_default_alloc_impl) +#define ehooks_default_commit_impl JEMALLOC_N(ehooks_default_commit_impl) +#define ehooks_default_dalloc_impl JEMALLOC_N(ehooks_default_dalloc_impl) +#define ehooks_default_decommit_impl JEMALLOC_N(ehooks_default_decommit_impl) +#define ehooks_default_destroy_impl JEMALLOC_N(ehooks_default_destroy_impl) +#define ehooks_default_extent_hooks JEMALLOC_N(ehooks_default_extent_hooks) +#define ehooks_default_guard_impl JEMALLOC_N(ehooks_default_guard_impl) +#define ehooks_default_merge JEMALLOC_N(ehooks_default_merge) +#define ehooks_default_merge_impl JEMALLOC_N(ehooks_default_merge_impl) +#define ehooks_default_purge_forced_impl JEMALLOC_N(ehooks_default_purge_forced_impl) +#define ehooks_default_purge_lazy_impl JEMALLOC_N(ehooks_default_purge_lazy_impl) +#define ehooks_default_split_impl JEMALLOC_N(ehooks_default_split_impl) +#define ehooks_default_unguard_impl JEMALLOC_N(ehooks_default_unguard_impl) +#define ehooks_default_zero_impl JEMALLOC_N(ehooks_default_zero_impl) +#define ehooks_init JEMALLOC_N(ehooks_init) +#define emap_deregister_boundary JEMALLOC_N(emap_deregister_boundary) +#define emap_deregister_interior JEMALLOC_N(emap_deregister_interior) +#define emap_do_assert_mapped JEMALLOC_N(emap_do_assert_mapped) +#define emap_do_assert_not_mapped JEMALLOC_N(emap_do_assert_not_mapped) +#define emap_init JEMALLOC_N(emap_init) +#define emap_merge_commit JEMALLOC_N(emap_merge_commit) +#define emap_merge_prepare JEMALLOC_N(emap_merge_prepare) +#define emap_register_boundary JEMALLOC_N(emap_register_boundary) +#define emap_register_interior JEMALLOC_N(emap_register_interior) +#define emap_release_edata JEMALLOC_N(emap_release_edata) +#define emap_remap JEMALLOC_N(emap_remap) +#define emap_split_commit JEMALLOC_N(emap_split_commit) +#define emap_split_prepare JEMALLOC_N(emap_split_prepare) +#define emap_try_acquire_edata_neighbor JEMALLOC_N(emap_try_acquire_edata_neighbor) +#define emap_try_acquire_edata_neighbor_expand JEMALLOC_N(emap_try_acquire_edata_neighbor_expand) +#define emap_update_edata_state JEMALLOC_N(emap_update_edata_state) +#define eset_fit JEMALLOC_N(eset_fit) +#define eset_init JEMALLOC_N(eset_init) +#define eset_insert JEMALLOC_N(eset_insert) +#define eset_nbytes_get JEMALLOC_N(eset_nbytes_get) +#define eset_nextents_get JEMALLOC_N(eset_nextents_get) +#define eset_npages_get JEMALLOC_N(eset_npages_get) +#define eset_remove JEMALLOC_N(eset_remove) +#define exp_grow_init JEMALLOC_N(exp_grow_init) +#define ecache_alloc JEMALLOC_N(ecache_alloc) +#define ecache_alloc_grow JEMALLOC_N(ecache_alloc_grow) +#define ecache_dalloc JEMALLOC_N(ecache_dalloc) +#define ecache_evict JEMALLOC_N(ecache_evict) #define extent_alloc_wrapper JEMALLOC_N(extent_alloc_wrapper) -#define extent_avail_any JEMALLOC_N(extent_avail_any) -#define extent_avail_empty JEMALLOC_N(extent_avail_empty) -#define extent_avail_first JEMALLOC_N(extent_avail_first) -#define extent_avail_insert JEMALLOC_N(extent_avail_insert) -#define extent_avail_new JEMALLOC_N(extent_avail_new) -#define extent_avail_remove JEMALLOC_N(extent_avail_remove) -#define extent_avail_remove_any JEMALLOC_N(extent_avail_remove_any) -#define extent_avail_remove_first JEMALLOC_N(extent_avail_remove_first) #define extent_boot JEMALLOC_N(extent_boot) #define extent_commit_wrapper JEMALLOC_N(extent_commit_wrapper) -#define extent_dalloc JEMALLOC_N(extent_dalloc) +#define extent_commit_zero JEMALLOC_N(extent_commit_zero) #define extent_dalloc_gap JEMALLOC_N(extent_dalloc_gap) #define extent_dalloc_wrapper JEMALLOC_N(extent_dalloc_wrapper) #define extent_decommit_wrapper JEMALLOC_N(extent_decommit_wrapper) #define extent_destroy_wrapper JEMALLOC_N(extent_destroy_wrapper) -#define extent_heap_any JEMALLOC_N(extent_heap_any) -#define extent_heap_empty JEMALLOC_N(extent_heap_empty) -#define extent_heap_first JEMALLOC_N(extent_heap_first) -#define extent_heap_insert JEMALLOC_N(extent_heap_insert) -#define extent_heap_new JEMALLOC_N(extent_heap_new) -#define extent_heap_remove JEMALLOC_N(extent_heap_remove) -#define extent_heap_remove_any JEMALLOC_N(extent_heap_remove_any) -#define extent_heap_remove_first JEMALLOC_N(extent_heap_remove_first) -#define extent_hooks_default JEMALLOC_N(extent_hooks_default) -#define extent_hooks_get JEMALLOC_N(extent_hooks_get) -#define extent_hooks_set JEMALLOC_N(extent_hooks_set) +#define extent_gdump_add JEMALLOC_N(extent_gdump_add) #define extent_merge_wrapper JEMALLOC_N(extent_merge_wrapper) -#define extent_mutex_pool JEMALLOC_N(extent_mutex_pool) #define extent_purge_forced_wrapper JEMALLOC_N(extent_purge_forced_wrapper) #define extent_purge_lazy_wrapper JEMALLOC_N(extent_purge_lazy_wrapper) +#define extent_record JEMALLOC_N(extent_record) +#define extent_sn_next JEMALLOC_N(extent_sn_next) #define extent_split_wrapper JEMALLOC_N(extent_split_wrapper) -#define extent_util_stats_get JEMALLOC_N(extent_util_stats_get) -#define extent_util_stats_verbose_get JEMALLOC_N(extent_util_stats_verbose_get) -#define extents_alloc JEMALLOC_N(extents_alloc) -#define extents_dalloc JEMALLOC_N(extents_dalloc) -#define extents_evict JEMALLOC_N(extents_evict) -#define extents_init JEMALLOC_N(extents_init) -#define extents_nbytes_get JEMALLOC_N(extents_nbytes_get) -#define extents_nextents_get JEMALLOC_N(extents_nextents_get) -#define extents_npages_get JEMALLOC_N(extents_npages_get) -#define extents_postfork_child JEMALLOC_N(extents_postfork_child) -#define extents_postfork_parent JEMALLOC_N(extents_postfork_parent) -#define extents_prefork JEMALLOC_N(extents_prefork) -#define extents_rtree JEMALLOC_N(extents_rtree) -#define extents_state_get JEMALLOC_N(extents_state_get) #define opt_lg_extent_max_active_fit JEMALLOC_N(opt_lg_extent_max_active_fit) #define dss_prec_names JEMALLOC_N(dss_prec_names) #define extent_alloc_dss JEMALLOC_N(extent_alloc_dss) @@ -216,24 +301,66 @@ #define extent_alloc_mmap JEMALLOC_N(extent_alloc_mmap) #define extent_dalloc_mmap JEMALLOC_N(extent_dalloc_mmap) #define opt_retain JEMALLOC_N(opt_retain) +#define fxp_parse JEMALLOC_N(fxp_parse) +#define fxp_print JEMALLOC_N(fxp_print) +#define opt_lg_san_uaf_align JEMALLOC_N(opt_lg_san_uaf_align) +#define opt_san_guard_large JEMALLOC_N(opt_san_guard_large) +#define opt_san_guard_small JEMALLOC_N(opt_san_guard_small) +#define san_cache_bin_nonfast_mask JEMALLOC_N(san_cache_bin_nonfast_mask) +#define san_check_stashed_ptrs JEMALLOC_N(san_check_stashed_ptrs) +#define san_guard_pages JEMALLOC_N(san_guard_pages) +#define san_init JEMALLOC_N(san_init) +#define san_unguard_pages JEMALLOC_N(san_unguard_pages) +#define san_unguard_pages_pre_destroy JEMALLOC_N(san_unguard_pages_pre_destroy) +#define tsd_san_init JEMALLOC_N(tsd_san_init) +#define san_bump_alloc JEMALLOC_N(san_bump_alloc) #define hook_boot JEMALLOC_N(hook_boot) #define hook_install JEMALLOC_N(hook_install) #define hook_invoke_alloc JEMALLOC_N(hook_invoke_alloc) #define hook_invoke_dalloc JEMALLOC_N(hook_invoke_dalloc) #define hook_invoke_expand JEMALLOC_N(hook_invoke_expand) #define hook_remove JEMALLOC_N(hook_remove) +#define hpa_central_extract JEMALLOC_N(hpa_central_extract) +#define hpa_central_init JEMALLOC_N(hpa_central_init) +#define hpa_shard_destroy JEMALLOC_N(hpa_shard_destroy) +#define hpa_shard_disable JEMALLOC_N(hpa_shard_disable) +#define hpa_shard_do_deferred_work JEMALLOC_N(hpa_shard_do_deferred_work) +#define hpa_shard_init JEMALLOC_N(hpa_shard_init) +#define hpa_shard_postfork_child JEMALLOC_N(hpa_shard_postfork_child) +#define hpa_shard_postfork_parent JEMALLOC_N(hpa_shard_postfork_parent) +#define hpa_shard_prefork3 JEMALLOC_N(hpa_shard_prefork3) +#define hpa_shard_prefork4 JEMALLOC_N(hpa_shard_prefork4) +#define hpa_shard_set_deferral_allowed JEMALLOC_N(hpa_shard_set_deferral_allowed) +#define hpa_shard_stats_accum JEMALLOC_N(hpa_shard_stats_accum) +#define hpa_shard_stats_merge JEMALLOC_N(hpa_shard_stats_merge) +#define hpa_supported JEMALLOC_N(hpa_supported) +#define hpa_hooks_default JEMALLOC_N(hpa_hooks_default) +#define hpdata_age_heap_any JEMALLOC_N(hpdata_age_heap_any) +#define hpdata_age_heap_empty JEMALLOC_N(hpdata_age_heap_empty) +#define hpdata_age_heap_first JEMALLOC_N(hpdata_age_heap_first) +#define hpdata_age_heap_insert JEMALLOC_N(hpdata_age_heap_insert) +#define hpdata_age_heap_new JEMALLOC_N(hpdata_age_heap_new) +#define hpdata_age_heap_remove JEMALLOC_N(hpdata_age_heap_remove) +#define hpdata_age_heap_remove_any JEMALLOC_N(hpdata_age_heap_remove_any) +#define hpdata_age_heap_remove_first JEMALLOC_N(hpdata_age_heap_remove_first) +#define hpdata_dehugify JEMALLOC_N(hpdata_dehugify) +#define hpdata_hugify JEMALLOC_N(hpdata_hugify) +#define hpdata_init JEMALLOC_N(hpdata_init) +#define hpdata_purge_begin JEMALLOC_N(hpdata_purge_begin) +#define hpdata_purge_end JEMALLOC_N(hpdata_purge_end) +#define hpdata_purge_next JEMALLOC_N(hpdata_purge_next) +#define hpdata_reserve_alloc JEMALLOC_N(hpdata_reserve_alloc) +#define hpdata_unreserve JEMALLOC_N(hpdata_unreserve) +#define inspect_extent_util_stats_get JEMALLOC_N(inspect_extent_util_stats_get) +#define inspect_extent_util_stats_verbose_get JEMALLOC_N(inspect_extent_util_stats_verbose_get) #define large_dalloc JEMALLOC_N(large_dalloc) #define large_dalloc_finish JEMALLOC_N(large_dalloc_finish) -#define large_dalloc_junk JEMALLOC_N(large_dalloc_junk) -#define large_dalloc_maybe_junk JEMALLOC_N(large_dalloc_maybe_junk) -#define large_dalloc_prep_junked_locked JEMALLOC_N(large_dalloc_prep_junked_locked) +#define large_dalloc_prep_locked JEMALLOC_N(large_dalloc_prep_locked) #define large_malloc JEMALLOC_N(large_malloc) #define large_palloc JEMALLOC_N(large_palloc) -#define large_prof_alloc_time_get JEMALLOC_N(large_prof_alloc_time_get) -#define large_prof_alloc_time_set JEMALLOC_N(large_prof_alloc_time_set) -#define large_prof_tctx_get JEMALLOC_N(large_prof_tctx_get) +#define large_prof_info_get JEMALLOC_N(large_prof_info_get) +#define large_prof_info_set JEMALLOC_N(large_prof_info_set) #define large_prof_tctx_reset JEMALLOC_N(large_prof_tctx_reset) -#define large_prof_tctx_set JEMALLOC_N(large_prof_tctx_set) #define large_ralloc JEMALLOC_N(large_ralloc) #define large_ralloc_no_move JEMALLOC_N(large_ralloc_no_move) #define large_salloc JEMALLOC_N(large_salloc) @@ -248,14 +375,17 @@ #define malloc_vcprintf JEMALLOC_N(malloc_vcprintf) #define malloc_vsnprintf JEMALLOC_N(malloc_vsnprintf) #define malloc_write JEMALLOC_N(malloc_write) +#define wrtmessage JEMALLOC_N(wrtmessage) +#define wrtmessage_1_0 JEMALLOC_N(wrtmessage_1_0) #define malloc_mutex_boot JEMALLOC_N(malloc_mutex_boot) +#define malloc_mutex_first_thread JEMALLOC_N(malloc_mutex_first_thread) #define malloc_mutex_init JEMALLOC_N(malloc_mutex_init) #define malloc_mutex_lock_slow JEMALLOC_N(malloc_mutex_lock_slow) #define malloc_mutex_postfork_child JEMALLOC_N(malloc_mutex_postfork_child) #define malloc_mutex_postfork_parent JEMALLOC_N(malloc_mutex_postfork_parent) #define malloc_mutex_prefork JEMALLOC_N(malloc_mutex_prefork) #define malloc_mutex_prof_data_reset JEMALLOC_N(malloc_mutex_prof_data_reset) -#define mutex_pool_init JEMALLOC_N(mutex_pool_init) +#define opt_mutex_max_spin JEMALLOC_N(opt_mutex_max_spin) #define nstime_add JEMALLOC_N(nstime_add) #define nstime_compare JEMALLOC_N(nstime_compare) #define nstime_copy JEMALLOC_N(nstime_copy) @@ -265,14 +395,56 @@ #define nstime_imultiply JEMALLOC_N(nstime_imultiply) #define nstime_init JEMALLOC_N(nstime_init) #define nstime_init2 JEMALLOC_N(nstime_init2) +#define nstime_init_update JEMALLOC_N(nstime_init_update) #define nstime_isubtract JEMALLOC_N(nstime_isubtract) #define nstime_monotonic JEMALLOC_N(nstime_monotonic) #define nstime_msec JEMALLOC_N(nstime_msec) #define nstime_ns JEMALLOC_N(nstime_ns) +#define nstime_ns_since JEMALLOC_N(nstime_ns_since) #define nstime_nsec JEMALLOC_N(nstime_nsec) +#define nstime_prof_init_update JEMALLOC_N(nstime_prof_init_update) +#define nstime_prof_update JEMALLOC_N(nstime_prof_update) #define nstime_sec JEMALLOC_N(nstime_sec) #define nstime_subtract JEMALLOC_N(nstime_subtract) #define nstime_update JEMALLOC_N(nstime_update) +#define opt_prof_time_res JEMALLOC_N(opt_prof_time_res) +#define prof_time_res_mode_names JEMALLOC_N(prof_time_res_mode_names) +#define pa_alloc JEMALLOC_N(pa_alloc) +#define pa_central_init JEMALLOC_N(pa_central_init) +#define pa_dalloc JEMALLOC_N(pa_dalloc) +#define pa_decay_ms_get JEMALLOC_N(pa_decay_ms_get) +#define pa_decay_ms_set JEMALLOC_N(pa_decay_ms_set) +#define pa_expand JEMALLOC_N(pa_expand) +#define pa_shard_destroy JEMALLOC_N(pa_shard_destroy) +#define pa_shard_disable_hpa JEMALLOC_N(pa_shard_disable_hpa) +#define pa_shard_do_deferred_work JEMALLOC_N(pa_shard_do_deferred_work) +#define pa_shard_enable_hpa JEMALLOC_N(pa_shard_enable_hpa) +#define pa_shard_init JEMALLOC_N(pa_shard_init) +#define pa_shard_reset JEMALLOC_N(pa_shard_reset) +#define pa_shard_retain_grow_limit_get_set JEMALLOC_N(pa_shard_retain_grow_limit_get_set) +#define pa_shard_set_deferral_allowed JEMALLOC_N(pa_shard_set_deferral_allowed) +#define pa_shard_time_until_deferred_work JEMALLOC_N(pa_shard_time_until_deferred_work) +#define pa_shrink JEMALLOC_N(pa_shrink) +#define pa_shard_basic_stats_merge JEMALLOC_N(pa_shard_basic_stats_merge) +#define pa_shard_mtx_stats_read JEMALLOC_N(pa_shard_mtx_stats_read) +#define pa_shard_postfork_child JEMALLOC_N(pa_shard_postfork_child) +#define pa_shard_postfork_parent JEMALLOC_N(pa_shard_postfork_parent) +#define pa_shard_prefork0 JEMALLOC_N(pa_shard_prefork0) +#define pa_shard_prefork2 JEMALLOC_N(pa_shard_prefork2) +#define pa_shard_prefork3 JEMALLOC_N(pa_shard_prefork3) +#define pa_shard_prefork4 JEMALLOC_N(pa_shard_prefork4) +#define pa_shard_prefork5 JEMALLOC_N(pa_shard_prefork5) +#define pa_shard_stats_merge JEMALLOC_N(pa_shard_stats_merge) +#define pai_alloc_batch_default JEMALLOC_N(pai_alloc_batch_default) +#define pai_dalloc_batch_default JEMALLOC_N(pai_dalloc_batch_default) +#define pac_decay_all JEMALLOC_N(pac_decay_all) +#define pac_decay_ms_get JEMALLOC_N(pac_decay_ms_get) +#define pac_decay_ms_set JEMALLOC_N(pac_decay_ms_set) +#define pac_destroy JEMALLOC_N(pac_destroy) +#define pac_init JEMALLOC_N(pac_init) +#define pac_maybe_decay_purge JEMALLOC_N(pac_maybe_decay_purge) +#define pac_reset JEMALLOC_N(pac_reset) +#define pac_retain_grow_limit_get_set JEMALLOC_N(pac_retain_grow_limit_get_set) #define init_system_thp_mode JEMALLOC_N(init_system_thp_mode) #define opt_thp JEMALLOC_N(opt_thp) #define pages_boot JEMALLOC_N(pages_boot) @@ -282,14 +454,23 @@ #define pages_dontdump JEMALLOC_N(pages_dontdump) #define pages_huge JEMALLOC_N(pages_huge) #define pages_map JEMALLOC_N(pages_map) +#define pages_mark_guards JEMALLOC_N(pages_mark_guards) #define pages_nohuge JEMALLOC_N(pages_nohuge) #define pages_purge_forced JEMALLOC_N(pages_purge_forced) #define pages_purge_lazy JEMALLOC_N(pages_purge_lazy) #define pages_set_thp_state JEMALLOC_N(pages_set_thp_state) #define pages_unmap JEMALLOC_N(pages_unmap) +#define pages_unmark_guards JEMALLOC_N(pages_unmark_guards) #define thp_mode_names JEMALLOC_N(thp_mode_names) -#define bt2gctx_mtx JEMALLOC_N(bt2gctx_mtx) -#define bt_init JEMALLOC_N(bt_init) +#define peak_alloc_event_handler JEMALLOC_N(peak_alloc_event_handler) +#define peak_alloc_new_event_wait JEMALLOC_N(peak_alloc_new_event_wait) +#define peak_alloc_postponed_event_wait JEMALLOC_N(peak_alloc_postponed_event_wait) +#define peak_dalloc_event_handler JEMALLOC_N(peak_dalloc_event_handler) +#define peak_dalloc_new_event_wait JEMALLOC_N(peak_dalloc_new_event_wait) +#define peak_dalloc_postponed_event_wait JEMALLOC_N(peak_dalloc_postponed_event_wait) +#define peak_event_max JEMALLOC_N(peak_event_max) +#define peak_event_update JEMALLOC_N(peak_event_update) +#define peak_event_zero JEMALLOC_N(peak_event_zero) #define lg_prof_sample JEMALLOC_N(lg_prof_sample) #define opt_lg_prof_interval JEMALLOC_N(opt_lg_prof_interval) #define opt_lg_prof_sample JEMALLOC_N(opt_lg_prof_sample) @@ -299,20 +480,25 @@ #define opt_prof_final JEMALLOC_N(opt_prof_final) #define opt_prof_gdump JEMALLOC_N(opt_prof_gdump) #define opt_prof_leak JEMALLOC_N(opt_prof_leak) -#define opt_prof_log JEMALLOC_N(opt_prof_log) +#define opt_prof_leak_error JEMALLOC_N(opt_prof_leak_error) #define opt_prof_prefix JEMALLOC_N(opt_prof_prefix) +#define opt_prof_sys_thread_name JEMALLOC_N(opt_prof_sys_thread_name) #define opt_prof_thread_active_init JEMALLOC_N(opt_prof_thread_active_init) -#define prof_accum_init JEMALLOC_N(prof_accum_init) -#define prof_active JEMALLOC_N(prof_active) +#define opt_prof_unbias JEMALLOC_N(opt_prof_unbias) #define prof_active_get JEMALLOC_N(prof_active_get) #define prof_active_set JEMALLOC_N(prof_active_set) +#define prof_active_state JEMALLOC_N(prof_active_state) #define prof_alloc_rollback JEMALLOC_N(prof_alloc_rollback) -#define prof_backtrace JEMALLOC_N(prof_backtrace) +#define prof_backtrace_hook JEMALLOC_N(prof_backtrace_hook) +#define prof_backtrace_hook_get JEMALLOC_N(prof_backtrace_hook_get) +#define prof_backtrace_hook_set JEMALLOC_N(prof_backtrace_hook_set) #define prof_boot0 JEMALLOC_N(prof_boot0) #define prof_boot1 JEMALLOC_N(prof_boot1) #define prof_boot2 JEMALLOC_N(prof_boot2) -#define prof_dump_header JEMALLOC_N(prof_dump_header) -#define prof_dump_open JEMALLOC_N(prof_dump_open) +#define prof_booted JEMALLOC_N(prof_booted) +#define prof_dump_hook JEMALLOC_N(prof_dump_hook) +#define prof_dump_hook_get JEMALLOC_N(prof_dump_hook_get) +#define prof_dump_hook_set JEMALLOC_N(prof_dump_hook_set) #define prof_free_sampled_object JEMALLOC_N(prof_free_sampled_object) #define prof_gdump JEMALLOC_N(prof_gdump) #define prof_gdump_get JEMALLOC_N(prof_gdump_get) @@ -320,18 +506,16 @@ #define prof_gdump_val JEMALLOC_N(prof_gdump_val) #define prof_idump JEMALLOC_N(prof_idump) #define prof_interval JEMALLOC_N(prof_interval) -#define prof_log_start JEMALLOC_N(prof_log_start) -#define prof_log_stop JEMALLOC_N(prof_log_stop) -#define prof_logging_state JEMALLOC_N(prof_logging_state) -#define prof_lookup JEMALLOC_N(prof_lookup) #define prof_malloc_sample_object JEMALLOC_N(prof_malloc_sample_object) #define prof_mdump JEMALLOC_N(prof_mdump) #define prof_postfork_child JEMALLOC_N(prof_postfork_child) #define prof_postfork_parent JEMALLOC_N(prof_postfork_parent) #define prof_prefork0 JEMALLOC_N(prof_prefork0) #define prof_prefork1 JEMALLOC_N(prof_prefork1) -#define prof_reset JEMALLOC_N(prof_reset) -#define prof_sample_threshold_update JEMALLOC_N(prof_sample_threshold_update) +#define prof_sample_event_handler JEMALLOC_N(prof_sample_event_handler) +#define prof_sample_new_event_wait JEMALLOC_N(prof_sample_new_event_wait) +#define prof_sample_postponed_event_wait JEMALLOC_N(prof_sample_postponed_event_wait) +#define prof_tctx_create JEMALLOC_N(prof_tctx_create) #define prof_tdata_cleanup JEMALLOC_N(prof_tdata_cleanup) #define prof_tdata_init JEMALLOC_N(prof_tdata_init) #define prof_tdata_reinit JEMALLOC_N(prof_tdata_reinit) @@ -341,42 +525,157 @@ #define prof_thread_active_set JEMALLOC_N(prof_thread_active_set) #define prof_thread_name_get JEMALLOC_N(prof_thread_name_get) #define prof_thread_name_set JEMALLOC_N(prof_thread_name_set) +#define bt2gctx_mtx JEMALLOC_N(bt2gctx_mtx) +#define gctx_locks JEMALLOC_N(gctx_locks) +#define prof_bt_count JEMALLOC_N(prof_bt_count) +#define prof_bt_hash JEMALLOC_N(prof_bt_hash) +#define prof_bt_keycomp JEMALLOC_N(prof_bt_keycomp) +#define prof_cnt_all JEMALLOC_N(prof_cnt_all) +#define prof_data_init JEMALLOC_N(prof_data_init) +#define prof_dump_impl JEMALLOC_N(prof_dump_impl) +#define prof_dump_mtx JEMALLOC_N(prof_dump_mtx) +#define prof_lookup JEMALLOC_N(prof_lookup) +#define prof_reset JEMALLOC_N(prof_reset) +#define prof_shifted_unbiased_cnt JEMALLOC_N(prof_shifted_unbiased_cnt) +#define prof_tctx_try_destroy JEMALLOC_N(prof_tctx_try_destroy) +#define prof_tdata_count JEMALLOC_N(prof_tdata_count) +#define prof_tdata_detach JEMALLOC_N(prof_tdata_detach) +#define prof_tdata_init_impl JEMALLOC_N(prof_tdata_init_impl) +#define prof_thread_name_alloc JEMALLOC_N(prof_thread_name_alloc) +#define prof_thread_name_set_impl JEMALLOC_N(prof_thread_name_set_impl) +#define prof_unbias_map_init JEMALLOC_N(prof_unbias_map_init) +#define prof_unbiased_sz JEMALLOC_N(prof_unbiased_sz) +#define tdata_locks JEMALLOC_N(tdata_locks) +#define tdatas_mtx JEMALLOC_N(tdatas_mtx) +#define log_mtx JEMALLOC_N(log_mtx) +#define opt_prof_log JEMALLOC_N(opt_prof_log) +#define prof_log_alloc_count JEMALLOC_N(prof_log_alloc_count) +#define prof_log_bt_count JEMALLOC_N(prof_log_bt_count) +#define prof_log_dummy_set JEMALLOC_N(prof_log_dummy_set) +#define prof_log_init JEMALLOC_N(prof_log_init) +#define prof_log_is_logging JEMALLOC_N(prof_log_is_logging) +#define prof_log_rep_check JEMALLOC_N(prof_log_rep_check) +#define prof_log_start JEMALLOC_N(prof_log_start) +#define prof_log_stop JEMALLOC_N(prof_log_stop) +#define prof_log_thr_count JEMALLOC_N(prof_log_thr_count) +#define prof_logging_state JEMALLOC_N(prof_logging_state) +#define prof_try_log JEMALLOC_N(prof_try_log) +#define edata_prof_recent_alloc_get_no_lock_test JEMALLOC_N(edata_prof_recent_alloc_get_no_lock_test) +#define edata_prof_recent_alloc_init JEMALLOC_N(edata_prof_recent_alloc_init) +#define opt_prof_recent_alloc_max JEMALLOC_N(opt_prof_recent_alloc_max) +#define prof_recent_alloc JEMALLOC_N(prof_recent_alloc) +#define prof_recent_alloc_dump JEMALLOC_N(prof_recent_alloc_dump) +#define prof_recent_alloc_edata_get_no_lock_test JEMALLOC_N(prof_recent_alloc_edata_get_no_lock_test) +#define prof_recent_alloc_list JEMALLOC_N(prof_recent_alloc_list) +#define prof_recent_alloc_max_ctl_read JEMALLOC_N(prof_recent_alloc_max_ctl_read) +#define prof_recent_alloc_max_ctl_write JEMALLOC_N(prof_recent_alloc_max_ctl_write) +#define prof_recent_alloc_mtx JEMALLOC_N(prof_recent_alloc_mtx) +#define prof_recent_alloc_prepare JEMALLOC_N(prof_recent_alloc_prepare) +#define prof_recent_alloc_reset JEMALLOC_N(prof_recent_alloc_reset) +#define prof_recent_dump_mtx JEMALLOC_N(prof_recent_dump_mtx) +#define prof_recent_init JEMALLOC_N(prof_recent_init) +#define opt_prof_stats JEMALLOC_N(opt_prof_stats) +#define prof_stats_dec JEMALLOC_N(prof_stats_dec) +#define prof_stats_get_accum JEMALLOC_N(prof_stats_get_accum) +#define prof_stats_get_live JEMALLOC_N(prof_stats_get_live) +#define prof_stats_inc JEMALLOC_N(prof_stats_inc) +#define prof_stats_mtx JEMALLOC_N(prof_stats_mtx) +#define bt_init JEMALLOC_N(bt_init) +#define prof_backtrace JEMALLOC_N(prof_backtrace) +#define prof_base JEMALLOC_N(prof_base) +#define prof_do_mock JEMALLOC_N(prof_do_mock) +#define prof_dump_filename_mtx JEMALLOC_N(prof_dump_filename_mtx) +#define prof_dump_open_file JEMALLOC_N(prof_dump_open_file) +#define prof_dump_open_maps JEMALLOC_N(prof_dump_open_maps) +#define prof_dump_write_file JEMALLOC_N(prof_dump_write_file) +#define prof_fdump_impl JEMALLOC_N(prof_fdump_impl) +#define prof_gdump_impl JEMALLOC_N(prof_gdump_impl) +#define prof_get_default_filename JEMALLOC_N(prof_get_default_filename) +#define prof_getpid JEMALLOC_N(prof_getpid) +#define prof_hooks_init JEMALLOC_N(prof_hooks_init) +#define prof_idump_impl JEMALLOC_N(prof_idump_impl) +#define prof_mdump_impl JEMALLOC_N(prof_mdump_impl) +#define prof_prefix_set JEMALLOC_N(prof_prefix_set) +#define prof_sys_thread_name_fetch JEMALLOC_N(prof_sys_thread_name_fetch) +#define prof_sys_thread_name_read JEMALLOC_N(prof_sys_thread_name_read) +#define prof_unwind_init JEMALLOC_N(prof_unwind_init) +#define psset_init JEMALLOC_N(psset_init) +#define psset_insert JEMALLOC_N(psset_insert) +#define psset_pick_alloc JEMALLOC_N(psset_pick_alloc) +#define psset_pick_hugify JEMALLOC_N(psset_pick_hugify) +#define psset_pick_purge JEMALLOC_N(psset_pick_purge) +#define psset_remove JEMALLOC_N(psset_remove) +#define psset_stats_accum JEMALLOC_N(psset_stats_accum) +#define psset_update_begin JEMALLOC_N(psset_update_begin) +#define psset_update_end JEMALLOC_N(psset_update_end) #define rtree_ctx_data_init JEMALLOC_N(rtree_ctx_data_init) -#define rtree_leaf_alloc JEMALLOC_N(rtree_leaf_alloc) -#define rtree_leaf_dalloc JEMALLOC_N(rtree_leaf_dalloc) #define rtree_leaf_elm_lookup_hard JEMALLOC_N(rtree_leaf_elm_lookup_hard) #define rtree_new JEMALLOC_N(rtree_new) -#define rtree_node_alloc JEMALLOC_N(rtree_node_alloc) -#define rtree_node_dalloc JEMALLOC_N(rtree_node_dalloc) #define safety_check_fail JEMALLOC_N(safety_check_fail) +#define safety_check_fail_sized_dealloc JEMALLOC_N(safety_check_fail_sized_dealloc) #define safety_check_set_abort JEMALLOC_N(safety_check_set_abort) +#define reg_size_compute JEMALLOC_N(reg_size_compute) +#define sc_boot JEMALLOC_N(sc_boot) +#define sc_data_init JEMALLOC_N(sc_data_init) +#define sc_data_update_slab_size JEMALLOC_N(sc_data_update_slab_size) +#define sec_disable JEMALLOC_N(sec_disable) +#define sec_flush JEMALLOC_N(sec_flush) +#define sec_init JEMALLOC_N(sec_init) +#define sec_mutex_stats_read JEMALLOC_N(sec_mutex_stats_read) +#define sec_postfork_child JEMALLOC_N(sec_postfork_child) +#define sec_postfork_parent JEMALLOC_N(sec_postfork_parent) +#define sec_prefork2 JEMALLOC_N(sec_prefork2) +#define sec_stats_merge JEMALLOC_N(sec_stats_merge) #define arena_mutex_names JEMALLOC_N(arena_mutex_names) #define global_mutex_names JEMALLOC_N(global_mutex_names) +#define opt_stats_interval JEMALLOC_N(opt_stats_interval) +#define opt_stats_interval_opts JEMALLOC_N(opt_stats_interval_opts) #define opt_stats_print JEMALLOC_N(opt_stats_print) #define opt_stats_print_opts JEMALLOC_N(opt_stats_print_opts) +#define stats_boot JEMALLOC_N(stats_boot) +#define stats_interval_event_handler JEMALLOC_N(stats_interval_event_handler) +#define stats_interval_new_event_wait JEMALLOC_N(stats_interval_new_event_wait) +#define stats_interval_postponed_event_wait JEMALLOC_N(stats_interval_postponed_event_wait) +#define stats_postfork_child JEMALLOC_N(stats_postfork_child) +#define stats_postfork_parent JEMALLOC_N(stats_postfork_parent) +#define stats_prefork JEMALLOC_N(stats_prefork) #define stats_print JEMALLOC_N(stats_print) -#define sc_boot JEMALLOC_N(sc_boot) -#define sc_data_global JEMALLOC_N(sc_data_global) -#define sc_data_init JEMALLOC_N(sc_data_init) -#define sc_data_update_slab_size JEMALLOC_N(sc_data_update_slab_size) #define sz_boot JEMALLOC_N(sz_boot) #define sz_index2size_tab JEMALLOC_N(sz_index2size_tab) +#define sz_large_pad JEMALLOC_N(sz_large_pad) #define sz_pind2sz_tab JEMALLOC_N(sz_pind2sz_tab) +#define sz_psz_quantize_ceil JEMALLOC_N(sz_psz_quantize_ceil) +#define sz_psz_quantize_floor JEMALLOC_N(sz_psz_quantize_floor) #define sz_size2index_tab JEMALLOC_N(sz_size2index_tab) #define nhbins JEMALLOC_N(nhbins) -#define opt_lg_tcache_max JEMALLOC_N(opt_lg_tcache_max) +#define opt_lg_tcache_flush_large_div JEMALLOC_N(opt_lg_tcache_flush_large_div) +#define opt_lg_tcache_flush_small_div JEMALLOC_N(opt_lg_tcache_flush_small_div) +#define opt_lg_tcache_nslots_mul JEMALLOC_N(opt_lg_tcache_nslots_mul) #define opt_tcache JEMALLOC_N(opt_tcache) +#define opt_tcache_gc_delay_bytes JEMALLOC_N(opt_tcache_gc_delay_bytes) +#define opt_tcache_gc_incr_bytes JEMALLOC_N(opt_tcache_gc_incr_bytes) +#define opt_tcache_max JEMALLOC_N(opt_tcache_max) +#define opt_tcache_nslots_large JEMALLOC_N(opt_tcache_nslots_large) +#define opt_tcache_nslots_small_max JEMALLOC_N(opt_tcache_nslots_small_max) +#define opt_tcache_nslots_small_min JEMALLOC_N(opt_tcache_nslots_small_min) #define tcache_alloc_small_hard JEMALLOC_N(tcache_alloc_small_hard) #define tcache_arena_associate JEMALLOC_N(tcache_arena_associate) #define tcache_arena_reassociate JEMALLOC_N(tcache_arena_reassociate) +#define tcache_assert_initialized JEMALLOC_N(tcache_assert_initialized) #define tcache_bin_flush_large JEMALLOC_N(tcache_bin_flush_large) #define tcache_bin_flush_small JEMALLOC_N(tcache_bin_flush_small) +#define tcache_bin_flush_stashed JEMALLOC_N(tcache_bin_flush_stashed) #define tcache_bin_info JEMALLOC_N(tcache_bin_info) #define tcache_boot JEMALLOC_N(tcache_boot) #define tcache_cleanup JEMALLOC_N(tcache_cleanup) #define tcache_create_explicit JEMALLOC_N(tcache_create_explicit) -#define tcache_event_hard JEMALLOC_N(tcache_event_hard) #define tcache_flush JEMALLOC_N(tcache_flush) +#define tcache_gc_dalloc_event_handler JEMALLOC_N(tcache_gc_dalloc_event_handler) +#define tcache_gc_dalloc_new_event_wait JEMALLOC_N(tcache_gc_dalloc_new_event_wait) +#define tcache_gc_dalloc_postponed_event_wait JEMALLOC_N(tcache_gc_dalloc_postponed_event_wait) +#define tcache_gc_event_handler JEMALLOC_N(tcache_gc_event_handler) +#define tcache_gc_new_event_wait JEMALLOC_N(tcache_gc_new_event_wait) +#define tcache_gc_postponed_event_wait JEMALLOC_N(tcache_gc_postponed_event_wait) #define tcache_maxclass JEMALLOC_N(tcache_maxclass) #define tcache_postfork_child JEMALLOC_N(tcache_postfork_child) #define tcache_postfork_parent JEMALLOC_N(tcache_postfork_parent) @@ -391,9 +690,13 @@ #define tsd_tcache_enabled_data_init JEMALLOC_N(tsd_tcache_enabled_data_init) #define test_hooks_arena_new_hook JEMALLOC_N(test_hooks_arena_new_hook) #define test_hooks_libc_hook JEMALLOC_N(test_hooks_libc_hook) +#define te_assert_invariants_debug JEMALLOC_N(te_assert_invariants_debug) +#define te_event_trigger JEMALLOC_N(te_event_trigger) +#define te_recompute_fast_threshold JEMALLOC_N(te_recompute_fast_threshold) +#define tsd_te_init JEMALLOC_N(tsd_te_init) +#define ticker_geom_table JEMALLOC_N(ticker_geom_table) #define malloc_tsd_boot0 JEMALLOC_N(malloc_tsd_boot0) #define malloc_tsd_boot1 JEMALLOC_N(malloc_tsd_boot1) -#define malloc_tsd_cleanup_register JEMALLOC_N(malloc_tsd_cleanup_register) #define malloc_tsd_dalloc JEMALLOC_N(malloc_tsd_dalloc) #define malloc_tsd_malloc JEMALLOC_N(malloc_tsd_malloc) #define tsd_booted JEMALLOC_N(tsd_booted) diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/public_namespace.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/public_namespace.h index 78d5c66377c3..6363f085f34b 100644 --- a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/public_namespace.h +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/internal/public_namespace.h @@ -7,11 +7,12 @@ #define je_mallctlnametomib JEMALLOC_N(mallctlnametomib) #define je_malloc JEMALLOC_N(malloc) #define je_malloc_conf JEMALLOC_N(malloc_conf) +#define je_malloc_conf_2_conf_harder JEMALLOC_N(malloc_conf_2_conf_harder) #define je_malloc_message JEMALLOC_N(malloc_message) #define je_malloc_stats_print JEMALLOC_N(malloc_stats_print) #define je_malloc_usable_size JEMALLOC_N(malloc_usable_size) #define je_mallocx JEMALLOC_N(mallocx) -#define je_smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756 JEMALLOC_N(smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756) +#define je_smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c JEMALLOC_N(smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c) #define je_nallocx JEMALLOC_N(nallocx) #define je_posix_memalign JEMALLOC_N(posix_memalign) #define je_rallocx JEMALLOC_N(rallocx) @@ -19,4 +20,5 @@ #define je_sallocx JEMALLOC_N(sallocx) #define je_sdallocx JEMALLOC_N(sdallocx) #define je_xallocx JEMALLOC_N(xallocx) +#define je_memalign JEMALLOC_N(memalign) #define je_valloc JEMALLOC_N(valloc) diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc.h index c3fa08e83f22..f9ed38656a87 100644 --- a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc.h +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc.h @@ -19,6 +19,12 @@ extern "C" { /* Defined if format(printf, ...) attribute is supported. */ #define JEMALLOC_HAVE_ATTR_FORMAT_PRINTF +/* Defined if fallthrough attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_FALLTHROUGH + +/* Defined if cold attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_COLD + /* * Define overrides for non-standard allocator-related functions if they are * present on the system. @@ -68,11 +74,12 @@ extern "C" { # define je_mallctlnametomib mallctlnametomib # define je_malloc malloc # define je_malloc_conf malloc_conf +# define je_malloc_conf_2_conf_harder malloc_conf_2_conf_harder # define je_malloc_message malloc_message # define je_malloc_stats_print malloc_stats_print # define je_malloc_usable_size malloc_usable_size # define je_mallocx mallocx -# define je_smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756 smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756 +# define je_smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c # define je_nallocx nallocx # define je_posix_memalign posix_memalign # define je_rallocx rallocx @@ -80,6 +87,7 @@ extern "C" { # define je_sallocx sallocx # define je_sdallocx sdallocx # define je_xallocx xallocx +# define je_memalign memalign # define je_valloc valloc #endif @@ -91,13 +99,13 @@ extern "C" { #include <limits.h> #include <strings.h> -#define JEMALLOC_VERSION "5.2.1-0-gea6b3e973b477b8061e0076bb257dbd7f3faa756" +#define JEMALLOC_VERSION "5.3.0-0-g54eaed1d8b56b1aa528be3bdd1877e59c56fa90c" #define JEMALLOC_VERSION_MAJOR 5 -#define JEMALLOC_VERSION_MINOR 2 -#define JEMALLOC_VERSION_BUGFIX 1 +#define JEMALLOC_VERSION_MINOR 3 +#define JEMALLOC_VERSION_BUGFIX 0 #define JEMALLOC_VERSION_NREV 0 -#define JEMALLOC_VERSION_GID "ea6b3e973b477b8061e0076bb257dbd7f3faa756" -#define JEMALLOC_VERSION_GID_IDENT ea6b3e973b477b8061e0076bb257dbd7f3faa756 +#define JEMALLOC_VERSION_GID "54eaed1d8b56b1aa528be3bdd1877e59c56fa90c" +#define JEMALLOC_VERSION_GID_IDENT 54eaed1d8b56b1aa528be3bdd1877e59c56fa90c #define MALLOCX_LG_ALIGN(la) ((int)(la)) #if LG_SIZEOF_PTR == 2 @@ -158,6 +166,7 @@ extern "C" { # endif # define JEMALLOC_FORMAT_ARG(i) # define JEMALLOC_FORMAT_PRINTF(s, i) +# define JEMALLOC_FALLTHROUGH # define JEMALLOC_NOINLINE __declspec(noinline) # ifdef __cplusplus # define JEMALLOC_NOTHROW __declspec(nothrow) @@ -171,6 +180,7 @@ extern "C" { # else # define JEMALLOC_ALLOCATOR # endif +# define JEMALLOC_COLD #elif defined(JEMALLOC_HAVE_ATTR) # define JEMALLOC_ATTR(s) __attribute__((s)) # define JEMALLOC_ALIGNED(s) JEMALLOC_ATTR(aligned(s)) @@ -196,11 +206,21 @@ extern "C" { # else # define JEMALLOC_FORMAT_PRINTF(s, i) # endif +# ifdef JEMALLOC_HAVE_ATTR_FALLTHROUGH +# define JEMALLOC_FALLTHROUGH JEMALLOC_ATTR(fallthrough) +# else +# define JEMALLOC_FALLTHROUGH +# endif # define JEMALLOC_NOINLINE JEMALLOC_ATTR(noinline) # define JEMALLOC_NOTHROW JEMALLOC_ATTR(nothrow) # define JEMALLOC_SECTION(s) JEMALLOC_ATTR(section(s)) # define JEMALLOC_RESTRICT_RETURN # define JEMALLOC_ALLOCATOR +# ifdef JEMALLOC_HAVE_ATTR_COLD +# define JEMALLOC_COLD JEMALLOC_ATTR(__cold__) +# else +# define JEMALLOC_COLD +# endif #else # define JEMALLOC_ATTR(s) # define JEMALLOC_ALIGNED(s) @@ -208,11 +228,19 @@ extern "C" { # define JEMALLOC_ALLOC_SIZE2(s1, s2) # define JEMALLOC_EXPORT # define JEMALLOC_FORMAT_PRINTF(s, i) +# define JEMALLOC_FALLTHROUGH # define JEMALLOC_NOINLINE # define JEMALLOC_NOTHROW # define JEMALLOC_SECTION(s) # define JEMALLOC_RESTRICT_RETURN # define JEMALLOC_ALLOCATOR +# define JEMALLOC_COLD +#endif + +#if (defined(__APPLE__) || defined(__FreeBSD__)) && !defined(JEMALLOC_NO_RENAME) +# define JEMALLOC_SYS_NOTHROW +#else +# define JEMALLOC_SYS_NOTHROW JEMALLOC_NOTHROW #endif /* @@ -225,21 +253,22 @@ extern JEMALLOC_EXPORT void (*je_malloc_message)(void *cbopaque, const char *s); JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN - void JEMALLOC_NOTHROW *je_malloc(size_t size) + void JEMALLOC_SYS_NOTHROW *je_malloc(size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(1); JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN - void JEMALLOC_NOTHROW *je_calloc(size_t num, size_t size) + void JEMALLOC_SYS_NOTHROW *je_calloc(size_t num, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE2(1, 2); -JEMALLOC_EXPORT int JEMALLOC_NOTHROW je_posix_memalign(void **memptr, - size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(nonnull(1)); +JEMALLOC_EXPORT int JEMALLOC_SYS_NOTHROW je_posix_memalign( + void **memptr, size_t alignment, size_t size) JEMALLOC_CXX_THROW + JEMALLOC_ATTR(nonnull(1)); JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN - void JEMALLOC_NOTHROW *je_aligned_alloc(size_t alignment, + void JEMALLOC_SYS_NOTHROW *je_aligned_alloc(size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc) JEMALLOC_ALLOC_SIZE(2); JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN - void JEMALLOC_NOTHROW *je_realloc(void *ptr, size_t size) + void JEMALLOC_SYS_NOTHROW *je_realloc(void *ptr, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ALLOC_SIZE(2); -JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_free(void *ptr) +JEMALLOC_EXPORT void JEMALLOC_SYS_NOTHROW je_free(void *ptr) JEMALLOC_CXX_THROW; JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN @@ -269,16 +298,20 @@ JEMALLOC_EXPORT void JEMALLOC_NOTHROW je_malloc_stats_print( const char *opts); JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_usable_size( JEMALLOC_USABLE_SIZE_CONST void *ptr) JEMALLOC_CXX_THROW; +#ifdef JEMALLOC_HAVE_MALLOC_SIZE +JEMALLOC_EXPORT size_t JEMALLOC_NOTHROW je_malloc_size( + const void *ptr); +#endif #ifdef JEMALLOC_OVERRIDE_MEMALIGN JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN - void JEMALLOC_NOTHROW *je_memalign(size_t alignment, size_t size) + void JEMALLOC_SYS_NOTHROW *je_memalign(size_t alignment, size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); #endif #ifdef JEMALLOC_OVERRIDE_VALLOC JEMALLOC_EXPORT JEMALLOC_ALLOCATOR JEMALLOC_RESTRICT_RETURN - void JEMALLOC_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW + void JEMALLOC_SYS_NOTHROW *je_valloc(size_t size) JEMALLOC_CXX_THROW JEMALLOC_ATTR(malloc); #endif @@ -380,11 +413,12 @@ struct extent_hooks_s { # define mallctlnametomib je_mallctlnametomib # define malloc je_malloc # define malloc_conf je_malloc_conf +# define malloc_conf_2_conf_harder je_malloc_conf_2_conf_harder # define malloc_message je_malloc_message # define malloc_stats_print je_malloc_stats_print # define malloc_usable_size je_malloc_usable_size # define mallocx je_mallocx -# define smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756 je_smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756 +# define smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c je_smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c # define nallocx je_nallocx # define posix_memalign je_posix_memalign # define rallocx je_rallocx @@ -412,11 +446,12 @@ struct extent_hooks_s { # undef je_mallctlnametomib # undef je_malloc # undef je_malloc_conf +# undef je_malloc_conf_2_conf_harder # undef je_malloc_message # undef je_malloc_stats_print # undef je_malloc_usable_size # undef je_mallocx -# undef je_smallocx_ea6b3e973b477b8061e0076bb257dbd7f3faa756 +# undef je_smallocx_54eaed1d8b56b1aa528be3bdd1877e59c56fa90c # undef je_nallocx # undef je_posix_memalign # undef je_rallocx diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_FreeBSD.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_FreeBSD.h index e733906bc146..34c86271ab2e 100644 --- a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_FreeBSD.h +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_FreeBSD.h @@ -2,6 +2,8 @@ * Override settings that were generated in jemalloc_defs.h as necessary. */ +#ifndef JEMALLOC_NO_PRIVATE_NAMESPACE + #undef JEMALLOC_OVERRIDE_VALLOC #ifndef MALLOC_PRODUCTION @@ -96,8 +98,12 @@ #include <machine/cpufunc.h> #define CPU_SPINWAIT cpu_spinwait() -/* Disable lazy-lock machinery, mangle isthreaded, and adjust its type. */ +/* + * Disable lazy-lock machinery, redirect isthreaded to libc's flag, undo + * jemalloc's namespace stuff for it and adjust its type. + */ #undef JEMALLOC_LAZY_LOCK +#undef isthreaded extern int __isthreaded; #define isthreaded ((bool)__isthreaded) @@ -197,3 +203,5 @@ __sym_compat(sallocm, weak_sallocm, FBSD_1.3); __sym_compat(dallocm, weak_dallocm, FBSD_1.3); __sym_compat(nallocm, weak_nallocm, FBSD_1.3); #endif + +#endif diff --git a/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_defs.h b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_defs.h new file mode 100644 index 000000000000..fb104aaeec98 --- /dev/null +++ b/lib/libc/stdlib/malloc/jemalloc/include/jemalloc/jemalloc_defs.h @@ -0,0 +1,55 @@ +/* include/jemalloc/jemalloc_defs.h. Generated from jemalloc_defs.h.in by configure. */ +/* Defined if __attribute__((...)) syntax is supported. */ +#define JEMALLOC_HAVE_ATTR + +/* Defined if alloc_size attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_ALLOC_SIZE + +/* Defined if format_arg(...) attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_FORMAT_ARG + +/* Defined if format(gnu_printf, ...) attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_FORMAT_GNU_PRINTF + +/* Defined if format(printf, ...) attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_FORMAT_PRINTF + +/* Defined if fallthrough attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_FALLTHROUGH + +/* Defined if cold attribute is supported. */ +#define JEMALLOC_HAVE_ATTR_COLD + +/* + * Define overrides for non-standard allocator-related functions if they are + * present on the system. + */ +#define JEMALLOC_OVERRIDE_MEMALIGN +#define JEMALLOC_OVERRIDE_VALLOC + +/* + * At least Linux omits the "const" in: + * + * size_t malloc_usable_size(const void *ptr); + * + * Match the operating system's prototype. + */ +#define JEMALLOC_USABLE_SIZE_CONST const + +/* + * If defined, specify throw() for the public function prototypes when compiling + * with C++. The only justification for this is to match the prototypes that + * glibc defines. + */ +/* #undef JEMALLOC_USE_CXX_THROW */ + +#ifdef _MSC_VER +# ifdef _WIN64 +# define LG_SIZEOF_PTR_WIN 3 +# else +# define LG_SIZEOF_PTR_WIN 2 +# endif +#endif + +/* sizeof(void *) == 2^LG_SIZEOF_PTR. */ +#define LG_SIZEOF_PTR 3 diff --git a/lib/libc/stdlib/reallocarray.3 b/lib/libc/stdlib/reallocarray.3 index 80035c67a497..9a2ab5c7a840 100644 --- a/lib/libc/stdlib/reallocarray.3 +++ b/lib/libc/stdlib/reallocarray.3 @@ -26,7 +26,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 1, 2015 +.Dd October 2, 2025 .Dt REALLOCARRAY 3 .Os .Sh NAME @@ -38,6 +38,8 @@ .In stdlib.h .Ft void * .Fn reallocarray "void *ptr" "size_t nmemb" "size_t size" +.Ft void * +.Fn recallocarray "void *ptr" "size_t oldnmeb" "size_t nmemb" size_t size" .Sh DESCRIPTION The .Fn reallocarray @@ -52,6 +54,33 @@ and checks for integer overflow in the calculation .Fa nmemb * .Fa size . +.Pp +The +.Fn recallocarray +function is similar to the +.Fn reallocarray +function +except it ensures newly allocated memory is cleared similar to +.Fn calloc . +If +.Fa ptr +is +.Dv NULL , +.Fa oldnmemb +is ignored and the call is equivalent to +.Fn calloc . +If +.Fa ptr +is not +.Dv NULL , +.Fa oldnmemb +must be a value such that +.Fa oldnmemb +* +.Fa size +is the size of the earlier allocation that returned +.Fa ptr , +otherwise the behaviour is undefined. .Sh RETURN VALUES The .Fn reallocarray @@ -142,3 +171,9 @@ function first appeared in .Ox 5.6 and .Fx 11.0 . +The +.Fn recallocarray +function first appeared in +.Ox 6.1 +and +.Fx 16.0 . diff --git a/lib/libc/stdlib/reallocarray.c b/lib/libc/stdlib/reallocarray.c index 0868804486cc..3632734c84de 100644 --- a/lib/libc/stdlib/reallocarray.c +++ b/lib/libc/stdlib/reallocarray.c @@ -17,23 +17,19 @@ #include <sys/types.h> #include <errno.h> +#include <stdckdint.h> #include <stdint.h> #include <stdlib.h> -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - void * reallocarray(void *optr, size_t nmemb, size_t size) { + size_t nbytes; - if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - nmemb > 0 && SIZE_MAX / nmemb < size) { + if (ckd_mul(&nbytes, nmemb, size)) { errno = ENOMEM; return (NULL); } - return (realloc(optr, size * nmemb)); + + return (realloc(optr, nbytes)); } diff --git a/lib/libc/stdlib/realpath.3 b/lib/libc/stdlib/realpath.3 index 065ba312c2ef..76f40249963b 100644 --- a/lib/libc/stdlib/realpath.3 +++ b/lib/libc/stdlib/realpath.3 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 11, 2012 +.Dd October 10, 2025 .Dt REALPATH 3 .Os .Sh NAME @@ -108,11 +108,11 @@ and .Xr getcwd 3 . .Sh SEE ALSO .Xr getcwd 3 -.\" .Sh STANDARDS -.\" The -.\" .Fn realpath -.\" function conforms to -.\" .St -p1003.1-2001 . +.Sh STANDARDS +The +.Fn realpath +function conforms to +.St -p1003.1-2001 . .Sh HISTORY The .Fn realpath diff --git a/lib/libc/stdlib/realpath.c b/lib/libc/stdlib/realpath.c index 4c52b73319ab..18f29e95ee6b 100644 --- a/lib/libc/stdlib/realpath.c +++ b/lib/libc/stdlib/realpath.c @@ -49,7 +49,7 @@ realpath1(const char *path, char *resolved) { struct stat sb; char *p, *q; - size_t left_len, resolved_len, next_token_len; + size_t left_len, prev_len, resolved_len, next_token_len; unsigned symlinks; ssize_t slen; char left[PATH_MAX], next_token[PATH_MAX], symlink[PATH_MAX]; @@ -98,6 +98,7 @@ realpath1(const char *path, char *resolved) left_len = 0; } + prev_len = resolved_len; if (resolved[resolved_len - 1] != '/') { if (resolved_len + 1 >= PATH_MAX) { errno = ENAMETOOLONG; @@ -133,8 +134,17 @@ realpath1(const char *path, char *resolved) errno = ENAMETOOLONG; return (NULL); } - if (lstat(resolved, &sb) != 0) + if (lstat(resolved, &sb) != 0) { + /* + * EACCES means the parent directory is not + * readable, while ENOTDIR means the parent + * directory is not a directory. Rewind the path + * to correctly indicate where the error lies. + */ + if (errno == EACCES || errno == ENOTDIR) + resolved[prev_len] = '\0'; return (NULL); + } if (S_ISLNK(sb.st_mode)) { if (symlinks++ > MAXSYMLINKS) { errno = ELOOP; diff --git a/lib/libopenbsd/recallocarray.c b/lib/libc/stdlib/recallocarray.c index 11e1fda744c7..cbf1fb2470cf 100644 --- a/lib/libopenbsd/recallocarray.c +++ b/lib/libc/stdlib/recallocarray.c @@ -16,17 +16,12 @@ */ #include <errno.h> +#include <stdckdint.h> #include <stdlib.h> #include <stdint.h> #include <string.h> #include <unistd.h> -/* - * This is sqrt(SIZE_MAX+1), as s1*s2 <= SIZE_MAX - * if both s1 < MUL_NO_OVERFLOW and s2 < MUL_NO_OVERFLOW - */ -#define MUL_NO_OVERFLOW ((size_t)1 << (sizeof(size_t) * 4)) - void *recallocarray(void *, size_t, size_t, size_t); void * @@ -38,19 +33,15 @@ recallocarray(void *ptr, size_t oldnmemb, size_t newnmemb, size_t size) if (ptr == NULL) return calloc(newnmemb, size); - if ((newnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - newnmemb > 0 && SIZE_MAX / newnmemb < size) { + if (ckd_mul(&newsize, newnmemb, size)) { errno = ENOMEM; return NULL; } - newsize = newnmemb * size; - if ((oldnmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) && - oldnmemb > 0 && SIZE_MAX / oldnmemb < size) { + if (ckd_mul(&oldsize, oldnmemb, size)) { errno = EINVAL; return NULL; } - oldsize = oldnmemb * size; /* * Don't bother too much if we're shrinking just a bit, diff --git a/lib/libc/stdtime/Makefile.inc b/lib/libc/stdtime/Makefile.inc index 647cbe6f40ba..1baa39a6c0a6 100644 --- a/lib/libc/stdtime/Makefile.inc +++ b/lib/libc/stdtime/Makefile.inc @@ -32,4 +32,5 @@ MLINKS+=strftime.3 strftime_l.3 MLINKS+=strptime.3 strptime_l.3 MLINKS+=time2posix.3 posix2time.3 MLINKS+=tzset.3 daylight.3 \ - tzset.3 timezone.3 + tzset.3 timezone.3 \ + tzset.3 tzname.3 diff --git a/lib/libc/stdtime/ctime.3 b/lib/libc/stdtime/ctime.3 index 96b7f775535a..6384e8bd959b 100644 --- a/lib/libc/stdtime/ctime.3 +++ b/lib/libc/stdtime/ctime.3 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 26, 2024 +.Dd September 23, 2025 .Dt CTIME 3 .Os .Sh NAME @@ -41,6 +41,8 @@ .Nm localtime , .Nm localtime_r , .Nm mktime , +.Nm offtime , +.Nm offtime_r , .Nm timegm .Nd transform binary date and time values .Sh LIBRARY @@ -68,14 +70,19 @@ .Fn localtime_r "const time_t *clock" "struct tm *result" .Ft time_t .Fn mktime "struct tm *tm" +.Ft struct tm * +.Fn offtime "const time_t *clock" "long offset" +.Ft struct tm * +.Fn offtime_r "const time_t *clock" "long offset" "struct tm *result" .Ft time_t .Fn timegm "struct tm *tm" .Sh DESCRIPTION The .Fn ctime , .Fn gmtime , +.Fn localtime , and -.Fn localtime +.Fn offtime functions all take as argument a pointer to a time value representing the time in seconds since the Epoch (00:00:00 UTC on January 1, 1970; see @@ -123,6 +130,18 @@ adjustment, and returns a pointer to a .Vt struct tm . .Pp The +.Fn offtime +function similarly converts the time value with a time zone adjustment +corresponding to the provided +.Fa offset , +which is expressed in seconds, with positive values indicating a time +zone ahead of UTC (east of the Prime Meridian). +It does not call +.Xr tzset 3 +or modify +.Va tzname . +.Pp +The .Fn ctime function adjusts the time value for the current time zone in the same manner as @@ -155,13 +174,15 @@ except the caller must provide the output buffer .Fa buf , which must be at least 26 characters long, to store the result in. The -.Fn localtime_r +.Fn localtime_r , +.Fn gmtime_r , and -.Fn gmtime_r +.Fn offtime_r functions provide the same functionality as -.Fn localtime +.Fn localtime , +.Fn gmtime , and -.Fn gmtime +.Fn offtime respectively, except the caller must provide the output buffer .Fa result . .Pp @@ -368,6 +389,12 @@ and .Fn localtime_r functions have been available since .Fx 8.0 . +The +.Fn offtime +and +.Fn offtime_r +functions were added in +.Fx 15.0 . .Sh BUGS Except for .Fn difftime , diff --git a/lib/libc/stdtime/strptime.3 b/lib/libc/stdtime/strptime.3 index 7df73d2d080a..9456fa757b85 100644 --- a/lib/libc/stdtime/strptime.3 +++ b/lib/libc/stdtime/strptime.3 @@ -171,7 +171,7 @@ is taken as noon. The .Fa %Z format specifier only accepts time zone abbreviations of the local time zone, -or the value "GMT". +and the values "GMT", "UTC", or "Z". This limitation is because of ambiguity due to of the over loading of time zone abbreviations. One such example is diff --git a/lib/libc/stdtime/strptime.c b/lib/libc/stdtime/strptime.c index 5f1293c7a267..375e49146639 100644 --- a/lib/libc/stdtime/strptime.c +++ b/lib/libc/stdtime/strptime.c @@ -546,7 +546,8 @@ label: zonestr[cp - buf] = '\0'; tzset(); if (0 == strcmp(zonestr, "GMT") || - 0 == strcmp(zonestr, "UTC")) { + 0 == strcmp(zonestr, "UTC") || + 0 == strcmp(zonestr, "Z")) { *GMTp = 1; } else if (0 == strcmp(zonestr, tzname[0])) { tm->tm_isdst = 0; diff --git a/lib/libc/stdtime/tzset.3 b/lib/libc/stdtime/tzset.3 index 94ccbec9aba7..33e6a556306d 100644 --- a/lib/libc/stdtime/tzset.3 +++ b/lib/libc/stdtime/tzset.3 @@ -28,7 +28,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 25, 2023 +.Dd September 30, 2025 .Dt TZSET 3 .Os .Sh NAME @@ -58,8 +58,8 @@ specifies how this is done. .Pp If .Ev TZ -does not appear in the environment, the best available approximation to -local wall clock time, as specified by the +does not appear in the environment, the best available approximation +to local wall clock time, as specified by the .Xr tzfile 5 Ns -format file .Pa /etc/localtime @@ -68,9 +68,7 @@ is used. If .Ev TZ appears in the environment but its value is a null string, Coordinated -Universal Time -.Pq Tn UTC -is used (without leap second correction). +Universal Time (UTC) is used (without leap second correction). .Pp If .Ev TZ @@ -81,13 +79,12 @@ the rest of its value is used as a pathname of a file from which to read the time conversion information. If the first character of the pathname is a slash .Pq Ql / -it is used as -an absolute pathname; otherwise, it is used as a pathname relative to -the system time conversion information directory. +it is used as an absolute pathname; otherwise, it is used as a +pathname relative to the system time conversion information directory. .Pp -If its value does not begin with a colon, it is first used as the pathname -of a file (as described above) from which to read the time conversion -information. +If its value does not begin with a colon, it is first used as the +pathname of a file (as described above) from which to read the time +conversion information. If that file cannot be read, the value is then interpreted as a direct specification (the format is described below) of the time conversion information. @@ -96,24 +93,23 @@ If the .Ev TZ environment variable does not specify a .Xr tzfile 5 Ns -format -file and cannot be interpreted as a direct specification, -.Tn UTC -is used. +file and cannot be interpreted as a direct specification, UTC is used. .Pp After the first call to .Nm tzset , the .Vt timezone -variable is set to the difference, in seconds, between Coordinated Universal -Time (UTC) and the local time. +variable is set to the difference, in seconds, between Coordinated +Universal Time (UTC) and the local time. The .Vt daylight variable is set to 0 if the local timezone is observing standard time. -It is set to 1 if the local timezone ever observes an alternate time, such as summer time. +It is set to 1 if the local timezone ever observes an alternate time, +such as summer time. The first element of the .Vt tzname -array is the timezone name of standard time, while the second element is the -name of the altnerative time zone. +array is the timezone name of standard time, while the second element +is the name of the altnerative time zone. .Sh SPECIFICATION FORMAT When .Ev TZ @@ -151,8 +147,7 @@ minus .Pq Ql \- , plus .Pq Ql + , -and -.Tn ASCII +and ASCII .Dv NUL are allowed. .It Em offset @@ -294,10 +289,8 @@ by the file .Em posixrules in the system time conversion information directory are used, with the -standard and summer time offsets from -.Tn UTC -replaced by those specified by -the +standard and summer time offsets from UTC replaced by those specified +by the .Em offset values in .Ev TZ . @@ -315,20 +308,14 @@ local time zone file .It Pa /usr/share/zoneinfo time zone directory .It Pa /usr/share/zoneinfo/posixrules -rules for -.Tn POSIX Ns -style -.Tn TZ Ns 's +rules for POSIX-style TZs .It Pa /usr/share/zoneinfo/Etc/GMT -for -.Tn UTC -leap seconds +for UTC leap seconds .El .Pp If the file .Pa /usr/share/zoneinfo/UTC -does not exist, -.Tn UTC -leap seconds are loaded from +does not exist, UTC leap seconds are loaded from .Pa /usr/share/zoneinfo/posixrules . .Sh SEE ALSO .Xr date 1 , diff --git a/lib/libc/string/ffs.3 b/lib/libc/string/ffs.3 index 2a5adb01c737..1cca54c0b30b 100644 --- a/lib/libc/string/ffs.3 +++ b/lib/libc/string/ffs.3 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd October 17, 2015 +.Dd October 25, 2025 .Dt FFS 3 .Os .Sh NAME @@ -80,6 +80,17 @@ argument was zero. .Sh SEE ALSO .Xr bitstring 3 , .Xr bitset 9 +.Sh STANDARDS +The +.Fn ffs +function conforms to +.St -p1003.1-2008 . +The +.Fn ffsl +and +.Fn ffsll +functions conform to +.St -p1003.1-2024 . .Sh HISTORY The .Fn ffs diff --git a/lib/libc/tests/gen/realpath2_test.c b/lib/libc/tests/gen/realpath2_test.c index f89dd99cbb72..431df8721ae0 100644 --- a/lib/libc/tests/gen/realpath2_test.c +++ b/lib/libc/tests/gen/realpath2_test.c @@ -1,6 +1,7 @@ /* * Copyright (c) 2017 Jan Kokemüller * All rights reserved. + * Copyright (c) 2025 Klara, Inc. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -25,6 +26,8 @@ */ #include <sys/param.h> +#include <sys/stat.h> + #include <errno.h> #include <fcntl.h> #include <stdio.h> @@ -34,6 +37,31 @@ #include <atf-c.h> +ATF_TC(realpath_null); +ATF_TC_HEAD(realpath_null, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test null input"); +} +ATF_TC_BODY(realpath_null, tc) +{ + ATF_REQUIRE_ERRNO(EINVAL, realpath(NULL, NULL) == NULL); +} + +ATF_TC(realpath_empty); +ATF_TC_HEAD(realpath_empty, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test empty input"); +} +ATF_TC_BODY(realpath_empty, tc) +{ + char resb[PATH_MAX] = ""; + + ATF_REQUIRE_EQ(0, mkdir("foo", 0755)); + ATF_REQUIRE_EQ(0, chdir("foo")); + ATF_REQUIRE_ERRNO(ENOENT, realpath("", resb) == NULL); + ATF_REQUIRE_STREQ("", resb); +} + ATF_TC(realpath_buffer_overflow); ATF_TC_HEAD(realpath_buffer_overflow, tc) { @@ -44,16 +72,11 @@ ATF_TC_HEAD(realpath_buffer_overflow, tc) ATF_TC_BODY(realpath_buffer_overflow, tc) { - char path[MAXPATHLEN] = { 0 }; - char resb[MAXPATHLEN] = { 0 }; - size_t i; + char path[PATH_MAX] = ""; + char resb[PATH_MAX] = ""; - path[0] = 'a'; + memset(path, 'a', sizeof(path) - 1); path[1] = '/'; - for (i = 2; i < sizeof(path) - 1; ++i) { - path[i] = 'a'; - } - ATF_REQUIRE(realpath(path, resb) == NULL); } @@ -66,9 +89,9 @@ ATF_TC_HEAD(realpath_empty_symlink, tc) ATF_TC_BODY(realpath_empty_symlink, tc) { - char path[MAXPATHLEN] = { 0 }; - char slnk[MAXPATHLEN] = { 0 }; - char resb[MAXPATHLEN] = { 0 }; + char path[PATH_MAX] = ""; + char slnk[PATH_MAX] = ""; + char resb[PATH_MAX] = ""; int fd; (void)strlcat(slnk, "empty_symlink", sizeof(slnk)); @@ -89,11 +112,70 @@ ATF_TC_BODY(realpath_empty_symlink, tc) ATF_REQUIRE(unlink(slnk) == 0); } -ATF_TP_ADD_TCS(tp) +ATF_TC(realpath_partial); +ATF_TC_HEAD(realpath_partial, tc) +{ + atf_tc_set_md_var(tc, "descr", + "Test that failure leaves a partial result"); + atf_tc_set_md_var(tc, "require.user", "unprivileged"); +} + +ATF_TC_BODY(realpath_partial, tc) { + char resb[PATH_MAX] = ""; + size_t len; + + /* scenario 1: missing directory */ + ATF_REQUIRE_EQ(0, mkdir("foo", 0755)); + ATF_REQUIRE_ERRNO(ENOENT, realpath("foo/bar/baz", resb) == NULL); + len = strnlen(resb, sizeof(resb)); + ATF_REQUIRE(len > 8 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/foo/bar", resb + len - 8); + + /* scenario 2: dead link 1 */ + ATF_REQUIRE_EQ(0, symlink("nix", "foo/bar")); + ATF_REQUIRE_ERRNO(ENOENT, realpath("foo/bar/baz", resb) == NULL); + len = strnlen(resb, sizeof(resb)); + ATF_REQUIRE(len > 8 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/foo/nix", resb + len - 8); + + /* scenario 3: missing file */ + ATF_REQUIRE_EQ(0, unlink("foo/bar")); + ATF_REQUIRE_EQ(0, mkdir("foo/bar", 0755)); + ATF_REQUIRE_ERRNO(ENOENT, realpath("foo/bar/baz", resb) == NULL); + len = strnlen(resb, sizeof(resb)); + ATF_REQUIRE(len > 12 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/foo/bar/baz", resb + len - 12); + + /* scenario 4: dead link 2 */ + ATF_REQUIRE_EQ(0, symlink("nix", "foo/bar/baz")); + ATF_REQUIRE_ERRNO(ENOENT, realpath("foo/bar/baz", resb) == NULL); + len = strnlen(resb, sizeof(resb)); + ATF_REQUIRE(len > 12 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/foo/bar/nix", resb + len - 12); + + /* scenario 5: unreadable directory */ + ATF_REQUIRE_EQ(0, chmod("foo", 000)); + ATF_REQUIRE_ERRNO(EACCES, realpath("foo/bar/baz", resb) == NULL); + len = strnlen(resb, sizeof(resb)); + ATF_REQUIRE(len > 4 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/foo", resb + len - 4); + + /* scenario 6: not a directory */ + ATF_REQUIRE_EQ(0, close(creat("bar", 0644))); + ATF_REQUIRE_ERRNO(ENOTDIR, realpath("bar/baz", resb) == NULL); + len = strnlen(resb, sizeof(resb)); + ATF_REQUIRE(len > 4 && len < sizeof(resb)); + ATF_REQUIRE_STREQ("/bar", resb + len - 4); +} +ATF_TP_ADD_TCS(tp) +{ + ATF_TP_ADD_TC(tp, realpath_null); + ATF_TP_ADD_TC(tp, realpath_empty); ATF_TP_ADD_TC(tp, realpath_buffer_overflow); ATF_TP_ADD_TC(tp, realpath_empty_symlink); + ATF_TP_ADD_TC(tp, realpath_partial); return atf_no_error(); } diff --git a/lib/libc/tests/net/Makefile b/lib/libc/tests/net/Makefile index 24cff61e8d24..ec0668633508 100644 --- a/lib/libc/tests/net/Makefile +++ b/lib/libc/tests/net/Makefile @@ -4,8 +4,10 @@ ATF_TESTS_C+= ether_test ATF_TESTS_C+= eui64_aton_test ATF_TESTS_C+= eui64_ntoa_test ATF_TESTS_CXX+= link_addr_test +ATF_TESTS_CXX+= inet_net_test CXXSTD.link_addr_test= c++20 +CXXSTD.inet_net_test= c++20 CFLAGS+= -I${.CURDIR} diff --git a/lib/libc/tests/net/inet_net_test.cc b/lib/libc/tests/net/inet_net_test.cc new file mode 100644 index 000000000000..60b60b152eca --- /dev/null +++ b/lib/libc/tests/net/inet_net_test.cc @@ -0,0 +1,333 @@ +/* + * SPDX-License-Identifier: ISC + * + * Copyright (c) 2025 Lexi Winter <ivy@FreeBSD.org> + * + * Permission to use, copy, modify, and distribute this software for any + * purpose with or without fee is hereby granted, provided that the above + * copyright notice and this permission notice appear in all copies. + * + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + */ + +/* + * Tests for inet_net_pton() and inet_net_ntop(). + */ + +#include <sys/types.h> +#include <sys/socket.h> + +#include <netinet/in.h> +#include <arpa/inet.h> + +#include <ranges> +#include <string> +#include <vector> + +#include <atf-c++.hpp> + +using namespace std::literals; + +/* + * inet_net_ntop() and inet_net_pton() for IPv4. + */ +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_inet4) +ATF_TEST_CASE_BODY(inet_net_inet4) +{ + /* + * Define a list of addresses we want to check. Each address is passed + * to inet_net_pton() to convert it to an in_addr, then we convert the + * in_addr back to a string and compare it with the expected value. We + * want to test over-long prefixes here (such as 10.0.0.1/8), so we also + * specify what the result is expected to be. + */ + + struct test_addr { + std::string input; + int bits; + std::string output; + }; + + auto test_addrs = std::vector<test_addr>{ + // Simple prefixes that fall on octet boundaries. + { "10.0.0.0/8", 8, "10/8" }, + { "10.1.0.0/16", 16, "10.1/16" }, + { "10.1.2.0/24", 24, "10.1.2/24" }, + { "10.1.2.3/32", 32, "10.1.2.3/32" }, + + // Simple prefixes with the short-form address. + { "10/8", 8, "10/8" }, + { "10.1/16", 16, "10.1/16" }, + { "10.1.2/24", 24, "10.1.2/24" }, + + // A prefix that doesn't fall on an octet boundary. + { "10.1.64/18", 18, "10.1.64/18" }, + + // An overlong prefix with bits that aren't part of the prefix. + { "10.0.0.1/8", 8, "10/8" }, + }; + + for (auto const &addr: test_addrs) { + /* + * Convert the input string to an in_addr + bits, and make + * sure the result produces the number of bits we expected. + */ + + auto in = in_addr{}; + auto bits = inet_net_pton(AF_INET, addr.input.c_str(), + &in, sizeof(in)); + ATF_REQUIRE(bits != -1); + ATF_REQUIRE_EQ(bits, addr.bits); + + /* + * Convert the in_addr back to a string + */ + + /* + * XXX: Should there be a constant for the size of the result + * buffer? For now, use ADDRSTRLEN + 3 ("/32") + 1 (NUL). + * + * Fill the buffer with 'Z', so we can check the result was + * properly terminated. + */ + auto strbuf = std::vector<char>(INET_ADDRSTRLEN + 3 + 1, 'Z'); + auto ret = inet_net_ntop(AF_INET, &in, bits, + strbuf.data(), strbuf.size()); + ATF_REQUIRE(ret != NULL); + ATF_REQUIRE_EQ(ret, strbuf.data()); + + /* Make sure the result was NUL-terminated and find the NUL */ + ATF_REQUIRE(strbuf.size() >= 1); + auto end = std::ranges::find(strbuf, '\0'); + ATF_REQUIRE(end != strbuf.end()); + + /* + * Check the result matches what we expect. Use a temporary + * string here instead of std::ranges::equal because this + * means ATF can print the mismatch. + */ + auto str = std::string(std::ranges::begin(strbuf), end); + ATF_REQUIRE_EQ(str, addr.output); + } +} + +/* + * inet_net_ntop() and inet_net_pton() for IPv6. + */ +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_inet6) +ATF_TEST_CASE_BODY(inet_net_inet6) +{ + /* + * Define a list of addresses we want to check. Each address is + * passed to inet_net_pton() to convert it to an in6_addr, then we + * convert the in6_addr back to a string and compare it with the + * expected value. We want to test over-long prefixes here (such + * as 2001:db8::1/32), so we also specify what the result is + * expected to be. + */ + + struct test_addr { + std::string input; + int bits; + std::string output; + }; + + auto test_addrs = std::vector<test_addr>{ + // A prefix with a trailing :: + { "2001:db8::/32", 32, "2001:db8::/32" }, + + // A prefix with a leading ::. Note that the output is + // different from the input because inet_ntop() renders + // this prefix with an IPv4 suffix for legacy reasons. + { "::ffff:0:0/96", 96, "::ffff:0.0.0.0/96" }, + + // The same prefix but with the IPv4 legacy form as input. + { "::ffff:0.0.0.0/96", 96, "::ffff:0.0.0.0/96" }, + + // A prefix with an infix ::. + { "2001:db8::1/128", 128, "2001:db8::1/128" }, + + // A prefix with bits set which are outside the prefix; + // these should be silently ignored. + { "2001:db8:1:1:1:1:1:1/32", 32, "2001:db8::/32" }, + + // As above but with infix ::. + { "2001:db8::1/32", 32, "2001:db8::/32" }, + + // A prefix with only ::, commonly used to represent the + // entire address space. + { "::/0", 0, "::/0" }, + + // A single address with no ::. + { "2001:db8:1:1:1:1:1:1/128", 128, "2001:db8:1:1:1:1:1:1/128" }, + + // A prefix with no ::. + { "2001:db8:1:1:0:0:0:0/64", 64, "2001:db8:1:1::/64" }, + + // A prefix which isn't on a 16-bit boundary. + { "2001:db8:c000::/56", 56, "2001:db8:c000::/56" }, + + // A prefix which isn't on a nibble boundary. + { "2001:db8:c100::/57", 57, "2001:db8:c100::/57" }, + + // An address without a prefix length, which should be treated + // as a /128. + { "2001:db8::", 128, "2001:db8::/128" }, + { "2001:db8::1", 128, "2001:db8::1/128" }, + + // Test vectors provided in PR bin/289198. + { "fe80::1/64", 64, "fe80::/64" }, + { "fe80::f000:74ff:fe54:bed2/64", + 64, "fe80::/64" }, + { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/64", + 64, "ffff:ffff:ffff:ffff::/64" }, + { "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff", 128, + "ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff/128" }, + }; + + for (auto const &addr: test_addrs) { + /* + * Convert the input string to an in6_addr + bits, and make + * sure the result produces the number of bits we expected. + */ + + auto in6 = in6_addr{}; + errno = 0; + auto bits = inet_net_pton(AF_INET6, addr.input.c_str(), + &in6, sizeof(in6)); + ATF_REQUIRE(bits != -1); + ATF_REQUIRE_EQ(bits, addr.bits); + + /* + * Convert the in6_addr back to a string + */ + + /* + * XXX: Should there be a constant for the size of the result + * buffer? For now, use ADDRSTRLEN + 4 ("/128") + 1 (NUL). + * + * Fill the buffer with 'Z', so we can check the result was + * properly terminated. + */ + auto strbuf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1, 'Z'); + auto ret = inet_net_ntop(AF_INET6, &in6, bits, + strbuf.data(), strbuf.size()); + ATF_REQUIRE(ret != NULL); + ATF_REQUIRE_EQ(ret, strbuf.data()); + + /* Make sure the result was NUL-terminated and find the NUL */ + ATF_REQUIRE(strbuf.size() >= 1); + auto end = std::ranges::find(strbuf, '\0'); + ATF_REQUIRE(end != strbuf.end()); + + /* + * Check the result matches what we expect. Use a temporary + * string here instead of std::ranges::equal because this + * means ATF can print the mismatch. + */ + auto str = std::string(std::ranges::begin(strbuf), end); + ATF_REQUIRE_EQ(str, addr.output); + } +} + +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_pton_invalid) +ATF_TEST_CASE_BODY(inet_net_pton_invalid) +{ + auto ret = int{}; + auto addr4 = in_addr{}; + auto str4 = "10.0.0.0"s; + auto addr6 = in6_addr{}; + auto str6 = "2001:db8::"s; + + /* Passing an address which is too short should be an error */ + ret = inet_net_pton(AF_INET6, str6.c_str(), &addr6, sizeof(addr6) - 1); + ATF_REQUIRE_EQ(ret, -1); + + ret = inet_net_pton(AF_INET, str4.c_str(), &addr4, sizeof(addr4) - 1); + ATF_REQUIRE_EQ(ret, -1); + + /* Test some generally invalid addresses. */ + auto invalid4 = std::vector<std::string>{ + // Prefix length too big + "10.0.0.0/33", + // Prefix length is negative + "10.0.0.0/-1", + // Prefix length is not a number + "10.0.0.0/foo", + // Input is not a network prefix + "this is not an IP address", + }; + + for (auto const &addr: invalid4) { + auto ret = inet_net_pton(AF_INET, addr.c_str(), &addr4, + sizeof(addr4)); + ATF_REQUIRE_EQ(ret, -1); + } + + auto invalid6 = std::vector<std::string>{ + // Prefix length too big + "2001:db8::/129", + // Prefix length is negative + "2001:db8::/-1", + // Prefix length is not a number + "2001:db8::/foo", + // Input is not a network prefix + "this is not an IP address", + }; + + for (auto const &addr: invalid6) { + auto ret = inet_net_pton(AF_INET6, addr.c_str(), &addr6, + sizeof(addr6)); + ATF_REQUIRE_EQ(ret, -1); + } +} + +ATF_TEST_CASE_WITHOUT_HEAD(inet_net_ntop_invalid) +ATF_TEST_CASE_BODY(inet_net_ntop_invalid) +{ + auto addr4 = in_addr{}; + auto addr6 = in6_addr{}; + auto strbuf = std::vector<char>(INET6_ADDRSTRLEN + 4 + 1); + + /* + * Passing a buffer which is too small should not overrun the buffer. + * Test this by initialising the buffer to 'Z', and only providing + * part of it to the function. + */ + + std::ranges::fill(strbuf, 'Z'); + auto ret = inet_net_ntop(AF_INET6, &addr6, 128, strbuf.data(), 1); + ATF_REQUIRE_EQ(ret, nullptr); + ATF_REQUIRE_EQ(strbuf[1], 'Z'); + + std::ranges::fill(strbuf, 'Z'); + ret = inet_net_ntop(AF_INET, &addr4, 32, strbuf.data(), 1); + ATF_REQUIRE_EQ(ret, nullptr); + ATF_REQUIRE_EQ(strbuf[1], 'Z'); + + /* Check that invalid prefix lengths return an error */ + + ret = inet_net_ntop(AF_INET6, &addr6, 129, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); + ret = inet_net_ntop(AF_INET6, &addr6, -1, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); + + ret = inet_net_ntop(AF_INET, &addr4, 33, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); + ret = inet_net_ntop(AF_INET, &addr4, -1, strbuf.data(), strbuf.size()); + ATF_REQUIRE_EQ(ret, nullptr); +} + +ATF_INIT_TEST_CASES(tcs) +{ + ATF_ADD_TEST_CASE(tcs, inet_net_inet4); + ATF_ADD_TEST_CASE(tcs, inet_net_inet6); + ATF_ADD_TEST_CASE(tcs, inet_net_pton_invalid); + ATF_ADD_TEST_CASE(tcs, inet_net_ntop_invalid); +} diff --git a/lib/libc/tests/stdio/printfloat_test.c b/lib/libc/tests/stdio/printfloat_test.c index 031859124163..4493fe1c15d3 100644 --- a/lib/libc/tests/stdio/printfloat_test.c +++ b/lib/libc/tests/stdio/printfloat_test.c @@ -398,6 +398,18 @@ ATF_TC_BODY(subnormal_float, tc) testfmt("-0X1P-149", "%A", negative); } +ATF_TC_WITHOUT_HEAD(hexadecimal_rounding_fullprec); +ATF_TC_BODY(hexadecimal_rounding_fullprec, tc) +{ + /* Double: %.13a with binary64 mantissa=53 */ + testfmt("0x1.1234567890bbbp+0", "%.13a", 0x1.1234567890bbbp+0); + +#if defined(__aarch64__) + /* On arm64, long double is IEEE binary128 (mantissa=113) */ + testfmt("0x1.3c0ca428c59fbbbbbbbbbbbbbbbbp+0", "%.28La", 0x1.3c0ca428c59fbbbbbbbbbbbbbbbbp+0L); +#endif +} + ATF_TP_ADD_TCS(tp) { @@ -414,6 +426,7 @@ ATF_TP_ADD_TCS(tp) ATF_TP_ADD_TC(tp, hexadecimal_rounding); ATF_TP_ADD_TC(tp, subnormal_double); ATF_TP_ADD_TC(tp, subnormal_float); + ATF_TP_ADD_TC(tp, hexadecimal_rounding_fullprec); return (atf_no_error()); } diff --git a/lib/libc/tests/stdtime/Makefile b/lib/libc/tests/stdtime/Makefile index adb883cc5b9a..590dea22da31 100644 --- a/lib/libc/tests/stdtime/Makefile +++ b/lib/libc/tests/stdtime/Makefile @@ -1,8 +1,11 @@ .include <src.opts.mk> ATF_TESTS_C+= strptime_test -.if ${MK_DETECT_TZ_CHANGES} != "no" ATF_TESTS_C+= detect_tz_changes_test + +CFLAGS.detect_tz_changes_test+= -I${SRCTOP}/contrib/tzcode +.if ${MK_DETECT_TZ_CHANGES} != "no" +CFLAGS.detect_tz_changes_test+= -DDETECT_TZ_CHANGES .endif TESTSDIR:= ${TESTSBASE}/${RELDIR:C/libc\/tests/libc/} diff --git a/lib/libc/tests/stdtime/detect_tz_changes_test.c b/lib/libc/tests/stdtime/detect_tz_changes_test.c index 9722546747fd..06c31c9fbc3d 100644 --- a/lib/libc/tests/stdtime/detect_tz_changes_test.c +++ b/lib/libc/tests/stdtime/detect_tz_changes_test.c @@ -4,6 +4,8 @@ * SPDX-License-Identifier: BSD-2-Clause */ +#include <sys/param.h> +#include <sys/conf.h> #include <sys/stat.h> #include <sys/wait.h> @@ -18,13 +20,34 @@ #include <time.h> #include <unistd.h> +#include "tzdir.h" + #include <atf-c.h> +struct tzcase { + const char *tzfn; + const char *expect; +}; + +static const struct tzcase tzcases[] = { + /* + * A handful of time zones and the expected result of + * strftime("%z (%Z)", tm) when that time zone is active + * and tm represents a date in the summer of 2025. + */ + { "America/Vancouver", "-0700 (PDT)" }, + { "America/New_York", "-0400 (EDT)" }, + { "Europe/London", "+0100 (BST)" }, + { "Europe/Paris", "+0200 (CEST)" }, + { "Asia/Kolkata", "+0530 (IST)" }, + { "Asia/Tokyo", "+0900 (JST)" }, + { "Australia/Canberra", "+1000 (AEST)" }, + { "UTC", "+0000 (UTC)" }, + { 0 }, +}; +static const struct tzcase utc = { "UTC", "+0000 (UTC)" }; +static const struct tzcase invalid = { "invalid", "+0000 (-00)" }; static const time_t then = 1751328000; /* 2025-07-01 00:00:00 UTC */ -static const char *tz_change_interval_sym = "__tz_change_interval"; -static int *tz_change_interval_p; -static const int tz_change_interval = 3; -static int tz_change_timeout = 90; static bool debugging; @@ -44,15 +67,15 @@ debug(const char *fmt, ...) static void change_tz(const char *tzn) { - static const char *zfn = "/usr/share/zoneinfo"; - static const char *tfn = "root/etc/.localtime"; - static const char *dfn = "root/etc/localtime"; + static const char *zfn = TZDIR; + static const char *tfn = "root" TZDEFAULT ".tmp"; + static const char *dfn = "root" TZDEFAULT; ssize_t clen; int zfd, sfd, dfd; ATF_REQUIRE((zfd = open(zfn, O_DIRECTORY | O_SEARCH)) >= 0); ATF_REQUIRE((sfd = openat(zfd, tzn, O_RDONLY)) >= 0); - ATF_REQUIRE((dfd = open(tfn, O_CREAT | O_TRUNC | O_WRONLY)) >= 0); + ATF_REQUIRE((dfd = open(tfn, O_CREAT | O_TRUNC | O_WRONLY, 0644)) >= 0); do { clen = copy_file_range(sfd, NULL, dfd, NULL, SSIZE_MAX, 0); ATF_REQUIRE_MSG(clen != -1, "failed to copy %s/%s: %m", @@ -65,6 +88,86 @@ change_tz(const char *tzn) debug("time zone %s installed", tzn); } +static void +test_tz(const char *expect) +{ + char buf[128]; + struct tm *tm; + size_t len; + + ATF_REQUIRE((tm = localtime(&then)) != NULL); + len = strftime(buf, sizeof(buf), "%z (%Z)", tm); + ATF_REQUIRE(len > 0); + ATF_CHECK_STREQ(expect, buf); +} + +ATF_TC(tz_default); +ATF_TC_HEAD(tz_default, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test default zone"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_default, tc) +{ + /* prepare chroot with no /etc/localtime */ + ATF_REQUIRE_EQ(0, mkdir("root", 0755)); + ATF_REQUIRE_EQ(0, mkdir("root/etc", 0755)); + /* enter chroot */ + ATF_REQUIRE_EQ(0, chroot("root")); + ATF_REQUIRE_EQ(0, chdir("/")); + /* check timezone */ + unsetenv("TZ"); + test_tz("+0000 (UTC)"); +} + +ATF_TC(tz_invalid_file); +ATF_TC_HEAD(tz_invalid_file, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test invalid zone file"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_invalid_file, tc) +{ + static const char *dfn = "root/etc/localtime"; + int fd; + + /* prepare chroot with bogus /etc/localtime */ + ATF_REQUIRE_EQ(0, mkdir("root", 0755)); + ATF_REQUIRE_EQ(0, mkdir("root/etc", 0755)); + ATF_REQUIRE((fd = open(dfn, O_RDWR | O_CREAT, 0644)) >= 0); + ATF_REQUIRE_EQ(8, write(fd, "invalid\n", 8)); + ATF_REQUIRE_EQ(0, close(fd)); + /* enter chroot */ + ATF_REQUIRE_EQ(0, chroot("root")); + ATF_REQUIRE_EQ(0, chdir("/")); + /* check timezone */ + unsetenv("TZ"); + test_tz(invalid.expect); +} + +ATF_TC(thin_jail); +ATF_TC_HEAD(thin_jail, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test typical thin jail scenario"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(thin_jail, tc) +{ + const struct tzcase *tzcase = tzcases; + + /* prepare chroot */ + ATF_REQUIRE_EQ(0, mkdir("root", 0755)); + ATF_REQUIRE_EQ(0, mkdir("root/etc", 0755)); + change_tz(tzcase->tzfn); + /* enter chroot */ + ATF_REQUIRE_EQ(0, chroot("root")); + ATF_REQUIRE_EQ(0, chdir("/")); + /* check timezone */ + unsetenv("TZ"); + test_tz(tzcase->expect); +} + +#ifdef DETECT_TZ_CHANGES /* * Test time zone change detection. * @@ -82,6 +185,11 @@ change_tz(const char *tzn) * after we've received and discarded the first report from the child, * which should come almost immediately on startup. */ +static const char *tz_change_interval_sym = "__tz_change_interval"; +static int *tz_change_interval_p; +static const int tz_change_interval = 3; +static int tz_change_timeout = 90; + ATF_TC(detect_tz_changes); ATF_TC_HEAD(detect_tz_changes, tc) { @@ -91,25 +199,6 @@ ATF_TC_HEAD(detect_tz_changes, tc) } ATF_TC_BODY(detect_tz_changes, tc) { - static const struct tzcase { - const char *tzfn; - const char *expect; - } tzcases[] = { - /* - * A handful of time zones and the expected result of - * strftime("%z (%Z)", tm) when that time zone is active - * and tm represents a date in the summer of 2025. - */ - { "America/Vancouver", "-0700 (PDT)" }, - { "America/New_York", "-0400 (EDT)" }, - { "Europe/London", "+0100 (BST)" }, - { "Europe/Paris", "+0200 (CEST)" }, - { "Asia/Kolkata", "+0530 (IST)" }, - { "Asia/Tokyo", "+0900 (JST)" }, - { "Australia/Canberra", "+1000 (AEST)" }, - { "UTC", "+0000 (UTC)" }, - { 0 }, - }; char obuf[1024] = ""; char ebuf[1024] = ""; struct pollfd fds[3]; @@ -271,11 +360,118 @@ ATF_TC_BODY(detect_tz_changes, tc) ATF_REQUIRE(WIFEXITED(status)); ATF_REQUIRE_EQ(0, WEXITSTATUS(status)); } +#endif /* DETECT_TZ_CHANGES */ + +static void +test_tz_env(const char *tzval, const char *expect) +{ + setenv("TZ", tzval, 1); + test_tz(expect); +} + +static void +tz_env_common(void) +{ + char path[MAXPATHLEN]; + const struct tzcase *tzcase = tzcases; + int len; + + /* relative path */ + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) + test_tz_env(tzcase->tzfn, tzcase->expect); + /* absolute path */ + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) { + len = snprintf(path, sizeof(path), "%s/%s", TZDIR, tzcase->tzfn); + ATF_REQUIRE(len > 0 && (size_t)len < sizeof(path)); + test_tz_env(path, tzcase->expect); + } + /* absolute path with additional slashes */ + for (tzcase = tzcases; tzcase->tzfn != NULL; tzcase++) { + len = snprintf(path, sizeof(path), "%s/////%s", TZDIR, tzcase->tzfn); + ATF_REQUIRE(len > 0 && (size_t)len < sizeof(path)); + test_tz_env(path, tzcase->expect); + } +} + +ATF_TC(tz_env); +ATF_TC_HEAD(tz_env, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test TZ environment variable"); +} +ATF_TC_BODY(tz_env, tc) +{ + tz_env_common(); + /* escape from TZDIR is permitted when not setugid */ + test_tz_env("../zoneinfo/UTC", utc.expect); +} + + +ATF_TC(tz_invalid_env); +ATF_TC_HEAD(tz_invalid_env, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test invalid TZ value"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_invalid_env, tc) +{ + test_tz_env("invalid", invalid.expect); + test_tz_env(":invalid", invalid.expect); +} + +ATF_TC(setugid); +ATF_TC_HEAD(setugid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test setugid process"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(setugid, tc) +{ + const struct tzcase *tzcase = tzcases; + + /* prepare chroot */ + ATF_REQUIRE_EQ(0, mkdir("root", 0755)); + ATF_REQUIRE_EQ(0, mkdir("root/etc", 0755)); + change_tz(tzcase->tzfn); + /* enter chroot */ + ATF_REQUIRE_EQ(0, chroot("root")); + ATF_REQUIRE_EQ(0, chdir("/")); + /* become setugid */ + ATF_REQUIRE_EQ(0, seteuid(UID_NOBODY)); + ATF_REQUIRE(issetugid()); + /* check timezone */ + unsetenv("TZ"); + test_tz(tzcases->expect); +} + +ATF_TC(tz_env_setugid); +ATF_TC_HEAD(tz_env_setugid, tc) +{ + atf_tc_set_md_var(tc, "descr", "Test TZ environment variable " + "in setugid process"); + atf_tc_set_md_var(tc, "require.user", "root"); +} +ATF_TC_BODY(tz_env_setugid, tc) +{ + ATF_REQUIRE_EQ(0, seteuid(UID_NOBODY)); + ATF_REQUIRE(issetugid()); + tz_env_common(); + /* escape from TZDIR is not permitted when setugid */ + test_tz_env("../zoneinfo/UTC", invalid.expect); +} ATF_TP_ADD_TCS(tp) { debugging = !getenv("__RUNNING_INSIDE_ATF_RUN") && isatty(STDERR_FILENO); + ATF_TP_ADD_TC(tp, tz_default); + ATF_TP_ADD_TC(tp, tz_invalid_file); + ATF_TP_ADD_TC(tp, thin_jail); +#ifdef DETECT_TZ_CHANGES ATF_TP_ADD_TC(tp, detect_tz_changes); +#endif /* DETECT_TZ_CHANGES */ + ATF_TP_ADD_TC(tp, tz_env); + ATF_TP_ADD_TC(tp, tz_invalid_env); + ATF_TP_ADD_TC(tp, setugid); + ATF_TP_ADD_TC(tp, tz_env_setugid); return (atf_no_error()); } diff --git a/lib/libc/tests/string/memcmp_test.c b/lib/libc/tests/string/memcmp_test.c index 5286a0b994f3..fa2f498ccfaf 100644 --- a/lib/libc/tests/string/memcmp_test.c +++ b/lib/libc/tests/string/memcmp_test.c @@ -41,14 +41,14 @@ #endif /* - * On FreeBSD we demand that memcmp returns the difference between the - * characters at the first site of mismatch. However, ISO/IEC 9899:1990 - * only specifies that a number greater than, equal to, or less than - * zero shall be returned. If a unit test for this less strict - * behaviour is desired, define RES(x) to be (((x) > 0) - ((x) < 0)). + * On FreeBSD we previously demanded that memcmp returns the difference + * between the characters at the first site of mismatch. However, + * ISO/IEC 9899:1990 only specifies that a number greater than, equal + * to, or less than zero shall be returned. If a unit test for the + * more strict behaviour is desired, define RES(x) to be (x). */ #ifndef RES -#define RES(x) (x) +#define RES(x) (((x) > 0) - ((x) < 0)) #endif static int (*memcmp_fn)(const void *, const void *, size_t); diff --git a/lib/libc/tests/tls/dso/Makefile b/lib/libc/tests/tls/dso/Makefile index 5efd8b29a6bd..783534ff7aae 100644 --- a/lib/libc/tests/tls/dso/Makefile +++ b/lib/libc/tests/tls/dso/Makefile @@ -6,6 +6,7 @@ SRCS= h_tls_dlopen.c MAN= PACKAGE= tests +NO_DEV_PACKAGE= LIBDIR= ${TESTSBASE}/lib/libc/tls SHLIB_MAJOR= 1 diff --git a/lib/libc/tests/tls_dso/Makefile b/lib/libc/tests/tls_dso/Makefile index 89296c643695..7cb8f98b431e 100644 --- a/lib/libc/tests/tls_dso/Makefile +++ b/lib/libc/tests/tls_dso/Makefile @@ -7,6 +7,7 @@ LIBDIR= ${TESTSBASE}/lib/libc/tls SHLIBDIR= ${TESTSBASE}/lib/libc/tls SHLIB_MAJOR= 1 PACKAGE= tests +NO_DEV_PACKAGE= WITHOUT_STATIC= WITHOUT_PROFILE= diff --git a/lib/libcasper/services/cap_fileargs/cap_fileargs.h b/lib/libcasper/services/cap_fileargs/cap_fileargs.h index 8207671d9753..d3a0150044d7 100644 --- a/lib/libcasper/services/cap_fileargs/cap_fileargs.h +++ b/lib/libcasper/services/cap_fileargs/cap_fileargs.h @@ -75,7 +75,7 @@ fileargs_init(int argc __unused, char *argv[] __unused, int flags, mode_t mode, cap_rights_t *rightsp __unused, int operations __unused) { fileargs_t *fa; - fa = malloc(sizeof(*fa)); + fa = (fileargs_t *)malloc(sizeof(*fa)); if (fa != NULL) { fa->fa_flags = flags; fa->fa_mode = mode; diff --git a/lib/libcom_err/Makefile b/lib/libcom_err/Makefile index f070fd534469..dab4794fcded 100644 --- a/lib/libcom_err/Makefile +++ b/lib/libcom_err/Makefile @@ -1,4 +1,5 @@ -PACKAGE= kerberos-lib +PACKAGE= kerberos +LIB_PACKAGE= LIB= com_err SRCS= com_err.c error.c diff --git a/lib/libcrypt/Makefile b/lib/libcrypt/Makefile index e939bae1bc25..2580c398155e 100644 --- a/lib/libcrypt/Makefile +++ b/lib/libcrypt/Makefile @@ -45,7 +45,7 @@ libcrypt.ald: ${.CURDIR}/${STATIC_LDSCRIPT} all: ${STATIC_LDSCRIPT} libcrypt.ald install-libcrypt.a: libcrypt.ald - ${INSTALL} ${TAG_ARGS:D${TAG_ARGS},dev} -S -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ + ${INSTALL} ${DEV_TAG_ARGS} -S -C -o ${LIBOWN} -g ${LIBGRP} -m ${LIBMODE} \ ${_INSTALLFLAGS} libcrypt.ald ${DESTDIR}${_LIBDIR}/lib${LIB}.a realinstall: install-libcrypt.a diff --git a/lib/libdiff/Makefile b/lib/libdiff/Makefile index 8541ff424de2..25f849a69e05 100644 --- a/lib/libdiff/Makefile +++ b/lib/libdiff/Makefile @@ -8,7 +8,7 @@ INTERNALLIB= # API not published or supported. SRCS= diff_atomize_text.c diff_main.c diff_myers.c \ diff_patience.c diff_output.c diff_output_plain.c \ - diff_output_unidiff.c diff_output_edscript.c recallocarray.c + diff_output_unidiff.c diff_output_edscript.c WARNS= CFLAGS+= -I${SRCTOP}/contrib/libdiff/compat/include diff --git a/lib/libedit/Makefile b/lib/libedit/Makefile index f0254c1f42bc..9161e05a7d36 100644 --- a/lib/libedit/Makefile +++ b/lib/libedit/Makefile @@ -1,7 +1,5 @@ # $NetBSD: Makefile,v 1.56 2016/03/02 19:24:20 christos Exp $ -PACKAGE=clibs - EDITDIR= ${SRCTOP}/contrib/libedit .PATH: ${EDITDIR} @@ -17,10 +15,10 @@ SRCS= chared.c chartype.c common.c el.c eln.c emacs.c filecomplete.c \ parse.c prompt.c read.c readline.c refresh.c search.c sig.c \ terminal.c tokenizer.c tokenizern.c tty.c vi.c +MAN= editline.3 +MANNODEV= editrc.5 editline.7 -MAN= editline.3 editrc.5 editline.7 - -MLINKS= \ +MLINKS=\ editline.3 el_deletestr.3 \ editline.3 el_end.3 \ editline.3 el_get.3 \ @@ -93,6 +91,7 @@ tc1.o: ${EDITDIR}/TEST/tc1.c test: tc1.o libedit.a ${DPADD} ${LIBTERMCAP} ${CC} ${CFLAGS} ${.ALLSRC} -o ${.TARGET} libedit.a ${LDADD} +.include "Makefile.inc" .include <bsd.lib.mk> CWARNFLAGS.chartype.c= ${NO_WUSE_AFTER_FREE} diff --git a/lib/libedit/Makefile.inc b/lib/libedit/Makefile.inc new file mode 100644 index 000000000000..9ec65b0d266f --- /dev/null +++ b/lib/libedit/Makefile.inc @@ -0,0 +1 @@ +PACKAGE?=runtime diff --git a/lib/libelftc/Makefile b/lib/libelftc/Makefile index a932b0c4b2a4..a6079b817d87 100644 --- a/lib/libelftc/Makefile +++ b/lib/libelftc/Makefile @@ -1,5 +1,6 @@ .include <bsd.own.mk> +PACKAGE= toolchain INTERNALLIB= ELFTCDIR= ${SRCTOP}/contrib/elftoolchain diff --git a/lib/libexpat/expat_config.h b/lib/libexpat/expat_config.h index 748f75ee157d..565404f1577b 100644 --- a/lib/libexpat/expat_config.h +++ b/lib/libexpat/expat_config.h @@ -31,7 +31,7 @@ /* Define to 1 if you have the <fcntl.h> header file. */ #define HAVE_FCNTL_H 1 -/* Define to 1 if you have the `getpagesize' function. */ +/* Define to 1 if you have the 'getpagesize' function. */ #define HAVE_GETPAGESIZE 1 /* Define to 1 if you have the `getrandom' function. */ @@ -40,10 +40,10 @@ /* Define to 1 if you have the <inttypes.h> header file. */ #define HAVE_INTTYPES_H 1 -/* Define to 1 if you have the `bsd' library (-lbsd). */ +/* Define to 1 if you have the 'bsd' library (-lbsd). */ /* #undef HAVE_LIBBSD */ -/* Define to 1 if you have a working `mmap' system call. */ +/* Define to 1 if you have a working 'mmap' system call. */ #define HAVE_MMAP 1 /* Define to 1 if you have the <stdint.h> header file. */ @@ -89,7 +89,7 @@ #define PACKAGE_NAME "expat" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "expat 2.7.1" +#define PACKAGE_STRING "expat 2.7.3" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "expat" @@ -98,15 +98,15 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "2.7.1" +#define PACKAGE_VERSION "2.7.3" -/* Define to 1 if all of the C90 standard headers exist (not just the ones +/* Define to 1 if all of the C89 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #define STDC_HEADERS 1 /* Version number of package */ -#define VERSION "2.7.1" +#define VERSION "2.7.3" /* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most significant byte first (like Motorola and SPARC, unlike Intel). */ @@ -140,10 +140,10 @@ /* Define to make XML Namespaces functionality available. */ #define XML_NS 1 -/* Define to empty if `const' does not conform to ANSI C. */ +/* Define to empty if 'const' does not conform to ANSI C. */ /* #undef const */ -/* Define to `long int' if <sys/types.h> does not define. */ +/* Define to 'long int' if <sys/types.h> does not define. */ /* #undef off_t */ #endif // ndef EXPAT_CONFIG_H diff --git a/lib/libexpat/libbsdxml.3 b/lib/libexpat/libbsdxml.3 index c91184840b70..d25249bbc155 100644 --- a/lib/libexpat/libbsdxml.3 +++ b/lib/libexpat/libbsdxml.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\"/ -.Dd April 7, 2025 +.Dd September 28, 2025 .Dt LIBBSDXML 3 .Os .Sh NAME @@ -34,7 +34,7 @@ .Sh DESCRIPTION The .Nm -library is a verbatim copy of the eXpat XML library version 2.7.1. +library is a verbatim copy of the eXpat XML library version 2.7.3. .Pp The .Nm diff --git a/lib/libfido2/Makefile b/lib/libfido2/Makefile index 10c008967e3d..021a32dd514b 100644 --- a/lib/libfido2/Makefile +++ b/lib/libfido2/Makefile @@ -43,7 +43,6 @@ SRCS+= u2f.c SRCS+= util.c SRCS+= openbsd-compat/freezero.c -SRCS+= openbsd-compat/recallocarray.c CFLAGS+= -I ${DIST}/src -I${SRCTOP}/contrib/libcbor/src -I${.CURDIR}/../libcbor CFLAGS+= -D_FIDO_INTERNAL diff --git a/lib/libgpio/Makefile b/lib/libgpio/Makefile index 42f822e97ba0..271595339792 100644 --- a/lib/libgpio/Makefile +++ b/lib/libgpio/Makefile @@ -27,6 +27,8 @@ MLINKS= gpio.3 gpio_open.3 \ gpio.3 gpio_pin_pulldown.3 \ gpio.3 gpio_pin_invin.3 \ gpio.3 gpio_pin_invout.3 \ - gpio.3 gpio_pin_pulsate.3 + gpio.3 gpio_pin_pulsate.3 \ + gpio.3 gpio_configure_events.3 \ + gpio.3 gpio_fileno.3 .include <bsd.lib.mk> diff --git a/lib/libgpio/gpio.3 b/lib/libgpio/gpio.3 index ed2860776c3c..cb413b838bd0 100644 --- a/lib/libgpio/gpio.3 +++ b/lib/libgpio/gpio.3 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd July 1, 2015 +.Dd September 3, 2025 .Dt GPIO 3 .Os .Sh NAME @@ -79,6 +79,10 @@ .Fn gpio_pin_invout "gpio_handle_t handle" "gpio_pin_t pin" .Ft int .Fn gpio_pin_pulsate "gpio_handle_t handle" "gpio_pin_t pin" +.Ft int +.Fn gpio_configure_events "gpio_handle_t handle" "uint32_t report_type" "uint32_t fifo_size" +.Ft int +.Fn gpio_fileno "gpio_handle_t handle" .Sh DESCRIPTION The .Nm libgpio @@ -125,7 +129,7 @@ The pin number should also be passed in through the variable. All other structure members will be ignored by this function. The list of flags can be found in -.Pa /usr/include/sys/gpio.h . +.In sys/gpio.h . .Pp The get or set the state of a GPIO pin, the functions .Fn gpio_pin_get @@ -156,6 +160,66 @@ and .Fn gpio_pin_pulsate are wrappers around .Fn gpio_pin_set_flags . +.Pp +The function +.Fn gpio_configure_events +configures the interrupt report type and FIFO size for buffered +gpio interrupts. +The report type is specified by one of the following values: +.Bl -tag -width indent +.It Dv GPIO_EVENT_REPORT_DETAIL +Events are reported using +.Ft struct gpio_event_detail . +.It Dv GPIO_EVENT_REPORT_SUMMARY +Events are reported using +.Ft struct gpio_event_summary . +.El +.Pp +By default, the report type is +.Dv GPIO_EVENT_REPORT_DETAIL , +with a default FIFO size of 2 * number of pins belonging to the +.Ft gpio_device_t +instance. +The FIFO argument is only meaningful when +.Fa report_type +is +.Dv GPIO_EVENT_REPORT_DETAIL . +The structures associated with each report type are defined in +.In sys/gpio.h . +This setting is tracked on a per device instance basis. +The FIFO size cannot be reduced below the default value, +nor can it be decreased after it has been increased. +If any pin on the device has already been configured for interrupts, +.Fn gpio_configure_events +fails and returns -1. +On success 0 is returned. +.Pp +The function +.Fn gpio_fileno +returns the file descriptor associated with the +.Ft gpio_handle_t +instance. +.Pp +File operations have the following semantics: +.Bl -tag -width "read (2)" +.It Xr read 2 +Read one or more gpio interrupts that have occured +since the last successful +.Xr read 2 . +The results are placed into the output buffer +of the type previously established via +.Fn gpio_configure_events . +If there are no pending interrupts, +.Xr read 2 +blocks until an interrupt occurs, unless +.Dv O_NONBLOCK +is set. +.It Xr poll 2 +When receiving notification via +.Xr poll 2 +or similar interfaces, the file descriptor becomes readable when +one or more gpio interrupts are pending. +.El .Sh EXAMPLES The following example shows how to configure pin 16 as output and then drive it high: diff --git a/lib/libgpio/gpio.c b/lib/libgpio/gpio.c index e37ac1cdf8e8..c789bb34cacd 100644 --- a/lib/libgpio/gpio.c +++ b/lib/libgpio/gpio.c @@ -274,3 +274,23 @@ gpio_pin_pulsate(gpio_handle_t handle, gpio_pin_t pin) { return (gpio_pin_set_flag(handle, pin, GPIO_PIN_PULSATE)); } + +int +gpio_configure_events(gpio_handle_t handle, uint32_t report_type, + uint32_t fifo_size) +{ + struct gpio_event_config gpevent_config; + + gpevent_config.gp_report_type = report_type; + gpevent_config.gp_fifo_size = fifo_size; + if (ioctl(handle, GPIOCONFIGEVENTS, &gpevent_config) < 0) + return (-1); + + return (0); +} + +int +gpio_fileno(gpio_handle_t handle) +{ + return (handle); +} diff --git a/lib/libgpio/libgpio.h b/lib/libgpio/libgpio.h index 35651ecd8cca..abffc7b1b6ab 100644 --- a/lib/libgpio/libgpio.h +++ b/lib/libgpio/libgpio.h @@ -102,6 +102,19 @@ int gpio_pin_pulldown(gpio_handle_t, gpio_pin_t); int gpio_pin_invin(gpio_handle_t, gpio_pin_t); int gpio_pin_invout(gpio_handle_t, gpio_pin_t); int gpio_pin_pulsate(gpio_handle_t, gpio_pin_t); +/* + * GPIO event reporting configuration + * + * Set the event reporting type, the default being GPIO_EVENT_REPORT_DETAIL, + * and fifo size of 2 * number of pins belonging to the gpioc device instance. + * FIFO size can only be changed when report_type is GPIO_EVENT_REPORT_DETAIL. + */ +int gpio_configure_events(gpio_handle_t, uint32_t, uint32_t); +/* + * Retrieve the file descriptor associated with gpio_handle_t, which can + * be used for gpio interrupts. + */ +int gpio_fileno(gpio_handle_t); __END_DECLS diff --git a/lib/libifconfig/Makefile b/lib/libifconfig/Makefile index e8e0651dc0d6..02629eb88f25 100644 --- a/lib/libifconfig/Makefile +++ b/lib/libifconfig/Makefile @@ -1,4 +1,3 @@ -PACKAGE= lib${LIB} LIB= ifconfig INTERNALLIB= true @@ -18,6 +17,7 @@ SRCS= libifconfig.c \ libifconfig_internal.c \ libifconfig_lagg.c \ libifconfig_media.c \ + libifconfig_nl.c \ libifconfig_sfp.c GEN= libifconfig_sfp_tables.h \ diff --git a/lib/libifconfig/Symbol.map b/lib/libifconfig/Symbol.map index 2d80fb31652a..2e11ff963909 100644 --- a/lib/libifconfig/Symbol.map +++ b/lib/libifconfig/Symbol.map @@ -40,7 +40,6 @@ FBSD_1.6 { ifconfig_open; ifconfig_set_capability; ifconfig_set_description; - ifconfig_set_fib; ifconfig_set_metric; ifconfig_set_mtu; ifconfig_set_name; @@ -81,7 +80,6 @@ FBSD_1.6 { ifconfig_sfp_fc_speed_symbol; ifconfig_sfp_id_description; ifconfig_sfp_id_display; - ifconfig_sfp_id_is_qsfp; ifconfig_sfp_id_symbol; ifconfig_sfp_rev_description; ifconfig_sfp_rev_symbol; diff --git a/lib/libifconfig/libifconfig.h b/lib/libifconfig/libifconfig.h index b2f0cf9744ea..817f52bd094e 100644 --- a/lib/libifconfig/libifconfig.h +++ b/lib/libifconfig/libifconfig.h @@ -35,6 +35,8 @@ #include <netinet/ip_carp.h> #include <netinet6/in6_var.h> +#include <stdbool.h> + #define ND6_IFF_DEFAULTIF 0x8000 typedef enum { @@ -171,7 +173,6 @@ int ifconfig_set_name(ifconfig_handle_t *h, const char *name, const char *newname); int ifconfig_get_orig_name(ifconfig_handle_t *h, const char *ifname, char **orig_name); -int ifconfig_set_fib(ifconfig_handle_t *h, const char *name, int fib); int ifconfig_get_fib(ifconfig_handle_t *h, const char *name, int *fib); int ifconfig_set_mtu(ifconfig_handle_t *h, const char *name, const int mtu); int ifconfig_get_mtu(ifconfig_handle_t *h, const char *name, int *mtu); @@ -382,3 +383,12 @@ int ifconfig_set_vlantag(ifconfig_handle_t *h, const char *name, * length of *lenp * IFNAMSIZ bytes. */ int ifconfig_list_cloners(ifconfig_handle_t *h, char **bufp, size_t *lenp); + +/** Brings the interface up/down + * @param h An open ifconfig state object + * @param ifname The interface name + * @param up true to bring the interface up, false to bring it down + * @return 0 on success, nonzero on failure. + * On failure, the error info on the handle is set. + */ +int ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up); diff --git a/lib/libifconfig/libifconfig_nl.c b/lib/libifconfig/libifconfig_nl.c new file mode 100644 index 000000000000..7d9decabe26f --- /dev/null +++ b/lib/libifconfig/libifconfig_nl.c @@ -0,0 +1,72 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2025, Muhammad Saheed <saheed@FreeBSD.org> + */ + +#include <netlink/netlink.h> +#include <netlink/netlink_snl.h> +#include <netlink/route/common.h> +#include <netlink/route/interface.h> + +#include "libifconfig.h" +#include "libifconfig_internal.h" + +static int ifconfig_modify_flags(ifconfig_handle_t *h, const char *ifname, + int ifi_flags, int ifi_change); + +static int +ifconfig_modify_flags(ifconfig_handle_t *h, const char *ifname, int ifi_flags, + int ifi_change) +{ + int ret = 0; + struct snl_state ss; + struct snl_writer nw; + struct nlmsghdr *hdr; + struct ifinfomsg *ifi; + struct snl_errmsg_data e = { 0 }; + + if (!snl_init(&ss, NETLINK_ROUTE)) { + ifconfig_error(h, NETLINK, ENOTSUP); + return (-1); + } + + snl_init_writer(&ss, &nw); + hdr = snl_create_msg_request(&nw, NL_RTM_NEWLINK); + ifi = snl_reserve_msg_object(&nw, struct ifinfomsg); + snl_add_msg_attr_string(&nw, IFLA_IFNAME, ifname); + + ifi->ifi_flags = ifi_flags; + ifi->ifi_change = ifi_change; + + hdr = snl_finalize_msg(&nw); + if (hdr == NULL) { + ifconfig_error(h, NETLINK, ENOMEM); + ret = -1; + goto out; + } + + if (!snl_send_message(&ss, hdr)) { + ifconfig_error(h, NETLINK, EIO); + ret = -1; + goto out; + } + + if (!snl_read_reply_code(&ss, hdr->nlmsg_seq, &e)) { + ifconfig_error(h, NETLINK, e.error); + ret = -1; + goto out; + } + +out: + snl_free(&ss); + return (ret); +} + +int +ifconfig_set_up(ifconfig_handle_t *h, const char *ifname, bool up) +{ + int flag = up ? IFF_UP : ~IFF_UP; + + return (ifconfig_modify_flags(h, ifname, flag, IFF_UP)); +} diff --git a/lib/libiscsiutil/Makefile b/lib/libiscsiutil/Makefile index c99fb6366536..d9762302fd40 100644 --- a/lib/libiscsiutil/Makefile +++ b/lib/libiscsiutil/Makefile @@ -1,6 +1,5 @@ LIB= iscsiutil INTERNALLIB= -PACKAGE= iscsi INCS= libiscsiutil.h diff --git a/lib/libjail/jail.c b/lib/libjail/jail.c index 30282e67866c..ad3348af0d2d 100644 --- a/lib/libjail/jail.c +++ b/lib/libjail/jail.c @@ -75,8 +75,9 @@ int jail_setv(int flags, ...) { va_list ap, tap; - struct jailparam *jp; - const char *name, *value; + struct jailparam *jp, *jp_desc; + const char *name; + char *value, *desc_value; int njp, jid; /* Create the parameter list and import the parameters. */ @@ -86,15 +87,24 @@ jail_setv(int flags, ...) (void)va_arg(tap, char *); va_end(tap); jp = alloca(njp * sizeof(struct jailparam)); - for (njp = 0; (name = va_arg(ap, char *)) != NULL;) { + jp_desc = NULL; + desc_value = NULL; + for (njp = 0; (name = va_arg(ap, char *)) != NULL; njp++) { value = va_arg(ap, char *); if (jailparam_init(jp + njp, name) < 0) goto error; - if (jailparam_import(jp + njp++, value) < 0) + if (jailparam_import(jp + njp, value) < 0) goto error; + if (!strcmp(name, "desc") && + (flags & (JAIL_GET_DESC | JAIL_OWN_DESC))) { + jp_desc = jp + njp; + desc_value = value; + } } va_end(ap); jid = jailparam_set(jp, njp, flags); + if (jid > 0 && jp_desc != NULL) + sprintf(desc_value, "%d", *(int *)jp_desc->jp_value); jailparam_free(jp, njp); return (jid); @@ -112,9 +122,10 @@ int jail_getv(int flags, ...) { va_list ap, tap; - struct jailparam *jp, *jp_lastjid, *jp_jid, *jp_name, *jp_key; + struct jailparam *jp, *jp_desc, *jp_lastjid, *jp_jid, *jp_name, *jp_key; char *valarg, *value; - const char *name, *key_value, *lastjid_value, *jid_value, *name_value; + const char *name, *key_value, *desc_value, *lastjid_value, *jid_value; + const char *name_value; int njp, i, jid; /* Create the parameter list and find the key. */ @@ -126,15 +137,19 @@ jail_getv(int flags, ...) jp = alloca(njp * sizeof(struct jailparam)); va_copy(tap, ap); - jp_lastjid = jp_jid = jp_name = NULL; - lastjid_value = jid_value = name_value = NULL; + jp_desc = jp_lastjid = jp_jid = jp_name = NULL; + desc_value = lastjid_value = jid_value = name_value = NULL; for (njp = 0; (name = va_arg(tap, char *)) != NULL; njp++) { value = va_arg(tap, char *); if (jailparam_init(jp + njp, name) < 0) { va_end(tap); goto error; } - if (!strcmp(jp[njp].jp_name, "lastjid")) { + if (!strcmp(jp[njp].jp_name, "desc") && + (flags & (JAIL_USE_DESC | JAIL_AT_DESC))) { + jp_desc = jp + njp; + desc_value = value; + } else if (!strcmp(jp[njp].jp_name, "lastjid")) { jp_lastjid = jp + njp; lastjid_value = value; } else if (!strcmp(jp[njp].jp_name, "jid")) { @@ -147,7 +162,10 @@ jail_getv(int flags, ...) } va_end(tap); /* Import the key parameter. */ - if (jp_lastjid != NULL) { + if (jp_desc != NULL && (flags & JAIL_USE_DESC)) { + jp_key = jp_desc; + key_value = desc_value; + } else if (jp_lastjid != NULL) { jp_key = jp_lastjid; key_value = lastjid_value; } else if (jp_jid != NULL && strtol(jid_value, NULL, 10) != 0) { @@ -163,6 +181,9 @@ jail_getv(int flags, ...) } if (jailparam_import(jp_key, key_value) < 0) goto error; + if (jp_desc != NULL && jp_desc != jp_key && + jailparam_import(jp_desc, desc_value) < 0) + goto error; /* Get the jail and export the parameters. */ jid = jailparam_get(jp, njp, flags); if (jid < 0) @@ -571,7 +592,7 @@ int jailparam_get(struct jailparam *jp, unsigned njp, int flags) { struct iovec *jiov; - struct jailparam *jp_lastjid, *jp_jid, *jp_name, *jp_key; + struct jailparam *jp_desc, *jp_lastjid, *jp_jid, *jp_name, *jp_key; int i, ai, ki, jid, arrays, sanity; unsigned j; @@ -580,10 +601,13 @@ jailparam_get(struct jailparam *jp, unsigned njp, int flags) * Find the key and any array parameters. */ jiov = alloca(sizeof(struct iovec) * 2 * (njp + 1)); - jp_lastjid = jp_jid = jp_name = NULL; + jp_desc = jp_lastjid = jp_jid = jp_name = NULL; arrays = 0; for (ai = j = 0; j < njp; j++) { - if (!strcmp(jp[j].jp_name, "lastjid")) + if (!strcmp(jp[j].jp_name, "desc") && + (flags & (JAIL_USE_DESC | JAIL_AT_DESC))) + jp_desc = jp + j; + else if (!strcmp(jp[j].jp_name, "lastjid")) jp_lastjid = jp + j; else if (!strcmp(jp[j].jp_name, "jid")) jp_jid = jp + j; @@ -599,7 +623,9 @@ jailparam_get(struct jailparam *jp, unsigned njp, int flags) ai++; } } - jp_key = jp_lastjid ? jp_lastjid : + jp_key = jp_desc && jp_desc->jp_valuelen == sizeof(int) && + jp_desc->jp_value && (flags & JAIL_USE_DESC) ? jp_desc : + jp_lastjid ? jp_lastjid : jp_jid && jp_jid->jp_valuelen == sizeof(int) && jp_jid->jp_value && *(int *)jp_jid->jp_value ? jp_jid : jp_name; if (jp_key == NULL || jp_key->jp_value == NULL) { @@ -622,6 +648,14 @@ jailparam_get(struct jailparam *jp, unsigned njp, int flags) jiov[ki].iov_len = JAIL_ERRMSGLEN; ki++; jail_errmsg[0] = 0; + if (jp_desc != NULL && jp_desc != jp_key) { + jiov[ki].iov_base = jp_desc->jp_name; + jiov[ki].iov_len = strlen(jp_desc->jp_name) + 1; + ki++; + jiov[ki].iov_base = jp_desc->jp_value; + jiov[ki].iov_len = jp_desc->jp_valuelen; + ki++; + } if (arrays && jail_get(jiov, ki, flags) < 0) { if (!jail_errmsg[0]) snprintf(jail_errmsg, sizeof(jail_errmsg), @@ -649,7 +683,7 @@ jailparam_get(struct jailparam *jp, unsigned njp, int flags) jiov[ai].iov_base = jp[j].jp_value; memset(jiov[ai].iov_base, 0, jiov[ai].iov_len); ai++; - } else if (jp + j != jp_key) { + } else if (jp + j != jp_key && jp + j != jp_desc) { jiov[i].iov_base = jp[j].jp_name; jiov[i].iov_len = strlen(jp[j].jp_name) + 1; i++; @@ -886,13 +920,21 @@ jailparam_type(struct jailparam *jp) } desc; int mib[CTL_MAXNAME]; - /* The "lastjid" parameter isn't real. */ + /* + * Some pseudo-parameters don't show up in the sysctl + * parameter list. + */ name = jp->jp_name; if (!strcmp(name, "lastjid")) { jp->jp_valuelen = sizeof(int); jp->jp_ctltype = CTLTYPE_INT | CTLFLAG_WR; return (0); } + if (!strcmp(name, "desc")) { + jp->jp_valuelen = sizeof(int); + jp->jp_ctltype = CTLTYPE_INT | CTLFLAG_RW; + return (0); + } /* Find the sysctl that describes the parameter. */ mib[0] = 0; diff --git a/lib/libkvm/kvm_proc.c b/lib/libkvm/kvm_proc.c index b2b7c6ecce56..fed483978e62 100644 --- a/lib/libkvm/kvm_proc.c +++ b/lib/libkvm/kvm_proc.c @@ -150,13 +150,14 @@ kvm_proclist(kvm_t *kd, int what, int arg, struct proc *p, kp->ki_cr_flags = 0; if (ucred.cr_flags & CRED_FLAG_CAPMODE) kp->ki_cr_flags |= KI_CRF_CAPABILITY_MODE; - if (ucred.cr_ngroups > KI_NGROUPS) { + if (1 + ucred.cr_ngroups > KI_NGROUPS) { kp->ki_ngroups = KI_NGROUPS; kp->ki_cr_flags |= KI_CRF_GRP_OVERFLOW; } else - kp->ki_ngroups = ucred.cr_ngroups; - kvm_read(kd, (u_long)ucred.cr_groups, kp->ki_groups, - kp->ki_ngroups * sizeof(gid_t)); + kp->ki_ngroups = 1 + ucred.cr_ngroups; + kp->ki_groups[0] = ucred.cr_gid; + kvm_read(kd, (u_long)ucred.cr_groups, kp->ki_groups + 1, + (kp->ki_ngroups - 1) * sizeof(gid_t)); if (ucred.cr_prison != NULL) { if (KREAD(kd, (u_long)ucred.cr_prison, &pr)) { _kvm_err(kd, kd->program, diff --git a/lib/liblzma/Makefile b/lib/liblzma/Makefile index 27e0521f5884..9c6ece74ffd0 100644 --- a/lib/liblzma/Makefile +++ b/lib/liblzma/Makefile @@ -1,4 +1,6 @@ -PACKAGE=lib${LIB} +PACKAGE= xz +LIB_PACKAGE= + LIB= lzma LZMADIR= ${SRCTOP}/contrib/xz/src/liblzma diff --git a/lib/libmagic/Makefile b/lib/libmagic/Makefile index 150ddc686241..fe04f5ea68c8 100644 --- a/lib/libmagic/Makefile +++ b/lib/libmagic/Makefile @@ -11,7 +11,9 @@ SHLIB_MAJOR= 4 .if !make(build-tools) LIBADD= z .endif -MAN= libmagic.3 magic.5 + +MAN= libmagic.3 +MANNODEV= magic.5 SRCS= apprentice.c apptype.c ascmagic.c buffer.c cdf.c cdf_time.c \ compress.c der.c encoding.c fsmagic.c funcs.c is_json.c \ @@ -73,8 +75,8 @@ magic.mgc: mkmagic FILEVER!= awk '$$1 == "\#define" && $$2 == "VERSION" { print $$3; exit }' \ ${.CURDIR}/config.h -CLEANFILES+= ${MAN} -.for mp in ${MAN} +CLEANFILES+= ${MAN} ${MANNODEV} +.for mp in ${MAN} ${MANNODEV} ${mp}: ${mp:C/[0-9]/man/} sed -e 's/__FSECTION__/5/g' -e 's/__CSECTION__/1/g' \ -e 's/__VERSION__/${FILEVER}/g' \ diff --git a/lib/libmd/Makefile b/lib/libmd/Makefile index 547a134fc440..c4ab767c8b2f 100644 --- a/lib/libmd/Makefile +++ b/lib/libmd/Makefile @@ -108,7 +108,7 @@ CFLAGS+= -DWEAK_REFS CFLAGS.skein_block.c+= -DSKEIN_LOOP=995 .PATH: ${.CURDIR}/${MACHINE_ARCH} ${SRCTOP}/sys/crypto/sha2 .PATH: ${SRCTOP}/sys/crypto/skein ${SRCTOP}/sys/crypto/skein/${MACHINE_ARCH} -.PATH: ${SRCTOP}/sys/kern +.PATH: ${SRCTOP}/sys/crypto USE_ASM_SOURCES?=1 .if defined(BOOTSTRAPPING) || ${MK_MACHDEP_OPTIMIZATIONS} == no @@ -117,6 +117,13 @@ USE_ASM_SOURCES:=0 .endif .if ${USE_ASM_SOURCES} != 0 +.if exists(${MACHINE_ARCH}/md5block.S) +SRCS+= md5block.S +CFLAGS+= -DMD5_ASM +.if exists(${MACHINE_ARCH}/md5dispatch.c) +SRCS+= md5dispatch.c +.endif +.endif .if exists(${MACHINE_ARCH}/sha1block.S) SRCS+= sha1block.S CFLAGS+= -DSHA1_ASM diff --git a/lib/libmd/aarch64/md5block.S b/lib/libmd/aarch64/md5block.S new file mode 100644 index 000000000000..b928c8dd795a --- /dev/null +++ b/lib/libmd/aarch64/md5block.S @@ -0,0 +1,206 @@ +/*- + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/elf_common.h> +#include <machine/asm.h> + +# optimal instruction sequence for k = \key + \m +.macro addkm key, m +.if 0x100000000 - \key > 0x00ffffff + movz k, #\key & 0xffff + movk k, #\key >> 16, lsl #16 + add k, k, \m +.elseif 0x100000000 - \key > 0x0000ffff + sub k, \m, #(0x100000000 - \key) & 0xfff000 + sub k, k, #(0x100000000 - \key) & 0xfff +.else + movz k, #0x100000000 - \key + sub k, \m, k +.endif +.endm + +.macro round a, b, c, d, f, key, m, s + \f f, \b, \c, \d + addkm \key, \m // k[i] + m[g] + add \a, \a, k // k[i] + m[g] + a + add \a, \a, f // k[i] + m[g] + a + f + ror \a, \a, #32-\s + add \a, \a, \b +.endm + + /* f = b ? c : d */ +.macro f0 f, b, c, d + eor \f, \c, \d + and \f, \f, \b + eor \f, \f, \d +.endm + + /* + * special cased round 1 function + * f1 = d ? b : c = (d & b) + (~d & c) + */ +.macro round1 a, b, c, d, key, m, s + bic tmp, \c, \d // ~d & c + addkm \key, \m // k[i] + m[g] + add \a, \a, k // k[i] + m[g] + a + and f, \b, \d // d & b + add \a, \a, tmp // k[i] + m[g] + a + (~d & c) + add \a, \a, f // k[i] + m[g] + a + (~d & c) + (d & b) + ror \a, \a, #32-\s + add \a, \a, \b +.endm + + /* f = b ^ c ^ d */ +.macro f2 f, b, c, d + eor \f, \c, \d + eor \f, \f, \b +.endm + + /* f = c ^ (b | ~d) */ +.macro f3 f, b, c, d + orn \f, \b, \d + eor \f, \f, \c +.endm + + /* do 4 rounds */ +.macro rounds f, m0, m1, m2, m3, s0, s1, s2, s3, k0, k1, k2, k3 + round a, b, c, d, \f, \k0, \m0, \s0 + round d, a, b, c, \f, \k1, \m1, \s1 + round c, d, a, b, \f, \k2, \m2, \s2 + round b, c, d, a, \f, \k3, \m3, \s3 +.endm + + /* do 4 rounds with f0, f1, f2, f3 */ +.macro rounds0 m0, m1, m2, m3, k0, k1, k2, k3 + rounds f0, \m0, \m1, \m2, \m3, 7, 12, 17, 22, \k0, \k1, \k2, \k3 +.endm + +.macro rounds1 m0, m1, m2, m3, k0, k1, k2, k3 + round1 a, b, c, d, \k0, \m0, 5 + round1 d, a, b, c, \k1, \m1, 9 + round1 c, d, a, b, \k2, \m2, 14 + round1 b, c, d, a, \k3, \m3, 20 +.endm + +.macro rounds2 m0, m1, m2, m3, k0, k1, k2, k3 + rounds f2, \m0, \m1, \m2, \m3, 4, 11, 16, 23, \k0, \k1, \k2, \k3 +.endm + +.macro rounds3 m0, m1, m2, m3, k0, k1, k2, k3 + rounds f3, \m0, \m1, \m2, \m3, 6, 10, 15, 21, \k0, \k1, \k2, \k3 +.endm + + /* md5block(MD5_CTX, buf, len) */ +ENTRY(_libmd_md5block) +ctx .req x0 +buf .req x1 +len .req x2 +end .req x2 // aliases len +a .req w3 +b .req w4 +c .req w5 +d .req w6 +f .req w7 +tmp .req w8 +k .req w9 +m0 .req w10 +m1 .req w11 +m2 .req w12 +m3 .req w13 +m4 .req w14 +m5 .req w15 +m6 .req w16 +m7 .req w17 + // x18 is the platform register +m8 .req w19 +m9 .req w20 +m10 .req w21 +m11 .req w22 +m12 .req w23 +m13 .req w24 +m14 .req w25 +m15 .req w26 + +a_ .req m0 +b_ .req m7 +c_ .req m14 +d_ .req m5 + + stp x19, x20, [sp, #-0x40]! + stp x21, x22, [sp, #0x10] + stp x23, x24, [sp, #0x20] + stp x25, x26, [sp, #0x30] + + bics len, len, #63 // length in blocks + add end, buf, len // end pointer + + beq .Lend // was len == 0 after BICS? + + ldp a, b, [ctx, #0] + ldp c, d, [ctx, #8] + + /* first eight rounds interleaved with data loads */ +.Lloop: ldp m0, m1, [buf, #0] + round a, b, c, d, f0, 0xd76aa478, m0, 7 + ldp m2, m3, [buf, #8] + round d, a, b, c, f0, 0xe8c7b756, m1, 12 + ldp m4, m5, [buf, #16] + round c, d, a, b, f0, 0x242070db, m2, 17 + ldp m6, m7, [buf, #24] + round b, c, d, a, f0, 0xc1bdceee, m3, 22 + + ldp m8, m9, [buf, #32] + round a, b, c, d, f0, 0xf57c0faf, m4, 7 + ldp m10, m11, [buf, #40] + round d, a, b, c, f0, 0x4787c62a, m5, 12 + ldp m12, m13, [buf, #48] + round c, d, a, b, f0, 0xa8304613, m6, 17 + ldp m14, m15, [buf, #56] + round b, c, d, a, f0, 0xfd469501, m7, 22 + + /* remaining rounds use the roundsX macros */ + rounds0 m8, m9, m10, m11, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be + rounds0 m12, m13, m14, m15, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 + + rounds1 m1, m6, m11, m0, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa + rounds1 m5, m10, m15, m4, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 + rounds1 m9, m14, m3, m8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed + rounds1 m13, m2, m7, m12, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a + + rounds2 m5, m8, m11, m14, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c + rounds2 m1, m4, m7, m10, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 + rounds2 m13, m0, m3, m6, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 + rounds2 m9, m12, m15, m2, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 + + rounds3 m0, m7, m14, m5, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 + rounds3 m12, m3, m10, m1, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 + rounds3 m8, m15, m6, m13, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 + rounds3 m4, m11, m2, m9, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 + + ldp a_, b_, [ctx, #0] + ldp c_, d_, [ctx, #8] + add a, a, a_ + add b, b, b_ + add c, c, c_ + add d, d, d_ + stp a, b, [ctx, #0] + stp c, d, [ctx, #8] + + add buf, buf, #64 + cmp buf, end + bne .Lloop + +.Lend: ldp x25, x26, [sp, #0x30] + ldp x23, x24, [sp, #0x20] + ldp x21, x22, [sp, #0x10] + ldp x19, x20, [sp], #0x40 + + ret +END(_libmd_md5block) + +GNU_PROPERTY_AARCH64_FEATURE_1_NOTE(GNU_PROPERTY_AARCH64_FEATURE_1_VAL) + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libmd/aarch64/sha1block.S b/lib/libmd/aarch64/sha1block.S index 56a0297efadd..e16fb36342fd 100644 --- a/lib/libmd/aarch64/sha1block.S +++ b/lib/libmd/aarch64/sha1block.S @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2024 Robert Clausecker <fuz@freebsd.org> + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> * * SPDX-License-Identifier: BSD-2-Clause * diff --git a/lib/libmd/aarch64/sha1dispatch.c b/lib/libmd/aarch64/sha1dispatch.c index e34bf0a1a344..045527044320 100644 --- a/lib/libmd/aarch64/sha1dispatch.c +++ b/lib/libmd/aarch64/sha1dispatch.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2024 Robert Clausecker <fuz@freebsd.org> + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> * * SPDX-License-Identifier: BSD-2-Clause */ diff --git a/lib/libmd/amd64/md5block.S b/lib/libmd/amd64/md5block.S new file mode 100644 index 000000000000..0dd594dd5dc2 --- /dev/null +++ b/lib/libmd/amd64/md5block.S @@ -0,0 +1,363 @@ +/*- + * Copyright (c) 2024, 2025 Robert Clausecker <fuz@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <machine/asm.h> + +/* apply the round keys to the four round functions */ +.macro allrounds rfn0, rfn1, rfn2, rfn3 + \rfn0 0, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee + \rfn0 4, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501 + \rfn0 8, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be + \rfn0 12, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821 + + \rfn1 16, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa + \rfn1 20, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8 + \rfn1 24, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed + \rfn1 28, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a + + \rfn2 32, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c + \rfn2 36, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70 + \rfn2 40, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05 + \rfn2 44, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665 + + \rfn3 48, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039 + \rfn3 52, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1 + \rfn3 56, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1 + \rfn3 60, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391 +.endm + + // md5block(MD5_CTX, buf, len) +ENTRY(_libmd_md5block_baseline) +.macro round a, b, c, d, f, k, m, s + \f %ebp, \b, \c, \d + add $\k, \a // a + k[i] + add ((\m)%16*4)(%rsi), \a // a + k[i] + m[g] + add %ebp, \a // a + k[i] + m[g] + f + rol $\s, \a + add \b, \a +.endm + + // f = b ? c : d +.macro f0 f, b, c, d + mov \c, \f + xor \d, \f + and \b, \f + xor \d, \f +.endm + + // f = d ? b : c +.macro f1 f, b, c, d + mov \c, \f + xor \b, \f + and \d, \f + xor \c, \f +.endm + + // f = b ^ c ^ d +.macro f2 f, b, c, d + mov \c, \f + xor \d, \f + xor \b, \f +.endm + + // f = c ^ (b | ~d) +.macro f3 f, b, c, d + mov $-1, \f + xor \d, \f + or \b, \f + xor \c, \f +.endm + + // do 4 rounds +.macro rounds f, p, q, s0, s1, s2, s3, k0, k1, k2, k3 + round %eax, %ebx, %ecx, %edx, \f, \k0, \p*0+\q, \s0 + round %edx, %eax, %ebx, %ecx, \f, \k1, \p*1+\q, \s1 + round %ecx, %edx, %eax, %ebx, \f, \k2, \p*2+\q, \s2 + round %ebx, %ecx, %edx, %eax, \f, \k3, \p*3+\q, \s3 +.endm + + // do 4 rounds with f0, f1, f2, f3 +.macro rounds0 i, k0, k1, k2, k3 + rounds f0, 1, \i, 7, 12, 17, 22, \k0, \k1, \k2, \k3 +.endm + +.macro rounds1 i, k0, k1, k2, k3 + rounds f1, 5, 5*\i+1, 5, 9, 14, 20, \k0, \k1, \k2, \k3 +.endm + +.macro rounds2 i, k0, k1, k2, k3 + rounds f2, 3, 3*\i+5, 4, 11, 16, 23, \k0, \k1, \k2, \k3 +.endm + +.macro rounds3 i, k0, k1, k2, k3 + rounds f3, 7, 7*\i, 6, 10, 15, 21, \k0, \k1, \k2, \k3 +.endm + + push %rbx + push %rbp + push %r12 + + and $~63, %rdx // length in blocks + lea (%rsi, %rdx, 1), %r12 // end pointer + + mov (%rdi), %eax // a + mov 4(%rdi), %ebx // b + mov 8(%rdi), %ecx // c + mov 12(%rdi), %edx // d + + cmp %rsi, %r12 // any data to process? + je .Lend + + .balign 16 +.Lloop: mov %eax, %r8d + mov %ebx, %r9d + mov %ecx, %r10d + mov %edx, %r11d + + allrounds rounds0, rounds1, rounds2, rounds3 + + add %r8d, %eax + add %r9d, %ebx + add %r10d, %ecx + add %r11d, %edx + + add $64, %rsi + cmp %rsi, %r12 + jne .Lloop + + mov %eax, (%rdi) + mov %ebx, 4(%rdi) + mov %ecx, 8(%rdi) + mov %edx, 12(%rdi) + +.Lend: pop %r12 + pop %rbp + pop %rbx + ret +END(_libmd_md5block_baseline) + + /* + * An implementation leveraging the ANDN instruction + * from BMI1 to shorten some dependency chains. + */ +ENTRY(_libmd_md5block_bmi1) + // special-cased round 1 + // f1 = d ? b : c = (d & b) + (~d & c) +.macro round1 a, b, c, d, k, m, s + andn \c, \d, %edi // ~d & c + add $\k, \a // a + k[i] + mov \d, %ebp + add ((\m)%16*4)(%rsi), \a // a + k[i] + m[g] + and \b, %ebp // d & b + add %edi, \a // a + k[i] + m[g] + (~d & c) + add %ebp, \a // a + k[i] + m[g] + (~d & c) + (d & b) + rol $\s, \a + add \b, \a +.endm + + // special-cased round 3 + // f3 = c ^ (b | ~d) = ~(c ^ ~b & d) = -1 - (c ^ ~b & d) +.macro round3 a, b, c, d, k, m, s + andn \d, \b, %ebp + add $\k - 1, \a // a + k[i] - 1 + add ((\m)%16*4)(%rsi), \a // a + k[i] + m[g] + xor \c, %ebp + sub %ebp, \a // a + k[i] + m[g] + f + rol $\s, \a + add \b, \a +.endm + + .purgem rounds1 +.macro rounds1 i, k0, k1, k2, k3 + round1 %eax, %ebx, %ecx, %edx, \k0, 5*\i+ 1, 5 + round1 %edx, %eax, %ebx, %ecx, \k1, 5*\i+ 6, 9 + round1 %ecx, %edx, %eax, %ebx, \k2, 5*\i+11, 14 + round1 %ebx, %ecx, %edx, %eax, \k3, 5*\i+16, 20 +.endm + + .purgem rounds3 +.macro rounds3 i, k0, k1, k2, k3 + round3 %eax, %ebx, %ecx, %edx, \k0, 7*\i+ 0, 6 + round3 %edx, %eax, %ebx, %ecx, \k1, 7*\i+ 7, 10 + round3 %ecx, %edx, %eax, %ebx, \k2, 7*\i+14, 15 + round3 %ebx, %ecx, %edx, %eax, \k3, 7*\i+21, 21 +.endm + + push %rbx + push %rbp + push %r12 + + and $~63, %rdx // length in blocks + lea (%rsi, %rdx, 1), %r12 // end pointer + + mov (%rdi), %eax // a + mov 4(%rdi), %ebx // b + mov 8(%rdi), %ecx // c + mov 12(%rdi), %edx // d + + cmp %rsi, %r12 // any data to process? + je 0f + + push %rdi + + .balign 16 +1: mov %eax, %r8d + mov %ebx, %r9d + mov %ecx, %r10d + mov %edx, %r11d + + allrounds rounds0, rounds1, rounds2, rounds3 + + add %r8d, %eax + add %r9d, %ebx + add %r10d, %ecx + add %r11d, %edx + + add $64, %rsi + cmp %rsi, %r12 + jne 1b + + pop %rdi + mov %eax, (%rdi) + mov %ebx, 4(%rdi) + mov %ecx, 8(%rdi) + mov %edx, 12(%rdi) + +0: pop %r12 + pop %rbp + pop %rbx + ret +END(_libmd_md5block_bmi1) + +#ifndef _KERNEL + /* + * An implementation leveraging AVX-512 for its VPTERNLOGD + * instruction. We're using only XMM registers here, + * avoiding costly thermal licensing. + */ +ENTRY(_libmd_md5block_avx512) +.macro vround a, b, c, d, f, i, m, mi, s + vmovdqa \b, %xmm4 + vpternlogd $\f, \d, \c, %xmm4 + vpaddd 4*(\i)(%rax){1to4}, \m, %xmm5 // m[g] + k[i] +.if \mi != 0 + vpshufd $0x55 * \mi, %xmm5, %xmm5 // broadcast to each dword +.endif + vpaddd %xmm5, \a, \a // a + k[i] + m[g] + vpaddd %xmm4, \a, \a // a + k[i] + m[g] + f + vprold $\s, \a, \a + vpaddd \b, \a, \a +.endm + +.macro vrounds f, i, m0, i0, m1, i1, m2, i2, m3, i3, s0, s1, s2, s3 + vround %xmm0, %xmm1, %xmm2, %xmm3, \f, \i+0, \m0, \i0, \s0 + vround %xmm3, %xmm0, %xmm1, %xmm2, \f, \i+1, \m1, \i1, \s1 + vround %xmm2, %xmm3, %xmm0, %xmm1, \f, \i+2, \m2, \i2, \s2 + vround %xmm1, %xmm2, %xmm3, %xmm0, \f, \i+3, \m3, \i3, \s3 +.endm + +/* + * d c b f0 f1 f2 f3 + * 0 0 0 0 0 0 1 + * 1 0 0 1 0 1 0 + * 0 1 0 0 1 1 0 + * 1 1 0 1 0 0 1 + * 0 0 1 0 0 1 1 + * 1 0 1 0 1 0 1 + * 0 1 1 1 1 0 0 + * 1 1 1 1 1 1 0 + */ + +.macro vrounds0 i, m + vrounds 0xca, \i, \m, 0, \m, 1, \m, 2, \m, 3, 7, 12, 17, 22 +.endm + +.macro vrounds1 i, m0, i0, m1, i1, m2, i2, m3, i3 + vrounds 0xe4, \i, \m0, \i0, \m1, \i1, \m2, \i2, \m3, \i3, 5, 9, 14, 20 +.endm + +.macro vrounds2 i, m0, i0, m1, i1, m2, i2, m3, i3 + vrounds 0x96, \i, \m0, \i0, \m1, \i1, \m2, \i2, \m3, \i3, 4, 11, 16, 23 +.endm + +.macro vrounds3 i, m0, i0, m1, i1, m2, i2, m3, i3 + vrounds 0x39, \i, \m0, \i0, \m1, \i1, \m2, \i2, \m3, \i3, 6, 10, 15, 21 +.endm + + and $~63, %rdx // length in blocks + add %rsi, %rdx // end pointer + + vmovd (%rdi), %xmm0 // a + vmovd 4(%rdi), %xmm1 // b + vmovd 8(%rdi), %xmm2 // c + vmovd 12(%rdi), %xmm3 // d + + lea keys(%rip), %rax + + cmp %rsi, %rdx // any data to process? + je 0f + + .balign 16 +1: vmovdqu 0*4(%rsi), %xmm8 // message words + vmovdqu 4*4(%rsi), %xmm9 + vmovdqu 8*4(%rsi), %xmm10 + vmovdqu 12*4(%rsi), %xmm11 + + vmovdqa %xmm0, %xmm12 // stash old state variables + vmovdqa %xmm1, %xmm13 + vmovdqa %xmm2, %xmm14 + vmovdqa %xmm3, %xmm15 + + vrounds0 0, %xmm8 + vrounds0 4, %xmm9 + vrounds0 8, %xmm10 + vrounds0 12, %xmm11 + + vrounds1 16, %xmm8, 1, %xmm9, 2, %xmm10, 3, %xmm8, 0 + vrounds1 20, %xmm9, 1, %xmm10, 2, %xmm11, 3, %xmm9, 0 + vrounds1 24, %xmm10, 1, %xmm11, 2, %xmm8, 3, %xmm10, 0 + vrounds1 28, %xmm11, 1, %xmm8, 2, %xmm9, 3, %xmm11, 0 + + vrounds2 32, %xmm9, 1, %xmm10, 0, %xmm10, 3, %xmm11, 2 + vrounds2 36, %xmm8, 1, %xmm9, 0, %xmm9, 3, %xmm10, 2 + vrounds2 40, %xmm11, 1, %xmm8, 0, %xmm8, 3, %xmm9, 2 + vrounds2 44 %xmm10, 1, %xmm11, 0, %xmm11, 3, %xmm8, 2 + + vrounds3 48, %xmm8, 0, %xmm9, 3, %xmm11, 2, %xmm9, 1 + vrounds3 52, %xmm11, 0, %xmm8, 3, %xmm10, 2, %xmm8, 1 + vrounds3 56, %xmm10, 0, %xmm11, 3, %xmm9, 2, %xmm11, 1 + vrounds3 60, %xmm9, 0, %xmm10, 3, %xmm8, 2, %xmm10, 1 + + vpaddd %xmm12, %xmm0, %xmm0 + vpaddd %xmm13, %xmm1, %xmm1 + vpaddd %xmm14, %xmm2, %xmm2 + vpaddd %xmm15, %xmm3, %xmm3 + + add $64, %rsi + cmp %rsi, %rdx + jne 1b + + vmovd %xmm0, (%rdi) + vmovd %xmm1, 4(%rdi) + vmovd %xmm2, 8(%rdi) + vmovd %xmm3, 12(%rdi) + +0: ret +END(_libmd_md5block_avx512) + + // round keys, for use in md5block_avx512 + .section .rodata + .balign 16 + +.macro putkeys i, a, b, c, d + .4byte \a, \b, \c, \d +.endm + +keys: allrounds putkeys, putkeys, putkeys, putkeys + .size keys, .-keys +#endif /* !defined(_KERNEL) */ + + .section .note.GNU-stack,"",%progbits diff --git a/lib/libmd/amd64/md5dispatch.c b/lib/libmd/amd64/md5dispatch.c new file mode 100644 index 000000000000..dd2131c5a57c --- /dev/null +++ b/lib/libmd/amd64/md5dispatch.c @@ -0,0 +1,41 @@ +/*- + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> + * + * SPDX-License-Identifier: BSD-2-Clause + */ + +#include <sys/types.h> +#include <sys/md5.h> + +#include <machine/cpufunc.h> +#include <machine/specialreg.h> +#include <stdint.h> +#include <string.h> +#include <x86/ifunc.h> + +extern void _libmd_md5block_baseline(MD5_CTX *, const void *, size_t); +extern void _libmd_md5block_bmi1(MD5_CTX *, const void *, size_t); +extern void _libmd_md5block_avx512(MD5_CTX *, const void *, size_t); + +DEFINE_UIFUNC(, void, _libmd_md5block, (MD5_CTX *, const void *, size_t)) +{ + if ((cpu_stdext_feature & (CPUID_STDEXT_AVX512F | CPUID_STDEXT_AVX512VL)) + == (CPUID_STDEXT_AVX512F | CPUID_STDEXT_AVX512VL)) { + u_int regs[4]; + char cpu_vendor[12]; + + do_cpuid(0, regs); + ((u_int *)&cpu_vendor)[0] = regs[1]; + ((u_int *)&cpu_vendor)[1] = regs[3]; + ((u_int *)&cpu_vendor)[2] = regs[2]; + + /* the AVX-512 kernel performs poorly on AMD */ + if (memcmp(cpu_vendor, AMD_VENDOR_ID, sizeof(cpu_vendor)) != 0) + return (_libmd_md5block_avx512); + } + + if (cpu_stdext_feature & CPUID_STDEXT_BMI1) + return (_libmd_md5block_bmi1); + else + return (_libmd_md5block_baseline); +} diff --git a/lib/libmd/amd64/sha1block.S b/lib/libmd/amd64/sha1block.S index f1291ef2647a..6ef083178abc 100644 --- a/lib/libmd/amd64/sha1block.S +++ b/lib/libmd/amd64/sha1block.S @@ -1,6 +1,6 @@ /*- * Copyright (c) 2013 The Go Authors. All rights reserved. - * Copyright (c) 2024 Robert Clausecker <fuz@freebsd.org> + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> * * Adapted from Go's crypto/sha1/sha1block_amd64.s. * diff --git a/lib/libmd/amd64/sha1dispatch.c b/lib/libmd/amd64/sha1dispatch.c index 86509195d56e..c82a60334739 100644 --- a/lib/libmd/amd64/sha1dispatch.c +++ b/lib/libmd/amd64/sha1dispatch.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2016 The Go Authors. All rights reserved. - * Copyright (c) 2024 Robert Clausecker <fuz@freebsd.org> + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> * * Adapted from Go's crypto/sha1/sha1block_amd64.go. * diff --git a/lib/libmd/sha1c.c b/lib/libmd/sha1c.c index 128e0b991742..02132d720dac 100644 --- a/lib/libmd/sha1c.c +++ b/lib/libmd/sha1c.c @@ -1,6 +1,6 @@ /*- * Copyright (c) 2009 The Go Authors. All rights reserved. - * Copyright (c) 2024 Robert Clausecker <fuz@freebsd.org> + * Copyright (c) 2024 Robert Clausecker <fuz@FreeBSD.org> * * Adapted from Go's crypto/sha1/sha1.go. * diff --git a/lib/libmilter/Makefile b/lib/libmilter/Makefile index dd6a481d1a15..ff16b4d00297 100644 --- a/lib/libmilter/Makefile +++ b/lib/libmilter/Makefile @@ -1,6 +1,6 @@ .include <src.opts.mk> -PACKAGE=sendmail +PACKAGE=lib${LIB} SENDMAIL_DIR=${SRCTOP}/contrib/sendmail .PATH: ${SENDMAIL_DIR}/libmilter ${SENDMAIL_DIR}/libsm diff --git a/lib/libmixer/Makefile b/lib/libmixer/Makefile index a0bb37a85fb8..49621ad1f188 100644 --- a/lib/libmixer/Makefile +++ b/lib/libmixer/Makefile @@ -1,3 +1,5 @@ +PACKAGE= sound + LIB= mixer SRCS= ${LIB}.c INCS= ${LIB}.h diff --git a/lib/libnetbsd/Makefile b/lib/libnetbsd/Makefile index 1639caf20d6b..4088c2b57176 100644 --- a/lib/libnetbsd/Makefile +++ b/lib/libnetbsd/Makefile @@ -1,6 +1,5 @@ .include <bsd.own.mk> -PACKAGE=lib${LIB} LIB= netbsd CFLAGS+= -I${.CURDIR} diff --git a/lib/libnvmf/Makefile b/lib/libnvmf/Makefile index b01f5ab82cac..945c31a2986c 100644 --- a/lib/libnvmf/Makefile +++ b/lib/libnvmf/Makefile @@ -3,7 +3,6 @@ LIB= nvmf INTERNALLIB= -PACKAGE= nvmf INCS= libnvmf.h diff --git a/lib/libnvmf/nvmf_tcp.c b/lib/libnvmf/nvmf_tcp.c index 6f41ca7ff502..48ddabaf506a 100644 --- a/lib/libnvmf/nvmf_tcp.c +++ b/lib/libnvmf/nvmf_tcp.c @@ -728,7 +728,7 @@ nvmf_tcp_handle_r2t(struct nvmf_tcp_qpair *qp, struct nvmf_tcp_rxpdu *pdu) } /* - * XXX: The spec does not specify how to handle R2T tranfers + * XXX: The spec does not specify how to handle R2T transfers * out of range of the original command. */ data_len = le32toh(r2t->r2tl); diff --git a/lib/libopenbsd/Makefile b/lib/libopenbsd/Makefile index dca1c08b0aed..80ae0f90621a 100644 --- a/lib/libopenbsd/Makefile +++ b/lib/libopenbsd/Makefile @@ -1,9 +1,12 @@ -PACKAGE=lib${LIB} LIB= openbsd SRCS= imsg-buffer.c \ imsg.c \ - ohash.c \ - recallocarray.c + ohash.c +.if defined(BOOTSTRAPPING) +.PATH: ${SRCTOP}/lib/libc/stdlib +SRCS+= recallocarray.c +.endif + .if !defined(BOOTSTRAPPING) # Skip getdtablecount.c when bootstrapping since it doesn't compile for Linux # and is not used by any of the bootstrap tools diff --git a/lib/libpam/libpam/Makefile b/lib/libpam/libpam/Makefile index dd19eba5c1ec..c6db4992bb36 100644 --- a/lib/libpam/libpam/Makefile +++ b/lib/libpam/libpam/Makefile @@ -148,10 +148,10 @@ MAN?= openpam.3 \ pam_strerror.3 \ pam_verror.3 \ pam_vinfo.3 \ - pam_vprompt.3 \ - pam.conf.5 + pam_vprompt.3 -MLINKS?= pam.conf.5 pam.d.5 +MANNODEV?= pam.conf.5 +MANNODEVLINKS?= pam.conf.5 pam.d.5 CFLAGS+= -DLOCALBASE=\"${LOCALBASE:U/usr/local}\" CFLAGS+= -I${OPENPAM}/include diff --git a/lib/libpam/modules/modules.inc b/lib/libpam/modules/modules.inc index f3ab65333f4f..1e9eb8970317 100644 --- a/lib/libpam/modules/modules.inc +++ b/lib/libpam/modules/modules.inc @@ -30,4 +30,4 @@ MODULES += pam_ssh .endif MODULES += pam_tacplus MODULES += pam_unix -MODULES += pam_xdg
\ No newline at end of file +MODULES += pam_xdg diff --git a/lib/libpam/modules/pam_xdg/pam_xdg.8 b/lib/libpam/modules/pam_xdg/pam_xdg.8 index 9b335751a9fb..031010953e98 100644 --- a/lib/libpam/modules/pam_xdg/pam_xdg.8 +++ b/lib/libpam/modules/pam_xdg/pam_xdg.8 @@ -50,7 +50,6 @@ Use an alternate base directory .Bl -tag -width indent .It Ev XDG_RUNTIME_DIR The location of the runtime files base directory created by this module. -Note that the module does not set this environment variable. .El .Sh STANDARDS The directory created by this module conforms to the diff --git a/lib/libpam/static_libpam/Makefile b/lib/libpam/static_libpam/Makefile index a1f0f209dea1..8830f09ef0da 100644 --- a/lib/libpam/static_libpam/Makefile +++ b/lib/libpam/static_libpam/Makefile @@ -42,6 +42,7 @@ NO_PIC= # Avoid redundancy with the master Makefile. MAN= +MANNODEV= INCS= MLINKS= MK_TESTS= no diff --git a/lib/libpcap/Makefile b/lib/libpcap/Makefile index 9ba91504852b..c4bd175b502a 100644 --- a/lib/libpcap/Makefile +++ b/lib/libpcap/Makefile @@ -109,10 +109,11 @@ MAN= pcap.3 \ pcap_strerror.3 \ pcap_tstamp_type_name_to_val.3 \ pcap_tstamp_type_val_to_name.3 \ - pcap-savefile.5 \ - pcap-filter.7 \ - pcap-linktype.7 \ - pcap-tstamp.7 + pcap-savefile.5 + +MANNODEV= pcap-filter.7 \ + pcap-linktype.7 \ + pcap-tstamp.7 MLINKS= \ pcap_datalink_val_to_name.3 pcap_datalink_val_to_description.3 \ @@ -129,7 +130,7 @@ MLINKS= \ pcap_setnonblock.3 pcap_getnonblock.3 # Our man pages are a special copy from the distdir. See below. -CLEANFILES+=${MAN} +CLEANFILES+=${MAN} ${MANNODEV} CLEANFILES+=grammar.y scanner.h tokdefs.h YFLAGS+=-p pcap_ @@ -175,7 +176,7 @@ tokdefs.h: grammar.h .NOMETA # # Magic to convert the man pages to something non Solarish # -.for _page in ${MAN} +.for _page in ${MAN} ${MANNODEV} ${_page}: if [ -f ${PCAP_DISTDIR}/${_page:S/3$/3pcap/} ]; then \ F=${_page:S/3$/3pcap/}; \ diff --git a/lib/libpfctl/Makefile b/lib/libpfctl/Makefile index d301d7850b44..4b16d81181a3 100644 --- a/lib/libpfctl/Makefile +++ b/lib/libpfctl/Makefile @@ -1,4 +1,3 @@ -PACKAGE= lib${LIB} LIB= pfctl INTERNALLIB= true diff --git a/lib/libpfctl/libpfctl.c b/lib/libpfctl/libpfctl.c index cbd9d4677146..17576066fcfd 100644 --- a/lib/libpfctl/libpfctl.c +++ b/lib/libpfctl/libpfctl.c @@ -391,6 +391,8 @@ static const struct snl_attr_parser ap_getstatus[] = { { .type = PF_GS_CHKSUM, .off = _OUT(pf_chksum), .arg_u32 = PF_MD5_DIGEST_LENGTH, .cb = snl_attr_get_bytes }, { .type = PF_GS_BCOUNTERS, .off = _OUT(bcounters), .arg_u32 = 2 * 2, .cb = snl_attr_get_uint64_array }, { .type = PF_GS_PCOUNTERS, .off = _OUT(pcounters), .arg_u32 = 2 * 2 * 2, .cb = snl_attr_get_uint64_array }, + { .type = PF_GS_NCOUNTERS, .off = _OUT(ncounters), .cb = snl_attr_get_counters }, + { .type = PF_GS_FRAGMENTS, .off = _OUT(fragments), .cb = snl_attr_get_uint64 }, }; SNL_DECLARE_PARSER(getstatus_parser, struct genlmsghdr, snl_f_p_empty, ap_getstatus); #undef _OUT @@ -429,6 +431,7 @@ pfctl_get_status_h(struct pfctl_handle *h) TAILQ_INIT(&status->lcounters); TAILQ_INIT(&status->fcounters); TAILQ_INIT(&status->scounters); + TAILQ_INIT(&status->ncounters); while ((hdr = snl_read_reply_multi(&h->ss, seq_id, &e)) != NULL) { if (! snl_parse_nlmsg(&h->ss, hdr, &getstatus_parser, status)) @@ -558,6 +561,10 @@ pfctl_free_status(struct pfctl_status *status) free(c->name); free(c); } + TAILQ_FOREACH_SAFE(c, &status->ncounters, entry, tmp) { + free(c->name); + free(c); + } free(status); } @@ -1284,8 +1291,8 @@ snl_add_msg_attr_pf_rule(struct snl_writer *nw, uint32_t type, const struct pfct snl_add_msg_attr_u8(nw, PF_RT_KEEP_STATE, r->keep_state); snl_add_msg_attr_u8(nw, PF_RT_AF, r->af); snl_add_msg_attr_u8(nw, PF_RT_PROTO, r->proto); - snl_add_msg_attr_u8(nw, PF_RT_TYPE, r->type); - snl_add_msg_attr_u8(nw, PF_RT_CODE, r->code); + snl_add_msg_attr_u16(nw, PF_RT_TYPE_2, r->type); + snl_add_msg_attr_u16(nw, PF_RT_CODE_2, r->code); snl_add_msg_attr_u8(nw, PF_RT_FLAGS, r->flags); snl_add_msg_attr_u8(nw, PF_RT_FLAGSET, r->flagset); snl_add_msg_attr_u8(nw, PF_RT_MIN_TTL, r->min_ttl); @@ -1694,6 +1701,9 @@ static struct snl_attr_parser ap_getrule[] = { { .type = PF_RT_SRC_NODES_ROUTE, .off = _OUT(r.src_nodes_type[PF_SN_ROUTE]), .cb = snl_attr_get_uint64 }, { .type = PF_RT_PKTRATE, .off = _OUT(r.pktrate), .arg = &pfctl_threshold_parser, .cb = snl_attr_get_nested }, { .type = PF_RT_MAX_PKT_SIZE, .off =_OUT(r.max_pkt_size), .cb = snl_attr_get_uint16 }, + { .type = PF_RT_TYPE_2, .off = _OUT(r.type), .cb = snl_attr_get_uint16 }, + { .type = PF_RT_CODE_2, .off = _OUT(r.code), .cb = snl_attr_get_uint16 }, + { .type = PF_RT_EXPTIME, .off = _OUT(r.exptime), .cb = snl_attr_get_time_t }, }; #undef _OUT SNL_DECLARE_PARSER(getrule_parser, struct genlmsghdr, snl_f_p_empty, ap_getrule); @@ -2453,7 +2463,7 @@ _pfctl_table_add_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, struct p snl_add_msg_attr_table(&nw, PF_TA_TABLE, tbl); snl_add_msg_attr_u32(&nw, PF_TA_FLAGS, flags); - for (int i = 0; i < size && i < 256; i++) + for (int i = 0; i < size; i++) snl_add_msg_attr_pfr_addr(&nw, PF_TA_ADDR, &addrs[i]); if ((hdr = snl_finalize_msg(&nw)) == NULL) @@ -2481,19 +2491,18 @@ pfctl_table_add_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, struct pf int ret; int off = 0; int partial_added; + int chunk_size; do { - ret = _pfctl_table_add_addrs_h(h, tbl, &addr[off], size - off, &partial_added, flags); + chunk_size = MIN(size - off, 256); + ret = _pfctl_table_add_addrs_h(h, tbl, &addr[off], chunk_size, &partial_added, flags); if (ret != 0) break; if (nadd) *nadd += partial_added; - off += partial_added; + off += chunk_size; } while (off < size); - if (nadd) - *nadd = off; - return (ret); } @@ -2521,7 +2530,7 @@ _pfctl_table_del_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, struct p snl_add_msg_attr_table(&nw, PF_TA_TABLE, tbl); snl_add_msg_attr_u32(&nw, PF_TA_FLAGS, flags); - for (int i = 0; i < size && i < 256; i++) + for (int i = 0; i < size; i++) snl_add_msg_attr_pfr_addr(&nw, PF_TA_ADDR, &addrs[i]); if ((hdr = snl_finalize_msg(&nw)) == NULL) @@ -2572,20 +2581,19 @@ pfctl_table_del_addrs_h(struct pfctl_handle *h, struct pfr_table *tbl, struct pf int ret; int off = 0; int partial_deleted; + int chunk_size; do { - ret = _pfctl_table_del_addrs_h(h, tbl, &addr[off], size - off, + chunk_size = MIN(size - off, 256); + ret = _pfctl_table_del_addrs_h(h, tbl, &addr[off], chunk_size, &partial_deleted, flags); if (ret != 0) break; if (ndel) *ndel += partial_deleted; - off += partial_deleted; + off += chunk_size; } while (off < size); - if (ndel) - *ndel = off; - return (ret); } @@ -3194,6 +3202,9 @@ pfctl_get_ruleset(struct pfctl_handle *h, const char *path, uint32_t nr, struct continue; } + rs->nr = nr; + strlcpy(rs->path, path, sizeof(rs->path)); + return (e.error); } diff --git a/lib/libpfctl/libpfctl.h b/lib/libpfctl/libpfctl.h index f6c8f6a2ccdb..5880e1a88371 100644 --- a/lib/libpfctl/libpfctl.h +++ b/lib/libpfctl/libpfctl.h @@ -62,6 +62,8 @@ struct pfctl_status { struct pfctl_status_counters lcounters; struct pfctl_status_counters fcounters; struct pfctl_status_counters scounters; + struct pfctl_status_counters ncounters; + uint64_t fragments; uint64_t pcounters[2][2][2]; uint64_t bcounters[2][2]; }; @@ -261,8 +263,8 @@ struct pfctl_rule { uint8_t keep_state; sa_family_t af; uint8_t proto; - uint8_t type; - uint8_t code; + uint16_t type; + uint16_t code; uint8_t flags; uint8_t flagset; uint8_t min_ttl; @@ -283,6 +285,8 @@ struct pfctl_rule { struct pf_addr addr; uint16_t port; } divert; + + time_t exptime; }; TAILQ_HEAD(pfctl_rulequeue, pfctl_rule); diff --git a/lib/libpmc/Makefile b/lib/libpmc/Makefile index 8728b0c1c76d..590f719ebff4 100644 --- a/lib/libpmc/Makefile +++ b/lib/libpmc/Makefile @@ -1,5 +1,5 @@ -LIB_CXX= pmc - +PACKAGE=pmc +LIB_CXX=pmc SRCS= libpmc.c pmclog.c libpmc_pmu_util.c libpmc_json.cc INCS= pmc.h pmclog.h pmcformat.h diff --git a/lib/libpmcstat/Makefile b/lib/libpmcstat/Makefile index d1d23cdd57c7..7ca93329e20f 100644 --- a/lib/libpmcstat/Makefile +++ b/lib/libpmcstat/Makefile @@ -1,4 +1,3 @@ -PACKAGE=lib${LIB} LIB= pmcstat INTERNALLIB= diff --git a/lib/libprocstat/libprocstat.c b/lib/libprocstat/libprocstat.c index eb8137f6c76f..df77cabcd36b 100644 --- a/lib/libprocstat/libprocstat.c +++ b/lib/libprocstat/libprocstat.c @@ -1330,8 +1330,7 @@ procstat_get_vnode_info_kvm(kvm_t *kd, struct filestat *fst, return (1); } vn->vn_mntdir = getmnton(kd, vnode.v_mount); - if ((vnode.v_type == VBLK || vnode.v_type == VCHR) && - vnode.v_rdev != NULL){ + if (VTYPE_ISDEV(vnode.v_type) && vnode.v_rdev != NULL) { vn->vn_dev = dev2udev(kd, vnode.v_rdev); (void)kdevtoname(kd, vnode.v_rdev, vn->vn_devname); } else { @@ -1974,6 +1973,7 @@ procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp) struct ucred ucred; gid_t *groups; size_t len; + unsigned int ngroups; assert(kd != NULL); assert(kp != NULL); @@ -1991,19 +1991,22 @@ procstat_getgroups_kvm(kvm_t *kd, struct kinfo_proc *kp, unsigned int *cntp) proc.p_ucred, kp->ki_pid); return (NULL); } - len = ucred.cr_ngroups * sizeof(gid_t); + ngroups = 1 + ucred.cr_ngroups; + len = ngroups * sizeof(gid_t); groups = malloc(len); if (groups == NULL) { warn("malloc(%zu)", len); return (NULL); } - if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups, len)) { + groups[0] = ucred.cr_gid; + if (!kvm_read_all(kd, (unsigned long)ucred.cr_groups, groups + 1, + len - sizeof(gid_t))) { warnx("can't read groups at %p for pid %d", ucred.cr_groups, kp->ki_pid); free(groups); return (NULL); } - *cntp = ucred.cr_ngroups; + *cntp = ngroups; return (groups); } diff --git a/lib/libradius/Makefile b/lib/libradius/Makefile index 0ab83d5418b1..b6857a71260a 100644 --- a/lib/libradius/Makefile +++ b/lib/libradius/Makefile @@ -31,7 +31,9 @@ INCS= radlib.h radlib_vs.h CFLAGS+= -Wall CFLAGS+= -DOPENSSL_API_COMPAT=0x10100000L SHLIB_MAJOR= 4 -MAN= libradius.3 radius.conf.5 + +MAN= libradius.3 +MANNODEV= radius.conf.5 MLINKS+=libradius.3 rad_acct_open.3 \ libradius.3 rad_add_server.3 \ diff --git a/lib/librpcsvc/Makefile b/lib/librpcsvc/Makefile index 04e57990a29d..bdd01c91adab 100644 --- a/lib/librpcsvc/Makefile +++ b/lib/librpcsvc/Makefile @@ -14,7 +14,7 @@ OTHERSRCS= rnusers.c rstat.c rwall.c SECRPCSRCS= secretkey.c xcrypt.c .if ${MK_NIS} != "no" -OTHERSRCS+= yp_passwd.c +OTHERSRCS+= yp_passwd.c yp_update.c .endif RPCCOM= RPCGEN_CPP=${CPP:Q} rpcgen -C diff --git a/lib/librpcsvc/yp_update.c b/lib/librpcsvc/yp_update.c new file mode 100644 index 000000000000..8a31b2c22d9b --- /dev/null +++ b/lib/librpcsvc/yp_update.c @@ -0,0 +1,199 @@ +/*- + * SPDX-License-Identifier: BSD-4-Clause + * + * Copyright (c) 1995, 1996 + * Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved. + * + * 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. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bill Paul. + * 4. Neither the name of the author nor the names of any co-contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY Bill Paul 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 Bill Paul 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. + * + * ypupdate client-side library function. + * + * Written by Bill Paul <wpaul@ctr.columbia.edu> + * Center for Telecommunications Research + * Columbia University, New York City + */ + +#include <sys/cdefs.h> +#include <stdlib.h> +#include <rpc/rpc.h> +#include <rpcsvc/yp_prot.h> +#include <rpcsvc/ypclnt.h> +#include <rpcsvc/ypupdate_prot.h> +#include <rpc/key_prot.h> + +#ifndef WINDOW +#define WINDOW (60*60) +#endif + +#ifndef TIMEOUT +#define TIMEOUT 300 +#endif + +int +yp_update(char *domain, char *map, unsigned int ypop, char *key, int keylen, + char *data, int datalen) +{ + char *master; + int rval; + unsigned int res; + struct ypupdate_args upargs; + struct ypdelete_args delargs; + CLIENT *clnt; + char netname[MAXNETNAMELEN+1]; + des_block des_key; + struct timeval timeout; + + /* Get the master server name for 'domain.' */ + if ((rval = yp_master(domain, map, &master))) + return(rval); + + /* Check that ypupdated is running there. */ + if (getrpcport(master, YPU_PROG, YPU_VERS, ypop)) + return(YPERR_DOMAIN); + + /* Get a handle. */ + if ((clnt = clnt_create(master, YPU_PROG, YPU_VERS, "tcp")) == NULL) + return(YPERR_RPC); + + /* + * Assemble netname of server. + * NOTE: It's difficult to discern from the documentation, but + * when you make a Secure RPC call, the netname you pass should + * be the netname of the guy on the other side, not your own + * netname. This is how the client side knows what public key + * to use for the initial exchange. Passing your own netname + * only works if the server on the other side is running under + * your UID. + */ + if (!host2netname(netname, master, domain)) { + clnt_destroy(clnt); + return(YPERR_BADARGS); + } + + /* Make up a DES session key. */ + key_gendes(&des_key); + + /* Set up DES authentication. */ + if ((clnt->cl_auth = (AUTH *)authdes_create(netname, WINDOW, NULL, + &des_key)) == NULL) { + clnt_destroy(clnt); + return(YPERR_RESRC); + } + + /* Set a timeout for clnt_call(). */ + timeout.tv_usec = 0; + timeout.tv_sec = TIMEOUT; + + /* + * Make the call. Note that we use clnt_call() here rather than + * the rpcgen-erated client stubs. We could use those stubs, but + * then we'd have to do some gymnastics to get at the error + * information to figure out what error code to send back to the + * caller. With clnt_call(), we get the error status returned to + * us right away, and we only have to exert a small amount of + * extra effort. + */ + switch (ypop) { + case YPOP_CHANGE: + upargs.mapname = map; + upargs.key.yp_buf_len = keylen; + upargs.key.yp_buf_val = key; + upargs.datum.yp_buf_len = datalen; + upargs.datum.yp_buf_val = data; + + if ((rval = clnt_call(clnt, YPU_CHANGE, + (xdrproc_t)xdr_ypupdate_args, &upargs, + (xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) { + if (rval == RPC_AUTHERROR) + res = YPERR_ACCESS; + else + res = YPERR_RPC; + } + + break; + case YPOP_INSERT: + upargs.mapname = map; + upargs.key.yp_buf_len = keylen; + upargs.key.yp_buf_val = key; + upargs.datum.yp_buf_len = datalen; + upargs.datum.yp_buf_val = data; + + if ((rval = clnt_call(clnt, YPU_INSERT, + (xdrproc_t)xdr_ypupdate_args, &upargs, + (xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) { + if (rval == RPC_AUTHERROR) + res = YPERR_ACCESS; + else + res = YPERR_RPC; + } + + break; + case YPOP_DELETE: + delargs.mapname = map; + delargs.key.yp_buf_len = keylen; + delargs.key.yp_buf_val = key; + + if ((rval = clnt_call(clnt, YPU_DELETE, + (xdrproc_t)xdr_ypdelete_args, &delargs, + (xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) { + if (rval == RPC_AUTHERROR) + res = YPERR_ACCESS; + else + res = YPERR_RPC; + } + + break; + case YPOP_STORE: + upargs.mapname = map; + upargs.key.yp_buf_len = keylen; + upargs.key.yp_buf_val = key; + upargs.datum.yp_buf_len = datalen; + upargs.datum.yp_buf_val = data; + + if ((rval = clnt_call(clnt, YPU_STORE, + (xdrproc_t)xdr_ypupdate_args, &upargs, + (xdrproc_t)xdr_u_int, &res, timeout)) != RPC_SUCCESS) { + if (rval == RPC_AUTHERROR) + res = YPERR_ACCESS; + else + res = YPERR_RPC; + } + + break; + default: + res = YPERR_BADARGS; + break; + } + + /* All done: tear down the connection. */ + auth_destroy(clnt->cl_auth); + clnt_destroy(clnt); + free(master); + + return(res); +} diff --git a/lib/libsamplerate/Makefile b/lib/libsamplerate/Makefile index 256f2087284f..4c55d5c2cb82 100644 --- a/lib/libsamplerate/Makefile +++ b/lib/libsamplerate/Makefile @@ -1,7 +1,9 @@ .PATH: ${SRCTOP}/contrib/libsamplerate +PACKAGE= sound + LIB= samplerate -INTERNALLIB= +PRIVATELIB= SRCS= samplerate.c \ src_linear.c \ diff --git a/lib/libsdp/Makefile b/lib/libsdp/Makefile index f0153e756dfd..8177c9bdbd1a 100644 --- a/lib/libsdp/Makefile +++ b/lib/libsdp/Makefile @@ -1,6 +1,7 @@ # $Id: Makefile,v 1.2 2003/09/07 20:34:19 max Exp $ -PACKAGE=lib${LIB} +PACKAGE= bluetooth +LIB_PACKAGE= LIB= sdp MAN= sdp.3 diff --git a/lib/libsdp/sdp.3 b/lib/libsdp/sdp.3 index dcd9077798ea..015f9cd8fb44 100644 --- a/lib/libsdp/sdp.3 +++ b/lib/libsdp/sdp.3 @@ -24,7 +24,7 @@ .\" .\" $Id: sdp.3,v 1.1 2003/09/07 20:34:19 max Exp $ .\" -.Dd April 30, 2018 +.Dd September 16, 2025 .Dt SDP 3 .Os .Sh NAME @@ -87,7 +87,7 @@ .Fn sdp_uuid2desc "uint16_t uuid" .Ft int32_t .Fo sdp_register_service -.Fa "void *xss" "uint16_t uuid" "bdaddr_p const bdaddr" "uint8_t const *data" +.Fa "void *xss" "uint16_t uuid" "const bdaddr_t *bdaddr" "uint8_t const *data" .Fa "uint32_t datalen" "uint32_t *handle" .Fc .Ft int32_t diff --git a/lib/libsdp/sdp.h b/lib/libsdp/sdp.h index faad36aefca6..0c9474a70eff 100644 --- a/lib/libsdp/sdp.h +++ b/lib/libsdp/sdp.h @@ -702,7 +702,7 @@ typedef struct sdp_panu_profile sdp_panu_profile_t; typedef struct sdp_panu_profile * sdp_panu_profile_p; int32_t sdp_register_service (void *xss, uint16_t uuid, - bdaddr_p const bdaddr, uint8_t const *data, + const bdaddr_t *bdaddr, uint8_t const *data, uint32_t datalen, uint32_t *handle); int32_t sdp_unregister_service (void *xss, uint32_t handle); int32_t sdp_change_service (void *xss, uint32_t handle, diff --git a/lib/libsdp/service.c b/lib/libsdp/service.c index 9f07d1ba86ba..2cce6c133600 100644 --- a/lib/libsdp/service.c +++ b/lib/libsdp/service.c @@ -45,7 +45,7 @@ static int32_t sdp_receive_error_pdu(sdp_session_p ss); int32_t -sdp_register_service(void *xss, uint16_t uuid, bdaddr_p const bdaddr, +sdp_register_service(void *xss, uint16_t uuid, const bdaddr_t *bdaddr, uint8_t const *data, uint32_t datalen, uint32_t *handle) { sdp_session_p ss = (sdp_session_p) xss; diff --git a/lib/libsm/Makefile b/lib/libsm/Makefile index 448abad59192..538407754f6a 100644 --- a/lib/libsm/Makefile +++ b/lib/libsm/Makefile @@ -1,6 +1,5 @@ .include <src.opts.mk> -PACKAGE=sendmail SENDMAIL_DIR=${SRCTOP}/contrib/sendmail .PATH: ${SENDMAIL_DIR}/libsm diff --git a/lib/libsmdb/Makefile b/lib/libsmdb/Makefile index 898af78d6101..e82deda57615 100644 --- a/lib/libsmdb/Makefile +++ b/lib/libsmdb/Makefile @@ -1,4 +1,3 @@ -PACKAGE=lib${LIB} SENDMAIL_DIR=${SRCTOP}/contrib/sendmail .PATH: ${SENDMAIL_DIR}/libsmdb diff --git a/lib/libsmutil/Makefile b/lib/libsmutil/Makefile index ef526ff8656d..37ad71e84f58 100644 --- a/lib/libsmutil/Makefile +++ b/lib/libsmutil/Makefile @@ -1,6 +1,5 @@ .include <src.opts.mk> -PACKAGE=lib${LIB} SENDMAIL_DIR=${SRCTOP}/contrib/sendmail .PATH: ${SENDMAIL_DIR}/libsmutil diff --git a/lib/libstdbuf/Makefile b/lib/libstdbuf/Makefile index 102c6745c593..9e289e0018fc 100644 --- a/lib/libstdbuf/Makefile +++ b/lib/libstdbuf/Makefile @@ -1,6 +1,5 @@ .include <bsd.own.mk> -PACKAGE=lib${LIB} LIB= stdbuf SRCS= stdbuf.c SHLIB_MAJOR= 1 diff --git a/lib/libstdthreads/Makefile b/lib/libstdthreads/Makefile index 49d024052420..dcdac58efc12 100644 --- a/lib/libstdthreads/Makefile +++ b/lib/libstdthreads/Makefile @@ -1,4 +1,4 @@ -PACKAGE=lib${LIB} +PACKAGE=runtime LIB= stdthreads SHLIB_MAJOR= 0 diff --git a/lib/libsys/Symbol.map b/lib/libsys/Symbol.map index eb71c813ae86..ae12124ca210 100644 --- a/lib/libsys/Symbol.map +++ b/lib/libsys/Symbol.map @@ -4,10 +4,4 @@ FBSDprivate_1.0 { __getosreldate; __libsys_interposing_slot; _elf_aux_info; - freebsd11_fstat; - freebsd11_fstatat; - freebsd11_getfsstat; - freebsd11_lstat; - freebsd11_stat; - freebsd11_statfs; }; diff --git a/lib/libsys/Symbol.sys.map b/lib/libsys/Symbol.sys.map index 1a297f9df581..e3fd8ac10621 100644 --- a/lib/libsys/Symbol.sys.map +++ b/lib/libsys/Symbol.sys.map @@ -382,6 +382,8 @@ FBSD_1.8 { getrlimitusage; inotify_add_watch_at; inotify_rm_watch; + jail_attach_jd; + jail_remove_jd; kcmp; setcred; setgroups; diff --git a/lib/libsys/_libsys.h b/lib/libsys/_libsys.h index 34eebc1aa67a..12417b572a60 100644 --- a/lib/libsys/_libsys.h +++ b/lib/libsys/_libsys.h @@ -32,6 +32,7 @@ struct itimerspec; struct itimerval; struct jail; struct kevent; +struct kexec_segment; struct kld_file_stat; struct mac; struct module_stat; @@ -468,6 +469,9 @@ typedef int (__sys_inotify_add_watch_at_t)(int, int, const char *, uint32_t); typedef int (__sys_inotify_rm_watch_t)(int, int); typedef int (__sys_getgroups_t)(int, gid_t *); typedef int (__sys_setgroups_t)(int, const gid_t *); +typedef int (__sys_jail_attach_jd_t)(int); +typedef int (__sys_jail_remove_jd_t)(int); +typedef int (__sys_kexec_load_t)(uint64_t, u_long, struct kexec_segment *, u_long); _Noreturn void __sys__exit(int rval); int __sys_fork(void); @@ -872,6 +876,9 @@ int __sys_inotify_add_watch_at(int fd, int dfd, const char * path, uint32_t mask int __sys_inotify_rm_watch(int fd, int wd); int __sys_getgroups(int gidsetsize, gid_t * gidset); int __sys_setgroups(int gidsetsize, const gid_t * gidset); +int __sys_jail_attach_jd(int fd); +int __sys_jail_remove_jd(int fd); +int __sys_kexec_load(uint64_t entry, u_long nseg, struct kexec_segment * segments, u_long flags); __END_DECLS #endif /* __LIBSYS_H_ */ diff --git a/lib/libsys/clock_gettime.2 b/lib/libsys/clock_gettime.2 index 89551d0f720b..841673648dfc 100644 --- a/lib/libsys/clock_gettime.2 +++ b/lib/libsys/clock_gettime.2 @@ -27,7 +27,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 10, 2024 +.Dd October 15, 2025 .Dt CLOCK_GETTIME 2 .Os .Sh NAME @@ -80,7 +80,6 @@ Behavior during a leap second is not defined by and POSIX standard. Increments in SI seconds, even while the system is suspended. Its epoch is unspecified. The count is not adjusted by leap seconds. -.Fx implements .It Dv CLOCK_UPTIME .It Dv CLOCK_UPTIME_PRECISE .It Dv CLOCK_UPTIME_FAST diff --git a/lib/libsys/closefrom.2 b/lib/libsys/closefrom.2 index 1885a6fdeaa8..e6b4a5a3e9d7 100644 --- a/lib/libsys/closefrom.2 +++ b/lib/libsys/closefrom.2 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 17, 2025 +.Dd October 27, 2025 .Dt CLOSEFROM 2 .Os .Sh NAME @@ -94,6 +94,11 @@ function first appeared in .Fx 8.0 . .Pp The +.Fn close_range +function first appeared in +.Fx 12.2 . +.Pp +The .Dv CLOSE_RANGE_CLOFORK flag appeared in .Fx 15.0 . diff --git a/lib/libsys/copy_file_range.2 b/lib/libsys/copy_file_range.2 index bcd9170842d5..829a5a5d3c13 100644 --- a/lib/libsys/copy_file_range.2 +++ b/lib/libsys/copy_file_range.2 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd December 28, 2023 +.Dd August 16, 2025 .Dt COPY_FILE_RANGE 2 .Os .Sh NAME @@ -74,6 +74,7 @@ argument must be opened for reading and the .Fa outfd argument must be opened for writing, but not .Dv O_APPEND . +.Pp If .Fa inoffp or @@ -101,9 +102,29 @@ respectively will be used/updated and the file offset for or .Fa outfd respectively will not be affected. -The +.Pp +The only +.Fa flags +argument currently defined is +.Dv COPY_FILE_RANGE_CLONE . +When this flag is set, +.Fn copy_file_range +will return +.Er EOPNOTSUPP +if the copy cannot be done via +block cloning. +When .Fa flags -argument must be 0. +is 0, a file system may do the copy via block cloning +or by data copying. +Block cloning is only possible when the offsets (plus +.Fa len +if not to EOF on the input file) are block +aligned. +The correct block alignment can normally be acquired via the +.Dv _PC_CLONE_BLKSIZE +query for +.Xr pathconf 2 . .Pp This system call attempts to maintain holes in the output file for the byte range being copied. @@ -203,9 +224,15 @@ refers to a directory. File system that stores .Fa outfd is full. +.It Bq Er EOPNOTSUPP +Cannot do the copy via block cloning and the +.Dv COPY_FILE_RANGE_CLONE +.Fa flags +argument is specified. .El .Sh SEE ALSO -.Xr lseek 2 +.Xr lseek 2 , +.Xr pathconf 2 .Sh STANDARDS The .Fn copy_file_range diff --git a/lib/libsys/getgroups.2 b/lib/libsys/getgroups.2 index 37c8fbad7215..4e94b32d4e7b 100644 --- a/lib/libsys/getgroups.2 +++ b/lib/libsys/getgroups.2 @@ -1,5 +1,13 @@ +.\"- +.\" SPDX-License-Identifier: BSD-3-Clause +.\" .\" Copyright (c) 1983, 1991, 1993 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 2025 The FreeBSD Foundation +.\" +.\" Portions of this documentation were written by Olivier Certner +.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD +.\" Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -25,12 +33,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 1, 2025 +.Dd October 10, 2025 .Dt GETGROUPS 2 .Os .Sh NAME .Nm getgroups -.Nd get group access list +.Nd get the calling process' supplementary groups .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -40,36 +48,39 @@ .Sh DESCRIPTION The .Fn getgroups -system call -gets the current supplementary groups of the user process and stores it in the -array -.Fa gidset . -The +system call gets the calling process' supplementary groups and stores them in +the +.Fa gidset +array in strictly ascending order. +The value of .Fa gidsetlen -argument -indicates the number of entries that may be placed in -.Fa gidset . -The -.Fn getgroups -system call -returns the actual number of groups returned in +indicates the maximum number of entries that may be placed in .Fa gidset . -As many as {NGROUPS_MAX} values may be returned. +.Pp If .Fa gidsetlen is zero, .Fn getgroups -returns the number of supplementary group IDs associated with -the calling process without modifying the array pointed to by +returns the cardinal of the calling process' supplementary groups set and +ignores argument .Fa gidset . .Pp +No more than +.Dv {NGROUPS_MAX} +values may ever be returned. The value of .Dv {NGROUPS_MAX} should be obtained using .Xr sysconf 3 to avoid hard-coding it into the executable. .Sh RETURN VALUES -A successful call returns the number of groups in the group set. +On success, the +.Fn getgroups +system call returns the cardinal of the supplementary groups set. +It always succeeds if argument +.Fa gidsetlen +is zero. +.Pp A value of -1 indicates that an error occurred, and the error code is stored in the global variable .Va errno . @@ -81,12 +92,12 @@ are: .It Bq Er EINVAL The argument .Fa gidsetlen -is smaller than the number of groups in the group set. +is smaller than the number of supplementary groups +.Pq but not zero . .It Bq Er EFAULT -The argument +An invalid address was encountered while reading from the .Fa gidset -specifies -an invalid address. +array. .El .Sh SEE ALSO .Xr setgroups 2 , @@ -96,16 +107,48 @@ an invalid address. The .Fn getgroups system call conforms to -.St -p1003.1-2008 . +.St -p1003.1-2008 , +not reporting the effective group ID. .Sh HISTORY The .Fn getgroups system call appeared in .Bx 4.2 . .Pp +Since +.Fx 14.3 , +the +.Fn getgroups +system call has been reporting the supplementary groups in strictly ascending +order. +.Pp Before .Fx 15.0 , the .Fn getgroups -system call always returned the effective group ID for the process as the first +system call would additionally return the effective group ID as the first element of the array, before the supplementary groups. +.Sh SECURITY CONSIDERATIONS +The +.Fn getgroups +system call gets the supplementary groups set in the +.Fa gidset +array. +In particular, as evoked in +.Sx HISTORY , +it does not anymore retrieve the effective group ID in the first slot of +.Fa gidset . +Programs that process this slot in a specific way must be modified to obtain the +effective group ID through other means, such as a call to +.Xr getegid 2 . +.Pp +The effective group ID is present in the supplementary groups set if and only if +it was explicitly set as a supplementary group. +The function +.Fn initgroups +enforces that, while the +.Fn setgroups +system call does not. +Please consult the +.Xr initgroups 3 +manual page for the rationale. diff --git a/lib/libsys/getrlimitusage.2 b/lib/libsys/getrlimitusage.2 index e2114def56c2..d0e92d7f88b4 100644 --- a/lib/libsys/getrlimitusage.2 +++ b/lib/libsys/getrlimitusage.2 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd September 27, 2024 +.Dd October 24, 2025 .Dt GETRLIMITUSAGE 2 .Os .Sh NAME @@ -97,4 +97,4 @@ and The .Fn getrlimitusage system call appeared in -.Bx 15.0 . +.Fx 14.2 . diff --git a/lib/libsys/jail.2 b/lib/libsys/jail.2 index 8f8b9925c712..ee4e5b03d38e 100644 --- a/lib/libsys/jail.2 +++ b/lib/libsys/jail.2 @@ -23,7 +23,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd November 29, 2023 +.Dd September 15, 2025 .Dt JAIL 2 .Os .Sh NAME @@ -31,7 +31,9 @@ .Nm jail_get , .Nm jail_set , .Nm jail_remove , -.Nm jail_attach +.Nm jail_attach , +.Nm jail_remove_jd , +.Nm jail_attach_jd .Nd create and manage system jails .Sh LIBRARY .Lb libc @@ -44,6 +46,10 @@ .Fn jail_attach "int jid" .Ft int .Fn jail_remove "int jid" +.Ft int +.Fn jail_attach_jd "int fd" +.Ft int +.Fn jail_remove_jd "int fd" .In sys/uio.h .Ft int .Fn jail_get "struct iovec *iov" "u_int niov" "int flags" @@ -188,6 +194,29 @@ system call. This is deprecated in .Fn jail_set and has no effect. +.It Dv JAIL_USE_DESC +Identify the jail by a descriptor in the +.Va desc +parameter. +.It Dv JAIL_AT_DESC +Operate in the context of the jail described by the +.Va desc +parameter, instead of the current jail. +Only one of +.Dv JAIL_USE_DESC +or +.Dv JAIL_AT_DESC +may be specified. +.It Dv JAIL_GET_DESC +Return a new jail descriptor for the jail in the +.Va desc +parameter. +.It Dv JAIL_OWN_DESC +Return an +.Dq owning +jail descriptor in the +.Va desc +parameter. .El .Pp The @@ -221,6 +250,9 @@ arguments consists of one or more following flags: .Bl -tag -width indent .It Dv JAIL_DYING Allow getting a jail that is in the process of being removed. +.It Dv JAIL_USE_DESC , Dv JAIL_AT_DESC , Dv JAIL_GET_DESC , Dv JAIL_OWN_DESC +These have the same meaning as they do in +.Fn jail_set . .El .Pp The @@ -238,6 +270,76 @@ system call removes the jail identified by .Fa jid . It will kill all processes belonging to the jail, and remove any children of that jail. +.Pp +The +.Fn jail_attach_fd +and +.Fn jail_remove_fd +system calls work the same as +.Fn jail_attach +and +.Fn jail_remove , +except that they operate on the jail identified by jail descriptor +.Fa fd . +.Ss Jail Descriptors +In addition to the jail ID, +jails can be referred to using a jail descriptor, +a type of file descriptor tied to a particular jail. +Jail descriptors are created by calling +.Fn jail_set +or +.Fn jail_get +with the special parameter +.Va desc , +and either the +.Dv JAIL_GET_DESC +or +.Dv JAIL_OWN_DESC +flags set. +The difference between the two flags is that descriptors created with +.Dv JAIL_OWN_DESC +.Po +called +.Dq owning +descriptors +.Pc +will automatically remove the jail when the descriptor is closed. +.Pp +Jail descriptors can be passed back to +.Fn jail_set +or +.Fm jail_get +with the +.Va desc +parameter, +and either the +.Dv JAIL_USE_DESC +or +.Dv JAIL_AT_DESC +flags set. +With +.Dv JAIL_USE_DESC , +the descriptor identifies the jail to operate on, +instead of the +.Va jid +or +.Va name +parameter. +With +.Dv JAIL_AT_DESC , +the descriptor is used in place of the current jail, +allowing accessing or creating jails that are children of the +descriptor jail. +.Pp +The system calls +.Fn jail_attach_jd +and +.Fn jail_aremove_jd +work the same as +.Fn jail_attach +and +.Fn jail_remove , +except that they operate on the jail referred to by the passed descriptor. .Sh RETURN VALUES If successful, .Fn jail , @@ -249,7 +351,7 @@ They return \-1 on failure, and set .Va errno to indicate the error. .Pp -.Rv -std jail_attach jail_remove +.Rv -std jail_attach jail_remove jail_attach_jd jail_remove_jd .Sh ERRORS The .Fn jail @@ -281,6 +383,13 @@ the super-user, or because it would exceed the jail's .Va children.max limit. .It Bq Er EPERM +The jail descriptor in the +.Va desc +parameter was created by a user other than the super-user, +and the +.Dv JAIL_USE_DESC +flag was set. +.It Bq Er EPERM A jail parameter was set to a less restrictive value then the current environment. .It Bq Er EFAULT @@ -298,8 +407,12 @@ flag is not set. .It Bq Er ENOENT The jail referred to by a .Va jid -is not accessible by the process, because the process is in a different -jail. +parameter is not accessible by the process, because the process is in a +different jail. +.It Bq Er ENOENT +The jail referred to by a +.Va desc +parameter has been removed. .It Bq Er EEXIST The jail referred to by a .Va jid @@ -326,6 +439,24 @@ flags is not set. A supplied string parameter is longer than allowed. .It Bq Er EAGAIN There are no jail IDs left. +.It Bq Er EMFILE +A jail descriptor could not be created for the +.Va desc +parameter with either the +.Dv JAIL_GET_DESC +or +.Dv JAIL_OWN_DESC +flag set, +because the process has already reached its limit for open file descriptors. +.It Bq Er ENFILE +A jail descriptor could not be created for the +.Va desc +parameter with either the +.Dv JAIL_GET_DESC +or +.Dv JAIL_OWN_DESC +flag set, +because the system file table is full. .El .Pp The @@ -333,10 +464,6 @@ The system call will fail if: .Bl -tag -width Er -.It Bq Er EFAULT -.Fa Iov , -or one of the addresses contained within it, -points to an address outside the allocated address space of the process. .It Bq Er ENOENT The jail referred to by a .Va jid @@ -352,10 +479,37 @@ jail. The .Va lastjid parameter is greater than the highest current jail ID. +.It Bq Er ENOENT +The jail referred to by a +.Va desc +parameter has been removed +.Pq even if the Dv JAIL_CREATE flag has been set . .It Bq Er EINVAL A supplied parameter is the wrong size. .It Bq Er EINVAL +A supplied parameter is out of range. +.It Bq Er EINVAL +A supplied string parameter is not null-terminated. +.It Bq Er EINVAL A supplied parameter name does not match any known parameters. +.It Bq Er EMFILE +A jail descriptor could not be created for the +.Va desc +parameter with either the +.Dv JAIL_GET_DESC +or +.Dv JAIL_OWN_DESC +flag set, +because the process has already reached its limit for open file descriptors. +.It Bq Er ENFILE +A jail descriptor could not be created for the +.Va desc +parameter with either the +.Dv JAIL_GET_DESC +or +.Dv JAIL_OWN_DESC +flag set, +because the system file table is full. .El .Pp The @@ -373,14 +527,37 @@ The jail specified by does not exist. .El .Pp +The +.Fn jail_attach_jd +and +.Fn jail_remove_jd +system calls +will fail if: +.Bl -tag -width Er +.It Bq Er EINVAL +The +.Fa fd +argument is not a valid jail descriptor. +.It Bq Er EPERM +The jail descriptor was created by a user other than the super-user. +.It Bq Er EINVAL +The jail specified by +.Fa jid +has been removed. +.El +.Pp Further .Fn jail , .Fn jail_set , +.Fn jail_attach , and -.Fn jail_attach +.Fn jail_attach_jd call .Xr chroot 2 internally, so they can fail for all the same reasons. +In particular, they return the +.Bq Er EPERM +error when the process to join a jail has open directories. Please consult the .Xr chroot 2 manual page for details. diff --git a/lib/libsys/kqueue.2 b/lib/libsys/kqueue.2 index d6e949baa24c..a8ebabf02cf7 100644 --- a/lib/libsys/kqueue.2 +++ b/lib/libsys/kqueue.2 @@ -22,7 +22,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 26, 2023 +.Dd September 12, 2025 .Dt KQUEUE 2 .Os .Sh NAME @@ -97,10 +97,37 @@ system call also creates a new kernel event queue, and additionally takes a .Fa flags argument, which is a bitwise-inclusive OR of the following flags: -.Bl -tag -width "KQUEUE_CLOEXEC" +.Bl -tag -width "KQUEUE_CPONFORK" .It Dv KQUEUE_CLOEXEC The returned file descriptor is automatically closed on .Xr execve 2 +.It Dv KQUEUE_CPONFORK +When this flag is set, the created kqueue is copied into +the child process on +.Xr fork 2 +calls. +The kqueue descriptor index of the new kqueue will be inherited by the child, +that is, the numeric value of the descriptor will remain the same. +.Pp +Copying is deep, that is, each registered event in the original kqueue is +copied (and not shared) into the new kqueue. +This is contrary to how other descriptor types are handled upon +.Xr fork 2 , +where the copied file descriptor references the same file object +as the source descriptor (shallow copy). +.Pp +By default, in other words, when the flag is not set, kqueues from +the parent are not copied on fork to the child process. +The corresponding file descriptor indeces are unused in the child. +.Pp +Registered events that reference file descriptors which are not +duplicated on fork, are not copied into the new kqueue. +For instance, if the event references a file descriptor opened with the +.Dv O_CLOEXEC +flag set, it is not copied. +Similarly, if event references a kqueue opened without the +.Dv KQUEUE_CPONFORK +flag, the event is not copied. .El .Pp The @@ -593,6 +620,64 @@ returns the number of times the signal has occurred since the last call to This filter automatically sets the .Dv EV_CLEAR flag internally. +.It Dv EVFILT_JAIL +Takes the jail ID to monitor as the identifier and the events to watch for +in +.Va fflags , +and returns when the jail performs one or more of the requested events. +If a process can normally see a jail, it can attach an event to it. +An identifier of zero will watch the process's own jail. +The events to monitor are: +.Bl -tag -width "Dv NOTE_JAIL_ATTACH" +.It Dv NOTE_JAIL_SET +The jail has been changed via +.Xr jail_set 2 . +.It Dv NOTE_JAIL_ATTACH +A process has attached to the jail via +.Xr jail_attach 2 +or a similar call. +The process ID will be stored in +.Va data . +If more than one process has attached since the last call to +.Fn kevent , +.Va data +will be zero. +.It Dv NOTE_JAIL_REMOVE +The jail has been removed. +.It Dv NOTE_JAIL_CHILD +A child of the watched jail has been created. +Its jail ID will be stored in +.Va data . +If more than one jail has been created since the last call to +.Fn kevent , +.Va data +will be zero. +.El +.Pp +On return, +.Va fflags +contains the events which triggered the filter. +It will also contain +.Dv NOTE_JAIL_MULTI +if more than one +.Dv NOTE_JAIL_ATTACH +or +.Dv NOTE_JAIL_CHILD +event has been received since the last call to +.Fn kevent . +.It Dv EVFILT_JAILDESC +Takes a jail descriptor returned by +.Xr jail_set 2 +or +.Xr jail_get 2 +as the identifier and the events to watch for in +.Va fflags , +and returns when the jail performs one or more of the requested events. +The events to monitor and the resulting +.Va fflags +are the same as those listed in +.Dv EVFILT_JAIL , +above. .It Dv EVFILT_TIMER Establishes an arbitrary timer identified by .Va ident . diff --git a/lib/libsys/setcred.2 b/lib/libsys/setcred.2 index 86f61ddfdb30..f5d1f15b631b 100644 --- a/lib/libsys/setcred.2 +++ b/lib/libsys/setcred.2 @@ -6,7 +6,7 @@ .\" This documentation was written by Olivier Certner <olce.freebsd@certner.fr> .\" at Kumacom SARL under sponsorship from the FreeBSD Foundation. .\" -.Dd December 19, 2024 +.Dd August 29, 2025 .Dt SETCRED 2 .Os .Sh NAME @@ -119,11 +119,6 @@ It must be less than or equal to An array of IDs to set the supplementary groups to, if flag .Dv SETCREDF_SUPP_GROUPS is specified. -Note that all groups in this array will be set as supplementary groups only, in -contrast to -.Xr setgroups 2 -which treats the first element specially as the new effective group, not adding -it to supplementary groups. .It Fa sc_label A pointer to a valid MAC label structure, e.g., built with the .Xr mac_from_text 3 diff --git a/lib/libsys/setgroups.2 b/lib/libsys/setgroups.2 index 451f63ba1266..0ec99507cfb0 100644 --- a/lib/libsys/setgroups.2 +++ b/lib/libsys/setgroups.2 @@ -1,5 +1,13 @@ +.\"- +.\" SPDX-License-Identifier: BSD-3-Clause +.\" .\" Copyright (c) 1983, 1991, 1993, 1994 .\" The Regents of the University of California. All rights reserved. +.\" Copyright (c) 2025 The FreeBSD Foundation +.\" +.\" Portions of this documentation were written by Olivier Certner +.\" <olce@FreeBSD.org> at Kumacom SARL under sponsorship from the FreeBSD +.\" Foundation. .\" .\" Redistribution and use in source and binary forms, with or without .\" modification, are permitted provided that the following conditions @@ -25,12 +33,12 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd August 1, 2025 +.Dd September 17, 2025 .Dt SETGROUPS 2 .Os .Sh NAME .Nm setgroups -.Nd set group access list +.Nd set the calling process' supplementary groups .Sh LIBRARY .Lb libc .Sh SYNOPSIS @@ -41,21 +49,21 @@ .Sh DESCRIPTION The .Fn setgroups -system call -sets the supplementary group list of the current user process -according to the array -.Fa gidset . +system call sets the calling process' supplementary groups according to the +.Fa gidset +array. The .Fa ngroups -argument -indicates the number of entries in the array and must be no -more than +argument indicates the number of entries in the array and must be no more than .Dv {NGROUPS_MAX} . +.Pp The .Fa ngroups -argument may be set to 0 to clear the supplementary group list. +argument may be set to zero to clear all supplementary groups, in which case +.Fa gidset +is ignored. .Pp -Only the super-user may set a new supplementary group list. +Only the super-user may install a new supplementary groups set. .Sh RETURN VALUES .Rv -std setgroups .Sh ERRORS @@ -69,16 +77,16 @@ The caller is not the super-user. The number specified in the .Fa ngroups argument is larger than the -.Dv {NGROUPS_MAX}+1 +.Dv {NGROUPS_MAX} limit. .It Bq Er EFAULT -The address specified for +Part of the groups array starting at .Fa gidset -is outside the process -address space. +is outside the process address space. .El .Sh SEE ALSO .Xr getgroups 2 , +.Xr setcred 2 , .Xr initgroups 3 .Sh HISTORY The @@ -92,4 +100,63 @@ the .Fn setgroups system call would set the effective group ID for the process to the first element of -.Fa gidset . +.Fa gidset , +and only the other elements as supplementary groups. +Despite treating the first element as the effective group ID to set, it accepted +an empty +.Fa gidset +.Po +.Fa ngroups +being zero +.Pc +as a stance requiring to drop all supplementary groups, leaving the effective +group ID unchanged. +.Sh SECURITY CONSIDERATIONS +The +.Fn setgroups +system call sets the process' supplementary groups to those contained in the +.Fa gidset +array. +In particular, as evoked in +.Sx HISTORY , +it does not anymore treat the first element of +.Fa gidset +separately. +Formerly, it would set it as the effective group ID while only the others were +used as supplementary groups. +.Pp +Programs solely relying on +.Fn setgroups +to change the effective group ID must be modified, e.g., to also call +.Xr setegid 2 +or to instead use +.Xr setcred 2 , +else they will unwillingly keep their effective group ID. +.Pp +Programs using +.Fn setgroups +with the effective group ID as the first element of array +.Fa gidset +and not duplicating it in the rest of the array, which includes those using +.Fn initgroups , +now insert this group ID in the supplementary groups set. +This is in general desirable, as explained in the +.Xr initgroups 3 +manual page, and has the consequence that subsequent process' effective group +ID's changes do not remove membership of the original effective group ID, since +these changes do not affect the supplementary groups. +Applications that expressly do not want that must be modified to stop passing +the effective group ID as the first element to +.Fn setgroups . +.Pp +To clear all the calling process' supplementary groups, always use the statement +.Bd -literal -offset indent +setgroups(0, NULL); +.Ed +.Pp +which works also on older FreeBSD version +.Po +see the +.Sx HISTORY +section +.Pc . diff --git a/lib/libsys/socket.2 b/lib/libsys/socket.2 index b211611c6354..48b8f4e87489 100644 --- a/lib/libsys/socket.2 +++ b/lib/libsys/socket.2 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd May 17, 2025 +.Dd September 28, 2025 .Dt SOCKET 2 .Os .Sh NAME @@ -64,7 +64,7 @@ PF_NETGRAPH Netgraph sockets, PF_NETLINK Netlink protocols, PF_BLUETOOTH Bluetooth protocols, PF_INET_SDP OFED socket direct protocol (IPv4), -AF_HYPERV HyperV sockets +PF_HYPERV HyperV sockets .Ed .Pp Each protocol family is connected to an address family, which has the @@ -89,32 +89,6 @@ SOCK_RAW Raw-protocol interface, SOCK_SEQPACKET Sequenced packet stream .Ed .Pp -A -.Dv SOCK_STREAM -type provides sequenced, reliable, -two-way connection based byte streams. -An out-of-band data transmission mechanism may be supported. -A -.Dv SOCK_DGRAM -socket supports -datagrams (connectionless, unreliable messages of -a fixed (typically small) maximum length). -A -.Dv SOCK_SEQPACKET -socket may provide a sequenced, reliable, -two-way connection-based data transmission path for datagrams -of fixed maximum length; a consumer may be required to read -an entire packet with each read system call. -This facility may have protocol-specific properties. -.Dv SOCK_RAW -sockets provide access to internal network protocols and interfaces. -The -.Dv SOCK_RAW -type is available only to the super-user and is described in -.Xr ip 4 -and -.Xr ip6 4 . -.Pp Additionally, the following flags are allowed in the .Fa type argument: @@ -140,32 +114,23 @@ particular to the in which communication is to take place; see .Xr protocols 5 . -.Pp The .Fa protocol argument may be set to zero (0) to request the default implementation of a socket type for the protocol, if any. -.Pp -Sockets of type +.Sh STREAM SOCKET TYPE +The +.Dv SOCK_STREAM +socket type provides reliable, sequenced, full-duplex octet streams between +the socket and a peer to which the socket is connected. +A socket of type .Dv SOCK_STREAM -are full-duplex byte streams, similar -to pipes. -A stream socket must be in a +needs to be in a .Em connected -state before any data may be sent or received -on it. +state before any data can be sent or received. A connection to another socket is created with a .Xr connect 2 system call. -Once connected, data may be transferred using -.Xr read 2 -and -.Xr write 2 -calls or some variant of the -.Xr send 2 -and -.Xr recv 2 -functions. (Some protocol families, such as the Internet family, support the notion of an .Dq implied connect , @@ -173,62 +138,210 @@ which permits data to be sent piggybacked onto a connect operation by using the .Xr sendto 2 system call.) -When a session has been completed a -.Xr close 2 -may be performed. -Out-of-band data may also be transmitted as described in +Once connected, data may be sent using +.Xr send 2 , +.Xr sendto 2 , +.Xr sendmsg 2 +and +.Xr write 2 +system calls. +Data may be received using +.Xr recv 2 , +.Xr recvfrom 2 , +.Xr recvmsg 2 , +and +.Xr read 2 +system calls. +Record boundaries are not maintained; data sent on a stream socket using output +operations of one size can be received using input operations of smaller or +larger sizes without loss of data. +Data may be buffered; successful return from an output function does not imply +that the data has been delivered to the peer or even transmitted from the local +system. +For certain protocols out-of-band data may also be transmitted as described in .Xr send 2 and received as described in .Xr recv 2 . .Pp -The communications protocols used to implement a -.Dv SOCK_STREAM -ensure that data -is not lost or duplicated. -If a piece of data for which the -peer protocol has buffer space cannot be successfully transmitted -within a reasonable length of time, then -the connection is considered broken and calls -will indicate an error with --1 returns and with -.Er ETIMEDOUT -as the specific code -in the global variable -.Va errno . -The protocols optionally keep sockets -.Dq warm -by forcing transmissions -roughly every minute in the absence of other activity. -An error is then indicated if no response can be -elicited on an otherwise -idle connection for an extended period (e.g.\& 5 minutes). -By default, a +If data cannot be successfully transmitted within a given time then the +connection is considered broken, and subsequent operations shall fail with +a protocol specific error code. +A .Dv SIGPIPE -signal is raised if a process sends -on a broken stream, but this behavior may be inhibited via +signal is raised if a thread attempts to send data on a broken stream (one that +is no longer connected). +The signal can be suppressed by the +.Dv MSG_NOSIGNAL +flag with distinct +.Xr send 2 , +.Xr sendto 2 , +and +.Xr sendmsg 2 +system calls or by the +.Dv SO_NOSIGPIPE +socket option set on the socket with .Xr setsockopt 2 . .Pp -.Dv SOCK_SEQPACKET -sockets employ the same system calls -as +The .Dv SOCK_STREAM -sockets. -The only difference -is that -.Xr read 2 -calls will return only the amount of data requested, -and any remaining in the arriving packet will be discarded. +socket is supported by the following protocol families: +.Dv PF_INET , +.Dv PF_INET6 , +.Dv PF_UNIX , +.Dv PF_BLUETOOTH , +.Dv PF_HYPERV , +and +.Dv PF_INET_SDP . +Out-of-band data transmission mechanism is supported for stream sockets of +.Dv PF_INET +and +.Dv PF_INET6 +protocol families. +.Sh DATAGRAM SOCKET TYPE +The +.Dv SOCK_DGRAM +socket type supports connectionless data transfer which is not necessarily +acknowledged or reliable. +Datagrams can be sent to the address specified (possibly multicast or +broadcast) in each output operation, and incoming datagrams can be received +from multiple sources. +The source address of each datagram is available when receiving the datagram +with +.Xr recvfrom 2 +or +.Xr recvmsg 2 . +An application can also pre-specify a peer address with +.Xr sendto 2 +or +.Xr sendmsg 2 , +in which case calls to output functions that do not specify a peer address +shall send to the pre-specified peer. +If a peer has been specified, only datagrams from that peer shall be received. +A datagram shall be sent in a single output operation, and needs to be received +in a single input operation. +The maximum size of a datagram is protocol-specific. +Output datagrams may be buffered within the system; thus, a successful return +from an output function does not guarantee that a datagram is actually sent or +received. .Pp +The .Dv SOCK_DGRAM +socket is supported by the following protocol families: +.Dv PF_INET , +.Dv PF_INET6 , +.Dv PF_UNIX , +.Dv PF_NETGRAPH , and -.Dv SOCK_RAW -sockets allow sending of datagrams to correspondents -named in +.Dv PF_NETLINK . +.Sh SEQUENCED PACKET SOCKET TYPE +The +.Dv SOCK_SEQPACKET +socket type is similar to the +.Dv SOCK_STREAM +type, and is also connection-oriented. +The only difference between these types is that record boundaries are +maintained using the +.Dv SOCK_SEQPACKET +type. +A record can be sent using one or more output operations and received using one +or more input operations, but a single operation never transfers parts of more +than one record. +Record boundaries are set by the sender with the +.Dv MSG_EOR +flag of .Xr send 2 -calls. -Datagrams are generally received with +or +.Xr sendmsg 2 +functions. +There is no possibility to set a record boundary with +.Xr write 2 . +Record boundaries are visible to the receiver via the +.Dv MSG_EOR +flag in the received message flags returned by the +.Xr recvmsg 2 +function. +It is protocol-specific whether a maximum record size is imposed. +.Pp +The +.Dv SOCK_SEQPACKET +socket is supported by the following protocol families: +.Dv PF_INET , +.Dv PF_INET6 , +and +.Dv PF_UNIX . +.Pp +.Sh RAW SOCKET TYPE +The +.Dv SOCK_RAW +socket type provides access to internal network protocols and interfaces. +It is a datagram socket in its nature, thus has the same semantics of +read and write operations. +The +.Dv SOCK_RAW +type is available only to the super-user and is described in +.Xr ip 4 +and +.Xr ip6 4 . +.Sh NON-BLOCKING MODE +A socket can be created in +.Em non-blocking mode +with the help of +.Dv SOCK_NONBLOCK +flag. +Alternatively, the non-blocking mode on a socket can be turned on and off with +the help of the +.Dv O_NONBLOCK +flag of the +.Xr fcntl 2 +system call. +.Pp +When a non-blocking socket has not enough data in its receive buffer to fulfill +the application supplied buffer, then data receiving system calls like +.Xr recv 2 , .Xr recvfrom 2 , -which returns the next datagram with its return address. +.Xr recvmsg 2 +and +.Xr read 2 +will not block waiting for the data but immediately return. +Return value will indicate amount of bytes read into the supplied buffer. +The +.Va errno +will be set to +.Dv EAGAIN +.Po +has same value as +.Dv EWOULDBLOCK +.Pc . +.Pp +If application tries to send more data on a non-blocking socket than the socket +send buffer can accomodate with +.Xr send 2 , +.Xr sendto 2 , +.Xr sendmsg 2 +or +.Xr write 2 +system calls partial data will be sent. +Return value will indicate amount of bytes sent. +The +.Va errno +will be set to +.Dv EAGAIN . +Note that sockets of +.Dv SOCK_DGRAM +type are unreliable, thus for these sockets sending operations will never fail +with +.Dv EAGAIN +in non-blocking mode neither will block in blocking mode. +.Sh OTHER OPERATIONS ON SOCKETS +Since socket descriptors are file descriptors, many generic file operations +performed by +.Xr fcntl 2 , +apply. +Socket descriptors can be used with all event engines, such as +.Xr kevent 2 , +.Xr select 2 +and +.Xr poll 2 . .Pp An .Xr fcntl 2 @@ -250,6 +363,12 @@ The and .Xr getsockopt 2 system calls are used to set and get options, respectively. +.Pp +Connection associated with a socket can be terminated by +.Xr close 2 +system call. +One direction of communication can be disabled with +.Xr shutdown 2 . .Sh RETURN VALUES A -1 is returned if an error occurs, otherwise the return value is a descriptor referencing the socket. @@ -282,16 +401,23 @@ The socket type is not supported by the protocol. .Sh SEE ALSO .Xr accept 2 , .Xr bind 2 , +.Xr close 2 , .Xr connect 2 , +.Xr fcntl 2 , .Xr getpeername 2 , .Xr getsockname 2 , .Xr getsockopt 2 , .Xr ioctl 2 , +.Xr kevent 2 , .Xr listen 2 , +.Xr poll 2 , .Xr read 2 , .Xr recv 2 , .Xr select 2 , .Xr send 2 , +.Xr sendmsg 2 , +.Xr sendto 2 , +.Xr signal 3 , .Xr shutdown 2 , .Xr socketpair 2 , .Xr write 2 , diff --git a/lib/libsys/stat.2 b/lib/libsys/stat.2 index bd9005710147..8107740bd901 100644 --- a/lib/libsys/stat.2 +++ b/lib/libsys/stat.2 @@ -25,7 +25,7 @@ .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF .\" SUCH DAMAGE. .\" -.Dd March 30, 2021 +.Dd August 17, 2025 .Dt STAT 2 .Os .Sh NAME @@ -169,6 +169,9 @@ Flags enabled for the file. See .Xr chflags 2 for the list of flags and their description. +.It Va st_rdev +Numeric ID of the device referenced by the file, if the file is a +character or block special; otherwise unspecified. .El .Pp The diff --git a/lib/libsys/syscalls.map b/lib/libsys/syscalls.map index 4cf80a2ffc69..d00c862eb462 100644 --- a/lib/libsys/syscalls.map +++ b/lib/libsys/syscalls.map @@ -813,4 +813,10 @@ FBSDprivate_1.0 { __sys_getgroups; _setgroups; __sys_setgroups; + _jail_attach_jd; + __sys_jail_attach_jd; + _jail_remove_jd; + __sys_jail_remove_jd; + _kexec_load; + __sys_kexec_load; }; diff --git a/lib/libsys/write.2 b/lib/libsys/write.2 index d2ff41ceead9..77067893ab4c 100644 --- a/lib/libsys/write.2 +++ b/lib/libsys/write.2 @@ -132,6 +132,26 @@ and may write fewer bytes than requested; the return value must be noted, and the remainder of the operation should be retried when possible. +.Sh ATOMICITY OF WRITES +When operating on regular files on local file systems, the effects of +.Fn write +are atomic. +As required by the POSIX standard, +the +.Fn read , +.Fn write , +and +.Fn ftruncate +functions and their variations are atomic with respect to +each other on the file data and metadata for regular files. +See for instance +.St -p1003.1-2024 +Volume 2, Section 2.9.7 for more information. +.Pp +.Fx +implements the requirement by taking +a read/write range lock on the file byte range +affected by the corresponding function. .Sh RETURN VALUES Upon successful completion the number of bytes which were written is returned. diff --git a/lib/libsysdecode/Makefile b/lib/libsysdecode/Makefile index ca020552a6e9..11f45355b8e2 100644 --- a/lib/libsysdecode/Makefile +++ b/lib/libsysdecode/Makefile @@ -27,7 +27,7 @@ MAN= sysdecode.3 \ sysdecode_sigcode.3 \ sysdecode_sockopt_name.3 \ sysdecode_socket_protocol.3 \ - sysdecode_syscallnames.3 \ + sysdecode_syscallname.3 \ sysdecode_utrace.3 MLINKS= sysdecode_abi_to_freebsd_errno.3 sysdecode_freebsd_to_abi_errno.3 MLINKS+=sysdecode_enum.3 sysdecode_acltype.3 \ diff --git a/lib/libsysdecode/Makefile.depend b/lib/libsysdecode/Makefile.depend index 1c40e21d361d..a9ccf3aa0870 100644 --- a/lib/libsysdecode/Makefile.depend +++ b/lib/libsysdecode/Makefile.depend @@ -38,7 +38,7 @@ DIRDEPS = \ lib/libarchive \ lib/libbe \ lib/libbegemot \ - lib/libblacklist \ + lib/libblocklist \ lib/libblocksruntime \ lib/libbluetooth \ lib/libbsddialog \ diff --git a/lib/libsysdecode/sysdecode.3 b/lib/libsysdecode/sysdecode.3 index 0aa4155c004b..32f7fad4e6c5 100644 --- a/lib/libsysdecode/sysdecode.3 +++ b/lib/libsysdecode/sysdecode.3 @@ -73,7 +73,7 @@ A placeholder for use when the ABI is not known. .Xr sysdecode_sigcode 3 , .Xr sysdecode_socket_protocol 3 , .Xr sysdecode_sockopt_name 3 , -.Xr sysdecode_syscallnames 3 , +.Xr sysdecode_syscallname 3 , .Xr sysdecode_utrace 3 .Sh HISTORY The diff --git a/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 b/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 index 8f710d1e3756..51955f062393 100644 --- a/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 +++ b/lib/libsysdecode/sysdecode_abi_to_freebsd_errno.3 @@ -89,4 +89,4 @@ see .Xr sysdecode 3 . .Sh SEE ALSO .Xr sysdecode 3 , -.Xr sysdecode_syscallnames 3 +.Xr sysdecode_syscallname 3 diff --git a/lib/libsysdecode/sysdecode_syscallnames.3 b/lib/libsysdecode/sysdecode_syscallname.3 index 610cbc9b2115..8ba88fd3c43e 100644 --- a/lib/libsysdecode/sysdecode_syscallnames.3 +++ b/lib/libsysdecode/sysdecode_syscallname.3 @@ -23,17 +23,17 @@ .\" SUCH DAMAGE. .\" .Dd October 17, 2016 -.Dt sysdecode_syscallnames 3 +.Dt sysdecode_syscallname 3 .Os .Sh NAME -.Nm sysdecode_syscallnames +.Nm sysdecode_syscallname .Nd lookup name of system calls .Sh LIBRARY .Lb libsysdecode .Sh SYNOPSIS .In sysdecode.h .Ft const char * -.Fn sysdecode_syscallnames "enum sysdecode_abi abi" "unsigned int code" +.Fn sysdecode_syscallname "enum sysdecode_abi abi" "unsigned int code" .Sh DESCRIPTION This function returns a pointer to the name of a system call identified by .Fa code diff --git a/lib/libtacplus/Makefile b/lib/libtacplus/Makefile index 43567350aeac..2149b57b124a 100644 --- a/lib/libtacplus/Makefile +++ b/lib/libtacplus/Makefile @@ -29,7 +29,9 @@ INCS= taclib.h CFLAGS+= -Wall LIBADD= md pam SHLIB_MAJOR= 5 -MAN= libtacplus.3 tacplus.conf.5 + +MAN= libtacplus.3 +MANNODEV= tacplus.conf.5 WARNS?= 2 diff --git a/lib/libtelnet/Makefile b/lib/libtelnet/Makefile index 6bc2f5a51de0..2eeac2d44f98 100644 --- a/lib/libtelnet/Makefile +++ b/lib/libtelnet/Makefile @@ -1,6 +1,5 @@ .include <src.opts.mk> -PACKAGE=lib${LIB} TELNETDIR= ${SRCTOP}/contrib/telnet .PATH: ${TELNETDIR}/libtelnet diff --git a/lib/libufs/Makefile b/lib/libufs/Makefile index ab913f834bb3..3b1911d7a5cd 100644 --- a/lib/libufs/Makefile +++ b/lib/libufs/Makefile @@ -1,4 +1,6 @@ -PACKAGE= libufs +PACKAGE= ufs +LIB_PACKAGE= + LIB= ufs SHLIBDIR?= /lib SHLIB_MAJOR= 8 diff --git a/lib/libunbound/Makefile b/lib/libunbound/Makefile index cdc965c20763..1a31e50e6416 100644 --- a/lib/libunbound/Makefile +++ b/lib/libunbound/Makefile @@ -1,4 +1,3 @@ -PACKAGE=lib${LIB} # Vendor sources and generated files LDNSDIR= ${SRCTOP}/contrib/ldns UNBOUNDDIR= ${SRCTOP}/contrib/unbound @@ -6,30 +5,28 @@ UNBOUNDDIR= ${SRCTOP}/contrib/unbound # Hold my beer and watch this .PATH: ${UNBOUNDDIR} ${UNBOUNDDIR}/cachedb ${UNBOUNDDIR}/dns64 ${UNBOUNDDIR}/iterator ${UNBOUNDDIR}/sldns ${UNBOUNDDIR}/libunbound ${UNBOUNDDIR}/services ${UNBOUNDDIR}/services/cache ${UNBOUNDDIR}/util ${UNBOUNDDIR}/util/data ${UNBOUNDDIR}/respip ${UNBOUNDDIR}/util/storage ${UNBOUNDDIR}/validator -LIB= unbound +PACKAGE= local-unbound + +LIB= unbound PRIVATELIB= -PACKAGE= unbound CFLAGS+= -I${UNBOUNDDIR} -I${LDNSDIR} -I${.OBJDIR} -I${.CURDIR} CFLAGS+= -DOPENSSL_API_COMPAT=0x10100000L -SRCS= alloc.c as112.c authzone.c autotrust.c cachedb.c config_file.c \ - configlexer.l configparser.y context.c dname.c dns.c dns64.c \ - dnstree.c edns.c fptr_wlist.c infra.c iter_delegpt.c iter_donotq.c \ - iter_fwd.c iter_hints.c iter_priv.c iter_resptype.c iter_scrub.c \ - iter_utils.c iterator.c keyraw.c libunbound.c libworker.c \ - listen_dnsport.c localzone.c locks.c log.c lookup3.c lruhash.c \ - mesh.c mini_event.c modstack.c module.c msgencode.c msgparse.c \ - msgreply.c net_help.c netevent.c outbound_list.c outside_network.c \ - packed_rrset.c parse.c parseutil.c proxy_protocol.c \ - random.c rbtree.c redis.c \ - regional.c respip.c rfc_1982.c rpz.c rrdef.c rrset.c rtt.c sbuffer.c \ - siphash.c slabhash.c \ - str2wire.c tcp_conn_limit.c timehist.c timeval_func.c \ - tube.c ub_event_pluggable.c \ - val_anchor.c val_kcache.c val_kentry.c val_neg.c val_nsec.c \ - val_nsec3.c val_secalgo.c val_sigcrypt.c val_utils.c validator.c \ - view.c winsock_event.c wire2str.c +SRCS= alloc.c as112.c authzone.c autotrust.c config_file.c configlexer.l \ + configparser.y context.c dname.c dns.c dns64.c dnstree.c edns.c \ + fptr_wlist.c infra.c iter_delegpt.c iter_donotq.c iter_fwd.c \ + iter_hints.c iter_priv.c iter_resptype.c iter_scrub.c iter_utils.c \ + iterator.c keyraw.c libunbound.c libworker.c listen_dnsport.c \ + localzone.c locks.c log.c lookup3.c lruhash.c mesh.c mini_event.c \ + modstack.c module.c msgencode.c msgparse.c msgreply.c net_help.c \ + netevent.c outbound_list.c outside_network.c packed_rrset.c parse.c \ + parseutil.c proxy_protocol.c random.c rbtree.c regional.c respip.c \ + rfc_1982.c rpz.c rrdef.c rrset.c rtt.c sbuffer.c siphash.c \ + slabhash.c str2wire.c tcp_conn_limit.c timehist.c timeval_func.c \ + tube.c ub_event_pluggable.c val_anchor.c val_kcache.c val_kentry.c \ + val_neg.c val_nsec.c val_nsec3.c val_secalgo.c val_sigcrypt.c \ + val_utils.c validator.c view.c winsock_event.c wire2str.c WARNS?= 2 NO_WTHREAD_SAFETY= true diff --git a/lib/libunbound/config.h b/lib/libunbound/config.h index a986bfc869a3..1b939b7f1074 100644 --- a/lib/libunbound/config.h +++ b/lib/libunbound/config.h @@ -20,7 +20,7 @@ /* #undef COMPAT_SHA512 */ /* Command line arguments used with configure */ -#define CONFCMDLINE "--with-ssl=/usr --with-libexpat=/usr --disable-dnscrypt --disable-dnstap --enable-ecdsa --disable-event-api --enable-gost --with-libevent --disable-subnet --disable-tfo-client --disable-tfo-server --with-pthreads--prefix=/usr --localstatedir=/var/unbound --mandir=/usr/share/man --build=freebsd" +#define CONFCMDLINE "--prefix= --exec-prefix=/usr --with-conf-file=/var/unbound/unbound.conf --with-run-dir=/var/unbound --with-username=unbound" /* Pathname to the Unbound configuration file */ #define CONFIGFILE "/var/unbound/unbound.conf" @@ -49,13 +49,13 @@ internal symbols */ /* #undef EXPORT_ALL_SYMBOLS */ -/* Define to 1 if you have the `accept4' function. */ +/* Define to 1 if you have the 'accept4' function. */ #define HAVE_ACCEPT4 1 -/* Define to 1 if you have the `arc4random' function. */ +/* Define to 1 if you have the 'arc4random' function. */ #define HAVE_ARC4RANDOM 1 -/* Define to 1 if you have the `arc4random_uniform' function. */ +/* Define to 1 if you have the 'arc4random_uniform' function. */ #define HAVE_ARC4RANDOM_UNIFORM 1 /* Define to 1 if you have the <arpa/inet.h> header file. */ @@ -77,13 +77,10 @@ #define HAVE_ATTR_WEAK 1 /* If we have be64toh */ -/* #undef HAVE_BE64TOH */ +#define HAVE_BE64TOH 1 -/* Define to 1 if you have the `BIO_set_callback_ex' function. */ -/* #undef HAVE_BIO_SET_CALLBACK_EX */ - -/* Define to 1 if you have the `BIO_set_callback_ex' function. */ -/* #undef HAVE_BIO_SET_CALLBACK_EX */ +/* Define to 1 if you have the 'BIO_set_callback_ex' function. */ +#define HAVE_BIO_SET_CALLBACK_EX 1 /* Define to 1 if you have the <bsd/stdlib.h> header file. */ /* #undef HAVE_BSD_STDLIB_H */ @@ -91,241 +88,241 @@ /* Define to 1 if you have the <bsd/string.h> header file. */ /* #undef HAVE_BSD_STRING_H */ -/* Define to 1 if you have the `chown' function. */ +/* Define to 1 if you have the 'chown' function. */ #define HAVE_CHOWN 1 -/* Define to 1 if you have the `chroot' function. */ +/* Define to 1 if you have the 'chroot' function. */ #define HAVE_CHROOT 1 -/* Define to 1 if you have the `CRYPTO_cleanup_all_ex_data' function. */ +/* Define to 1 if you have the 'CRYPTO_cleanup_all_ex_data' function. */ /* #undef HAVE_CRYPTO_CLEANUP_ALL_EX_DATA */ -/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */ +/* Define to 1 if you have the 'CRYPTO_THREADID_set_callback' function. */ /* #undef HAVE_CRYPTO_THREADID_SET_CALLBACK */ -/* Define to 1 if you have the `ctime_r' function. */ +/* Define to 1 if you have the 'ctime_r' function. */ #define HAVE_CTIME_R 1 -/* Define to 1 if you have the `daemon' function. */ +/* Define to 1 if you have the 'daemon' function. */ #define HAVE_DAEMON 1 -/* Define to 1 if you have the declaration of `arc4random', and to 0 if you +/* Define to 1 if you have the declaration of 'arc4random', and to 0 if you don't. */ /* #undef HAVE_DECL_ARC4RANDOM */ -/* Define to 1 if you have the declaration of `arc4random_uniform', and to 0 +/* Define to 1 if you have the declaration of 'arc4random_uniform', and to 0 if you don't. */ /* #undef HAVE_DECL_ARC4RANDOM_UNIFORM */ -/* Define to 1 if you have the declaration of `evsignal_assign', and to 0 if +/* Define to 1 if you have the declaration of 'evsignal_assign', and to 0 if you don't. */ /* #undef HAVE_DECL_EVSIGNAL_ASSIGN */ -/* Define to 1 if you have the declaration of `inet_ntop', and to 0 if you +/* Define to 1 if you have the declaration of 'inet_ntop', and to 0 if you don't. */ #define HAVE_DECL_INET_NTOP 1 -/* Define to 1 if you have the declaration of `inet_pton', and to 0 if you +/* Define to 1 if you have the declaration of 'inet_pton', and to 0 if you don't. */ #define HAVE_DECL_INET_PTON 1 -/* Define to 1 if you have the declaration of `nghttp2_session_server_new', +/* Define to 1 if you have the declaration of 'nghttp2_session_server_new', and to 0 if you don't. */ /* #undef HAVE_DECL_NGHTTP2_SESSION_SERVER_NEW */ -/* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you +/* Define to 1 if you have the declaration of 'ngtcp2_conn_server_new', and to + 0 if you don't. */ +/* #undef HAVE_DECL_NGTCP2_CONN_SERVER_NEW */ + +/* Define to 1 if you have the declaration of 'ngtcp2_crypto_encrypt_cb', and + to 0 if you don't. */ +/* #undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB */ + +/* Define to 1 if you have the declaration of 'NID_ED25519', and to 0 if you don't. */ #define HAVE_DECL_NID_ED25519 1 -/* Define to 1 if you have the declaration of `NID_ED448', and to 0 if you +/* Define to 1 if you have the declaration of 'NID_ED448', and to 0 if you don't. */ #define HAVE_DECL_NID_ED448 1 -/* Define to 1 if you have the declaration of `NID_secp384r1', and to 0 if you +/* Define to 1 if you have the declaration of 'NID_secp384r1', and to 0 if you don't. */ #define HAVE_DECL_NID_SECP384R1 1 -/* Define to 1 if you have the declaration of `NID_X9_62_prime256v1', and to 0 +/* Define to 1 if you have the declaration of 'NID_X9_62_prime256v1', and to 0 if you don't. */ #define HAVE_DECL_NID_X9_62_PRIME256V1 1 -/* Define to 1 if you have the declaration of `reallocarray', and to 0 if you +/* Define to 1 if you have the declaration of 'reallocarray', and to 0 if you don't. */ #define HAVE_DECL_REALLOCARRAY 1 -/* Define to 1 if you have the declaration of `redisConnect', and to 0 if you +/* Define to 1 if you have the declaration of 'redisConnect', and to 0 if you don't. */ /* #undef HAVE_DECL_REDISCONNECT */ -/* Define to 1 if you have the declaration of `sk_SSL_COMP_pop_free', and to 0 +/* Define to 1 if you have the declaration of 'sk_SSL_COMP_pop_free', and to 0 if you don't. */ #define HAVE_DECL_SK_SSL_COMP_POP_FREE 1 /* Define to 1 if you have the declaration of - `SSL_COMP_get_compression_methods', and to 0 if you don't. */ + 'SSL_COMP_get_compression_methods', and to 0 if you don't. */ #define HAVE_DECL_SSL_COMP_GET_COMPRESSION_METHODS 1 -/* Define to 1 if you have the declaration of `SSL_CTX_set_ecdh_auto', and to +/* Define to 1 if you have the declaration of 'SSL_CTX_set_ecdh_auto', and to 0 if you don't. */ -/* #undef HAVE_DECL_SSL_CTX_SET_ECDH_AUTO */ +#define HAVE_DECL_SSL_CTX_SET_ECDH_AUTO 1 -/* Define to 1 if you have the declaration of `strlcat', and to 0 if you +/* Define to 1 if you have the declaration of 'strlcat', and to 0 if you don't. */ /* #undef HAVE_DECL_STRLCAT */ -/* Define to 1 if you have the declaration of `strlcpy', and to 0 if you +/* Define to 1 if you have the declaration of 'strlcpy', and to 0 if you don't. */ /* #undef HAVE_DECL_STRLCPY */ -/* Define to 1 if you have the declaration of `XML_StopParser', and to 0 if +/* Define to 1 if you have the declaration of 'XML_StopParser', and to 0 if you don't. */ #define HAVE_DECL_XML_STOPPARSER 1 /* Define to 1 if you have the <dlfcn.h> header file. */ #define HAVE_DLFCN_H 1 -/* Define to 1 if you have the `DSA_SIG_set0' function. */ +/* Define to 1 if you have the 'DSA_SIG_set0' function. */ #define HAVE_DSA_SIG_SET0 1 /* Define to 1 if you have the <endian.h> header file. */ -/* #undef HAVE_ENDIAN_H */ +#define HAVE_ENDIAN_H 1 -/* Define to 1 if you have the `endprotoent' function. */ +/* Define to 1 if you have the 'endprotoent' function. */ #define HAVE_ENDPROTOENT 1 -/* Define to 1 if you have the `endpwent' function. */ +/* Define to 1 if you have the 'endpwent' function. */ #define HAVE_ENDPWENT 1 -/* Define to 1 if you have the `endservent' function. */ +/* Define to 1 if you have the 'endservent' function. */ #define HAVE_ENDSERVENT 1 -/* Define to 1 if you have the `ENGINE_cleanup' function. */ +/* Define to 1 if you have the 'ENGINE_cleanup' function. */ /* #undef HAVE_ENGINE_CLEANUP */ -/* Define to 1 if you have the `ERR_free_strings' function. */ +/* Define to 1 if you have the 'ERR_free_strings' function. */ /* #undef HAVE_ERR_FREE_STRINGS */ -/* Define to 1 if you have the `ERR_load_crypto_strings' function. */ +/* Define to 1 if you have the 'ERR_load_crypto_strings' function. */ /* #undef HAVE_ERR_LOAD_CRYPTO_STRINGS */ -/* Define to 1 if you have the `event_assign' function. */ +/* Define to 1 if you have the 'event_assign' function. */ /* #undef HAVE_EVENT_ASSIGN */ -/* Define to 1 if you have the `event_base_free' function. */ +/* Define to 1 if you have the 'event_base_free' function. */ /* #undef HAVE_EVENT_BASE_FREE */ -/* Define to 1 if you have the `event_base_get_method' function. */ +/* Define to 1 if you have the 'event_base_get_method' function. */ /* #undef HAVE_EVENT_BASE_GET_METHOD */ -/* Define to 1 if you have the `event_base_new' function. */ +/* Define to 1 if you have the 'event_base_new' function. */ /* #undef HAVE_EVENT_BASE_NEW */ -/* Define to 1 if you have the `event_base_once' function. */ +/* Define to 1 if you have the 'event_base_once' function. */ /* #undef HAVE_EVENT_BASE_ONCE */ /* Define to 1 if you have the <event.h> header file. */ /* #undef HAVE_EVENT_H */ -/* Define to 1 if you have the `EVP_aes_256_cbc' function. */ +/* Define to 1 if you have the 'EVP_aes_256_cbc' function. */ #define HAVE_EVP_AES_256_CBC 1 -/* Define to 1 if you have the `EVP_cleanup' function. */ +/* Define to 1 if you have the 'EVP_cleanup' function. */ /* #undef HAVE_EVP_CLEANUP */ -/* Define to 1 if you have the `EVP_default_properties_is_fips_enabled' +/* Define to 1 if you have the 'EVP_default_properties_is_fips_enabled' function. */ -/* #undef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED */ - +#define HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED 1 -/* Define to 1 if you have the `EVP_default_properties_is_fips_enabled' - function. */ -/* #undef HAVE_EVP_DEFAULT_PROPERTIES_IS_FIPS_ENABLED */ - -/* Define to 1 if you have the `EVP_DigestVerify' function. */ +/* Define to 1 if you have the 'EVP_DigestVerify' function. */ #define HAVE_EVP_DIGESTVERIFY 1 -/* Define to 1 if you have the `EVP_dss1' function. */ +/* Define to 1 if you have the 'EVP_dss1' function. */ /* #undef HAVE_EVP_DSS1 */ -/* Define to 1 if you have the `EVP_EncryptInit_ex' function. */ +/* Define to 1 if you have the 'EVP_EncryptInit_ex' function. */ #define HAVE_EVP_ENCRYPTINIT_EX 1 -/* Define to 1 if you have the `EVP_MAC_CTX_set_params' function. */ -/* #undef HAVE_EVP_MAC_CTX_SET_PARAMS */ +/* Define to 1 if you have the 'EVP_MAC_CTX_set_params' function. */ +#define HAVE_EVP_MAC_CTX_SET_PARAMS 1 -/* Define to 1 if you have the `EVP_MD_CTX_new' function. */ +/* Define to 1 if you have the 'EVP_MD_CTX_new' function. */ #define HAVE_EVP_MD_CTX_NEW 1 -/* Define to 1 if you have the `EVP_sha1' function. */ +/* Define to 1 if you have the 'EVP_sha1' function. */ #define HAVE_EVP_SHA1 1 -/* Define to 1 if you have the `EVP_sha256' function. */ +/* Define to 1 if you have the 'EVP_sha256' function. */ #define HAVE_EVP_SHA256 1 -/* Define to 1 if you have the `EVP_sha512' function. */ +/* Define to 1 if you have the 'EVP_sha512' function. */ #define HAVE_EVP_SHA512 1 -/* Define to 1 if you have the `ev_default_loop' function. */ +/* Define to 1 if you have the 'ev_default_loop' function. */ /* #undef HAVE_EV_DEFAULT_LOOP */ -/* Define to 1 if you have the `ev_loop' function. */ +/* Define to 1 if you have the 'ev_loop' function. */ /* #undef HAVE_EV_LOOP */ /* Define to 1 if you have the <expat.h> header file. */ #define HAVE_EXPAT_H 1 -/* Define to 1 if you have the `explicit_bzero' function. */ +/* Define to 1 if you have the 'explicit_bzero' function. */ #define HAVE_EXPLICIT_BZERO 1 -/* Define to 1 if you have the `fcntl' function. */ +/* Define to 1 if you have the 'fcntl' function. */ #define HAVE_FCNTL 1 -/* Define to 1 if you have the `FIPS_mode' function. */ -#define HAVE_FIPS_MODE 1 +/* Define to 1 if you have the 'FIPS_mode' function. */ +/* #undef HAVE_FIPS_MODE */ -/* Define to 1 if you have the `fork' function. */ +/* Define to 1 if you have the 'fork' function. */ #define HAVE_FORK 1 -/* Define to 1 if fseeko (and presumably ftello) exists and is declared. */ +/* Define to 1 if fseeko (and ftello) are declared in stdio.h. */ #define HAVE_FSEEKO 1 -/* Define to 1 if you have the `fsync' function. */ +/* Define to 1 if you have the 'fsync' function. */ #define HAVE_FSYNC 1 /* Whether getaddrinfo is available */ #define HAVE_GETADDRINFO 1 -/* Define to 1 if you have the `getauxval' function. */ +/* Define to 1 if you have the 'getauxval' function. */ /* #undef HAVE_GETAUXVAL */ -/* Define to 1 if you have the `getentropy' function. */ +/* Define to 1 if you have the 'getentropy' function. */ /* #undef HAVE_GETENTROPY */ -/* Define to 1 if you have the `getifaddrs' function. */ +/* Define to 1 if you have the 'getifaddrs' function. */ #define HAVE_GETIFADDRS 1 /* Define to 1 if you have the <getopt.h> header file. */ #define HAVE_GETOPT_H 1 -/* Define to 1 if you have the `getpwnam' function. */ +/* Define to 1 if you have the 'getpwnam' function. */ #define HAVE_GETPWNAM 1 -/* Define to 1 if you have the `getrlimit' function. */ +/* Define to 1 if you have the 'getrlimit' function. */ #define HAVE_GETRLIMIT 1 -/* Define to 1 if you have the `gettid' function. */ -/* #undef HAVE_GETTID */ - -/* Define to 1 if you have the `gettid' function. */ +/* Define to 1 if you have the 'gettid' function. */ /* #undef HAVE_GETTID */ -/* Define to 1 if you have the `glob' function. */ +/* Define to 1 if you have the 'glob' function. */ #define HAVE_GLOB 1 /* Define to 1 if you have the <glob.h> header file. */ #define HAVE_GLOB_H 1 -/* Define to 1 if you have the `gmtime_r' function. */ +/* Define to 1 if you have the 'gmtime_r' function. */ #define HAVE_GMTIME_R 1 /* Define to 1 if you have the <grp.h> header file. */ @@ -334,31 +331,28 @@ /* Define to 1 if you have the <hiredis/hiredis.h> header file. */ /* #undef HAVE_HIREDIS_HIREDIS_H */ -/* Define to 1 if you have the `HMAC_Init_ex' function. */ +/* Define to 1 if you have the 'HMAC_Init_ex' function. */ #define HAVE_HMAC_INIT_EX 1 /* If we have htobe64 */ -/* #undef HAVE_HTOBE64 */ +#define HAVE_HTOBE64 1 /* Define to 1 if you have the <ifaddrs.h> header file. */ #define HAVE_IFADDRS_H 1 -/* Define to 1 if you have the `if_nametoindex' function. */ +/* Define to 1 if you have the 'if_nametoindex' function. */ #define HAVE_IF_NAMETOINDEX 1 -/* Define to 1 if you have the `if_nametoindex' function. */ -#define HAVE_IF_NAMETOINDEX 1 - -/* Define to 1 if you have the `inet_aton' function. */ +/* Define to 1 if you have the 'inet_aton' function. */ #define HAVE_INET_ATON 1 -/* Define to 1 if you have the `inet_ntop' function. */ +/* Define to 1 if you have the 'inet_ntop' function. */ #define HAVE_INET_NTOP 1 -/* Define to 1 if you have the `inet_pton' function. */ +/* Define to 1 if you have the 'inet_pton' function. */ #define HAVE_INET_PTON 1 -/* Define to 1 if you have the `initgroups' function. */ +/* Define to 1 if you have the 'initgroups' function. */ #define HAVE_INITGROUPS 1 /* Define to 1 if you have the <inttypes.h> header file. */ @@ -370,10 +364,10 @@ /* Define to 1 if you have the <iphlpapi.h> header file. */ /* #undef HAVE_IPHLPAPI_H */ -/* Define to 1 if you have the `isblank' function. */ +/* Define to 1 if you have the 'isblank' function. */ #define HAVE_ISBLANK 1 -/* Define to 1 if you have the `kill' function. */ +/* Define to 1 if you have the 'kill' function. */ #define HAVE_KILL 1 /* Use portable libbsd functions */ @@ -385,7 +379,13 @@ /* Define if we have LibreSSL */ /* #undef HAVE_LIBRESSL */ -/* Define to 1 if you have the `localtime_r' function. */ +/* If we have atomic_store */ +#define HAVE_LINK_ATOMIC_STORE 1 + +/* Define to 1 if you have the <linux/net_tstamp.h> header file. */ +/* #undef HAVE_LINUX_NET_TSTAMP_H */ + +/* Define to 1 if you have the 'localtime_r' function. */ #define HAVE_LOCALTIME_R 1 /* Define to 1 if you have the <login_cap.h> header file. */ @@ -394,7 +394,7 @@ /* If have GNU libc compatible malloc */ #define HAVE_MALLOC 1 -/* Define to 1 if you have the `memmove' function. */ +/* Define to 1 if you have the 'memmove' function. */ #define HAVE_MEMMOVE 1 /* Define to 1 if you have the <minix/config.h> header file. */ @@ -424,29 +424,91 @@ /* Define to 1 if you have the <net/if.h> header file. */ #define HAVE_NET_IF_H 1 +/* Define to 1 if you have the <net/pfvar.h> header file. */ +/* #undef HAVE_NET_PFVAR_H */ + /* Define this to use nghttp2 client. */ /* #undef HAVE_NGHTTP2 */ /* Define to 1 if you have the <nghttp2/nghttp2.h> header file. */ /* #undef HAVE_NGHTTP2_NGHTTP2_H */ +/* Define this to use ngtcp2. */ +/* #undef HAVE_NGTCP2 */ + +/* Define to 1 if you have the 'ngtcp2_ccerr_default' function. */ +/* #undef HAVE_NGTCP2_CCERR_DEFAULT */ + +/* Define to 1 if you have the 'ngtcp2_conn_encode_0rtt_transport_params' + function. */ +/* #undef HAVE_NGTCP2_CONN_ENCODE_0RTT_TRANSPORT_PARAMS */ + +/* Define to 1 if you have the 'ngtcp2_conn_get_max_local_streams_uni' + function. */ +/* #undef HAVE_NGTCP2_CONN_GET_MAX_LOCAL_STREAMS_UNI */ + +/* Define to 1 if you have the 'ngtcp2_conn_get_num_scid' function. */ +/* #undef HAVE_NGTCP2_CONN_GET_NUM_SCID */ + +/* Define to 1 if you have the 'ngtcp2_conn_in_closing_period' function. */ +/* #undef HAVE_NGTCP2_CONN_IN_CLOSING_PERIOD */ + +/* Define to 1 if you have the 'ngtcp2_conn_in_draining_period' function. */ +/* #undef HAVE_NGTCP2_CONN_IN_DRAINING_PERIOD */ + +/* Define if ngtcp2_conn_shutdown_stream has 4 arguments. */ +/* #undef HAVE_NGTCP2_CONN_SHUTDOWN_STREAM4 */ + +/* Define to 1 if you have the 'ngtcp2_conn_tls_early_data_rejected' function. + */ +/* #undef HAVE_NGTCP2_CONN_TLS_EARLY_DATA_REJECTED */ + +/* Define to 1 if you have the 'ngtcp2_crypto_encrypt_cb' function. */ +/* #undef HAVE_NGTCP2_CRYPTO_ENCRYPT_CB */ + +/* Define to 1 if you have the + 'ngtcp2_crypto_quictls_configure_client_context' function. */ +/* #undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_CLIENT_CONTEXT */ + +/* Define to 1 if you have the + 'ngtcp2_crypto_quictls_configure_server_context' function. */ +/* #undef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */ + +/* Define to 1 if you have the + 'ngtcp2_crypto_quictls_from_ossl_encryption_level' function. */ +/* #undef HAVE_NGTCP2_CRYPTO_QUICTLS_FROM_OSSL_ENCRYPTION_LEVEL */ + +/* Define to 1 if the system has the type 'ngtcp2_encryption_level'. */ +/* #undef HAVE_NGTCP2_ENCRYPTION_LEVEL */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_openssl.h> header file. + */ +/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_OPENSSL_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2_crypto_quictls.h> header file. + */ +/* #undef HAVE_NGTCP2_NGTCP2_CRYPTO_QUICTLS_H */ + +/* Define to 1 if you have the <ngtcp2/ngtcp2.h> header file. */ +/* #undef HAVE_NGTCP2_NGTCP2_H */ + /* Use libnss for crypto */ /* #undef HAVE_NSS */ -/* Define to 1 if you have the `OpenSSL_add_all_digests' function. */ +/* Define to 1 if you have the 'OpenSSL_add_all_digests' function. */ /* #undef HAVE_OPENSSL_ADD_ALL_DIGESTS */ /* Define to 1 if you have the <openssl/bn.h> header file. */ #define HAVE_OPENSSL_BN_H 1 -/* Define to 1 if you have the `OPENSSL_config' function. */ +/* Define to 1 if you have the 'OPENSSL_config' function. */ #define HAVE_OPENSSL_CONFIG 1 /* Define to 1 if you have the <openssl/conf.h> header file. */ #define HAVE_OPENSSL_CONF_H 1 /* Define to 1 if you have the <openssl/core_names.h> header file. */ -/* #undef HAVE_OPENSSL_CORE_NAMES_H */ +#define HAVE_OPENSSL_CORE_NAMES_H 1 /* Define to 1 if you have the <openssl/dh.h> header file. */ #define HAVE_OPENSSL_DH_H 1 @@ -460,14 +522,14 @@ /* Define to 1 if you have the <openssl/err.h> header file. */ #define HAVE_OPENSSL_ERR_H 1 -/* Define to 1 if you have the `OPENSSL_init_crypto' function. */ +/* Define to 1 if you have the 'OPENSSL_init_crypto' function. */ #define HAVE_OPENSSL_INIT_CRYPTO 1 -/* Define to 1 if you have the `OPENSSL_init_ssl' function. */ +/* Define to 1 if you have the 'OPENSSL_init_ssl' function. */ #define HAVE_OPENSSL_INIT_SSL 1 /* Define to 1 if you have the <openssl/param_build.h> header file. */ -/* #undef HAVE_OPENSSL_PARAM_BUILD_H */ +#define HAVE_OPENSSL_PARAM_BUILD_H 1 /* Define to 1 if you have the <openssl/rand.h> header file. */ #define HAVE_OPENSSL_RAND_H 1 @@ -478,10 +540,10 @@ /* Define to 1 if you have the <openssl/ssl.h> header file. */ #define HAVE_OPENSSL_SSL_H 1 -/* Define to 1 if you have the `OSSL_PARAM_BLD_new' function. */ -/* #undef HAVE_OSSL_PARAM_BLD_NEW */ +/* Define to 1 if you have the 'OSSL_PARAM_BLD_new' function. */ +#define HAVE_OSSL_PARAM_BLD_NEW 1 -/* Define to 1 if you have the `poll' function. */ +/* Define to 1 if you have the 'poll' function. */ #define HAVE_POLL 1 /* Define to 1 if you have the <poll.h> header file. */ @@ -493,10 +555,10 @@ /* Have PTHREAD_PRIO_INHERIT. */ #define HAVE_PTHREAD_PRIO_INHERIT 1 -/* Define to 1 if the system has the type `pthread_rwlock_t'. */ +/* Define to 1 if the system has the type 'pthread_rwlock_t'. */ #define HAVE_PTHREAD_RWLOCK_T 1 -/* Define to 1 if the system has the type `pthread_spinlock_t'. */ +/* Define to 1 if the system has the type 'pthread_spinlock_t'. */ #define HAVE_PTHREAD_SPINLOCK_T 1 /* Define to 1 if you have the <pwd.h> header file. */ @@ -505,100 +567,109 @@ /* Define if you have Python libraries and header files. */ /* #undef HAVE_PYTHON */ -/* Define to 1 if you have the `random' function. */ +/* Define to 1 if you have the 'random' function. */ #define HAVE_RANDOM 1 -/* Define to 1 if you have the `RAND_cleanup' function. */ +/* Define to 1 if you have the 'RAND_cleanup' function. */ /* #undef HAVE_RAND_CLEANUP */ /* If we have reallocarray(3) */ #define HAVE_REALLOCARRAY 1 -/* Define to 1 if you have the `recvmsg' function. */ +/* Define to 1 if you have the 'recvmsg' function. */ #define HAVE_RECVMSG 1 -/* Define to 1 if you have the `sendmsg' function. */ +/* Define to 1 if you have the 'sendmsg' function. */ #define HAVE_SENDMSG 1 -/* Define to 1 if you have the `setregid' function. */ +/* Define to 1 if you have the 'setregid' function. */ /* #undef HAVE_SETREGID */ -/* Define to 1 if you have the `setresgid' function. */ +/* Define to 1 if you have the 'setresgid' function. */ #define HAVE_SETRESGID 1 -/* Define to 1 if you have the `setresuid' function. */ +/* Define to 1 if you have the 'setresuid' function. */ #define HAVE_SETRESUID 1 -/* Define to 1 if you have the `setreuid' function. */ +/* Define to 1 if you have the 'setreuid' function. */ /* #undef HAVE_SETREUID */ -/* Define to 1 if you have the `setrlimit' function. */ +/* Define to 1 if you have the 'setrlimit' function. */ #define HAVE_SETRLIMIT 1 -/* Define to 1 if you have the `setsid' function. */ +/* Define to 1 if you have the 'setsid' function. */ #define HAVE_SETSID 1 -/* Define to 1 if you have the `setusercontext' function. */ +/* Define to 1 if you have the 'setusercontext' function. */ #define HAVE_SETUSERCONTEXT 1 -/* Define to 1 if you have the `SHA512_Update' function. */ +/* Define to 1 if you have the 'SHA512_Update' function. */ /* #undef HAVE_SHA512_UPDATE */ -/* Define to 1 if you have the `shmget' function. */ +/* Define to 1 if you have the 'shmget' function. */ #define HAVE_SHMGET 1 -/* Define to 1 if you have the `sigprocmask' function. */ +/* Define to 1 if you have the 'sigprocmask' function. */ #define HAVE_SIGPROCMASK 1 -/* Define to 1 if you have the `sleep' function. */ +/* Define to 1 if you have the 'sleep' function. */ #define HAVE_SLEEP 1 -/* Define to 1 if you have the `snprintf' function. */ +/* Define to 1 if you have the 'snprintf' function. */ #define HAVE_SNPRINTF 1 -/* Define to 1 if you have the `socketpair' function. */ +/* Define to 1 if you have the 'socketpair' function. */ #define HAVE_SOCKETPAIR 1 /* Using Solaris threads */ /* #undef HAVE_SOLARIS_THREADS */ -/* Define to 1 if you have the `srandom' function. */ +/* Define to 1 if you have the 'srandom' function. */ #define HAVE_SRANDOM 1 /* Define if you have the SSL libraries installed. */ #define HAVE_SSL /**/ -/* Define to 1 if you have the `SSL_CTX_set_alpn_protos' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_alpn_protos' function. */ #define HAVE_SSL_CTX_SET_ALPN_PROTOS 1 -/* Define to 1 if you have the `SSL_CTX_set_alpn_select_cb' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_alpn_select_cb' function. */ #define HAVE_SSL_CTX_SET_ALPN_SELECT_CB 1 -/* Define to 1 if you have the `SSL_CTX_set_ciphersuites' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_ciphersuites' function. */ #define HAVE_SSL_CTX_SET_CIPHERSUITES 1 -/* Define to 1 if you have the `SSL_CTX_set_security_level' function. */ +/* Define to 1 if you have the 'SSL_CTX_set_security_level' function. */ #define HAVE_SSL_CTX_SET_SECURITY_LEVEL 1 -/* Define to 1 if you have the `SSL_CTX_set_tlsext_ticket_key_evp_cb' +/* Define to 1 if you have the 'SSL_CTX_set_tlsext_ticket_key_evp_cb' function. */ -/* #undef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB */ +#define HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB 1 + +/* Define to 1 if you have the 'SSL_CTX_set_tmp_ecdh' function. */ +/* #undef HAVE_SSL_CTX_SET_TMP_ECDH */ -/* Define to 1 if you have the `SSL_get0_alpn_selected' function. */ +/* Define to 1 if you have the 'SSL_get0_alpn_selected' function. */ #define HAVE_SSL_GET0_ALPN_SELECTED 1 -/* Define to 1 if you have the `SSL_get0_peername' function. */ +/* Define to 1 if you have the 'SSL_get0_peername' function. */ #define HAVE_SSL_GET0_PEERNAME 1 -/* Define to 1 if you have the `SSL_get1_peer_certificate' function. */ -/* #undef HAVE_SSL_GET1_PEER_CERTIFICATE */ +/* Define to 1 if you have the 'SSL_get1_peer_certificate' function. */ +#define HAVE_SSL_GET1_PEER_CERTIFICATE 1 -/* Define to 1 if you have the `SSL_set1_host' function. */ +/* Define to 1 if you have the 'SSL_is_quic' function. */ +/* #undef HAVE_SSL_IS_QUIC */ + +/* Define to 1 if you have the 'SSL_set1_host' function. */ #define HAVE_SSL_SET1_HOST 1 /* Define to 1 if you have the <stdarg.h> header file. */ #define HAVE_STDARG_H 1 +/* Define to 1 if you have the <stdatomic.h> header file. */ +#define HAVE_STDATOMIC_H 1 + /* Define to 1 if you have the <stdbool.h> header file. */ #define HAVE_STDBOOL_H 1 @@ -611,7 +682,7 @@ /* Define to 1 if you have the <stdlib.h> header file. */ #define HAVE_STDLIB_H 1 -/* Define to 1 if you have the `strftime' function. */ +/* Define to 1 if you have the 'strftime' function. */ #define HAVE_STRFTIME 1 /* Define to 1 if you have the <strings.h> header file. */ @@ -620,22 +691,39 @@ /* Define to 1 if you have the <string.h> header file. */ #define HAVE_STRING_H 1 -/* Define to 1 if you have the `strlcat' function. */ +/* Define to 1 if you have the 'strlcat' function. */ #define HAVE_STRLCAT 1 -/* Define to 1 if you have the `strlcpy' function. */ +/* Define to 1 if you have the 'strlcpy' function. */ #define HAVE_STRLCPY 1 -/* Define to 1 if you have the `strptime' function. */ +/* Define to 1 if you have the 'strptime' function. */ #define HAVE_STRPTIME 1 -/* Define to 1 if you have the `strsep' function. */ +/* Define to 1 if you have the 'strsep' function. */ #define HAVE_STRSEP 1 -/* Define to 1 if `ipi_spec_dst' is a member of `struct in_pktinfo'. */ +/* Define to 1 if 'ipi_spec_dst' is a member of 'struct in_pktinfo'. */ /* #undef HAVE_STRUCT_IN_PKTINFO_IPI_SPEC_DST */ -/* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */ +/* Define to 1 if 'tokenlen' is a member of 'struct ngtcp2_pkt_hd'. */ +/* #undef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN */ + +/* Define to 1 if 'max_tx_udp_payload_size' is a member of 'struct + ngtcp2_settings'. */ +/* #undef HAVE_STRUCT_NGTCP2_SETTINGS_MAX_TX_UDP_PAYLOAD_SIZE */ + +/* Define to 1 if 'tokenlen' is a member of 'struct ngtcp2_settings'. */ +/* #undef HAVE_STRUCT_NGTCP2_SETTINGS_TOKENLEN */ + +/* Define to 1 if 'original_dcid_present' is a member of 'struct + ngtcp2_transport_params'. */ +/* #undef HAVE_STRUCT_NGTCP2_TRANSPORT_PARAMS_ORIGINAL_DCID_PRESENT */ + +/* Define to 1 if the system has the type 'struct ngtcp2_version_cid'. */ +/* #undef HAVE_STRUCT_NGTCP2_VERSION_CID */ + +/* Define to 1 if 'sun_len' is a member of 'struct sockaddr_un'. */ #define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1 /* Define if you have Swig libraries and header files. */ @@ -695,16 +783,16 @@ /* Define to 1 if you have the <time.h> header file. */ #define HAVE_TIME_H 1 -/* Define to 1 if you have the `tzset' function. */ +/* Define to 1 if you have the 'tzset' function. */ #define HAVE_TZSET 1 /* Define to 1 if you have the <unistd.h> header file. */ #define HAVE_UNISTD_H 1 -/* Define to 1 if you have the `usleep' function. */ +/* Define to 1 if you have the 'usleep' function. */ #define HAVE_USLEEP 1 -/* Define to 1 if you have the `vfork' function. */ +/* Define to 1 if you have the 'vfork' function. */ #define HAVE_VFORK 1 /* Define to 1 if you have the <vfork.h> header file. */ @@ -722,22 +810,22 @@ /* Define to 1 if you have the <winsock2.h> header file. */ /* #undef HAVE_WINSOCK2_H */ -/* Define to 1 if `fork' works. */ +/* Define to 1 if 'fork' works. */ #define HAVE_WORKING_FORK 1 -/* Define to 1 if `vfork' works. */ +/* Define to 1 if 'vfork' works. */ #define HAVE_WORKING_VFORK 1 -/* Define to 1 if you have the `writev' function. */ +/* Define to 1 if you have the 'writev' function. */ #define HAVE_WRITEV 1 /* Define to 1 if you have the <ws2tcpip.h> header file. */ /* #undef HAVE_WS2TCPIP_H */ -/* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */ +/* Define to 1 if you have the 'X509_VERIFY_PARAM_set1_host' function. */ #define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 -/* Define to 1 if you have the `_beginthreadex' function. */ +/* Define to 1 if you have the '_beginthreadex' function. */ /* #undef HAVE__BEGINTHREADEX */ /* If HMAC_Init_ex() returns void */ @@ -796,7 +884,7 @@ #define PACKAGE_NAME "unbound" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "unbound 1.23.0" +#define PACKAGE_STRING "unbound 1.24.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "unbound" @@ -805,7 +893,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.23.0" +#define PACKAGE_VERSION "1.24.1" /* default pidfile location */ #define PIDFILE "/var/unbound/unbound.pid" @@ -828,7 +916,7 @@ #define ROOT_CERT_FILE "/var/unbound/icannbundle.pem" /* version number for resource files */ -#define RSRC_PACKAGE_VERSION 1,23,0,0 +#define RSRC_PACKAGE_VERSION 1,23,1,0 /* Directory to chdir to */ #define RUN_DIR "/var/unbound" @@ -836,32 +924,17 @@ /* Shared data */ #define SHARE_DIR "/var/unbound" -#ifdef __LP64__ -/* The size of `size_t', as computed by sizeof. */ -#define SIZEOF_SIZE_T 8 -/* The size of `size_t'. */ -/* The size of `pthread_t', as computed by sizeof. */ +/* The size of 'pthread_t', as computed by sizeof. */ #define SIZEOF_PTHREAD_T 8 -#else -#define SIZEOF_SIZE_T 4 -/* The size of `size_t'. */ -/* The size of `pthread_t', as computed by sizeof. */ -#define SIZEOF_PTHREAD_T 4 -#endif -/* The size of `time_t', as computed by sizeof. */ -#ifdef __i386__ -#define SIZEOF_TIME_T 4 -#else +/* The size of 'size_t', as computed by sizeof. */ +#define SIZEOF_SIZE_T 8 + +/* The size of 'time_t', as computed by sizeof. */ #define SIZEOF_TIME_T 8 -#endif -/* The size of `unsigned long', as computed by sizeof. */ -#ifdef __LP64__ +/* The size of 'unsigned long', as computed by sizeof. */ #define SIZEOF_UNSIGNED_LONG 8 -#else -#define SIZEOF_UNSIGNED_LONG 4 -#endif /* define if (v)snprintf does not return length needed, (but length used) */ /* #undef SNPRINTF_RET_BROKEN */ @@ -869,7 +942,7 @@ /* Define to 1 if libsodium supports sodium_set_misuse_handler */ /* #undef SODIUM_MISUSE_HANDLER */ -/* Define to 1 if all of the C90 standard headers exist (not just the ones +/* Define to 1 if all of the C89 standard headers exist (not just the ones required in a freestanding environment). This macro is provided for backward compatibility; new code need not use it. */ #define STDC_HEADERS 1 @@ -911,7 +984,7 @@ /* #undef USE_DNSTAP */ /* Define this to enable DSA support. */ -#define USE_DSA 1 +/* #undef USE_DSA */ /* Define this to enable ECDSA support. */ #define USE_ECDSA 1 @@ -935,7 +1008,7 @@ /* #undef USE_IPSET */ /* Define if you enable libevent */ -#define USE_LIBEVENT 1 +/* #undef USE_LIBEVENT */ /* Define this to enable use of /proc/sys/net/ipv4/ip_local_port_range as a default outgoing port range. This is only for the libunbound on Linux and @@ -963,7 +1036,7 @@ /* Define this to enable SHA256 and SHA512 support. */ #define USE_SHA2 1 -/* Enable extensions on AIX 3, Interix. */ +/* Enable extensions on AIX, Interix, z/OS. */ #ifndef _ALL_SOURCE # define _ALL_SOURCE 1 #endif @@ -1024,11 +1097,15 @@ #ifndef __STDC_WANT_IEC_60559_DFP_EXT__ # define __STDC_WANT_IEC_60559_DFP_EXT__ 1 #endif +/* Enable extensions specified by C23 Annex F. */ +#ifndef __STDC_WANT_IEC_60559_EXT__ +# define __STDC_WANT_IEC_60559_EXT__ 1 +#endif /* Enable extensions specified by ISO/IEC TS 18661-4:2015. */ #ifndef __STDC_WANT_IEC_60559_FUNCS_EXT__ # define __STDC_WANT_IEC_60559_FUNCS_EXT__ 1 #endif -/* Enable extensions specified by ISO/IEC TS 18661-3:2015. */ +/* Enable extensions specified by C23 Annex H and ISO/IEC TS 18661-3:2015. */ #ifndef __STDC_WANT_IEC_60559_TYPES_EXT__ # define __STDC_WANT_IEC_60559_TYPES_EXT__ 1 #endif @@ -1069,30 +1146,36 @@ /* Define if you want PyUnbound. */ /* #undef WITH_PYUNBOUND */ -/* Define to 1 if `lex' declares `yytext' as a `char *' by default, not a - `char[]'. */ +/* Define to 1 if 'lex' declares 'yytext' as a 'char *' by default, not a + 'char[]'. */ #define YYTEXT_POINTER 1 /* Number of bits in a file offset, on hosts where this is settable. */ /* #undef _FILE_OFFSET_BITS */ -/* Define to 1 to make fseeko visible on some hosts (e.g. glibc 2.2). */ +/* Define to 1 if necessary to make fseeko visible. */ /* #undef _LARGEFILE_SOURCE */ -/* Define for large files, on AIX-style hosts. */ +/* Define to 1 on platforms where this makes off_t a 64-bit type. */ /* #undef _LARGE_FILES */ /* Enable for compile on Minix */ #define _NETBSD_SOURCE 1 +/* Number of bits in time_t, on hosts where this is settable. */ +/* #undef _TIME_BITS */ + +/* Define to 1 on platforms where this makes time_t a 64-bit type. */ +/* #undef __MINGW_USE_VC2005_COMPAT */ + /* defined to use gcc ansi snprintf and sscanf that understands %lld when compiled for windows. */ /* #undef __USE_MINGW_ANSI_STDIO */ -/* Define to empty if `const' does not conform to ANSI C. */ +/* Define to empty if 'const' does not conform to ANSI C. */ /* #undef const */ -/* Define to `int' if <sys/types.h> doesn't define. */ +/* Define as 'int' if <sys/types.h> doesn't define. */ /* #undef gid_t */ /* in_addr_t */ @@ -1101,28 +1184,28 @@ /* in_port_t */ /* #undef in_port_t */ -/* Define to `__inline__' or `__inline' if that's what the C compiler +/* Define to '__inline__' or '__inline' if that's what the C compiler calls it, or to nothing if 'inline' is not supported under any name. */ #ifndef __cplusplus /* #undef inline */ #endif -/* Define to `short' if <sys/types.h> does not define. */ +/* Define to 'short' if <sys/types.h> does not define. */ /* #undef int16_t */ -/* Define to `int' if <sys/types.h> does not define. */ +/* Define to 'int' if <sys/types.h> does not define. */ /* #undef int32_t */ -/* Define to `long long' if <sys/types.h> does not define. */ +/* Define to 'long long' if <sys/types.h> does not define. */ /* #undef int64_t */ -/* Define to `signed char' if <sys/types.h> does not define. */ +/* Define to 'signed char' if <sys/types.h> does not define. */ /* #undef int8_t */ /* Define if replacement function should be used. */ /* #undef malloc */ -/* Define to `long int' if <sys/types.h> does not define. */ +/* Define to 'long int' if <sys/types.h> does not define. */ /* #undef off_t */ /* Define as a signed integer type capable of holding a process identifier. */ @@ -1131,71 +1214,71 @@ /* Define to 'int' if not defined */ /* #undef rlim_t */ -/* Define to `unsigned int' if <sys/types.h> does not define. */ +/* Define as 'unsigned int' if <stddef.h> doesn't define. */ /* #undef size_t */ /* Define to 'int' if not defined */ /* #undef socklen_t */ -/* Define to `int' if <sys/types.h> does not define. */ +/* Define to 'int' if <sys/types.h> does not define. */ /* #undef ssize_t */ /* Define to 'unsigned char if not defined */ /* #undef u_char */ -/* Define to `int' if <sys/types.h> doesn't define. */ +/* Define as 'int' if <sys/types.h> doesn't define. */ /* #undef uid_t */ -/* Define to `unsigned short' if <sys/types.h> does not define. */ +/* Define to 'unsigned short' if <sys/types.h> does not define. */ /* #undef uint16_t */ -/* Define to `unsigned int' if <sys/types.h> does not define. */ +/* Define to 'unsigned int' if <sys/types.h> does not define. */ /* #undef uint32_t */ -/* Define to `unsigned long long' if <sys/types.h> does not define. */ +/* Define to 'unsigned long long' if <sys/types.h> does not define. */ /* #undef uint64_t */ -/* Define to `unsigned char' if <sys/types.h> does not define. */ +/* Define to 'unsigned char' if <sys/types.h> does not define. */ /* #undef uint8_t */ -/* Define as `fork' if `vfork' does not work. */ +/* Define as 'fork' if 'vfork' does not work. */ /* #undef vfork */ #if defined(OMITTED__D_GNU_SOURCE) && !defined(_GNU_SOURCE) #define _GNU_SOURCE 1 -#endif +#endif #if defined(OMITTED__D_BSD_SOURCE) && !defined(_BSD_SOURCE) #define _BSD_SOURCE 1 -#endif +#endif #if defined(OMITTED__D_DEFAULT_SOURCE) && !defined(_DEFAULT_SOURCE) #define _DEFAULT_SOURCE 1 -#endif +#endif #if defined(OMITTED__D__EXTENSIONS__) && !defined(__EXTENSIONS__) #define __EXTENSIONS__ 1 -#endif +#endif #if defined(OMITTED__D_POSIX_C_SOURCE_200112) && !defined(_POSIX_C_SOURCE) #define _POSIX_C_SOURCE 200112 -#endif +#endif #if defined(OMITTED__D_XOPEN_SOURCE_600) && !defined(_XOPEN_SOURCE) #define _XOPEN_SOURCE 600 -#endif +#endif #if defined(OMITTED__D_XOPEN_SOURCE_EXTENDED_1) && !defined(_XOPEN_SOURCE_EXTENDED) #define _XOPEN_SOURCE_EXTENDED 1 -#endif +#endif #if defined(OMITTED__D_ALL_SOURCE) && !defined(_ALL_SOURCE) #define _ALL_SOURCE 1 -#endif +#endif #if defined(OMITTED__D_LARGEFILE_SOURCE_1) && !defined(_LARGEFILE_SOURCE) #define _LARGEFILE_SOURCE 1 -#endif +#endif @@ -1279,7 +1362,7 @@ #endif - + #ifdef HAVE_ATTR_FORMAT # define ATTR_FORMAT(archetype, string_index, first_to_check) \ __attribute__ ((format (archetype, string_index, first_to_check))) @@ -1389,7 +1472,7 @@ void* reallocarray(void *ptr, size_t nmemb, size_t size); #ifdef HAVE_WINSOCK2_H #define FD_SET_T (u_int) #else -#define FD_SET_T +#define FD_SET_T #endif @@ -1517,6 +1600,10 @@ struct sockaddr_storage; # define calloc(n,s) unbound_stat_calloc_log(n, s, __FILE__, __LINE__, __func__) # define free(p) unbound_stat_free_log(p, __FILE__, __LINE__, __func__) # define realloc(p,s) unbound_stat_realloc_log(p, s, __FILE__, __LINE__, __func__) +# define strdup(s) unbound_stat_strdup_log(s, __FILE__, __LINE__, __func__) +#ifdef HAVE_REALLOCARRAY +# define reallocarray(p,n,s) unbound_stat_reallocarray_log(p, n, s, __FILE__, __LINE__, __func__) +#endif void *unbound_stat_malloc(size_t size); void *unbound_stat_calloc(size_t nmemb, size_t size); void unbound_stat_free(void *ptr); @@ -1529,6 +1616,10 @@ void unbound_stat_free_log(void *ptr, const char* file, int line, const char* func); void *unbound_stat_realloc_log(void *ptr, size_t size, const char* file, int line, const char* func); +void *unbound_stat_reallocarray_log(void *ptr, size_t nmemb, size_t size, + const char* file, int line, const char* func); +char *unbound_stat_strdup_log(const char *s, const char* file, int line, + const char* func); #elif defined(UNBOUND_ALLOC_LITE) # include "util/alloc.h" #endif /* UNBOUND_ALLOC_LITE and UNBOUND_ALLOC_STATS */ diff --git a/lib/libutil++/Makefile b/lib/libutil++/Makefile index 56b64bbf358c..2e7a614df800 100644 --- a/lib/libutil++/Makefile +++ b/lib/libutil++/Makefile @@ -11,6 +11,10 @@ MAN+= freebsd::FILE_up.3 \ freebsd::pidfile.3 \ freebsd::stringf.3 +.for page in ${MAN} +MANSRC.${page}= ${page:S/:/_/g} +.endfor + .include <src.opts.mk> HAS_TESTS= diff --git a/lib/libutil++/freebsd::FILE_up.3 b/lib/libutil++/freebsd__FILE_up.3 index ea63b1233b43..ea63b1233b43 100644 --- a/lib/libutil++/freebsd::FILE_up.3 +++ b/lib/libutil++/freebsd__FILE_up.3 diff --git a/lib/libutil++/freebsd::addrinfo_up.3 b/lib/libutil++/freebsd__addrinfo_up.3 index 4845a76bfb61..4845a76bfb61 100644 --- a/lib/libutil++/freebsd::addrinfo_up.3 +++ b/lib/libutil++/freebsd__addrinfo_up.3 diff --git a/lib/libutil++/freebsd::fd_up.3 b/lib/libutil++/freebsd__fd_up.3 index 2ef2241a5c40..2ef2241a5c40 100644 --- a/lib/libutil++/freebsd::fd_up.3 +++ b/lib/libutil++/freebsd__fd_up.3 diff --git a/lib/libutil++/freebsd::malloc_up.3 b/lib/libutil++/freebsd__malloc_up.3 index b18e7854213a..b18e7854213a 100644 --- a/lib/libutil++/freebsd::malloc_up.3 +++ b/lib/libutil++/freebsd__malloc_up.3 diff --git a/lib/libutil++/freebsd::nvlist_up.3 b/lib/libutil++/freebsd__nvlist_up.3 index 43f76cf3ead3..43f76cf3ead3 100644 --- a/lib/libutil++/freebsd::nvlist_up.3 +++ b/lib/libutil++/freebsd__nvlist_up.3 diff --git a/lib/libutil++/freebsd::pidfile.3 b/lib/libutil++/freebsd__pidfile.3 index fb67253f5c02..fb67253f5c02 100644 --- a/lib/libutil++/freebsd::pidfile.3 +++ b/lib/libutil++/freebsd__pidfile.3 diff --git a/lib/libutil++/freebsd::stringf.3 b/lib/libutil++/freebsd__stringf.3 index 341fedef4343..341fedef4343 100644 --- a/lib/libutil++/freebsd::stringf.3 +++ b/lib/libutil++/freebsd__stringf.3 diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index f6251c093345..d54d9af38a34 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -147,7 +147,8 @@ MLINKS+=uucplock.3 uu_lock.3 MLINKS+=uucplock.3 uu_lock_txfr.3 MLINKS+=uucplock.3 uu_lockerr.3 MLINKS+=uucplock.3 uu_unlock.3 -MAN+= login.conf.5 + +MANNODEV= login.conf.5 HAS_TESTS= SUBDIR.${MK_TESTS}+= tests diff --git a/lib/libutil/login.conf.5 b/lib/libutil/login.conf.5 index 27f37fb5fc30..942f3ecd2661 100644 --- a/lib/libutil/login.conf.5 +++ b/lib/libutil/login.conf.5 @@ -17,7 +17,7 @@ .\" 5. Modifications may be freely made to this file providing the above .\" conditions are met. .\" -.Dd June 28, 2023 +.Dd September 25, 2025 .Dt LOGIN.CONF 5 .Os .Sh NAME @@ -496,7 +496,7 @@ lists. .Xr pam 3 , .Xr passwd 5 , .Xr ttys 5 , -.Xr ftpd 8 , +.Xr ftpd 8 Pq Pa ports/ftp/freebsd-ftpd , .Xr pam_passwdqc 8 .Sh HISTORY The file diff --git a/lib/libutil/mntopts.c b/lib/libutil/mntopts.c index 1d9347e3108a..4a064a086fd5 100644 --- a/lib/libutil/mntopts.c +++ b/lib/libutil/mntopts.c @@ -145,6 +145,18 @@ checkpath_allow_file(const char *path, char *resolved) return (0); } +static char * +prependdevtopath(const char *path, char *buf, u_long buflen) +{ + u_long len; + + if ((len = strlen(_PATH_DEV) + strlen(path) + 1) > buflen) + return NULL; + strncpy(buf, _PATH_DEV, len); + strncat(buf, path, len - sizeof(_PATH_DEV)); + return (buf); +} + /* * Get the mount point information for name. Name may be mount point name * or device name (with or without /dev/ preprended). @@ -153,19 +165,27 @@ struct statfs * getmntpoint(const char *name) { struct stat devstat, mntdevstat; - char device[sizeof(_PATH_DEV) - 1 + MNAMELEN]; - char *ddevname; + char *devname; struct statfs *mntbuf, *statfsp; - int i, mntsize, isdev; - u_long len; + int i, len, isdev, mntsize, mntfromnamesize; + char device[sizeof(_PATH_DEV) - 1 + MNAMELEN]; + u_long devlen; - if (stat(name, &devstat) != 0) + devlen = sizeof(device); + /* + * Note that stat(NULL, &statbuf) returns -1 (EBADF) which will + * cause us to return NULL if prependdevtopath() returns NULL. + */ + if (stat(name, &devstat) != 0 && + (name[0] != '/' && + stat(prependdevtopath(name, device, devlen), &devstat) != 0)) return (NULL); if (S_ISCHR(devstat.st_mode) || S_ISBLK(devstat.st_mode)) isdev = 1; else isdev = 0; mntsize = getmntinfo(&mntbuf, MNT_NOWAIT); + mntfromnamesize = sizeof(statfsp->f_mntfromname); for (i = 0; i < mntsize; i++) { statfsp = &mntbuf[i]; if (isdev == 0) { @@ -173,18 +193,20 @@ getmntpoint(const char *name) continue; return (statfsp); } - ddevname = statfsp->f_mntfromname; - if (*ddevname != '/') { - if ((len = strlen(_PATH_DEV) + strlen(ddevname) + 1) > - sizeof(statfsp->f_mntfromname) || - len > sizeof(device)) + devname = statfsp->f_mntfromname; + if (*devname == '/') { + if (stat(devname, &mntdevstat) != 0) + continue; + } else { + devname = prependdevtopath(devname, device, devlen); + if (devname == NULL || + (len = strlen(devname)) > mntfromnamesize) + continue; + if (stat(devname, &mntdevstat) != 0) continue; - strncpy(device, _PATH_DEV, len); - strncat(device, ddevname, len); - if (stat(device, &mntdevstat) == 0) - strncpy(statfsp->f_mntfromname, device, len); + strncpy(statfsp->f_mntfromname, devname, len); } - if (stat(ddevname, &mntdevstat) == 0 && + if (S_ISCHR(mntdevstat.st_mode) && mntdevstat.st_rdev == devstat.st_rdev) return (statfsp); } diff --git a/lib/libwrap/Makefile b/lib/libwrap/Makefile index bc39d5804637..7c302e0f0dc5 100644 --- a/lib/libwrap/Makefile +++ b/lib/libwrap/Makefile @@ -1,6 +1,3 @@ -# -# - .include <src.opts.mk> PACKAGE= tcpd @@ -9,12 +6,14 @@ CONFS= hosts.allow LIB= wrap SHLIB_MAJOR= 6 INCS= tcpd.h -MAN= hosts_access.3 -MAN+= hosts_access.5 hosts_options.5 -MLINKS= hosts_access.3 hosts_ctl.3 \ - hosts_access.3 request_init.3 \ - hosts_access.3 request_set.3 \ - hosts_options.5 hosts.allow.5 + +MAN= hosts_access.3 +MLINKS= hosts_access.3 hosts_ctl.3 \ + hosts_access.3 request_init.3 \ + hosts_access.3 request_set.3 + +MANNODEV= hosts_access.5 hosts_options.5 +MANNODEVLINKS= hosts_options.5 hosts.allow.5 .PATH: ${SRCTOP}/contrib/tcp_wrappers diff --git a/lib/libxo/libxo/Makefile b/lib/libxo/libxo/Makefile index 38e6ff031c7f..9caf8a498b05 100644 --- a/lib/libxo/libxo/Makefile +++ b/lib/libxo/libxo/Makefile @@ -51,7 +51,7 @@ MAN+= xo_attr.3 \ MAN+= xo_format.5 -MAN+= xo_options.7 +MANNODEV= xo_options.7 MLINKS= xo_attr.3 xo_attr_h.3 \ xo_attr.3 xo_attr_hv.3 \ diff --git a/lib/libxo/tests/encoder/Makefile b/lib/libxo/tests/encoder/Makefile index 7522328b0818..02634b971ace 100644 --- a/lib/libxo/tests/encoder/Makefile +++ b/lib/libxo/tests/encoder/Makefile @@ -1,4 +1,5 @@ PACKAGE= tests +NO_DEV_PACKAGE= LIBXOSRC= ${SRCTOP}/contrib/libxo diff --git a/lib/liby/Makefile b/lib/liby/Makefile index 93f72ee440f8..ace8f8457d22 100644 --- a/lib/liby/Makefile +++ b/lib/liby/Makefile @@ -1,4 +1,4 @@ -PACKAGE=lib${LIB} +PACKAGE=toolchain LIB= y SRCS= main.c yyerror.c NO_PIC= diff --git a/lib/libz/Makefile b/lib/libz/Makefile index 6a135158e134..03204e388674 100644 --- a/lib/libz/Makefile +++ b/lib/libz/Makefile @@ -1,7 +1,4 @@ -# -# - -PACKAGE= runtime +PACKAGE= zlib LIB= z SHLIBDIR?= /lib SHLIB_MAJOR= 6 diff --git a/lib/msun/src/e_remainder.c b/lib/msun/src/e_remainder.c index a5fb7141d01a..cc6cd320073e 100644 --- a/lib/msun/src/e_remainder.c +++ b/lib/msun/src/e_remainder.c @@ -64,8 +64,8 @@ remainder(double x, double p) if(x>=p_half) x -= p; } } - GET_HIGH_WORD(hx,x); - if ((hx&0x7fffffff)==0) hx = 0; + EXTRACT_WORDS(hx, lx, x); + if (((hx&0x7fffffff)|lx) == 0) hx = 0; SET_HIGH_WORD(x,hx^sx); return x; } diff --git a/lib/msun/src/s_cpow.c b/lib/msun/src/s_cpow.c index b887db51aa2a..2c20a8f3b48b 100644 --- a/lib/msun/src/s_cpow.c +++ b/lib/msun/src/s_cpow.c @@ -58,7 +58,10 @@ cpow(double complex a, double complex z) y = cimag (z); absa = cabs (a); if (absa == 0.0) { - return (CMPLX(0.0, 0.0)); + if (x == 0 && y == 0) + return (CMPLX(1., 0.)); + else + return (CMPLX(0., 0.)); } arga = carg (a); r = pow (absa, x); diff --git a/lib/msun/src/s_cpowf.c b/lib/msun/src/s_cpowf.c index 144291079f97..b8bdbd9cb07b 100644 --- a/lib/msun/src/s_cpowf.c +++ b/lib/msun/src/s_cpowf.c @@ -57,7 +57,10 @@ cpowf(float complex a, float complex z) y = cimagf(z); absa = cabsf (a); if (absa == 0.0f) { - return (CMPLXF(0.0f, 0.0f)); + if (x == 0 && y == 0) + return (CMPLXF(1.f, 0.f)); + else + return (CMPLXF(0.f, 0.f)); } arga = cargf (a); r = powf (absa, x); diff --git a/lib/msun/src/s_cpowl.c b/lib/msun/src/s_cpowl.c index 39797cadcfcb..efbe4936895f 100644 --- a/lib/msun/src/s_cpowl.c +++ b/lib/msun/src/s_cpowl.c @@ -57,7 +57,10 @@ cpowl(long double complex a, long double complex z) y = cimagl(z); absa = cabsl(a); if (absa == 0.0L) { - return (CMPLXL(0.0L, 0.0L)); + if (x == 0 && y == 0) + return (CMPLXL(1.L, 0.L)); + else + return (CMPLXL(0.L, 0.L)); } arga = cargl(a); r = powl(absa, x); diff --git a/lib/ncurses/Makefile.inc b/lib/ncurses/Makefile.inc index f2ed84e2e38f..e14867696834 100644 --- a/lib/ncurses/Makefile.inc +++ b/lib/ncurses/Makefile.inc @@ -1,5 +1,7 @@ # This is to include src/lib/Makefile.inc +PACKAGE?= ncurses +LIB_PACKAGE= WARNS?= 3 .include "../Makefile.inc" diff --git a/lib/ncurses/form/Makefile b/lib/ncurses/form/Makefile index d4774a5f51a8..7d8963b05ae8 100644 --- a/lib/ncurses/form/Makefile +++ b/lib/ncurses/form/Makefile @@ -3,7 +3,6 @@ SRCDIR= ${NCURSES_DIR}/form -PACKAGE= clibs LIB= formw SHLIB_MAJOR= 6 diff --git a/lib/ncurses/ncurses/Makefile b/lib/ncurses/ncurses/Makefile index 512a452ad6d0..b60760281b39 100644 --- a/lib/ncurses/ncurses/Makefile +++ b/lib/ncurses/ncurses/Makefile @@ -1,4 +1,3 @@ -PACKAGE= clibs SHLIBDIR?= /lib .include <src.opts.mk> diff --git a/lib/ncurses/panel/Makefile b/lib/ncurses/panel/Makefile index a51129df42e3..dfb478aa5f5b 100644 --- a/lib/ncurses/panel/Makefile +++ b/lib/ncurses/panel/Makefile @@ -3,7 +3,6 @@ SRCDIR= ${NCURSES_DIR}/panel -PACKAGE= clibs LIB= panelw SHLIB_MAJOR= 6 diff --git a/lib/ncurses/tinfo/Makefile b/lib/ncurses/tinfo/Makefile index 476df54bb72a..08c2311cd7a9 100644 --- a/lib/ncurses/tinfo/Makefile +++ b/lib/ncurses/tinfo/Makefile @@ -1,4 +1,3 @@ -PACKAGE= clibs SHLIBDIR?= /lib .include <src.opts.mk> @@ -400,6 +399,7 @@ terminfo.5: MKterminfo.sh terminfo.head Caps CLEANFILES+= terminfo.5 .PATH: ${NCURSES_DIR}/man + MAN= \ curs_addch.3 \ curs_addchstr.3 \ @@ -476,8 +476,9 @@ MAN+= \ curs_printw.3 \ curs_scanw.3 -MAN+= term.5 terminfo.5 scr_dump.5 user_caps.5 -MAN+= term.7 +MAN+= scr_dump.5 + +MANNODEV= term.5 term.7 terminfo.5 user_caps.5 CLEANFILES+= ${MAN:M*.3} diff --git a/lib/nss_tacplus/Makefile b/lib/nss_tacplus/Makefile index f39788cfbdea..e6fb934c234b 100644 --- a/lib/nss_tacplus/Makefile +++ b/lib/nss_tacplus/Makefile @@ -1,9 +1,9 @@ LIB= nss_tacplus -SRCS= ${LIB}.8 +SRCS= ${LIB}.c SHLIB_MAJOR= 1 SHLIB_NAME= ${LIB}.so.${SHLIB_MAJOR} LIBADD= tacplus -MK_INSTALLIB= no -MAN= ${LIB}.8 +MK_INSTALLLIB= no +MANNODEV= ${LIB}.8 .include <bsd.lib.mk> diff --git a/lib/virtual_oss/Makefile b/lib/virtual_oss/Makefile new file mode 100644 index 000000000000..dc83edd4b980 --- /dev/null +++ b/lib/virtual_oss/Makefile @@ -0,0 +1,9 @@ +.include <src.opts.mk> + +SHLIBDIR?= ${LIBDIR}/virtual_oss + +SUBDIR+= null \ + oss + +.include "Makefile.inc" +.include <bsd.subdir.mk> diff --git a/lib/virtual_oss/Makefile.inc b/lib/virtual_oss/Makefile.inc new file mode 100644 index 000000000000..877465a5c548 --- /dev/null +++ b/lib/virtual_oss/Makefile.inc @@ -0,0 +1,5 @@ +PACKAGE= sound + +.include "../Makefile.inc" + +LDFLAGS+= -L${.OBJDIR:H:H}/libsamplerate diff --git a/lib/virtual_oss/bt/Makefile b/lib/virtual_oss/bt/Makefile new file mode 100644 index 000000000000..15413b7a1f1e --- /dev/null +++ b/lib/virtual_oss/bt/Makefile @@ -0,0 +1,19 @@ +SHLIB_NAME= voss_bt.so +SHLIBDIR= ${LIBDIR}/virtual_oss + +SRCS= bt.c \ + avdtp.c \ + sbc_encode.c + +CFLAGS+= -I${SRCTOP}/usr.sbin/virtual_oss/virtual_oss \ + -I${SRCTOP}/contrib/libsamplerate +LDFLAGS+= -lbluetooth -lsdp +LIBADD= samplerate + +.if defined(HAVE_LIBAV) +CFLAGS+= -I${LOCALBASE:U/usr/local}/include -DHAVE_LIBAV +LDFLAGS+= -L${LOCALBASE:U/usr/local}/lib \ + -lavdevice -lavutil -lavcodec -lavformat +.endif + +.include <bsd.lib.mk> diff --git a/lib/virtual_oss/bt/avdtp.c b/lib/virtual_oss/bt/avdtp.c new file mode 100644 index 000000000000..82ed0fb942b6 --- /dev/null +++ b/lib/virtual_oss/bt/avdtp.c @@ -0,0 +1,720 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2015-2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> + * Copyright (c) 2016-2019 Hans Petter Selasky <hps@selasky.org> + * Copyright (c) 2019 Google LLC, written by Richard Kralovic <riso@google.com> + * + * This software is dedicated to the memory of - + * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012. + * + * Barry was a man who loved his music. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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/uio.h> + +#include <stdio.h> +#include <errno.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "avdtp_signal.h" +#include "bt.h" + +#define DPRINTF(...) printf("backend_bt: " __VA_ARGS__) + +struct avdtpGetPacketInfo { + uint8_t buffer_data[512]; + uint16_t buffer_len; + uint8_t trans; + uint8_t signalID; +}; + +static int avdtpAutoConfig(struct bt_config *); + +/* Return received message type if success, < 0 if failure. */ +static int +avdtpGetPacket(int fd, struct avdtpGetPacketInfo *info) +{ + uint8_t *pos = info->buffer_data; + uint8_t *end = info->buffer_data + sizeof(info->buffer_data); + uint8_t message_type; + int len; + + memset(info, 0, sizeof(*info)); + + /* Handle fragmented packets */ + for (int remaining = 1; remaining > 0; --remaining) { + len = read(fd, pos, end - pos); + + if (len < AVDTP_LEN_SUCCESS) + return (-1); + if (len == (int)(end - pos)) + return (-1); /* buffer too small */ + + uint8_t trans = (pos[0] & TRANSACTIONLABEL) >> TRANSACTIONLABEL_S; + uint8_t packet_type = (pos[0] & PACKETTYPE) >> PACKETTYPE_S; + uint8_t current_message_type = (info->buffer_data[0] & MESSAGETYPE); + uint8_t shift; + if (pos == info->buffer_data) { + info->trans = trans; + message_type = current_message_type; + if (packet_type == singlePacket) { + info->signalID = (pos[1] & SIGNALID_MASK); + shift = 2; + } else { + if (packet_type != startPacket) + return (-1); + remaining = pos[1]; + info->signalID = (pos[2] & SIGNALID_MASK); + shift = 3; + } + } else { + if (info->trans != trans || + message_type != current_message_type || + (remaining == 1 && packet_type != endPacket) || + (remaining > 1 && packet_type != continuePacket)) { + return (-1); + } + shift = 1; + } + memmove(pos, pos + shift, len); + pos += len; + } + info->buffer_len = pos - info->buffer_data; + return (message_type); +} + +/* Returns 0 on success, < 0 on failure. */ +static int +avdtpSendPacket(int fd, uint8_t command, uint8_t trans, uint8_t type, + uint8_t * data0, int datasize0, uint8_t * data1, + int datasize1) +{ + struct iovec iov[3]; + uint8_t header[2]; + int retval; + + /* fill out command header */ + header[0] = (trans << 4) | (type & 3); + if (command != 0) + header[1] = command & 0x3f; + else + header[1] = 3; + + iov[0].iov_base = header; + iov[0].iov_len = 2; + iov[1].iov_base = data0; + iov[1].iov_len = datasize0; + iov[2].iov_base = data1; + iov[2].iov_len = datasize1; + + retval = writev(fd, iov, 3); + if (retval != (2 + datasize0 + datasize1)) + return (-EINVAL); + else + return (0); +} + +/* Returns 0 on success, < 0 on failure. */ +static int +avdtpSendSyncCommand(int fd, struct avdtpGetPacketInfo *info, + uint8_t command, uint8_t type, uint8_t * data0, + int datasize0, uint8_t * data1, int datasize1) +{ + static uint8_t transLabel; + uint8_t trans; + int retval; + + alarm(8); /* set timeout */ + + trans = (transLabel++) & 0xF; + + retval = avdtpSendPacket(fd, command, trans, type, + data0, datasize0, data1, datasize1); + if (retval) + goto done; +retry: + switch (avdtpGetPacket(fd, info)) { + case RESPONSEACCEPT: + if (info->trans != trans) + goto retry; + retval = 0; + break; + case RESPONSEREJECT: + if (info->trans != trans) + goto retry; + retval = -EINVAL; + break; + case COMMAND: + retval = avdtpSendReject(fd, info->trans, info->signalID); + if (retval == 0) + goto retry; + break; + default: + retval = -ENXIO; + break; + } +done: + alarm(0); /* clear timeout */ + + return (retval); +} + +/* + * Variant for acceptor role: We support any frequency, blocks, bands, and + * allocation. Returns 0 on success, < 0 on failure. + */ +static int +avdtpSendCapabilitiesResponseSBCForACP(int fd, int trans) +{ + uint8_t data[10]; + + data[0] = mediaTransport; + data[1] = 0; + data[2] = mediaCodec; + data[3] = 0x6; + data[4] = mediaTypeAudio; + data[5] = SBC_CODEC_ID; + data[6] = + (1 << (3 - MODE_STEREO)) | + (1 << (3 - MODE_JOINT)) | + (1 << (3 - MODE_DUAL)) | + (1 << (3 - MODE_MONO)) | + (1 << (7 - FREQ_44_1K)) | + (1 << (7 - FREQ_48K)) | + (1 << (7 - FREQ_32K)) | + (1 << (7 - FREQ_16K)); + data[7] = + (1 << (7 - BLOCKS_4)) | + (1 << (7 - BLOCKS_8)) | + (1 << (7 - BLOCKS_12)) | + (1 << (7 - BLOCKS_16)) | + (1 << (3 - BANDS_4)) | + (1 << (3 - BANDS_8)) | (1 << ALLOC_LOUDNESS) | (1 << ALLOC_SNR); + data[8] = MIN_BITPOOL; + data[9] = DEFAULT_MAXBPOOL; + + return (avdtpSendPacket(fd, AVDTP_GET_CAPABILITIES, trans, + RESPONSEACCEPT, data, sizeof(data), NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpSendAccept(int fd, uint8_t trans, uint8_t myCommand) +{ + return (avdtpSendPacket(fd, myCommand, trans, RESPONSEACCEPT, + NULL, 0, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpSendReject(int fd, uint8_t trans, uint8_t myCommand) +{ + uint8_t value = 0; + + return (avdtpSendPacket(fd, myCommand, trans, RESPONSEREJECT, + &value, 1, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpSendDiscResponseAudio(int fd, uint8_t trans, + uint8_t mySep, uint8_t is_sink) +{ + uint8_t data[2]; + + data[0] = mySep << 2; + data[1] = mediaTypeAudio << 4 | (is_sink ? (1 << 3) : 0); + + return (avdtpSendPacket(fd, AVDTP_DISCOVER, trans, RESPONSEACCEPT, + data, 2, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpDiscoverAndConfig(struct bt_config *cfg, bool isSink) +{ + struct avdtpGetPacketInfo info; + uint16_t offset; + uint8_t chmode = cfg->chmode; + uint8_t aacMode1 = cfg->aacMode1; + uint8_t aacMode2 = cfg->aacMode2; + int retval; + + retval = avdtpSendSyncCommand(cfg->hc, &info, AVDTP_DISCOVER, 0, + NULL, 0, NULL, 0); + if (retval) + return (retval); + + retval = -EBUSY; + for (offset = 0; offset + 2 <= info.buffer_len; offset += 2) { + cfg->sep = info.buffer_data[offset] >> 2; + cfg->media_Type = info.buffer_data[offset + 1] >> 4; + cfg->chmode = chmode; + cfg->aacMode1 = aacMode1; + cfg->aacMode2 = aacMode2; + if (info.buffer_data[offset] & DISCOVER_SEP_IN_USE) + continue; + if (info.buffer_data[offset + 1] & DISCOVER_IS_SINK) { + if (!isSink) + continue; + } else { + if (isSink) + continue; + } + /* try to configure SBC */ + retval = avdtpAutoConfig(cfg); + if (retval == 0) + return (0); + } + return (retval); +} + +/* Returns 0 on success, < 0 on failure. */ +static int +avdtpGetCapabilities(int fd, uint8_t sep, struct avdtpGetPacketInfo *info) +{ + uint8_t address = (sep << 2); + + return (avdtpSendSyncCommand(fd, info, + AVDTP_GET_CAPABILITIES, 0, &address, 1, + NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpSetConfiguration(int fd, uint8_t sep, uint8_t * data, int datasize) +{ + struct avdtpGetPacketInfo info; + uint8_t configAddresses[2]; + + configAddresses[0] = sep << 2; + configAddresses[1] = INTSEP << 2; + + return (avdtpSendSyncCommand(fd, &info, AVDTP_SET_CONFIGURATION, 0, + configAddresses, 2, data, datasize)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpOpen(int fd, uint8_t sep) +{ + struct avdtpGetPacketInfo info; + uint8_t address = sep << 2; + + return (avdtpSendSyncCommand(fd, &info, AVDTP_OPEN, 0, + &address, 1, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpStart(int fd, uint8_t sep) +{ + struct avdtpGetPacketInfo info; + uint8_t address = sep << 2; + + return (avdtpSendSyncCommand(fd, &info, AVDTP_START, 0, + &address, 1, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpClose(int fd, uint8_t sep) +{ + struct avdtpGetPacketInfo info; + uint8_t address = sep << 2; + + return (avdtpSendSyncCommand(fd, &info, AVDTP_CLOSE, 0, + &address, 1, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpSuspend(int fd, uint8_t sep) +{ + struct avdtpGetPacketInfo info; + uint8_t address = sep << 2; + + return (avdtpSendSyncCommand(fd, &info, AVDTP_SUSPEND, 0, + &address, 1, NULL, 0)); +} + +/* Returns 0 on success, < 0 on failure. */ +int +avdtpAbort(int fd, uint8_t sep) +{ + struct avdtpGetPacketInfo info; + uint8_t address = sep << 2; + + return (avdtpSendSyncCommand(fd, &info, AVDTP_ABORT, 0, + &address, 1, NULL, 0)); +} + +static int +avdtpAutoConfig(struct bt_config *cfg) +{ + struct avdtpGetPacketInfo info; + uint8_t freqmode; + uint8_t blk_len_sb_alloc; + uint8_t availFreqMode = 0; + uint8_t availConfig = 0; + uint8_t supBitpoolMin = 0; + uint8_t supBitpoolMax = 0; + uint8_t aacMode1 = 0; + uint8_t aacMode2 = 0; +#ifdef HAVE_LIBAV + uint8_t aacBitrate3 = 0; + uint8_t aacBitrate4 = 0; + uint8_t aacBitrate5 = 0; +#endif + int retval; + int i; + + retval = avdtpGetCapabilities(cfg->hc, cfg->sep, &info); + if (retval) { + DPRINTF("Cannot get capabilities\n"); + return (retval); + } +retry: + for (i = 0; (i + 1) < info.buffer_len;) { +#if 0 + DPRINTF("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", + info.buffer_data[i + 0], + info.buffer_data[i + 1], + info.buffer_data[i + 2], + info.buffer_data[i + 3], + info.buffer_data[i + 4], info.buffer_data[i + 5]); +#endif + if (i + 2 + info.buffer_data[i + 1] > info.buffer_len) + break; + switch (info.buffer_data[i]) { + case mediaTransport: + break; + case mediaCodec: + if (info.buffer_data[i + 1] < 2) + break; + /* check codec */ + switch (info.buffer_data[i + 3]) { + case 0: /* SBC */ + if (info.buffer_data[i + 1] < 6) + break; + availFreqMode = info.buffer_data[i + 4]; + availConfig = info.buffer_data[i + 5]; + supBitpoolMin = info.buffer_data[i + 6]; + supBitpoolMax = info.buffer_data[i + 7]; + break; + case 2: /* MPEG2/4 AAC */ + if (info.buffer_data[i + 1] < 8) + break; + aacMode1 = info.buffer_data[i + 5]; + aacMode2 = info.buffer_data[i + 6]; +#ifdef HAVE_LIBAV + aacBitrate3 = info.buffer_data[i + 7]; + aacBitrate4 = info.buffer_data[i + 8]; + aacBitrate5 = info.buffer_data[i + 9]; +#endif + break; + default: + break; + } + } + /* jump to next information element */ + i += 2 + info.buffer_data[i + 1]; + } + aacMode1 &= cfg->aacMode1; + aacMode2 &= cfg->aacMode2; + + /* Try AAC first */ + if (aacMode1 == cfg->aacMode1 && aacMode2 == cfg->aacMode2) { +#ifdef HAVE_LIBAV + uint8_t config[12] = { mediaTransport, 0x0, mediaCodec, + 0x8, 0x0, 0x02, 0x80, aacMode1, aacMode2, aacBitrate3, + aacBitrate4, aacBitrate5 + }; + + if (avdtpSetConfiguration + (cfg->hc, cfg->sep, config, sizeof(config)) == 0) { + cfg->codec = CODEC_AAC; + return (0); + } +#endif + } + /* Try SBC second */ + if (cfg->freq == FREQ_UNDEFINED) + goto auto_config_failed; + + freqmode = (1 << (3 - cfg->freq + 4)) | (1 << (3 - cfg->chmode)); + + if ((availFreqMode & freqmode) != freqmode) { + DPRINTF("No frequency and mode match\n"); + goto auto_config_failed; + } + for (i = 0; i != 4; i++) { + blk_len_sb_alloc = (1 << (i + 4)) | + (1 << (1 - cfg->bands + 2)) | (1 << cfg->allocm); + + if ((availConfig & blk_len_sb_alloc) == blk_len_sb_alloc) + break; + } + if (i == 4) { + DPRINTF("No bands available\n"); + goto auto_config_failed; + } + cfg->blocks = (3 - i); + + if (cfg->allocm == ALLOC_SNR) + supBitpoolMax &= ~1; + + if (cfg->chmode == MODE_DUAL || cfg->chmode == MODE_MONO) + supBitpoolMax /= 2; + + if (cfg->bands == BANDS_4) + supBitpoolMax /= 2; + + if (supBitpoolMax > cfg->bitpool) + supBitpoolMax = cfg->bitpool; + else + cfg->bitpool = supBitpoolMax; + + do { + uint8_t config[10] = { mediaTransport, 0x0, mediaCodec, 0x6, + 0x0, 0x0, freqmode, blk_len_sb_alloc, supBitpoolMin, + supBitpoolMax + }; + + if (avdtpSetConfiguration + (cfg->hc, cfg->sep, config, sizeof(config)) == 0) { + cfg->codec = CODEC_SBC; + return (0); + } + } while (0); + +auto_config_failed: + if (cfg->chmode == MODE_STEREO) { + cfg->chmode = MODE_MONO; + cfg->aacMode2 ^= 0x0C; + goto retry; + } + return (-EINVAL); +} + +void +avdtpACPFree(struct bt_config *cfg) +{ + if (cfg->handle.sbc_enc) { + free(cfg->handle.sbc_enc); + cfg->handle.sbc_enc = NULL; + } +} + +/* Returns 0 on success, < 0 on failure. */ +static int +avdtpParseSBCConfig(uint8_t * data, struct bt_config *cfg) +{ + if (data[0] & (1 << (7 - FREQ_48K))) { + cfg->freq = FREQ_48K; + } else if (data[0] & (1 << (7 - FREQ_44_1K))) { + cfg->freq = FREQ_44_1K; + } else if (data[0] & (1 << (7 - FREQ_32K))) { + cfg->freq = FREQ_32K; + } else if (data[0] & (1 << (7 - FREQ_16K))) { + cfg->freq = FREQ_16K; + } else { + return -EINVAL; + } + + if (data[0] & (1 << (3 - MODE_STEREO))) { + cfg->chmode = MODE_STEREO; + } else if (data[0] & (1 << (3 - MODE_JOINT))) { + cfg->chmode = MODE_JOINT; + } else if (data[0] & (1 << (3 - MODE_DUAL))) { + cfg->chmode = MODE_DUAL; + } else if (data[0] & (1 << (3 - MODE_MONO))) { + cfg->chmode = MODE_MONO; + } else { + return -EINVAL; + } + + if (data[1] & (1 << (7 - BLOCKS_16))) { + cfg->blocks = BLOCKS_16; + } else if (data[1] & (1 << (7 - BLOCKS_12))) { + cfg->blocks = BLOCKS_12; + } else if (data[1] & (1 << (7 - BLOCKS_8))) { + cfg->blocks = BLOCKS_8; + } else if (data[1] & (1 << (7 - BLOCKS_4))) { + cfg->blocks = BLOCKS_4; + } else { + return -EINVAL; + } + + if (data[1] & (1 << (3 - BANDS_8))) { + cfg->bands = BANDS_8; + } else if (data[1] & (1 << (3 - BANDS_4))) { + cfg->bands = BANDS_4; + } else { + return -EINVAL; + } + + if (data[1] & (1 << ALLOC_LOUDNESS)) { + cfg->allocm = ALLOC_LOUDNESS; + } else if (data[1] & (1 << ALLOC_SNR)) { + cfg->allocm = ALLOC_SNR; + } else { + return -EINVAL; + } + cfg->bitpool = data[3]; + return 0; +} + +int +avdtpACPHandlePacket(struct bt_config *cfg) +{ + struct avdtpGetPacketInfo info; + int retval; + + if (avdtpGetPacket(cfg->hc, &info) != COMMAND) + return (-ENXIO); + + switch (info.signalID) { + case AVDTP_DISCOVER: + retval = + avdtpSendDiscResponseAudio(cfg->hc, info.trans, ACPSEP, 1); + if (!retval) + retval = AVDTP_DISCOVER; + break; + case AVDTP_GET_CAPABILITIES: + retval = + avdtpSendCapabilitiesResponseSBCForACP(cfg->hc, info.trans); + if (!retval) + retval = AVDTP_GET_CAPABILITIES; + break; + case AVDTP_SET_CONFIGURATION: + if (cfg->acceptor_state != acpInitial) + goto err; + cfg->sep = info.buffer_data[1] >> 2; + int is_configured = 0; + for (int i = 2; (i + 1) < info.buffer_len;) { + if (i + 2 + info.buffer_data[i + 1] > info.buffer_len) + break; + switch (info.buffer_data[i]) { + case mediaTransport: + break; + case mediaCodec: + if (info.buffer_data[i + 1] < 2) + break; + /* check codec */ + switch (info.buffer_data[i + 3]) { + case 0: /* SBC */ + if (info.buffer_data[i + 1] < 6) + break; + retval = + avdtpParseSBCConfig(info.buffer_data + i + 4, cfg); + if (retval) + return retval; + is_configured = 1; + break; + case 2: /* MPEG2/4 AAC */ + /* TODO: Add support */ + default: + break; + } + } + /* jump to next information element */ + i += 2 + info.buffer_data[i + 1]; + } + if (!is_configured) + goto err; + + retval = + avdtpSendAccept(cfg->hc, info.trans, AVDTP_SET_CONFIGURATION); + if (retval) + return (retval); + + /* TODO: Handle other codecs */ + if (cfg->handle.sbc_enc == NULL) { + cfg->handle.sbc_enc = malloc(sizeof(*cfg->handle.sbc_enc)); + if (cfg->handle.sbc_enc == NULL) + return (-ENOMEM); + } + memset(cfg->handle.sbc_enc, 0, sizeof(*cfg->handle.sbc_enc)); + + retval = AVDTP_SET_CONFIGURATION; + cfg->acceptor_state = acpConfigurationSet; + break; + case AVDTP_OPEN: + if (cfg->acceptor_state != acpConfigurationSet) + goto err; + retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); + if (retval) + return (retval); + retval = info.signalID; + cfg->acceptor_state = acpStreamOpened; + break; + case AVDTP_START: + if (cfg->acceptor_state != acpStreamOpened && + cfg->acceptor_state != acpStreamSuspended) { + goto err; + } + retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); + if (retval) + return retval; + retval = info.signalID; + cfg->acceptor_state = acpStreamStarted; + break; + case AVDTP_CLOSE: + if (cfg->acceptor_state != acpStreamOpened && + cfg->acceptor_state != acpStreamStarted && + cfg->acceptor_state != acpStreamSuspended) { + goto err; + } + retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); + if (retval) + return (retval); + retval = info.signalID; + cfg->acceptor_state = acpStreamClosed; + break; + case AVDTP_SUSPEND: + if (cfg->acceptor_state != acpStreamOpened && + cfg->acceptor_state != acpStreamStarted) { + goto err; + } + retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); + if (retval) + return (retval); + retval = info.signalID; + cfg->acceptor_state = acpStreamSuspended; + break; + case AVDTP_GET_CONFIGURATION: + case AVDTP_RECONFIGURE: + case AVDTP_ABORT: + /* TODO: Implement this. */ + default: +err: + avdtpSendReject(cfg->hc, info.trans, info.signalID); + return (-ENXIO); + } + return (retval); +} diff --git a/lib/virtual_oss/bt/avdtp_signal.h b/lib/virtual_oss/bt/avdtp_signal.h new file mode 100644 index 000000000000..a46cc6dd9dcf --- /dev/null +++ b/lib/virtual_oss/bt/avdtp_signal.h @@ -0,0 +1,139 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2015 Nathanial Sloss <nathanialsloss@yahoo.com.au> + * + * This software is dedicated to the memory of - + * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012. + * + * Barry was a man who loved his music. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _AVDTP_SIGNAL_H_ +#define _AVDTP_SIGNAL_H_ + +#include <stdint.h> +#include <stdbool.h> + +/* Our endpoint. */ +#define INTSEP 8 +#define ACPSEP 8 + +/* AVDTP signals. */ + +#define AVDTP_DISCOVER 0x01 +#define AVDTP_GET_CAPABILITIES 0x02 +#define AVDTP_SET_CONFIGURATION 0x03 +#define AVDTP_GET_CONFIGURATION 0x04 +#define AVDTP_RECONFIGURE 0x05 +#define AVDTP_OPEN 0x06 +#define AVDTP_START 0x07 +#define AVDTP_CLOSE 0x08 +#define AVDTP_SUSPEND 0x09 +#define AVDTP_ABORT 0x0a +#define AVDTP_SECUURITY_CONTROL 0x0b + +/* Signal Command & Response Header Masks. */ + +#define TRANSACTIONLABEL 0xf0 +#define TRANSACTIONLABEL_S 4 +#define SIGNALID_MASK 0x3f +#define PACKETTYPE 0x0c +#define PACKETTYPE_S 0x02 +#define MESSAGETYPE 0x03 +#define SIGNALIDENTIFIER 0x3f +#define DISCOVER_SEP_IN_USE 0x02 +#define DISCOVER_IS_SINK 0x08 + +/* Packet Types */ +#define singlePacket 0x0 +#define startPacket 0x1 +#define continuePacket 0x2 +#define endPacket 0x3 + +/* Message Types */ +#define COMMAND 0x0 +#define RESPONSEACCEPT 0x2 +#define RESPONSEREJECT 0x3 + +/* Response general error/success lengths */ +#define AVDTP_LEN_SUCCESS 2 +#define AVDTP_LEN_ERROR 3 + +/* Error codes */ +#define BAD_HEADER_FORMAT 0x01 +#define BAD_LENGTH 0x11 +#define BAD_ACP_SEID 0x12 +#define SEP_IN_USE 0x13 +#define SEP_NOT_IN_USE 0x14 +#define BAD_SERV_CATAGORY 0x17 +#define BAD_PAYLOAD_FORMAT 0x18 +#define NOT_SUPPORTED_COMMAND 0x19 +#define INVALID_CAPABILITIES 0x1a + +#define BAD_RECOVERY_TYPE 0x22 +#define BAD_MEDIA_TRANSPORT_FORMAT 0x23 +#define BAD_RECOVERY_FORMAT 0x25 +#define BAD_ROHC_FORMAT 0x26 +#define BAD_CP_FORMAT 0x27 +#define BAD_MULTIPLEXING_FORMAT 0x28 +#define UNSUPPORTED_CONFIGURATION 0x29 +#define BAD_STATE 0x31 + +/* Service Capabilities Field. */ +#define mediaTransport 0x1 +#define reporting 0x2 +#define recovery 0x3 +#define contentProtection 0x4 +#define headerCompression 0x5 +#define multiplexing 0x6 +#define mediaCodec 0x7 + +/* Media Codec Capabilities */ +#define mediaCodecSbc 0x00 +#define mediaCodecMpeg1 0x01 +#define mediaCodecMpeg2 0x02 + +#define SBC_CODEC_ID 0x0 +#define mediaTypeAudio 0x0 + +struct bt_config; + +int avdtpSendAccept(int, uint8_t, uint8_t); +int avdtpSendReject(int, uint8_t, uint8_t); +int avdtpSendDiscResponseAudio(int, uint8_t, uint8_t, uint8_t); +int avdtpDiscoverAndConfig(struct bt_config *, bool); +int avdtpSetConfiguration(int, uint8_t, uint8_t *, int); +int avdtpOpen(int, uint8_t); +int avdtpStart(int, uint8_t); +int avdtpClose(int, uint8_t); +int avdtpSuspend(int, uint8_t); +int avdtpAbort(int, uint8_t); + +/* Return < 0 if error, processed signal otherwise. */ +int avdtpACPHandlePacket(struct bt_config *cfg); +/* Free state allocated in avdtpACPHandlePacket(), if any. */ +void avdtpACPFree(struct bt_config *cfg); + +#endif /* _AVDTP_SIGNAL_H_ */ diff --git a/lib/virtual_oss/bt/bt.c b/lib/virtual_oss/bt/bt.c new file mode 100644 index 000000000000..57f000b067d5 --- /dev/null +++ b/lib/virtual_oss/bt/bt.c @@ -0,0 +1,1061 @@ +/*- + * Copyright (c) 2015-2019 Hans Petter Selasky + * Copyright (c) 2015 Nathanial Sloss <nathanialsloss@yahoo.com.au> + * Copyright (c) 2006 Itronix Inc + * + * 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/queue.h> +#include <sys/filio.h> +#include <sys/soundcard.h> + +#include <stdio.h> +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <err.h> +#define L2CAP_SOCKET_CHECKED +#include <bluetooth.h> +#include <sdp.h> + +#include "backend.h" +#include "int.h" + +#include "avdtp_signal.h" +#include "bt.h" + +#define DPRINTF(...) printf("backend_bt: " __VA_ARGS__) + +struct l2cap_info { + bdaddr_t laddr; + bdaddr_t raddr; +}; + +static struct bt_config bt_play_cfg; +static struct bt_config bt_rec_cfg; + +int +bt_receive(struct bt_config *cfg, void *ptr, int len, int use_delay) +{ + struct sbc_header *phdr = (struct sbc_header *)cfg->mtu_data; + struct sbc_encode *sbc = cfg->handle.sbc_enc; + uint8_t *tmp = ptr; + int old_len = len; + int delta; + int err; + + /* wait for service interval, if any */ + if (use_delay) + virtual_oss_wait(); + + switch (cfg->blocks) { + case BLOCKS_4: + sbc->blocks = 4; + break; + case BLOCKS_8: + sbc->blocks = 8; + break; + case BLOCKS_12: + sbc->blocks = 12; + break; + default: + sbc->blocks = 16; + break; + } + + switch (cfg->bands) { + case BANDS_4: + sbc->bands = 4; + break; + default: + sbc->bands = 8; + break; + } + + if (cfg->chmode != MODE_MONO) { + sbc->channels = 2; + } else { + sbc->channels = 1; + } + + while (1) { + delta = len & ~1; + if (delta > (int)(2 * sbc->rem_len)) + delta = (2 * sbc->rem_len); + + /* copy out samples, if any */ + memcpy(tmp, (char *)sbc->music_data + sbc->rem_off, delta); + tmp += delta; + len -= delta; + sbc->rem_off += delta / 2; + sbc->rem_len -= delta / 2; + if (len == 0) + break; + + if (sbc->rem_len == 0 && + sbc->rem_data_frames != 0) { + err = sbc_decode_frame(cfg, sbc->rem_data_len * 8); + sbc->rem_data_frames--; + sbc->rem_data_ptr += err; + sbc->rem_data_len -= err; + continue; + } + /* TODO: Support fragmented SBC frames */ + err = read(cfg->fd, cfg->mtu_data, cfg->mtu); + + if (err == 0) { + break; + } else if (err < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) + break; + else + return (-1); /* disconnected */ + } + + /* verify RTP header */ + if (err < (int)sizeof(*phdr) || phdr->id != 0x80) + continue; + + sbc->rem_data_frames = phdr->numFrames; + sbc->rem_data_ptr = (uint8_t *)(phdr + 1); + sbc->rem_data_len = err - sizeof(*phdr); + } + return (old_len - len); +} + +static int +bt_set_format(int *format) +{ + int value; + + value = *format & AFMT_S16_NE; + if (value != 0) { + *format = value; + return (0); + } + return (-1); +} + +static void +bt_close(struct voss_backend *pbe) +{ + struct bt_config *cfg = pbe->arg; + + if (cfg->hc > 0) { + avdtpAbort(cfg->hc, cfg->sep); + avdtpClose(cfg->hc, cfg->sep); + close(cfg->hc); + cfg->hc = -1; + } + if (cfg->fd > 0) { + close(cfg->fd); + cfg->fd = -1; + } +} + +static void +bt_play_close(struct voss_backend *pbe) +{ + struct bt_config *cfg = pbe->arg; + + switch (cfg->codec) { + case CODEC_SBC: + if (cfg->handle.sbc_enc == NULL) + break; + free(cfg->handle.sbc_enc); + cfg->handle.sbc_enc = NULL; + break; +#ifdef HAVE_LIBAV + case CODEC_AAC: + if (cfg->handle.av.context == NULL) + break; + av_free(cfg->rem_in_data); + av_frame_free(&cfg->handle.av.frame); + avcodec_close(cfg->handle.av.context); + avformat_free_context(cfg->handle.av.format); + cfg->handle.av.context = NULL; + break; +#endif + default: + break; + } + return (bt_close(pbe)); +} + +static void +bt_rec_close(struct voss_backend *pbe) +{ + struct bt_config *cfg = pbe->arg; + + switch (cfg->codec) { + case CODEC_SBC: + break; +#ifdef HAVE_LIBAV + case CODEC_AAC: + break; +#endif + + default: + break; + } + return (bt_close(pbe)); +} + +static const uint32_t bt_attrs[] = { + SDP_ATTR_RANGE(SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST, + SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST), +}; + +#define BT_NUM_VALUES 32 +#define BT_BUF_SIZE 32 + +static int +bt_find_psm(const uint8_t *start, const uint8_t *end) +{ + uint32_t type; + uint32_t len; + int protover = 0; + int psm = -1; + + if ((end - start) < 2) + return (-1); + + SDP_GET8(type, start); + switch (type) { + case SDP_DATA_SEQ8: + SDP_GET8(len, start); + break; + + case SDP_DATA_SEQ16: + SDP_GET16(len, start); + break; + + case SDP_DATA_SEQ32: + SDP_GET32(len, start); + break; + + default: + return (-1); + } + + while (start < end) { + SDP_GET8(type, start); + switch (type) { + case SDP_DATA_SEQ8: + SDP_GET8(len, start); + break; + + case SDP_DATA_SEQ16: + SDP_GET16(len, start); + break; + + case SDP_DATA_SEQ32: + SDP_GET32(len, start); + break; + + default: + return (-1); + } + /* check range */ + if (len > (uint32_t)(end - start)) + break; + + if (len >= 6) { + const uint8_t *ptr = start; + + SDP_GET8(type, ptr); + if (type == SDP_DATA_UUID16) { + uint16_t temp; + + SDP_GET16(temp, ptr); + switch (temp) { + case SDP_UUID_PROTOCOL_L2CAP: + SDP_GET8(type, ptr); + SDP_GET16(psm, ptr); + break; + case SDP_UUID_PROTOCOL_AVDTP: + SDP_GET8(type, ptr); + SDP_GET16(protover, ptr); + break; + default: + break; + } + } + } + start += len; + + if (protover >= 0x0100 && psm > -1) + return (htole16(psm)); + } + return (-1); +} + +static int +bt_query(struct l2cap_info *info, uint16_t service_class) +{ + sdp_attr_t values[BT_NUM_VALUES]; + uint8_t buffer[BT_NUM_VALUES][BT_BUF_SIZE]; + void *ss; + int psm = -1; + int n; + + memset(buffer, 0, sizeof(buffer)); + memset(values, 0, sizeof(values)); + + ss = sdp_open(&info->laddr, &info->raddr); + if (ss == NULL || sdp_error(ss) != 0) { + DPRINTF("Could not open SDP\n"); + sdp_close(ss); + return (psm); + } + /* Initialize attribute values array */ + for (n = 0; n != BT_NUM_VALUES; n++) { + values[n].flags = SDP_ATTR_INVALID; + values[n].vlen = BT_BUF_SIZE; + values[n].value = buffer[n]; + } + + /* Do SDP Service Search Attribute Request */ + n = sdp_search(ss, 1, &service_class, 1, bt_attrs, BT_NUM_VALUES, values); + if (n != 0) { + DPRINTF("SDP search failed\n"); + goto done; + } + /* Print attributes values */ + for (n = 0; n != BT_NUM_VALUES; n++) { + if (values[n].flags != SDP_ATTR_OK) + break; + if (values[n].attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST) + continue; + psm = bt_find_psm(values[n].value, values[n].value + values[n].vlen); + if (psm > -1) + break; + } +done: + sdp_close(ss); + return (psm); +} + +static int +bt_open(struct voss_backend *pbe __unused, const char *devname, int samplerate, + int bufsize __unused, int *pchannels, int *pformat, struct bt_config *cfg, + int service_class, int isSink) +{ + struct sockaddr_l2cap addr; + struct l2cap_info info; + socklen_t mtusize = sizeof(uint16_t); + int tmpbitpool; + int l2cap_psm; + int temp; + + memset(&info, 0, sizeof(info)); + + if (strstr(devname, "/dev/bluetooth/") != devname) { + printf("Invalid device name '%s'", devname); + goto error; + } + /* skip prefix */ + devname += sizeof("/dev/bluetooth/") - 1; + + if (!bt_aton(devname, &info.raddr)) { + struct hostent *he = NULL; + + if ((he = bt_gethostbyname(devname)) == NULL) { + DPRINTF("Could not get host by name\n"); + goto error; + } + bdaddr_copy(&info.raddr, (bdaddr_t *)he->h_addr); + } + switch (samplerate) { + case 8000: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0x80; + cfg->aacMode2 = 0x0C; + break; + case 11025: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0x40; + cfg->aacMode2 = 0x0C; + break; + case 12000: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0x20; + cfg->aacMode2 = 0x0C; + break; + case 16000: + cfg->freq = FREQ_16K; + cfg->aacMode1 = 0x10; + cfg->aacMode2 = 0x0C; + break; + case 22050: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0x08; + cfg->aacMode2 = 0x0C; + break; + case 24000: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0x04; + cfg->aacMode2 = 0x0C; + break; + case 32000: + cfg->freq = FREQ_32K; + cfg->aacMode1 = 0x02; + cfg->aacMode2 = 0x0C; + break; + case 44100: + cfg->freq = FREQ_44_1K; + cfg->aacMode1 = 0x01; + cfg->aacMode2 = 0x0C; + break; + case 48000: + cfg->freq = FREQ_48K; + cfg->aacMode1 = 0; + cfg->aacMode2 = 0x8C; + break; + case 64000: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0; + cfg->aacMode2 = 0x4C; + break; + case 88200: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0; + cfg->aacMode2 = 0x2C; + break; + case 96000: + cfg->freq = FREQ_UNDEFINED; + cfg->aacMode1 = 0; + cfg->aacMode2 = 0x1C; + break; + default: + DPRINTF("Invalid samplerate %d", samplerate); + goto error; + } + cfg->bands = BANDS_8; + cfg->bitpool = 0; + + switch (*pchannels) { + case 1: + cfg->aacMode2 &= 0xF8; + cfg->chmode = MODE_MONO; + break; + default: + cfg->aacMode2 &= 0xF4; + cfg->chmode = MODE_STEREO; + break; + } + + cfg->allocm = ALLOC_LOUDNESS; + + if (cfg->chmode == MODE_MONO || cfg->chmode == MODE_DUAL) + tmpbitpool = 16; + else + tmpbitpool = 32; + + if (cfg->bands == BANDS_8) + tmpbitpool *= 8; + else + tmpbitpool *= 4; + + if (tmpbitpool > DEFAULT_MAXBPOOL) + tmpbitpool = DEFAULT_MAXBPOOL; + + cfg->bitpool = tmpbitpool; + + if (bt_set_format(pformat)) { + DPRINTF("Unsupported sample format\n"); + goto error; + } + l2cap_psm = bt_query(&info, service_class); + DPRINTF("PSM=0x%02x\n", l2cap_psm); + if (l2cap_psm < 0) { + DPRINTF("PSM not found\n"); + goto error; + } + cfg->hc = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP); + if (cfg->hc < 0) { + DPRINTF("Could not create BT socket\n"); + goto error; + } + memset(&addr, 0, sizeof(addr)); + addr.l2cap_len = sizeof(addr); + addr.l2cap_family = AF_BLUETOOTH; + bdaddr_copy(&addr.l2cap_bdaddr, &info.laddr); + + if (bind(cfg->hc, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + DPRINTF("Could not bind to HC\n"); + goto error; + } + bdaddr_copy(&addr.l2cap_bdaddr, &info.raddr); + addr.l2cap_psm = l2cap_psm; + if (connect(cfg->hc, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + DPRINTF("Could not connect to HC: %d\n", errno); + goto error; + } + if (avdtpDiscoverAndConfig(cfg, isSink)) { + DPRINTF("DISCOVER FAILED\n"); + goto error; + } + if (avdtpOpen(cfg->hc, cfg->sep)) { + DPRINTF("OPEN FAILED\n"); + goto error; + } + cfg->fd = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BLUETOOTH_PROTO_L2CAP); + if (cfg->fd < 0) { + DPRINTF("Could not create BT socket\n"); + goto error; + } + memset(&addr, 0, sizeof(addr)); + + addr.l2cap_len = sizeof(addr); + addr.l2cap_family = AF_BLUETOOTH; + bdaddr_copy(&addr.l2cap_bdaddr, &info.laddr); + + if (bind(cfg->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + DPRINTF("Could not bind\n"); + goto error; + } + bdaddr_copy(&addr.l2cap_bdaddr, &info.raddr); + addr.l2cap_psm = l2cap_psm; + if (connect(cfg->fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + DPRINTF("Could not connect: %d\n", errno); + goto error; + } + if (isSink) { + if (getsockopt(cfg->fd, SOL_L2CAP, SO_L2CAP_OMTU, &cfg->mtu, &mtusize) == -1) { + DPRINTF("Could not get MTU\n"); + goto error; + } + temp = cfg->mtu * 16; + if (setsockopt(cfg->fd, SOL_SOCKET, SO_SNDBUF, &temp, sizeof(temp)) == -1) { + DPRINTF("Could not set send buffer size\n"); + goto error; + } + temp = cfg->mtu; + if (setsockopt(cfg->fd, SOL_SOCKET, SO_SNDLOWAT, &temp, sizeof(temp)) == -1) { + DPRINTF("Could not set low water mark\n"); + goto error; + } + } else { + if (getsockopt(cfg->fd, SOL_L2CAP, SO_L2CAP_IMTU, &cfg->mtu, &mtusize) == -1) { + DPRINTF("Could not get MTU\n"); + goto error; + } + temp = cfg->mtu * 16; + if (setsockopt(cfg->fd, SOL_SOCKET, SO_RCVBUF, &temp, sizeof(temp)) == -1) { + DPRINTF("Could not set receive buffer size\n"); + goto error; + } + temp = 1; + if (setsockopt(cfg->fd, SOL_SOCKET, SO_RCVLOWAT, &temp, sizeof(temp)) == -1) { + DPRINTF("Could not set low water mark\n"); + goto error; + } + temp = 1; + if (ioctl(cfg->fd, FIONBIO, &temp) == -1) { + DPRINTF("Could not set non-blocking I/O for receive direction\n"); + goto error; + } + } + + if (avdtpStart(cfg->hc, cfg->sep)) { + DPRINTF("START FAILED\n"); + goto error; + } + switch (cfg->chmode) { + case MODE_MONO: + *pchannels = 1; + break; + default: + *pchannels = 2; + break; + } + return (0); + +error: + if (cfg->hc > 0) { + close(cfg->hc); + cfg->hc = -1; + } + if (cfg->fd > 0) { + close(cfg->fd); + cfg->fd = -1; + } + return (-1); +} + +static void +bt_init_cfg(struct bt_config *cfg) +{ + memset(cfg, 0, sizeof(*cfg)); +} + +static int +bt_rec_open(struct voss_backend *pbe, const char *devname, int samplerate, + int bufsize, int *pchannels, int *pformat) +{ + struct bt_config *cfg = pbe->arg; + int retval; + + bt_init_cfg(cfg); + + retval = bt_open(pbe, devname, samplerate, bufsize, pchannels, pformat, + cfg, SDP_SERVICE_CLASS_AUDIO_SOURCE, 0); + if (retval != 0) + return (retval); + return (0); +} + +static int +bt_play_open(struct voss_backend *pbe, const char *devname, int samplerate, + int bufsize, int *pchannels, int *pformat) +{ + struct bt_config *cfg = pbe->arg; + int retval; + + bt_init_cfg(cfg); + + retval = bt_open(pbe, devname, samplerate, bufsize, pchannels, pformat, + cfg, SDP_SERVICE_CLASS_AUDIO_SINK, 1); + if (retval != 0) + return (retval); + + /* setup codec */ + switch (cfg->codec) { + case CODEC_SBC: + cfg->handle.sbc_enc = + malloc(sizeof(*cfg->handle.sbc_enc)); + if (cfg->handle.sbc_enc == NULL) + return (-1); + memset(cfg->handle.sbc_enc, 0, sizeof(*cfg->handle.sbc_enc)); + break; +#ifdef HAVE_LIBAV + case CODEC_AAC: + cfg->handle.av.codec = __DECONST(AVCodec *, + avcodec_find_encoder_by_name("aac")); + if (cfg->handle.av.codec == NULL) { + DPRINTF("Codec AAC encoder not found\n"); + goto av_error_0; + } + cfg->handle.av.format = avformat_alloc_context(); + if (cfg->handle.av.format == NULL) { + DPRINTF("Could not allocate format context\n"); + goto av_error_0; + } + cfg->handle.av.format->oformat = + av_guess_format("latm", NULL, NULL); + if (cfg->handle.av.format->oformat == NULL) { + DPRINTF("Could not guess output format\n"); + goto av_error_1; + } + cfg->handle.av.stream = avformat_new_stream( + cfg->handle.av.format, cfg->handle.av.codec); + + if (cfg->handle.av.stream == NULL) { + DPRINTF("Could not create new stream\n"); + goto av_error_1; + } + cfg->handle.av.context = avcodec_alloc_context3(cfg->handle.av.codec); + if (cfg->handle.av.context == NULL) { + DPRINTF("Could not allocate audio context\n"); + goto av_error_1; + } + /*avcodec_get_context_defaults3(cfg->handle.av.context,*/ + /*cfg->handle.av.codec);*/ + + cfg->handle.av.context->bit_rate = 128000; + cfg->handle.av.context->sample_fmt = AV_SAMPLE_FMT_FLTP; + cfg->handle.av.context->sample_rate = samplerate; + switch (*pchannels) { + case 1: + cfg->handle.av.context->ch_layout = *(AVChannelLayout *)AV_CH_LAYOUT_MONO; + break; + default: + cfg->handle.av.context->ch_layout = *(AVChannelLayout *)AV_CH_LAYOUT_STEREO; + break; + } + + cfg->handle.av.context->profile = FF_PROFILE_AAC_LOW; + if (1) { + AVDictionary *opts = NULL; + + av_dict_set(&opts, "strict", "-2", 0); + av_dict_set_int(&opts, "latm", 1, 0); + + if (avcodec_open2(cfg->handle.av.context, + cfg->handle.av.codec, &opts) < 0) { + av_dict_free(&opts); + + DPRINTF("Could not open codec\n"); + goto av_error_1; + } + av_dict_free(&opts); + } + cfg->handle.av.frame = av_frame_alloc(); + if (cfg->handle.av.frame == NULL) { + DPRINTF("Could not allocate audio frame\n"); + goto av_error_2; + } + cfg->handle.av.frame->nb_samples = cfg->handle.av.context->frame_size; + cfg->handle.av.frame->format = cfg->handle.av.context->sample_fmt; + cfg->handle.av.frame->ch_layout = cfg->handle.av.context->ch_layout; + cfg->rem_in_size = av_samples_get_buffer_size(NULL, + cfg->handle.av.context->ch_layout.nb_channels, + cfg->handle.av.context->frame_size, + cfg->handle.av.context->sample_fmt, 0); + + cfg->rem_in_data = av_malloc(cfg->rem_in_size); + if (cfg->rem_in_data == NULL) { + DPRINTF("Could not allocate %u bytes sample buffer\n", + (unsigned)cfg->rem_in_size); + goto av_error_3; + } + retval = avcodec_fill_audio_frame(cfg->handle.av.frame, + cfg->handle.av.context->ch_layout.nb_channels, + cfg->handle.av.context->sample_fmt, + cfg->rem_in_data, cfg->rem_in_size, 0); + if (retval < 0) { + DPRINTF("Could not setup audio frame\n"); + goto av_error_4; + } + break; +av_error_4: + av_free(cfg->rem_in_data); +av_error_3: + av_frame_free(&cfg->handle.av.frame); +av_error_2: + avcodec_close(cfg->handle.av.context); +av_error_1: + avformat_free_context(cfg->handle.av.format); + cfg->handle.av.context = NULL; +av_error_0: + bt_close(pbe); + return (-1); +#endif + default: + bt_close(pbe); + return (-1); + } + return (0); +} + +static int +bt_rec_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + return (bt_receive(pbe->arg, ptr, len, 1)); +} + +static int +bt_play_sbc_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + struct bt_config *cfg = pbe->arg; + struct sbc_encode *sbc = cfg->handle.sbc_enc; + int rem_size = 1; + int old_len = len; + int err = 0; + + switch (cfg->blocks) { + case BLOCKS_4: + sbc->blocks = 4; + rem_size *= 4; + break; + case BLOCKS_8: + sbc->blocks = 8; + rem_size *= 8; + break; + case BLOCKS_12: + sbc->blocks = 12; + rem_size *= 12; + break; + default: + sbc->blocks = 16; + rem_size *= 16; + break; + } + + switch (cfg->bands) { + case BANDS_4: + rem_size *= 4; + sbc->bands = 4; + break; + default: + rem_size *= 8; + sbc->bands = 8; + break; + } + + /* store number of samples per frame */ + sbc->framesamples = rem_size; + + if (cfg->chmode != MODE_MONO) { + rem_size *= 2; + sbc->channels = 2; + } else { + sbc->channels = 1; + } + + rem_size *= 2; /* 16-bit samples */ + + while (len > 0) { + int delta = len; + + if (delta > (int)(rem_size - sbc->rem_len)) + delta = (int)(rem_size - sbc->rem_len); + + /* copy in samples */ + memcpy((char *)sbc->music_data + sbc->rem_len, ptr, delta); + + ptr = (char *)ptr + delta; + len -= delta; + sbc->rem_len += delta; + + /* check if buffer is full */ + if ((int)sbc->rem_len == rem_size) { + struct sbc_header *phdr = (struct sbc_header *)cfg->mtu_data; + uint32_t pkt_len; + uint32_t rem; + + if (cfg->chmode == MODE_MONO) + sbc->channels = 1; + else + sbc->channels = 2; + + pkt_len = sbc_encode_frame(cfg); + + retry: + if (cfg->mtu_offset == 0) { + phdr->id = 0x80; /* RTP v2 */ + phdr->id2 = 0x60; /* payload type 96. */ + phdr->seqnumMSB = (uint8_t)(cfg->mtu_seqnumber >> 8); + phdr->seqnumLSB = (uint8_t)(cfg->mtu_seqnumber); + phdr->ts3 = (uint8_t)(cfg->mtu_timestamp >> 24); + phdr->ts2 = (uint8_t)(cfg->mtu_timestamp >> 16); + phdr->ts1 = (uint8_t)(cfg->mtu_timestamp >> 8); + phdr->ts0 = (uint8_t)(cfg->mtu_timestamp); + phdr->reserved0 = 0x01; + phdr->numFrames = 0; + + cfg->mtu_seqnumber++; + cfg->mtu_offset += sizeof(*phdr); + } + /* compute bytes left */ + rem = cfg->mtu - cfg->mtu_offset; + + if (phdr->numFrames == 255 || rem < pkt_len) { + int xlen; + + if (phdr->numFrames == 0) + return (-1); + do { + xlen = write(cfg->fd, cfg->mtu_data, cfg->mtu_offset); + } while (xlen < 0 && errno == EAGAIN); + + if (xlen < 0) + return (-1); + + cfg->mtu_offset = 0; + goto retry; + } + memcpy(cfg->mtu_data + cfg->mtu_offset, sbc->data, pkt_len); + memset(sbc->data, 0, pkt_len); + cfg->mtu_offset += pkt_len; + cfg->mtu_timestamp += sbc->framesamples; + phdr->numFrames++; + + sbc->rem_len = 0; + } + } + if (err == 0) + return (old_len); + return (err); +} + +#ifdef HAVE_LIBAV +static int +bt_play_aac_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + struct bt_config *cfg = pbe->arg; + struct aac_header { + uint8_t id; + uint8_t id2; + uint8_t seqnumMSB; + uint8_t seqnumLSB; + uint8_t ts3; + uint8_t ts2; + uint8_t ts1; + uint8_t ts0; + uint8_t sync3; + uint8_t sync2; + uint8_t sync1; + uint8_t sync0; + uint8_t fixed[8]; + }; + int old_len = len; + int err = 0; + + while (len > 0) { + int delta = len; + int rem; + + if (delta > (int)(cfg->rem_in_size - cfg->rem_in_len)) + delta = (int)(cfg->rem_in_size - cfg->rem_in_len); + + memcpy(cfg->rem_in_data + cfg->rem_in_len, ptr, delta); + + ptr = (char *)ptr + delta; + len -= delta; + cfg->rem_in_len += delta; + + /* check if buffer is full */ + if (cfg->rem_in_len == cfg->rem_in_size) { + struct aac_header *phdr = (struct aac_header *)cfg->mtu_data; + AVPacket *pkt; + uint8_t *pkt_buf; + int pkt_len; + + pkt = av_packet_alloc(); + err = avcodec_send_frame(cfg->handle.av.context, + cfg->handle.av.frame); + if (err < 0) { + DPRINTF("Error encoding audio frame\n"); + return (-1); + } + phdr->id = 0x80;/* RTP v2 */ + phdr->id2 = 0x60; /* payload type 96. */ + phdr->seqnumMSB = (uint8_t)(cfg->mtu_seqnumber >> 8); + phdr->seqnumLSB = (uint8_t)(cfg->mtu_seqnumber); + phdr->ts3 = (uint8_t)(cfg->mtu_timestamp >> 24); + phdr->ts2 = (uint8_t)(cfg->mtu_timestamp >> 16); + phdr->ts1 = (uint8_t)(cfg->mtu_timestamp >> 8); + phdr->ts0 = (uint8_t)(cfg->mtu_timestamp); + phdr->sync3 = 0; + phdr->sync2 = 0; + phdr->sync1 = 0; + phdr->sync0 = 0; + phdr->fixed[0] = 0xfc; + phdr->fixed[1] = 0x00; + phdr->fixed[2] = 0x00; + phdr->fixed[3] = 0xb0; + phdr->fixed[4] = 0x90; + phdr->fixed[5] = 0x80; + phdr->fixed[6] = 0x03; + phdr->fixed[7] = 0x00; + + cfg->mtu_seqnumber++; + cfg->mtu_offset = sizeof(*phdr); + + /* compute bytes left */ + rem = cfg->mtu - cfg->mtu_offset; + + if (avio_open_dyn_buf(&cfg->handle.av.format->pb) == 0) { + static int once = 0; + + if (!once++) + (void)avformat_write_header(cfg->handle.av.format, NULL); + av_write_frame(cfg->handle.av.format, pkt); + av_packet_unref(pkt); + pkt_len = avio_close_dyn_buf(cfg->handle.av.format->pb, &pkt_buf); + if (rem < pkt_len) + DPRINTF("Out of buffer space\n"); + if (pkt_len >= 3 && rem >= pkt_len) { + int xlen; + + memcpy(cfg->mtu_data + cfg->mtu_offset, pkt_buf + 3, pkt_len - 3); + + av_free(pkt_buf); + + cfg->mtu_offset += pkt_len - 3; + if (cfg->chmode != MODE_MONO) + cfg->mtu_timestamp += cfg->rem_in_size / 4; + else + cfg->mtu_timestamp += cfg->rem_in_size / 2; + do { + xlen = write(cfg->fd, cfg->mtu_data, cfg->mtu_offset); + } while (xlen < 0 && errno == EAGAIN); + + if (xlen < 0) + return (-1); + } else { + av_free(pkt_buf); + } + } else { + av_packet_unref(pkt); + } + /* reset remaining length */ + cfg->rem_in_len = 0; + } + } + if (err == 0) + return (old_len); + return (err); +} + +#endif + +static int +bt_play_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + struct bt_config *cfg = pbe->arg; + + switch (cfg->codec) { + case CODEC_SBC: + return (bt_play_sbc_transfer(pbe, ptr, len)); +#ifdef HAVE_LIBAV + case CODEC_AAC: + return (bt_play_aac_transfer(pbe, ptr, len)); +#endif + default: + return (-1); + } +} + +static void +bt_rec_delay(struct voss_backend *pbe __unused, int *pdelay) +{ + *pdelay = -1; +} + +static void +bt_play_delay(struct voss_backend *pbe __unused, int *pdelay) +{ + /* TODO */ + *pdelay = -1; +} + +struct voss_backend voss_backend_bt_rec = { + .open = bt_rec_open, + .close = bt_rec_close, + .transfer = bt_rec_transfer, + .delay = bt_rec_delay, + .arg = &bt_rec_cfg, +}; + +struct voss_backend voss_backend_bt_play = { + .open = bt_play_open, + .close = bt_play_close, + .transfer = bt_play_transfer, + .delay = bt_play_delay, + .arg = &bt_play_cfg, +}; diff --git a/lib/virtual_oss/bt/bt.h b/lib/virtual_oss/bt/bt.h new file mode 100644 index 000000000000..2abdb9eb021a --- /dev/null +++ b/lib/virtual_oss/bt/bt.h @@ -0,0 +1,116 @@ +/*- + * Copyright (c) 2015 Hans Petter Selasky + * + * 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. + */ + +#ifndef _BACKEND_BT_H_ +#define _BACKEND_BT_H_ + +#ifdef HAVE_LIBAV +#include <libavformat/avformat.h> +#include <libavcodec/avcodec.h> +#include <libavutil/opt.h> +#endif + +#include "sbc_encode.h" + +struct bt_config { + uint8_t sep; /* SEID of the peer */ + uint8_t media_Type; + uint8_t chmode; +#define MODE_STEREO 2 +#define MODE_JOINT 3 +#define MODE_DUAL 1 +#define MODE_MONO 0 + uint8_t allocm; +#define ALLOC_LOUDNESS 0 +#define ALLOC_SNR 1 + uint8_t bitpool; + uint8_t bands; +#define BANDS_4 0 +#define BANDS_8 1 + uint8_t blocks; +#define BLOCKS_4 0 +#define BLOCKS_8 1 +#define BLOCKS_12 2 +#define BLOCKS_16 3 + uint8_t freq; +#define FREQ_UNDEFINED 255 +#define FREQ_16K 0 +#define FREQ_32K 1 +#define FREQ_44_1K 2 +#define FREQ_48K 3 + uint16_t mtu; + uint8_t codec; +#define CODEC_SBC 0x00 +#define CODEC_AAC 0x02 + uint8_t aacMode1; + uint8_t aacMode2; + + /* transcoding handle(s) */ + union { +#ifdef HAVE_LIBAV + struct { + AVCodec *codec; + AVCodecContext *context; + AVFormatContext *format; + AVFrame *frame; + AVStream *stream; + } av; +#endif + struct sbc_encode *sbc_enc; + } handle; + + /* audio input buffer */ + uint32_t rem_in_len; + uint32_t rem_in_size; + uint8_t *rem_in_data; + + /* data transport */ + uint32_t mtu_seqnumber; + uint32_t mtu_timestamp; + uint32_t mtu_offset; + + /* bluetooth file handles */ + int fd; + int hc; + + /* scratch buffer */ + uint8_t mtu_data[65536]; + + /* acceptor state */ + int8_t acceptor_state; +#define acpInitial 1 +#define acpConfigurationSet 2 +#define acpStreamOpened 3 +#define acpStreamStarted 4 +#define acpStreamSuspended 5 +#define acpStreamClosed 6 +}; + +size_t sbc_encode_frame(struct bt_config *); +size_t sbc_decode_frame(struct bt_config *, int); + +int bt_receive(struct bt_config *cfg, void *ptr, int len, int use_delay); + +#endif /* _BACKEND_BT_H_ */ diff --git a/lib/virtual_oss/bt/cosdata-gen/Makefile b/lib/virtual_oss/bt/cosdata-gen/Makefile new file mode 100644 index 000000000000..d08e263f32b5 --- /dev/null +++ b/lib/virtual_oss/bt/cosdata-gen/Makefile @@ -0,0 +1,12 @@ +# $NetBSD$ + +WARNS?= 3 + +PROG= cosdata +SRCS= cosdata.c +MAN= + +DPADD+= ${LIBMATH} +LDADD+= -lm + +.include <bsd.prog.mk> diff --git a/lib/virtual_oss/bt/cosdata-gen/cosdata.c b/lib/virtual_oss/bt/cosdata-gen/cosdata.c new file mode 100644 index 000000000000..b8409cbd0216 --- /dev/null +++ b/lib/virtual_oss/bt/cosdata-gen/cosdata.c @@ -0,0 +1,177 @@ +/*- + * Copyright (c) 2015 - 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> + * All rights reserved. + * + * This software is dedicated to the memory of - + * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012. + * + * Barry was a man who loved his music. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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 <math.h> +#include <stdio.h> +#include <stdint.h> + +static const double sbc8_coeffs[] = { + 0.00000000e+00, 1.56575398e-04, 3.43256425e-04, 5.54620202e-04, + 8.23919506e-04, 1.13992507e-03, 1.47640169e-03, 1.78371725e-03, + 2.01182542e-03, 2.10371989e-03, 1.99454554e-03, 1.61656283e-03, + 9.02154502e-04, -1.78805361e-04, -1.64973098e-03, -3.49717454e-03, + 5.65949473e-03, 8.02941163e-03, 1.04584443e-02, 1.27472335e-02, + 1.46525263e-02, 1.59045603e-02, 1.62208471e-02, 1.53184106e-02, + 1.29371806e-02, 8.85757540e-03, 2.92408442e-03, -4.91578024e-03, + -1.46404076e-02, -2.61098752e-02, -3.90751381e-02, -5.31873032e-02, + 6.79989431e-02, 8.29847578e-02, 9.75753918e-02, 1.11196689e-01, + 1.23264548e-01, 1.33264415e-01, 1.40753505e-01, 1.45389847e-01, + 1.46955068e-01, 1.45389847e-01, 1.40753505e-01, 1.33264415e-01, + 1.23264548e-01, 1.11196689e-01, 9.75753918e-02, 8.29847578e-02, + -6.79989431e-02, -5.31873032e-02, -3.90751381e-02, -2.61098752e-02, + -1.46404076e-02, -4.91578024e-03, 2.92408442e-03, 8.85757540e-03, + 1.29371806e-02, 1.53184106e-02, 1.62208471e-02, 1.59045603e-02, + 1.46525263e-02, 1.27472335e-02, 1.04584443e-02, 8.02941163e-03, + -5.65949473e-03, -3.49717454e-03, -1.64973098e-03, -1.78805361e-04, + 9.02154502e-04, 1.61656283e-03, 1.99454554e-03, 2.10371989e-03, + 2.01182542e-03, 1.78371725e-03, 1.47640169e-03, 1.13992507e-03, + 8.23919506e-04, 5.54620202e-04, 3.43256425e-04, 1.56575398e-04, +}; + +static const double sbc4_coeffs[] = { + 0.00000000e+00, 5.36548976e-04, 1.49188357e-03, 2.73370904e-03, + 3.83720193e-03, 3.89205149e-03, 1.86581691e-03, -3.06012286e-03, + 1.09137620e-02, 2.04385087e-02, 2.88757392e-02, 3.21939290e-02, + 2.58767811e-02, 6.13245186e-03, -2.88217274e-02, -7.76463494e-02, + 1.35593274e-01, 1.94987841e-01, 2.46636662e-01, 2.81828203e-01, + 2.94315332e-01, 2.81828203e-01, 2.46636662e-01, 1.94987841e-01, + -1.35593274e-01, -7.76463494e-02, -2.88217274e-02, 6.13245186e-03, + 2.58767811e-02, 3.21939290e-02, 2.88757392e-02, 2.04385087e-02, + -1.09137620e-02, -3.06012286e-03, 1.86581691e-03, 3.89205149e-03, + 3.83720193e-03, 2.73370904e-03, 1.49188357e-03, 5.36548976e-04, +}; + +#define AC(x) (int)(sizeof(x) / sizeof((x)[0])) + +int +main(int argc, char **argv) +{ + float S[8][16]; + int i; + int k; + int count = 0; + + printf("/* sbc_coeffs.h - Automatically generated by cosdata.c. */\n" + "\n"); + + printf("static const float sbc_coeffs8[] = {\n "); + for (k = 0; k < AC(sbc8_coeffs); k++) { + if ((count % 8) == 0 && count != 0) + printf("\n "); + printf("%0.12ff, ", (float)sbc8_coeffs[k]); + count++; + } + printf("\n};\n"); + + count = 0; + printf("static const float sbc_coeffs4[] = {\n "); + for (k = 0; k < AC(sbc4_coeffs); k++) { + if ((count % 8) == 0 && count != 0) + printf("\n "); + printf("%0.12ff, ", (float)sbc4_coeffs[k]); + count++; + } + printf("\n};\n"); + + count = 0; + printf("static const float cosdata8[8][16] = {\n "); + for (i = 0; i < 8; i++) { + for (k = 0; k < 16; k++) { + S[i][k] = cosf((float)((i + 0.5) * (k - 4) * (M_PI / 8.0))); + + if ((count % 8) == 0 && count != 0) + printf("\n "); + if (k == 0) + printf("{ "); + printf("%0.12ff, ", S[i][k]); + if (k == 15) + printf("},"); + count++; + } + } + printf("\n};\n"); + + count = 0; + printf("static const float cosdata4[4][8] = {\n "); + for (i = 0; i < 4; i++) { + for (k = 0; k < 8; k++) { + S[i][k] = cosf((float)((i + 0.5) * (k - 2) * (M_PI / 4.0))); + + if ((count % 8) == 0 && count != 0) + printf("\n "); + if (k == 0) + printf("{ "); + printf("%0.12ff, ", S[i][k]); + if (k == 7) + printf("},"); + count++; + } + } + printf("\n};\n"); + + count = 0; + printf("static const float cosdecdata8[8][16] = {\n "); + for (i = 0; i < 8; i++) { + for (k = 0; k < 16; k++) { + S[i][k] = cosf((float)((i + 0.5) * (k + 4) * (M_PI / 8.0))); + + if ((count % 8) == 0 && count != 0) + printf("\n "); + if (k == 0) + printf("{ "); + printf("%0.12ff, ", S[i][k]); + if (k == 15) + printf("},"); + count++; + } + } + printf("\n};\n"); + + count = 0; + printf("static const float cosdecdata4[4][8] = {\n "); + for (i = 0; i < 4; i++) { + for (k = 0; k < 8; k++) { + S[i][k] = cosf((float)((i + 0.5) * (k + 2) * (M_PI / 4.0))); + + if ((count % 8) == 0 && count != 0) + printf("\n "); + if (k == 0) + printf("{ "); + printf("%0.12ff, ", S[i][k]); + if (k == 7) + printf("},"); + count++; + } + } + printf("\n};\n"); + + return (0); +} diff --git a/lib/virtual_oss/bt/sbc_coeffs.h b/lib/virtual_oss/bt/sbc_coeffs.h new file mode 100644 index 000000000000..b9428033d50b --- /dev/null +++ b/lib/virtual_oss/bt/sbc_coeffs.h @@ -0,0 +1,69 @@ +/* sbc_coeffs.h - Automatically generated by cosdata.c. */ + +static const float sbc_coeffs8[] = { + 0.000000000000f, 0.000156575392f, 0.000343256426f, 0.000554620230f, 0.000823919487f, 0.001139925094f, 0.001476401696f, 0.001783717307f, + 0.002011825331f, 0.002103719860f, 0.001994545572f, 0.001616562833f, 0.000902154483f, -0.000178805363f, -0.001649730955f, -0.003497174475f, + 0.005659494549f, 0.008029411547f, 0.010458444245f, 0.012747233734f, 0.014652526006f, 0.015904560685f, 0.016220847145f, 0.015318410471f, + 0.012937180698f, 0.008857575245f, 0.002924084431f, -0.004915780388f, -0.014640407637f, -0.026109876111f, -0.039075139910f, -0.053187303245f, + 0.067998945713f, 0.082984760404f, 0.097575388849f, 0.111196689308f, 0.123264551163f, 0.133264422417f, 0.140753507614f, 0.145389840007f, + 0.146955072880f, 0.145389840007f, 0.140753507614f, 0.133264422417f, 0.123264551163f, 0.111196689308f, 0.097575388849f, 0.082984760404f, + -0.067998945713f, -0.053187303245f, -0.039075139910f, -0.026109876111f, -0.014640407637f, -0.004915780388f, 0.002924084431f, 0.008857575245f, + 0.012937180698f, 0.015318410471f, 0.016220847145f, 0.015904560685f, 0.014652526006f, 0.012747233734f, 0.010458444245f, 0.008029411547f, + -0.005659494549f, -0.003497174475f, -0.001649730955f, -0.000178805363f, 0.000902154483f, 0.001616562833f, 0.001994545572f, 0.002103719860f, + 0.002011825331f, 0.001783717307f, 0.001476401696f, 0.001139925094f, 0.000823919487f, 0.000554620230f, 0.000343256426f, 0.000156575392f, +}; +static const float sbc_coeffs4[] = { + 0.000000000000f, 0.000536548963f, 0.001491883537f, 0.002733709058f, 0.003837201977f, 0.003892051522f, 0.001865816885f, -0.003060122952f, + 0.010913762264f, 0.020438509062f, 0.028875738382f, 0.032193928957f, 0.025876780972f, 0.006132451817f, -0.028821727261f, -0.077646352351f, + 0.135593280196f, 0.194987848401f, 0.246636658907f, 0.281828194857f, 0.294315338135f, 0.281828194857f, 0.246636658907f, 0.194987848401f, + -0.135593280196f, -0.077646352351f, -0.028821727261f, 0.006132451817f, 0.025876780972f, 0.032193928957f, 0.028875738382f, 0.020438509062f, + -0.010913762264f, -0.003060122952f, 0.001865816885f, 0.003892051522f, 0.003837201977f, 0.002733709058f, 0.001491883537f, 0.000536548963f, +}; +static const float cosdata8[8][16] = { + { 0.707106769085f, 0.831469595432f, 0.923879504204f, 0.980785250664f, 1.000000000000f, 0.980785250664f, 0.923879504204f, 0.831469595432f, + 0.707106769085f, 0.555570244789f, 0.382683426142f, 0.195090353489f, -0.000000043711f, -0.195090323687f, -0.382683396339f, -0.555570185184f, }, + { -0.707106769085f, -0.195090323687f, 0.382683426142f, 0.831469595432f, 1.000000000000f, 0.831469595432f, 0.382683426142f, -0.195090323687f, + -0.707106769085f, -0.980785310268f, -0.923879504204f, -0.555570423603f, 0.000000011925f, 0.555570065975f, 0.923879563808f, 0.980785310268f, }, + { -0.707106828690f, -0.980785310268f, -0.382683396339f, 0.555570244789f, 1.000000000000f, 0.555570244789f, -0.382683396339f, -0.980785310268f, + -0.707106828690f, 0.195090413094f, 0.923879563808f, 0.831469655037f, 0.000000139071f, -0.831469774246f, -0.923879444599f, -0.195090219378f, }, + { 0.707106649876f, -0.555570423603f, -0.923879504204f, 0.195090353489f, 1.000000000000f, 0.195090353489f, -0.923879504204f, -0.555570423603f, + 0.707106649876f, 0.831469655037f, -0.382683008909f, -0.980785369873f, -0.000000290067f, 0.980785250664f, 0.382683545351f, -0.831469595432f, }, + { 0.707106769085f, 0.555570065975f, -0.923879504204f, -0.195090323687f, 1.000000000000f, -0.195090323687f, -0.923879504204f, 0.555570065975f, + 0.707106769085f, -0.831469774246f, -0.382683843374f, 0.980785250664f, -0.000000035775f, -0.980785250664f, 0.382683902979f, 0.831469714642f, }, + { -0.707106590271f, 0.980785310268f, -0.382683575153f, -0.555570185184f, 1.000000000000f, -0.555570185184f, -0.382683575153f, 0.980785310268f, + -0.707106590271f, -0.195090219378f, 0.923879683018f, -0.831469595432f, -0.000000592058f, 0.831469714642f, -0.923879623413f, 0.195090919733f, }, + { -0.707106530666f, 0.195090532303f, 0.382683604956f, -0.831469655037f, 1.000000000000f, -0.831469655037f, 0.382683604956f, 0.195090532303f, + -0.707106530666f, 0.980785310268f, -0.923879384995f, 0.555569529533f, -0.000000687457f, -0.555570006371f, 0.923879563808f, -0.980785191059f, }, + { 0.707106828690f, -0.831469774246f, 0.923879563808f, -0.980785310268f, 1.000000000000f, -0.980785310268f, 0.923879563808f, -0.831469774246f, + 0.707106828690f, -0.555570065975f, 0.382683902979f, -0.195089668036f, 0.000000059624f, 0.195089548826f, -0.382683813572f, 0.555569946766f, }, +}; +static const float cosdata4[4][8] = { + { 0.707106769085f, 0.923879504204f, 1.000000000000f, 0.923879504204f, 0.707106769085f, 0.382683426142f, -0.000000043711f, -0.382683396339f, }, + { -0.707106769085f, 0.382683426142f, 1.000000000000f, 0.382683426142f, -0.707106769085f, -0.923879504204f, 0.000000011925f, 0.923879563808f, }, + { -0.707106828690f, -0.382683396339f, 1.000000000000f, -0.382683396339f, -0.707106828690f, 0.923879563808f, 0.000000139071f, -0.923879444599f, }, + { 0.707106649876f, -0.923879504204f, 1.000000000000f, -0.923879504204f, 0.707106649876f, -0.382683008909f, -0.000000290067f, 0.382683545351f, }, +}; +static const float cosdecdata8[8][16] = { + { 0.707106769085f, 0.555570244789f, 0.382683426142f, 0.195090353489f, -0.000000043711f, -0.195090323687f, -0.382683396339f, -0.555570185184f, + -0.707106769085f, -0.831469655037f, -0.923879504204f, -0.980785310268f, -1.000000000000f, -0.980785310268f, -0.923879504204f, -0.831469535828f, }, + { -0.707106769085f, -0.980785310268f, -0.923879504204f, -0.555570423603f, 0.000000011925f, 0.555570065975f, 0.923879563808f, 0.980785310268f, + 0.707106769085f, 0.195090532303f, -0.382683008909f, -0.831469774246f, -1.000000000000f, -0.831469714642f, -0.382683843374f, 0.195090577006f, }, + { -0.707106828690f, 0.195090413094f, 0.923879563808f, 0.831469655037f, 0.000000139071f, -0.831469774246f, -0.923879444599f, -0.195090219378f, + 0.707106828690f, 0.980785310268f, 0.382683545351f, -0.555570065975f, -1.000000000000f, -0.555570542812f, 0.382683902979f, 0.980785191059f, }, + { 0.707106649876f, 0.831469655037f, -0.382683008909f, -0.980785369873f, -0.000000290067f, 0.980785250664f, 0.382683545351f, -0.831469595432f, + -0.707107424736f, 0.555569529533f, 0.923879802227f, -0.195089668036f, -1.000000000000f, -0.195090815425f, 0.923879384995f, 0.555570483208f, }, + { 0.707106769085f, -0.831469774246f, -0.382683843374f, 0.980785250664f, -0.000000035775f, -0.980785250664f, 0.382683902979f, 0.831469714642f, + -0.707106173038f, -0.555570006371f, 0.923879384995f, 0.195089548826f, -1.000000000000f, 0.195089697838f, 0.923879325390f, -0.555570125580f, }, + { -0.707106590271f, -0.195090219378f, 0.923879683018f, -0.831469595432f, -0.000000592058f, 0.831469714642f, -0.923879623413f, 0.195090919733f, + 0.707107424736f, -0.980785191059f, 0.382683366537f, 0.555569946766f, -1.000000000000f, 0.555571198463f, 0.382683783770f, -0.980785667896f, }, + { -0.707106530666f, 0.980785310268f, -0.923879384995f, 0.555569529533f, -0.000000687457f, -0.555570006371f, 0.923879563808f, -0.980785191059f, + 0.707106173038f, -0.195089071989f, -0.382684975863f, 0.831468641758f, -1.000000000000f, 0.831470131874f, -0.382683992386f, -0.195090129972f, }, + { 0.707106828690f, -0.555570065975f, 0.382683902979f, -0.195089668036f, 0.000000059624f, 0.195089548826f, -0.382683813572f, 0.555569946766f, + -0.707106053829f, 0.831468641758f, -0.923880040646f, 0.980785369873f, -1.000000000000f, 0.980785429478f, -0.923880159855f, 0.831468760967f, }, +}; +static const float cosdecdata4[4][8] = { + { 0.707106769085f, 0.382683426142f, -0.000000043711f, -0.382683396339f, -0.707106769085f, -0.923879504204f, -1.000000000000f, -0.923879504204f, }, + { -0.707106769085f, -0.923879504204f, 0.000000011925f, 0.923879563808f, 0.707106769085f, -0.382683008909f, -1.000000000000f, -0.382683843374f, }, + { -0.707106828690f, 0.923879563808f, 0.000000139071f, -0.923879444599f, 0.707106828690f, 0.382683545351f, -1.000000000000f, 0.382683902979f, }, + { 0.707106649876f, -0.382683008909f, -0.000000290067f, 0.382683545351f, -0.707107424736f, 0.923879802227f, -1.000000000000f, 0.923879384995f, }, +}; diff --git a/lib/virtual_oss/bt/sbc_encode.c b/lib/virtual_oss/bt/sbc_encode.c new file mode 100644 index 000000000000..153f2e69e76e --- /dev/null +++ b/lib/virtual_oss/bt/sbc_encode.c @@ -0,0 +1,701 @@ +/*- + * Copyright (c) 2015 Nathanial Sloss <nathanialsloss@yahoo.com.au> + * + * This software is dedicated to the memory of - + * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012. + * + * Barry was a man who loved his music. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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> +#include <sys/types.h> +#include <sys/param.h> +#include <sys/endian.h> +#include <sys/uio.h> + +#include <stdio.h> +#include <errno.h> +#include <stdbool.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <math.h> + +#include "sbc_coeffs.h" +#include "bt.h" + +#define SYNCWORD 0x9c +#define ABS(x) (((x) < 0) ? -(x) : (x)) +#define BIT30 (1U << 30) +#define BM(x) ((1LL << (x)) - 1LL) + +/* Loudness offset allocations. */ +static const int loudnessoffset8[4][8] = { + {-2, 0, 0, 0, 0, 0, 0, 1}, + {-3, 0, 0, 0, 0, 0, 1, 2}, + {-4, 0, 0, 0, 0, 0, 1, 2}, + {-4, 0, 0, 0, 0, 0, 1, 2}, +}; + +static const int loudnessoffset4[4][4] = { + {-1, 0, 0, 0}, + {-2, 0, 0, 1}, + {-2, 0, 0, 1}, + {-2, 0, 0, 1}, +}; + +static uint8_t +calc_scalefactors_joint(struct sbc_encode *sbc) +{ + float sb_j[16][2]; + uint32_t x; + uint32_t y; + uint8_t block; + uint8_t joint; + uint8_t sb; + uint8_t lz; + + joint = 0; + for (sb = 0; sb != sbc->bands - 1; sb++) { + for (block = 0; block < sbc->blocks; block++) { + sb_j[block][0] = (sbc->samples[block][0][sb] + + sbc->samples[block][1][sb]) / 2.0f; + sb_j[block][1] = (sbc->samples[block][0][sb] - + sbc->samples[block][1][sb]) / 2.0f; + } + + x = 1 << 15; + y = 1 << 15; + for (block = 0; block < sbc->blocks; block++) { + x |= (uint32_t)ABS(sb_j[block][0]); + y |= (uint32_t)ABS(sb_j[block][1]); + } + + lz = 1; + while (!(x & BIT30)) { + lz++; + x <<= 1; + } + x = 16 - lz; + + lz = 1; + while (!(y & BIT30)) { + lz++; + y <<= 1; + } + y = 16 - lz; + + if ((sbc->scalefactor[0][sb] + sbc->scalefactor[1][sb]) > x + y) { + joint |= 1 << (sbc->bands - sb - 1); + sbc->scalefactor[0][sb] = x; + sbc->scalefactor[1][sb] = y; + for (block = 0; block < sbc->blocks; block++) { + sbc->samples[block][0][sb] = sb_j[block][0]; + sbc->samples[block][1][sb] = sb_j[block][1]; + } + } + } + return (joint); +} + +static void +calc_scalefactors(struct sbc_encode *sbc) +{ + uint8_t block; + uint8_t ch; + uint8_t sb; + + for (ch = 0; ch != sbc->channels; ch++) { + for (sb = 0; sb != sbc->bands; sb++) { + uint32_t x = 1 << 15; + uint8_t lx = 1; + + for (block = 0; block != sbc->blocks; block++) + x |= (uint32_t)ABS(sbc->samples[block][ch][sb]); + + while (!(x & BIT30)) { + lx++; + x <<= 1; + } + sbc->scalefactor[ch][sb] = 16 - lx; + } + } +} + +static void +calc_bitneed(struct bt_config *cfg) +{ + struct sbc_encode *sbc = cfg->handle.sbc_enc; + int32_t bitneed[2][8]; + int32_t max_bitneed, bitcount; + int32_t slicecount, bitslice; + int32_t loudness; + int ch, sb, start_chan = 0; + + if (cfg->chmode == MODE_DUAL) + sbc->channels = 1; + +next_chan: + max_bitneed = 0; + bitcount = 0; + slicecount = 0; + + if (cfg->allocm == ALLOC_SNR) { + for (ch = start_chan; ch < sbc->channels; ch++) { + for (sb = 0; sb < sbc->bands; sb++) { + bitneed[ch][sb] = sbc->scalefactor[ch][sb]; + + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } + } + } else { + for (ch = start_chan; ch < sbc->channels; ch++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->scalefactor[ch][sb] == 0) { + bitneed[ch][sb] = -5; + } else { + if (sbc->bands == 8) { + loudness = sbc->scalefactor[ch][sb] - + loudnessoffset8[cfg->freq][sb]; + } else { + loudness = sbc->scalefactor[ch][sb] - + loudnessoffset4[cfg->freq][sb]; + } + if (loudness > 0) + bitneed[ch][sb] = loudness / 2; + else + bitneed[ch][sb] = loudness; + } + if (bitneed[ch][sb] > max_bitneed) + max_bitneed = bitneed[ch][sb]; + } + } + } + + slicecount = bitcount = 0; + bitslice = max_bitneed + 1; + do { + bitslice--; + bitcount += slicecount; + slicecount = 0; + for (ch = start_chan; ch < sbc->channels; ch++) { + for (sb = 0; sb < sbc->bands; sb++) { + if ((bitneed[ch][sb] > bitslice + 1) && + (bitneed[ch][sb] < bitslice + 16)) + slicecount++; + else if (bitneed[ch][sb] == bitslice + 1) + slicecount += 2; + } + } + } while (bitcount + slicecount < cfg->bitpool); + + /* check if exactly one more fits */ + if (bitcount + slicecount == cfg->bitpool) { + bitcount += slicecount; + bitslice--; + } + for (ch = start_chan; ch < sbc->channels; ch++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (bitneed[ch][sb] < bitslice + 2) { + sbc->bits[ch][sb] = 0; + } else { + sbc->bits[ch][sb] = bitneed[ch][sb] - bitslice; + if (sbc->bits[ch][sb] > 16) + sbc->bits[ch][sb] = 16; + } + } + } + + if (cfg->chmode == MODE_DUAL) + ch = start_chan; + else + ch = 0; + sb = 0; + while (bitcount < cfg->bitpool && sb < sbc->bands) { + if ((sbc->bits[ch][sb] >= 2) && (sbc->bits[ch][sb] < 16)) { + sbc->bits[ch][sb]++; + bitcount++; + } else if ((bitneed[ch][sb] == bitslice + 1) && + (cfg->bitpool > bitcount + 1)) { + sbc->bits[ch][sb] = 2; + bitcount += 2; + } + if (sbc->channels == 1 || start_chan == 1) + sb++; + else if (ch == 1) { + ch = 0; + sb++; + } else + ch = 1; + } + + if (cfg->chmode == MODE_DUAL) + ch = start_chan; + else + ch = 0; + sb = 0; + while (bitcount < cfg->bitpool && sb < sbc->bands) { + if (sbc->bits[ch][sb] < 16) { + sbc->bits[ch][sb]++; + bitcount++; + } + if (sbc->channels == 1 || start_chan == 1) + sb++; + else if (ch == 1) { + ch = 0; + sb++; + } else + ch = 1; + } + + if (cfg->chmode == MODE_DUAL && start_chan == 0) { + start_chan = 1; + sbc->channels = 2; + goto next_chan; + } +} + +static void +sbc_store_bits_crc(struct sbc_encode *sbc, uint32_t numbits, uint32_t value) +{ + uint32_t off = sbc->bitoffset; + + while (numbits-- && off != sbc->maxoffset) { + if (value & (1 << numbits)) { + sbc->data[off / 8] |= 1 << ((7 - off) & 7); + sbc->crc ^= 0x80; + } + sbc->crc *= 2; + if (sbc->crc & 0x100) + sbc->crc ^= 0x11d; /* CRC-8 polynomial */ + + off++; + } + sbc->bitoffset = off; +} + +static int +sbc_encode(struct bt_config *cfg) +{ + struct sbc_encode *sbc = cfg->handle.sbc_enc; + const int16_t *input = sbc->music_data; + float delta[2][8]; + float levels[2][8]; + float mask[2][8]; + float S; + float *X; + float Z[80]; + float Y[80]; + float audioout; + int16_t left[8]; + int16_t right[8]; + int16_t *data; + int numsamples; + int i; + int k; + int block; + int chan; + int sb; + + for (block = 0; block < sbc->blocks; block++) { + + for (i = 0; i < sbc->bands; i++) { + left[i] = *input++; + if (sbc->channels == 2) + right[i] = *input++; + } + + for (chan = 0; chan < sbc->channels; chan++) { + + /* select right or left channel */ + if (chan == 0) { + X = sbc->left; + data = left; + } else { + X = sbc->right; + data = right; + } + + /* shift up old data */ + for (i = (sbc->bands * 10) - 1; i > sbc->bands - 1; i--) + X[i] = X[i - sbc->bands]; + k = 0; + for (i = sbc->bands - 1; i >= 0; i--) + X[i] = data[k++]; + for (i = 0; i < sbc->bands * 10; i++) { + if (sbc->bands == 8) + Z[i] = sbc_coeffs8[i] * X[i]; + else + Z[i] = sbc_coeffs4[i] * X[i]; + } + for (i = 0; i < sbc->bands * 2; i++) { + Y[i] = 0; + for (k = 0; k < 5; k++) + Y[i] += Z[i + k * sbc->bands * 2]; + } + for (i = 0; i < sbc->bands; i++) { + S = 0; + for (k = 0; k < sbc->bands * 2; k++) { + if (sbc->bands == 8) { + S += cosdata8[i][k] * Y[k]; + } else { + S += cosdata4[i][k] * Y[k]; + } + } + sbc->samples[block][chan][i] = S * (1 << 15); + } + } + } + + calc_scalefactors(sbc); + + if (cfg->chmode == MODE_JOINT) + sbc->join = calc_scalefactors_joint(sbc); + else + sbc->join = 0; + + calc_bitneed(cfg); + + for (chan = 0; chan < sbc->channels; chan++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->bits[chan][sb] == 0) + continue; + mask[chan][sb] = BM(sbc->bits[chan][sb]); + levels[chan][sb] = mask[chan][sb] * + (1LL << (15 - sbc->scalefactor[chan][sb])); + delta[chan][sb] = + (1LL << (sbc->scalefactor[chan][sb] + 16)); + } + } + + numsamples = 0; + for (block = 0; block < sbc->blocks; block++) { + for (chan = 0; chan < sbc->channels; chan++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->bits[chan][sb] == 0) + continue; + audioout = (levels[chan][sb] * + (delta[chan][sb] + sbc->samples[block][chan][sb])); + audioout /= (1LL << 32); + + audioout = roundf(audioout); + + /* range check */ + if (audioout > mask[chan][sb]) + audioout = mask[chan][sb]; + + sbc->output[numsamples++] = audioout; + } + } + } + return (numsamples); +} + +static void +sbc_decode(struct bt_config *cfg) +{ + struct sbc_encode *sbc = cfg->handle.sbc_enc; + float delta[2][8]; + float levels[2][8]; + float audioout; + float *X; + float *V; + float left[160]; + float right[160]; + float U[160]; + float W[160]; + float S[8]; + int position; + int block; + int chan; + int sb; + int i; + int k; + + for (chan = 0; chan < sbc->channels; chan++) { + for (sb = 0; sb < sbc->bands; sb++) { + levels[chan][sb] = (1 << sbc->bits[chan][sb]) - 1; + delta[chan][sb] = (1 << sbc->scalefactor[chan][sb]); + } + } + + i = 0; + for (block = 0; block < sbc->blocks; block++) { + for (chan = 0; chan < sbc->channels; chan++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->bits[chan][sb] == 0) { + audioout = 0; + } else { + audioout = + ((((sbc->output[i] * 2.0f) + 1.0f) * delta[chan][sb]) / + levels[chan][sb]) - delta[chan][sb]; + } + sbc->output[i++] = audioout; + } + } + } + + if (cfg->chmode == MODE_JOINT) { + i = 0; + while (i < (sbc->blocks * sbc->bands * sbc->channels)) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->join & (1 << (sbc->bands - sb - 1))) { + audioout = sbc->output[i]; + sbc->output[i] = (2.0f * sbc->output[i]) + + (2.0f * sbc->output[i + sbc->bands]); + sbc->output[i + sbc->bands] = + (2.0f * audioout) - + (2.0f * sbc->output[i + sbc->bands]); + sbc->output[i] /= 2.0f; + sbc->output[i + sbc->bands] /= 2.0f; + } + i++; + } + i += sbc->bands; + } + } + position = 0; + for (block = 0; block < sbc->blocks; block++) { + for (chan = 0; chan < sbc->channels; chan++) { + /* select right or left channel */ + if (chan == 0) { + X = left; + V = sbc->left; + } else { + X = right; + V = sbc->right; + } + for (i = 0; i < sbc->bands; i++) + S[i] = sbc->output[position++]; + + for (i = (sbc->bands * 20) - 1; i >= (sbc->bands * 2); i--) + V[i] = V[i - (sbc->bands * 2)]; + for (k = 0; k < sbc->bands * 2; k++) { + float vk = 0; + for (i = 0; i < sbc->bands; i++) { + if (sbc->bands == 8) { + vk += cosdecdata8[i][k] * S[i]; + } else { + vk += cosdecdata4[i][k] * S[i]; + } + } + V[k] = vk; + } + for (i = 0; i <= 4; i++) { + for (k = 0; k < sbc->bands; k++) { + U[(i * sbc->bands * 2) + k] = + V[(i * sbc->bands * 4) + k]; + U[(i * sbc->bands + * 2) + sbc->bands + k] = + V[(i * sbc->bands * 4) + + (sbc->bands * 3) + k]; + } + } + for (i = 0; i < sbc->bands * 10; i++) { + if (sbc->bands == 4) { + W[i] = U[i] * (sbc_coeffs4[i] * -4.0f); + } else if (sbc->bands == 8) { + W[i] = U[i] * (sbc_coeffs8[i] * -8.0f); + } else { + W[i] = 0; + } + } + + for (k = 0; k < sbc->bands; k++) { + unsigned int offset = k + (block * sbc->bands); + + X[offset] = 0; + for (i = 0; i < 10; i++) { + X[offset] += W[k + (i * sbc->bands)]; + } + + if (X[offset] > 32767.0) + X[offset] = 32767.0; + else if (X[offset] < -32767.0) + X[offset] = -32767.0; + } + } + } + + for (i = 0, k = 0; k != (sbc->blocks * sbc->bands); k++) { + sbc->music_data[i++] = left[k]; + if (sbc->channels == 2) + sbc->music_data[i++] = right[k]; + } +} + +size_t +sbc_encode_frame(struct bt_config *cfg) +{ + struct sbc_encode *sbc = cfg->handle.sbc_enc; + uint8_t config; + uint8_t block; + uint8_t chan; + uint8_t sb; + uint8_t j; + uint8_t i; + + config = (cfg->freq << 6) | (cfg->blocks << 4) | + (cfg->chmode << 2) | (cfg->allocm << 1) | cfg->bands; + + sbc_encode(cfg); + + /* set initial CRC */ + sbc->crc = 0x5e; + + /* reset data position and size */ + sbc->bitoffset = 0; + sbc->maxoffset = sizeof(sbc->data) * 8; + + sbc_store_bits_crc(sbc, 8, SYNCWORD); + sbc_store_bits_crc(sbc, 8, config); + sbc_store_bits_crc(sbc, 8, cfg->bitpool); + + /* skip 8-bit CRC */ + sbc->bitoffset += 8; + + if (cfg->chmode == MODE_JOINT) { + if (sbc->bands == 8) + sbc_store_bits_crc(sbc, 8, sbc->join); + else if (sbc->bands == 4) + sbc_store_bits_crc(sbc, 4, sbc->join); + } + for (i = 0; i < sbc->channels; i++) { + for (j = 0; j < sbc->bands; j++) + sbc_store_bits_crc(sbc, 4, sbc->scalefactor[i][j]); + } + + /* store 8-bit CRC */ + sbc->data[3] = (sbc->crc & 0xFF); + + i = 0; + for (block = 0; block < sbc->blocks; block++) { + for (chan = 0; chan < sbc->channels; chan++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->bits[chan][sb] == 0) + continue; + + sbc_store_bits_crc(sbc, sbc->bits[chan][sb], sbc->output[i++]); + } + } + } + return ((sbc->bitoffset + 7) / 8); +} + +static uint32_t +sbc_load_bits_crc(struct sbc_encode *sbc, uint32_t numbits) +{ + uint32_t off = sbc->bitoffset; + uint32_t value = 0; + + while (numbits-- && off != sbc->maxoffset) { + if (sbc->rem_data_ptr[off / 8] & (1 << ((7 - off) & 7))) { + value |= (1 << numbits); + sbc->crc ^= 0x80; + } + sbc->crc *= 2; + if (sbc->crc & 0x100) + sbc->crc ^= 0x11d; /* CRC-8 polynomial */ + + off++; + } + sbc->bitoffset = off; + return (value); +} + +size_t +sbc_decode_frame(struct bt_config *cfg, int bits) +{ + struct sbc_encode *sbc = cfg->handle.sbc_enc; + uint8_t config; + uint8_t block; + uint8_t chan; + uint8_t sb; + uint8_t j; + uint8_t i; + + sbc->rem_off = 0; + sbc->rem_len = 0; + + config = (cfg->freq << 6) | (cfg->blocks << 4) | + (cfg->chmode << 2) | (cfg->allocm << 1) | cfg->bands; + + /* set initial CRC */ + sbc->crc = 0x5e; + + /* reset data position and size */ + sbc->bitoffset = 0; + sbc->maxoffset = bits; + + /* verify SBC header */ + if (sbc->maxoffset < (8 * 4)) + return (0); + if (sbc_load_bits_crc(sbc, 8) != SYNCWORD) + return (0); + if (sbc_load_bits_crc(sbc, 8) != config) + return (0); + cfg->bitpool = sbc_load_bits_crc(sbc, 8); + + (void)sbc_load_bits_crc(sbc, 8);/* CRC */ + + if (cfg->chmode == MODE_JOINT) { + if (sbc->bands == 8) + sbc->join = sbc_load_bits_crc(sbc, 8); + else if (sbc->bands == 4) + sbc->join = sbc_load_bits_crc(sbc, 4); + else + sbc->join = 0; + } else { + sbc->join = 0; + } + + for (i = 0; i < sbc->channels; i++) { + for (j = 0; j < sbc->bands; j++) + sbc->scalefactor[i][j] = sbc_load_bits_crc(sbc, 4); + } + + calc_bitneed(cfg); + + i = 0; + for (block = 0; block < sbc->blocks; block++) { + for (chan = 0; chan < sbc->channels; chan++) { + for (sb = 0; sb < sbc->bands; sb++) { + if (sbc->bits[chan][sb] == 0) { + i++; + continue; + } + sbc->output[i++] = + sbc_load_bits_crc(sbc, sbc->bits[chan][sb]); + } + } + } + + sbc_decode(cfg); + + sbc->rem_off = 0; + sbc->rem_len = sbc->blocks * sbc->channels * sbc->bands; + + return ((sbc->bitoffset + 7) / 8); +} diff --git a/lib/virtual_oss/bt/sbc_encode.h b/lib/virtual_oss/bt/sbc_encode.h new file mode 100644 index 000000000000..71f8460a242e --- /dev/null +++ b/lib/virtual_oss/bt/sbc_encode.h @@ -0,0 +1,82 @@ +/* $NetBSD$ */ + +/*- + * Copyright (c) 2015 Nathanial Sloss <nathanialsloss@yahoo.com.au> + * + * This software is dedicated to the memory of - + * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012. + * + * Barry was a man who loved his music. + * + * 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 NETBSD FOUNDATION, INC. 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 FOUNDATION 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. + */ + +#ifndef _SBC_ENCODE_H_ +#define _SBC_ENCODE_H_ + +#define MIN_BITPOOL 2 +#define DEFAULT_MAXBPOOL 250 + +/* + * SBC header format + */ +struct sbc_header { + uint8_t id; + uint8_t id2; + uint8_t seqnumMSB; + uint8_t seqnumLSB; + uint8_t ts3; + uint8_t ts2; + uint8_t ts1; + uint8_t ts0; + uint8_t reserved3; + uint8_t reserved2; + uint8_t reserved1; + uint8_t reserved0; + uint8_t numFrames; +}; + +struct sbc_encode { + int16_t music_data[256]; + uint8_t data[1024]; + uint8_t *rem_data_ptr; + int rem_data_len; + int rem_data_frames; + int bits[2][8]; + float output[256]; + float left[160]; + float right[160]; + float samples[16][2][8]; + uint32_t rem_len; + uint32_t rem_off; + uint32_t bitoffset; + uint32_t maxoffset; + uint32_t crc; + uint16_t framesamples; + uint8_t scalefactor[2][8]; + uint8_t channels; + uint8_t bands; + uint8_t blocks; + uint8_t join; +}; + +#endif /* _SBC_ENCODE_H_ */ diff --git a/lib/virtual_oss/null/Makefile b/lib/virtual_oss/null/Makefile new file mode 100644 index 000000000000..ec5c2d40f665 --- /dev/null +++ b/lib/virtual_oss/null/Makefile @@ -0,0 +1,10 @@ +SHLIB_NAME= voss_null.so +SHLIBDIR= ${LIBDIR}/virtual_oss + +SRCS= null.c + +CFLAGS+= -I${SRCTOP}/usr.sbin/virtual_oss/virtual_oss \ + -I${SRCTOP}/contrib/libsamplerate +LIBADD= samplerate + +.include <bsd.lib.mk> diff --git a/lib/virtual_oss/null/null.c b/lib/virtual_oss/null/null.c new file mode 100644 index 000000000000..149c6e3e8c6a --- /dev/null +++ b/lib/virtual_oss/null/null.c @@ -0,0 +1,102 @@ +/*- + * Copyright (c) 2015-2022 Hans Petter Selasky + * + * 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/queue.h> +#include <sys/filio.h> +#include <sys/soundcard.h> + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <err.h> +#include <time.h> + +#include "backend.h" +#include "int.h" + +static void +null_close(struct voss_backend *pbe __unused) +{ +} + +static int +null_open(struct voss_backend *pbe __unused, const char *devname __unused, + int samplerate __unused, int bufsize __unused, int *pchannels __unused, + int *pformat) +{ + int value[3]; + int i; + + value[0] = *pformat & VPREFERRED_SNE_AFMT; + value[1] = *pformat & VPREFERRED_SLE_AFMT; + value[2] = *pformat & VPREFERRED_SBE_AFMT; + + for (i = 0; i != 3; i++) { + if (value[i] == 0) + continue; + *pformat = value[i]; + return (0); + } + return (-1); +} + +static int +null_rec_transfer(struct voss_backend *pbe __unused, void *ptr, int len) +{ + + if (voss_has_synchronization == 0) + virtual_oss_wait(); + memset(ptr, 0, len); + return (len); +} + +static int +null_play_transfer(struct voss_backend *pbe __unused, void *ptr __unused, + int len) +{ + return (len); +} + +static void +null_delay(struct voss_backend *pbe __unused, int *pdelay) +{ + *pdelay = -1; +} + +struct voss_backend voss_backend_null_rec = { + .open = null_open, + .close = null_close, + .transfer = null_rec_transfer, + .delay = null_delay, +}; + +struct voss_backend voss_backend_null_play = { + .open = null_open, + .close = null_close, + .transfer = null_play_transfer, + .delay = null_delay, +}; diff --git a/lib/virtual_oss/oss/Makefile b/lib/virtual_oss/oss/Makefile new file mode 100644 index 000000000000..257d7f0c0bae --- /dev/null +++ b/lib/virtual_oss/oss/Makefile @@ -0,0 +1,10 @@ +SHLIB_NAME= voss_oss.so +SHLIBDIR= ${LIBDIR}/virtual_oss + +SRCS= oss.c + +CFLAGS+= -I${SRCTOP}/usr.sbin/virtual_oss/virtual_oss \ + -I${SRCTOP}/contrib/libsamplerate +LIBADD= samplerate + +.include <bsd.lib.mk> diff --git a/lib/virtual_oss/oss/oss.c b/lib/virtual_oss/oss/oss.c new file mode 100644 index 000000000000..b4779f9108d9 --- /dev/null +++ b/lib/virtual_oss/oss/oss.c @@ -0,0 +1,197 @@ +/*- + * Copyright (c) 2015-2019 Hans Petter Selasky + * + * 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/queue.h> +#include <sys/filio.h> +#include <sys/soundcard.h> + +#include <stdint.h> +#include <stdlib.h> +#include <string.h> +#include <fcntl.h> +#include <unistd.h> +#include <err.h> +#include <poll.h> + +#include "backend.h" +#include "int.h" + +static int +oss_set_format(int fd, int *format) +{ + int value[6]; + int error; + int fmt; + int i; + + value[0] = *format & VPREFERRED_SNE_AFMT; + value[1] = *format & VPREFERRED_UNE_AFMT; + value[2] = *format & VPREFERRED_SLE_AFMT; + value[3] = *format & VPREFERRED_SBE_AFMT; + value[4] = *format & VPREFERRED_ULE_AFMT; + value[5] = *format & VPREFERRED_UBE_AFMT; + + for (i = 0; i != 6; i++) { + fmt = value[i]; + if (fmt == 0) + continue; + error = ioctl(fd, SNDCTL_DSP_SETFMT, &fmt); + /* make sure we got the format we asked for */ + if (error == 0 && fmt == value[i]) { + *format = fmt; + return (0); + } + } + return (-1); +} + +static void +oss_close(struct voss_backend *pbe) +{ + if (pbe->fd > -1) { + close(pbe->fd); + pbe->fd = -1; + } +} + +static int +oss_open(struct voss_backend *pbe, const char *devname, int samplerate, + int bufsize, int *pchannels, int *pformat, int attr, int fionbio) +{ + int temp; + int err; + + pbe->fd = open(devname, attr); + if (pbe->fd < 0) { + warn("Could not open DSP device '%s'", devname); + return (-1); + } + err = ioctl(pbe->fd, FIONBIO, &fionbio); + if (err < 0) { + warn("Could not set blocking mode on DSP"); + goto error; + } + err = oss_set_format(pbe->fd, pformat); + if (err < 0) { + warn("Could not set sample format 0x%08x", *pformat); + goto error; + } + temp = *pchannels; + bufsize /= temp; /* get buffer size per channel */ + do { + err = ioctl(pbe->fd, SOUND_PCM_WRITE_CHANNELS, &temp); + } while (err < 0 && --temp > 0); + + err = ioctl(pbe->fd, SOUND_PCM_READ_CHANNELS, &temp); + if (err < 0 || temp <= 0 || temp > *pchannels) { + warn("Could not set DSP channels: %d / %d", temp, *pchannels); + goto error; + } + *pchannels = temp; + + temp = samplerate; + err = ioctl(pbe->fd, SNDCTL_DSP_SPEED, &temp); + if (err < 0 || temp != samplerate) { + warn("Could not set sample rate to %d / %d Hz", temp, samplerate); + goto error; + } + + temp = bufsize * (*pchannels); + err = ioctl(pbe->fd, SNDCTL_DSP_SETBLKSIZE, &temp); + if (err < 0) { + warn("Could not set block size to %d", temp); + goto error; + } + return (0); +error: + close(pbe->fd); + pbe->fd = -1; + return (-1); +} + +static int +oss_rec_open(struct voss_backend *pbe, const char *devname, int samplerate, + int bufsize, int *pchannels, int *pformat) +{ + return (oss_open(pbe, devname, samplerate, bufsize, pchannels, pformat, O_RDONLY, 0)); +} + +static int +oss_play_open(struct voss_backend *pbe, const char *devname, int samplerate, + int bufsize, int *pchannels, int *pformat) +{ + bufsize *= 4; /* XXX allow extra space for jitter */ + return (oss_open(pbe, devname, samplerate, bufsize, pchannels, pformat, O_WRONLY, 0)); +} + +static int +oss_rec_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + struct pollfd fds = { .fd = pbe->fd, .events = POLLIN | POLLRDNORM }; + int err; + + /* wait at maximum 2 seconds for data, else something is wrong */ + err = poll(&fds, 1, 2000); + if (err < 1) + return (-1); + return (read(pbe->fd, ptr, len)); +} + +static int +oss_play_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + return (write(pbe->fd, ptr, len)); +} + +static void +oss_rec_delay(struct voss_backend *pbe, int *pdelay) +{ + if (ioctl(pbe->fd, FIONREAD, pdelay) != 0) + *pdelay = -1; +} + +static void +oss_play_delay(struct voss_backend *pbe, int *pdelay) +{ + if (voss_has_synchronization != 0 || + ioctl(pbe->fd, SNDCTL_DSP_GETODELAY, pdelay) != 0) + *pdelay = -1; +} + +struct voss_backend voss_backend_oss_rec = { + .open = oss_rec_open, + .close = oss_close, + .transfer = oss_rec_transfer, + .delay = oss_rec_delay, + .fd = -1, +}; + +struct voss_backend voss_backend_oss_play = { + .open = oss_play_open, + .close = oss_close, + .transfer = oss_play_transfer, + .delay = oss_play_delay, + .fd = -1, +}; diff --git a/lib/virtual_oss/sndio/Makefile b/lib/virtual_oss/sndio/Makefile new file mode 100644 index 000000000000..9b5af63a3246 --- /dev/null +++ b/lib/virtual_oss/sndio/Makefile @@ -0,0 +1,12 @@ +SHLIB_NAME= voss_sndio.so +SHLIBDIR= ${LIBDIR}/virtual_oss + +SRCS= sndio.c + +CFLAGS+= -I${SRCTOP}/usr.sbin/virtual_oss/virtual_oss \ + -I${SRCTOP}/contrib/libsamplerate \ + -I${LOCALBASE:U/usr/local}/include +LDFLAGS+= -L${LOCALBASE:U/usr/local}/lib -lsndio +LIBADD= samplerate + +.include <bsd.lib.mk> diff --git a/lib/virtual_oss/sndio/sndio.c b/lib/virtual_oss/sndio/sndio.c new file mode 100644 index 000000000000..2d1a3411049b --- /dev/null +++ b/lib/virtual_oss/sndio/sndio.c @@ -0,0 +1,203 @@ +/*- + * Copyright (c) 2021 Tim Creech <tcreech@tcreech.com> + * + * 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/queue.h> +#include <sys/soundcard.h> + +#include <err.h> +#include <stdlib.h> +#include <string.h> + +#include <sndio.h> + +#include "backend.h" +#include "int.h" + +static struct sio_hdl * +get_sio_hdl(struct voss_backend *pbe) +{ + if (pbe) + return (pbe->arg); + + return (NULL); +} + +static void +sndio_close(struct voss_backend *pbe) +{ + if (!pbe) + return; + + if (get_sio_hdl(pbe)) + sio_close(get_sio_hdl(pbe)); +} + +static int +sndio_get_signedness(int *fmt) +{ + int s_fmt = *fmt & (VPREFERRED_SLE_AFMT | VPREFERRED_SBE_AFMT); + + if (s_fmt) { + *fmt = s_fmt; + return (1); + } + *fmt = *fmt & (VPREFERRED_ULE_AFMT | VPREFERRED_UBE_AFMT); + return (0); +} + +static int +sndio_get_endianness_is_le(int *fmt) +{ + int le_fmt = *fmt & (VPREFERRED_SLE_AFMT | VPREFERRED_ULE_AFMT); + + if (le_fmt) { + *fmt = le_fmt; + return (1); + } + *fmt = *fmt & (VPREFERRED_SBE_AFMT | VPREFERRED_UBE_AFMT); + return (0); +} + +static int +sndio_get_bits(int *fmt) +{ + if (*fmt & AFMT_16BIT) + return (16); + if (*fmt & AFMT_24BIT) + return (24); + if (*fmt & AFMT_32BIT) + return (32); + if (*fmt & AFMT_8BIT) + return (8); + return (-1); + /* TODO AFMT_BIT */ +} + +static int +sndio_open(struct voss_backend *pbe, const char *devname, + int samplerate, int bufsize, int *pchannels, int *pformat, int direction) +{ + const char *sndio_name = devname + strlen("/dev/sndio/"); + + int sig = sndio_get_signedness(pformat); + int le = sndio_get_endianness_is_le(pformat); + int bits = sndio_get_bits(pformat); + + if (bits == -1) { + warn("unsupported format precision"); + return (-1); + } + + struct sio_hdl *hdl = sio_open(sndio_name, direction, 0); + + if (hdl == 0) { + warn("sndio: failed to open device"); + return (-1); + } + + struct sio_par par; + + sio_initpar(&par); + par.pchan = *pchannels; + par.sig = sig; + par.bits = bits; + par.bps = SIO_BPS(bits); + par.le = le; + par.rate = samplerate; + par.appbufsz = bufsize; + par.xrun = SIO_SYNC; + if (!sio_setpar(hdl, &par)) + errx(1, "internal error, sio_setpar() failed"); + if (!sio_getpar(hdl, &par)) + errx(1, "internal error, sio_getpar() failed"); + if ((int)par.pchan != *pchannels) + errx(1, "couldn't set number of channels"); + if ((int)par.sig != sig || (int)par.bits != bits || (int)par.le != le) + errx(1, "couldn't set format"); + if ((int)par.bits != bits) + errx(1, "couldn't set precision"); + if ((int)par.rate < samplerate * 995 / 1000 || + (int)par.rate > samplerate * 1005 / 1000) + errx(1, "couldn't set rate"); + if (par.xrun != SIO_SYNC) + errx(1, "couldn't set xun policy"); + + /* Save the device handle with the backend */ + pbe->arg = hdl; + + /* Start the device. */ + if (!sio_start(hdl)) + errx(1, "couldn't start device"); + + return (0); +} + +static int +sndio_open_play(struct voss_backend *pbe, const char *devname, + int samplerate, int bufsize, int *pchannels, int *pformat) +{ + return (sndio_open(pbe, devname, samplerate, bufsize, pchannels, pformat, SIO_PLAY)); +} + +static int +sndio_open_rec(struct voss_backend *pbe, const char *devname, + int samplerate, int bufsize, int *pchannels, int *pformat) +{ + return (sndio_open(pbe, devname, samplerate, bufsize, pchannels, pformat, SIO_REC)); +} + +static int +sndio_play_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + return (sio_write(get_sio_hdl(pbe), ptr, len)); +} + +static int +sndio_rec_transfer(struct voss_backend *pbe, void *ptr, int len) +{ + return (sio_read(get_sio_hdl(pbe), ptr, len)); +} + +static void +sndio_delay(struct voss_backend *pbe __unused, int *pdelay) +{ + *pdelay = -1; +} + +struct voss_backend voss_backend_sndio_rec = { + .open = sndio_open_rec, + .close = sndio_close, + .transfer = sndio_rec_transfer, + .delay = sndio_delay, + .fd = -1, +}; + +struct voss_backend voss_backend_sndio_play = { + .open = sndio_open_play, + .close = sndio_close, + .transfer = sndio_play_transfer, + .delay = sndio_delay, + .fd = -1, +}; |
