aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Makefile1
-rw-r--r--lib/geom/part/gpart.822
-rw-r--r--lib/libarchive/tests/Makefile6
-rw-r--r--lib/libblacklist/Makefile7
-rw-r--r--lib/libblocklist/Makefile30
-rw-r--r--lib/libblocklist/Makefile.depend16
-rw-r--r--lib/libbluetooth/Makefile2
-rw-r--r--lib/libbz2/Makefile13
-rw-r--r--lib/libbz2/bzip2.pc.in11
-rw-r--r--lib/libc/gen/fts.3146
-rw-r--r--lib/libc/gen/fts.c3
-rw-r--r--lib/libc/gen/getgrouplist.333
-rw-r--r--lib/libc/gen/initgroups.38
-rw-r--r--lib/libc/inet/inet_net_ntop.c206
-rw-r--r--lib/libc/inet/inet_net_pton.c363
-rw-r--r--lib/libc/stdlib/realpath.312
-rw-r--r--lib/libc/stdlib/realpath.c14
-rw-r--r--lib/libc/stdtime/strptime.32
-rw-r--r--lib/libc/stdtime/strptime.c3
-rw-r--r--lib/libc/tests/gen/realpath2_test.c106
-rw-r--r--lib/libc/tests/net/Makefile2
-rw-r--r--lib/libc/tests/net/inet_net_test.cc333
-rw-r--r--lib/libcasper/services/cap_fileargs/cap_fileargs.h2
-rw-r--r--lib/libmd/Makefile9
-rw-r--r--lib/libmd/aarch64/md5block.S206
-rw-r--r--lib/libmd/aarch64/sha1block.S2
-rw-r--r--lib/libmd/aarch64/sha1dispatch.c2
-rw-r--r--lib/libmd/amd64/md5block.S363
-rw-r--r--lib/libmd/amd64/md5dispatch.c41
-rw-r--r--lib/libmd/amd64/sha1block.S2
-rw-r--r--lib/libmd/amd64/sha1dispatch.c2
-rw-r--r--lib/libmd/sha1c.c2
-rw-r--r--lib/libpam/modules/modules.inc2
-rw-r--r--lib/libpam/modules/pam_xdg/pam_xdg.81
-rw-r--r--lib/libsys/clock_gettime.23
-rw-r--r--lib/libsys/getgroups.225
-rw-r--r--lib/libsys/getrlimitusage.24
-rw-r--r--lib/libsys/kqueue.229
-rw-r--r--lib/libsys/socket.2302
-rw-r--r--lib/libsysdecode/Makefile.depend2
-rw-r--r--lib/libunbound/Makefile6
-rw-r--r--lib/libunbound/config.h4
-rw-r--r--lib/libutil/mntopts.c53
-rw-r--r--lib/msun/src/e_remainder.c4
-rw-r--r--lib/ncurses/Makefile.inc1
-rw-r--r--lib/virtual_oss/Makefile.inc2
46 files changed, 1793 insertions, 615 deletions
diff --git a/lib/Makefile b/lib/Makefile
index d43e4d395f56..75a2355aa452 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -163,6 +163,7 @@ SUBDIR_DEPEND_virtual_oss= libsamplerate
SUBDIR.${MK_BEARSSL}+= libbearssl libsecureboot
SUBDIR.${MK_BLACKLIST}+=libblacklist
+SUBDIR.${MK_BLOCKLIST}+=libblocklist
SUBDIR.${MK_BLUETOOTH}+=libbluetooth libsdp
SUBDIR.${MK_BSNMP}+= libbsnmp
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/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/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/libbz2/Makefile b/lib/libbz2/Makefile
index d773f202dd67..2aedbaed4328 100644
--- a/lib/libbz2/Makefile
+++ b/lib/libbz2/Makefile
@@ -13,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/gen/fts.3 b/lib/libc/gen/fts.3
index b937607b48e0..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 October 1, 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).
@@ -544,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
@@ -625,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
@@ -639,9 +649,9 @@ 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.
+function in post-order.
.Ss Fn fts_children
The
.Fn fts_children
@@ -717,10 +727,10 @@ and
fields.
.El
.Ss Fn fts_set
-The function
+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 .
@@ -786,6 +796,39 @@ The file may be one of those most recently returned by either
or
.Fn fts_read .
.El
+.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
@@ -797,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
@@ -853,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/getgrouplist.3 b/lib/libc/gen/getgrouplist.3
index e3939fc2481a..9e05ff7e7a29 100644
--- a/lib/libc/gen/getgrouplist.3
+++ b/lib/libc/gen/getgrouplist.3
@@ -33,7 +33,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd August 29, 2025
+.Dd October 9, 2025
.Dt GETGROUPLIST 3
.Os
.Sh NAME
@@ -48,30 +48,37 @@
.Sh DESCRIPTION
The
.Fn getgrouplist
-function reads through the group database to retrieve the supplementary groups
-for the user specified in
-.Fa name ,
+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 retrieved supplementary groups.
+and the others are the supplementary groups.
.Fa basegid
-typically is the user's group number from the password database.
+typically is the user's initial numerical group ID from the password database.
.Pp
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
diff --git a/lib/libc/gen/initgroups.3 b/lib/libc/gen/initgroups.3
index 4f538fb180ec..74133e7d7048 100644
--- a/lib/libc/gen/initgroups.3
+++ b/lib/libc/gen/initgroups.3
@@ -33,7 +33,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 17, 2025
+.Dd October 9, 2025
.Dt INITGROUPS 3
.Os
.Sh NAME
@@ -67,9 +67,9 @@ The
.Fn initgroups
function may fail and set
.Va errno
-to 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
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/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/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/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/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/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/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/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/getgroups.2 b/lib/libsys/getgroups.2
index 4881a65d532e..4e94b32d4e7b 100644
--- a/lib/libsys/getgroups.2
+++ b/lib/libsys/getgroups.2
@@ -33,7 +33,7 @@
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
.\" SUCH DAMAGE.
.\"
-.Dd September 17, 2025
+.Dd October 10, 2025
.Dt GETGROUPS 2
.Os
.Sh NAME
@@ -107,10 +107,8 @@ array.
The
.Fn getgroups
system call conforms to
-.St -p1003.1-2008
-with the additional properties that supplementary groups are reported in
-strictly ascending order and the returned size coincides with the cardinal of
-the set.
+.St -p1003.1-2008 ,
+not reporting the effective group ID.
.Sh HISTORY
The
.Fn getgroups
@@ -121,8 +119,8 @@ Since
.Fx 14.3 ,
the
.Fn getgroups
-system call has treated the supplementary groups as a set, reporting them in
-strictly ascending order and returning the cardinal of the set.
+system call has been reporting the supplementary groups in strictly ascending
+order.
.Pp
Before
.Fx 15.0 ,
@@ -138,15 +136,14 @@ system call gets the supplementary groups set in the
array.
In particular, as evoked in
.Sx HISTORY ,
-it does not anymore retrieve the effective GID in the first slot of
+it does not anymore retrieve the effective group ID in the first slot of
.Fa gidset .
-Programs should not make any assumption about which group is placed in the first
-slot of
-.Fa gidset
-other than it being the supplementary group with smallest GID.
+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 GID is present in the supplementary groups set if and only if it
-was explicitly set as a supplementary group.
+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
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/kqueue.2 b/lib/libsys/kqueue.2
index 96c9b0222a37..a8ebabf02cf7 100644
--- a/lib/libsys/kqueue.2
+++ b/lib/libsys/kqueue.2
@@ -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
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/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/libunbound/Makefile b/lib/libunbound/Makefile
index e2cd25ea8b34..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,9 +5,10 @@ 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
diff --git a/lib/libunbound/config.h b/lib/libunbound/config.h
index 51105977b20a..1b939b7f1074 100644
--- a/lib/libunbound/config.h
+++ b/lib/libunbound/config.h
@@ -884,7 +884,7 @@
#define PACKAGE_NAME "unbound"
/* Define to the full name and version of this package. */
-#define PACKAGE_STRING "unbound 1.23.1"
+#define PACKAGE_STRING "unbound 1.24.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "unbound"
@@ -893,7 +893,7 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
-#define PACKAGE_VERSION "1.23.1"
+#define PACKAGE_VERSION "1.24.1"
/* default pidfile location */
#define PIDFILE "/var/unbound/unbound.pid"
diff --git a/lib/libutil/mntopts.c b/lib/libutil/mntopts.c
index 07d3dd6d98a3..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,19 +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 &&
- S_ISCHR(mntdevstat.st_mode) &&
+ if (S_ISCHR(mntdevstat.st_mode) &&
mntdevstat.st_rdev == devstat.st_rdev)
return (statfsp);
}
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/ncurses/Makefile.inc b/lib/ncurses/Makefile.inc
index eea49908474c..e14867696834 100644
--- a/lib/ncurses/Makefile.inc
+++ b/lib/ncurses/Makefile.inc
@@ -1,6 +1,7 @@
# This is to include src/lib/Makefile.inc
PACKAGE?= ncurses
+LIB_PACKAGE=
WARNS?= 3
.include "../Makefile.inc"
diff --git a/lib/virtual_oss/Makefile.inc b/lib/virtual_oss/Makefile.inc
index 45c8e0b1fdfc..877465a5c548 100644
--- a/lib/virtual_oss/Makefile.inc
+++ b/lib/virtual_oss/Makefile.inc
@@ -1,3 +1,5 @@
+PACKAGE= sound
+
.include "../Makefile.inc"
LDFLAGS+= -L${.OBJDIR:H:H}/libsamplerate