diff --git a/distrib/sets/lists/base/mi b/distrib/sets/lists/base/mi index 1d6334861..be9b7dadf 100644 --- a/distrib/sets/lists/base/mi +++ b/distrib/sets/lists/base/mi @@ -734,7 +734,7 @@ ./usr/lib/crtendS.o ./usr/lib/gcrt0.o ./usr/lib/libagentx.so.1.1 -./usr/lib/libc.so.97.1 +./usr/lib/libc.so.98.0 ./usr/lib/libcbor.so.2.0 ./usr/lib/libcrypto.so.52.0 ./usr/lib/libcurses.so.15.0 @@ -770,7 +770,7 @@ ./usr/lib/libtermlib.so.15.0 ./usr/lib/libtls.so.28.0 ./usr/lib/libusbhid.so.7.1 -./usr/lib/libutil.so.17.0 +./usr/lib/libutil.so.18.0 ./usr/lib/libz.so.7.0 ./usr/lib/locate ./usr/lib/locate/src.db @@ -2963,7 +2963,7 @@ ./usr/share/relink/kernel.tgz ./usr/share/relink/usr ./usr/share/relink/usr/lib -./usr/share/relink/usr/lib/libc.so.97.1.a +./usr/share/relink/usr/lib/libc.so.98.0.a ./usr/share/relink/usr/lib/libcrypto.so.52.0.a ./usr/share/relink/usr/libexec ./usr/share/relink/usr/libexec/ld.so.a diff --git a/distrib/sets/lists/comp/mi b/distrib/sets/lists/comp/mi index a6013023a..90813a4be 100644 --- a/distrib/sets/lists/comp/mi +++ b/distrib/sets/lists/comp/mi @@ -1740,7 +1740,6 @@ ./usr/share/man/man2/symlink.2 ./usr/share/man/man2/sync.2 ./usr/share/man/man2/sysarch.2 -./usr/share/man/man2/syscall.2 ./usr/share/man/man2/sysctl.2 ./usr/share/man/man2/thrkill.2 ./usr/share/man/man2/truncate.2 @@ -2664,6 +2663,7 @@ ./usr/share/man/man3/i2a_ASN1_STRING.3 ./usr/share/man/man3/i2d_CMS_bio_stream.3 ./usr/share/man/man3/i2d_PKCS7_bio_stream.3 +./usr/share/man/man3/ibuf_add.3 ./usr/share/man/man3/if_indextoname.3 ./usr/share/man/man3/ilogb.3 ./usr/share/man/man3/imaxabs.3 diff --git a/distrib/sets/lists/man/mi b/distrib/sets/lists/man/mi index 50abc960a..064fe7afd 100644 --- a/distrib/sets/lists/man/mi +++ b/distrib/sets/lists/man/mi @@ -1248,6 +1248,7 @@ ./usr/share/man/man4/arm64 ./usr/share/man/man4/arm64/agintc.4 ./usr/share/man/man4/arm64/agtimer.4 +./usr/share/man/man4/arm64/ampchwm.4 ./usr/share/man/man4/arm64/ampintc.4 ./usr/share/man/man4/arm64/aplaudio.4 ./usr/share/man/man4/arm64/aplcpu.4 diff --git a/etc/skel/dot.version b/etc/skel/dot.version index 096149f4e..d1170351f 100644 --- a/etc/skel/dot.version +++ b/etc/skel/dot.version @@ -1 +1 @@ -# SecBSD 1.4-6dd7abc: Thu Dec 7 18:11:47 UTC 2023 (Mictlantecuhtli) +# SecBSD 1.4-0445948: Tue Dec 12 20:24:48 UTC 2023 (Mictlantecuhtli) diff --git a/include/unistd.h b/include/unistd.h index 44fb855e5..295ad1d15 100644 --- a/include/unistd.h +++ b/include/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.107 2023/01/07 05:24:58 guenther Exp $ */ +/* $OpenBSD: unistd.h,v 1.108 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: unistd.h,v 1.26.4.1 1996/05/28 02:31:51 mrg Exp $ */ /*- @@ -522,7 +522,6 @@ int setthrname(pid_t, const char *); void setusershell(void); int strtofflags(char **, u_int32_t *, u_int32_t *); int swapctl(int cmd, const void *arg, int misc); -int syscall(int, ...); int getentropy(void *, size_t); int pledge(const char *, const char *); int unveil(const char *, const char *); diff --git a/lib/libc/Symbols.list b/lib/libc/Symbols.list index f18c6baa0..a6bc65f50 100644 --- a/lib/libc/Symbols.list +++ b/lib/libc/Symbols.list @@ -434,7 +434,6 @@ symlink symlinkat sync sysarch -syscall timer_create timer_delete timer_getoverrun diff --git a/lib/libc/hidden/unistd.h b/lib/libc/hidden/unistd.h index c59509553..74918f596 100644 --- a/lib/libc/hidden/unistd.h +++ b/lib/libc/hidden/unistd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: unistd.h,v 1.12 2023/05/18 16:11:09 guenther Exp $ */ +/* $OpenBSD: unistd.h,v 1.13 2023/12/12 15:30:55 deraadt Exp $ */ /* * Copyright (c) 2015 Philip Guenther * @@ -157,7 +157,6 @@ PROTO_NORMAL(swapctl); PROTO_NORMAL(symlink); PROTO_NORMAL(symlinkat); PROTO_NORMAL(sync); -PROTO_NORMAL(syscall); PROTO_NORMAL(sysconf); PROTO_DEPRECATED(tcgetpgrp); PROTO_DEPRECATED(tcsetpgrp); diff --git a/lib/libc/shlib_version b/lib/libc/shlib_version index 6e63f1afe..211c24639 100644 --- a/lib/libc/shlib_version +++ b/lib/libc/shlib_version @@ -1,4 +1,4 @@ -major=97 -minor=1 +major=98 +minor=0 # note: If changes were made to include/thread_private.h or if system calls # were added/changed then librthread/shlib_version must also be updated. diff --git a/lib/libc/sys/Makefile.inc b/lib/libc/sys/Makefile.inc index 3d23e9611..c635830d3 100644 --- a/lib/libc/sys/Makefile.inc +++ b/lib/libc/sys/Makefile.inc @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile.inc,v 1.175 2023/12/11 00:34:24 deraadt Exp $ +# $OpenBSD: Makefile.inc,v 1.176 2023/12/12 15:30:55 deraadt Exp $ # $NetBSD: Makefile.inc,v 1.35 1995/10/16 23:49:07 jtc Exp $ # @(#)Makefile.inc 8.1 (Berkeley) 6/17/93 @@ -8,7 +8,7 @@ # modules with non-default implementations on at least one architecture: SRCS+= Ovfork.S brk.S ${CERROR} \ sbrk.S sigpending.S sigprocmask.S \ - sigsuspend.S syscall.S tfork_thread.S + sigsuspend.S tfork_thread.S # glue to offer userland wrappers for some syscalls SRCS+= posix_madvise.c pthread_sigmask.c \ @@ -216,7 +216,7 @@ MAN+= __get_tcb.2 __thrsigdivert.2 __thrsleep.2 _exit.2 accept.2 \ shmctl.2 shmget.2 shutdown.2 sigaction.2 sigaltstack.2 sigpending.2 \ sigprocmask.2 sigreturn.2 sigsuspend.2 socket.2 \ socketpair.2 stat.2 statfs.2 swapctl.2 symlink.2 \ - sync.2 sysarch.2 syscall.2 sysctl.2 thrkill.2 truncate.2 \ + sync.2 sysarch.2 sysctl.2 thrkill.2 truncate.2 \ umask.2 unlink.2 unveil.2 utimes.2 utrace.2 vfork.2 \ wait.2 waitid.2 write.2 \ ypconnect.2 diff --git a/lib/libc/sys/syscall.2 b/lib/libc/sys/syscall.2 index 754d012f2..e69de29bb 100644 --- a/lib/libc/sys/syscall.2 +++ b/lib/libc/sys/syscall.2 @@ -1,68 +0,0 @@ -.\" $OpenBSD: syscall.2,v 1.16 2023/02/22 07:04:50 jmc Exp $ -.\" $NetBSD: syscall.2,v 1.4 1995/02/27 12:38:53 cgd Exp $ -.\" -.\" Copyright (c) 1980, 1991, 1993 -.\" The Regents of the University of California. All rights reserved. -.\" -.\" Redistribution and use in source and binary forms, with or without -.\" modification, are permitted provided that the following conditions -.\" are met: -.\" 1. Redistributions of source code must retain the above copyright -.\" notice, this list of conditions and the following disclaimer. -.\" 2. Redistributions in binary form must reproduce the above copyright -.\" notice, this list of conditions and the following disclaimer in the -.\" documentation and/or other materials provided with the distribution. -.\" 3. Neither the name of the University nor the names of its contributors -.\" may be used to endorse or promote products derived from this software -.\" without specific prior written permission. -.\" -.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND -.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE -.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE -.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS -.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) -.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT -.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY -.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF -.\" SUCH DAMAGE. -.\" -.\" @(#)syscall.2 8.1 (Berkeley) 6/16/93 -.\" -.Dd $Mdocdate: February 22 2023 $ -.Dt SYSCALL 2 -.Os -.Sh NAME -.Nm syscall -.Nd indirect system call -.Sh SYNOPSIS -.In sys/syscall.h -.In unistd.h -.Ft int -.Fn syscall "int number" "..." -.Sh DESCRIPTION -.Fn syscall -performs the system call whose assembly language -interface has the specified -.Fa number -with the specified arguments. -Symbolic constants for system calls can be found in the header file -.In sys/syscall.h . -.Sh RETURN VALUES -The return values are defined by the system call being invoked. -In general, for system calls returning -.Va int , -a 0 return value indicates success. -A \-1 return value indicates an error, -and an error code is stored in -.Va errno . -.Sh HISTORY -The predecessor of these functions, the former -.Fn indir -system call, first appeared in -.At v4 . -The -.Fn syscall -function first appeared in -.Bx 3 . diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile index c0d889a5a..7d4ed30ed 100644 --- a/lib/libutil/Makefile +++ b/lib/libutil/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.44 2019/10/24 12:39:26 tb Exp $ +# $OpenBSD: Makefile,v 1.45 2023/12/12 15:49:21 claudio Exp $ # $NetBSD: Makefile,v 1.8 1996/05/16 07:03:28 thorpej Exp $ LIB= util @@ -20,7 +20,7 @@ MAN= bcrypt_pbkdf.3 \ ober_read_elements.3 ober_set_header.3 \ opendev.3 openpty.3 pw_init.3 pw_lock.3 readlabelfs.3 uu_lock.3 \ fparseln.3 opendisk.3 login_fbtab.3 pidfile.3 fmt_scaled.3 imsg_init.3 \ - pkcs5_pbkdf2.3 + ibuf_add.3 pkcs5_pbkdf2.3 SRCS+= ohash.c HDRS += ohash.h diff --git a/lib/libutil/Symbols.map b/lib/libutil/Symbols.map index 00472fbb3..c1bac13aa 100644 --- a/lib/libutil/Symbols.map +++ b/lib/libutil/Symbols.map @@ -19,10 +19,14 @@ getrawpartition; ibuf_add; ibuf_add_buf; - ibuf_add_n8; + ibuf_add_ibuf; + ibuf_add_h16; + ibuf_add_h32; + ibuf_add_h64; ibuf_add_n16; ibuf_add_n32; ibuf_add_n64; + ibuf_add_n8; ibuf_add_zero; ibuf_close; ibuf_data; @@ -31,28 +35,53 @@ ibuf_fd_get; ibuf_fd_set; ibuf_free; + ibuf_from_buffer; + ibuf_from_ibuf; + ibuf_get; + ibuf_get_ibuf; + ibuf_get_h16; + ibuf_get_h32; + ibuf_get_h64; + ibuf_get_n16; + ibuf_get_n32; + ibuf_get_n64; + ibuf_get_n8; ibuf_left; ibuf_open; ibuf_reserve; + ibuf_rewind; ibuf_seek; ibuf_set; - ibuf_set_n8; + ibuf_set_h16; + ibuf_set_h32; + ibuf_set_h64; ibuf_set_n16; ibuf_set_n32; ibuf_set_n64; + ibuf_set_n8; ibuf_size; + ibuf_skip; + ibuf_truncate; ibuf_write; imsg_add; imsg_clear; imsg_close; imsg_compose; - imsg_composev; imsg_compose_ibuf; + imsg_composev; imsg_create; imsg_fd_overhead; imsg_flush; + imsg_forward; imsg_free; imsg_get; + imsg_get_ibuf; + imsg_get_data; + imsg_get_fd; + imsg_get_id; + imsg_get_len; + imsg_get_pid; + imsg_get_type; imsg_init; imsg_read; isduid; @@ -64,6 +93,7 @@ logwtmp; msgbuf_clear; msgbuf_init; + msgbuf_queuelen; msgbuf_write; ober_add_bitstring; ober_add_boolean; diff --git a/lib/libutil/ibuf_add.3 b/lib/libutil/ibuf_add.3 new file mode 100644 index 000000000..fa3e2dace --- /dev/null +++ b/lib/libutil/ibuf_add.3 @@ -0,0 +1,496 @@ +.\" $OpenBSD: ibuf_add.3,v 1.1 2023/12/12 15:49:21 claudio Exp $ +.\" +.\" Copyright (c) 2023 Claudio Jeker +.\" Copyright (c) 2010 Nicholas Marriott +.\" +.\" 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 MIND, 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. +.\" +.Dd $Mdocdate: December 12 2023 $ +.Dt IBUF_ADD 3 +.Os +.Sh NAME +.Nm ibuf_add , +.Nm ibuf_add_ibuf , +.Nm ibuf_add_h16 , +.Nm ibuf_add_h32 , +.Nm ibuf_add_h64 , +.Nm ibuf_add_n16 , +.Nm ibuf_add_n32 , +.Nm ibuf_add_n64 , +.Nm ibuf_add_n8 , +.Nm ibuf_add_zero , +.Nm ibuf_close , +.Nm ibuf_data , +.Nm ibuf_dynamic , +.Nm ibuf_fd_avail , +.Nm ibuf_fd_get , +.Nm ibuf_fd_set , +.Nm ibuf_free , +.Nm ibuf_from_buffer , +.Nm ibuf_from_ibuf , +.Nm ibuf_get , +.Nm ibuf_get_ibuf , +.Nm ibuf_get_h16 , +.Nm ibuf_get_h32 , +.Nm ibuf_get_h64 , +.Nm ibuf_get_n16 , +.Nm ibuf_get_n32 , +.Nm ibuf_get_n64 , +.Nm ibuf_get_n8 , +.Nm ibuf_left , +.Nm ibuf_open , +.Nm ibuf_reserve , +.Nm ibuf_rewind , +.Nm ibuf_seek , +.Nm ibuf_set , +.Nm ibuf_set_h16 , +.Nm ibuf_set_h32 , +.Nm ibuf_set_h64 , +.Nm ibuf_set_n16 , +.Nm ibuf_set_n32 , +.Nm ibuf_set_n64 , +.Nm ibuf_set_n8 , +.Nm ibuf_size , +.Nm ibuf_skip , +.Nm ibuf_truncate , +.Nm ibuf_write , +.Nm msgbuf_clear , +.Nm msgbuf_init , +.Nm msgbuf_queuelen , +.Nm msgbuf_write +.Nd save buffer API for basic IO +.Sh SYNOPSIS +.In sys/queue.h +.In imsg.h +.Ft int +.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len" +.Ft int +.Fn ibuf_add_ibuf "struct ibuf *buf" "const struct ibuf *from" +.Ft int +.Fn ibuf_add_h16 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_h32 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_h64 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_n16 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_n32 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_n64 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_n8 "struct ibuf *buf" "uint64_t value" +.Ft int +.Fn ibuf_add_zero "struct ibuf *buf" "size_t len" +.Ft void +.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf" +.Ft "void *" +.Fn ibuf_data "struct ibuf *buf" +.Ft "struct ibuf *" +.Fn ibuf_dynamic "size_t len" "size_t max" +.Ft int +.Fn ibuf_fd_avail "struct ibuf *buf" +.Ft int +.Fn ibuf_fd_get "struct ibuf *buf" +.Ft void +.Fn ibuf_fd_set "struct ibuf *buf" "int fd" +.Ft void +.Fn ibuf_free "struct ibuf *buf" +.Ft void +.Fn ibuf_from_buffer "struct ibuf *buf" "void *data" "size_t len" +.Ft void +.Fn ibuf_from_ibuf "struct ibuf *buf" "const ibuf *from" +.Ft int +.Fn ibuf_get "struct ibuf *buf" "void *data" "size_t len" +.Ft int +.Fn ibuf_get_ibuf "struct ibuf *buf" "size_t len" "struct ibuf *new" +.Ft int +.Fn ibuf_get_h16 "struct ibuf *buf" "uint16_t *value" +.Ft int +.Fn ibuf_get_h32 "struct ibuf *buf" "uint32_t *value" +.Ft int +.Fn ibuf_get_h64 "struct ibuf *buf" "uint64_t *value" +.Ft int +.Fn ibuf_get_n16 "struct ibuf *buf" "uint16_t *value" +.Ft int +.Fn ibuf_get_n32 "struct ibuf *buf" "uint32_t *value" +.Ft int +.Fn ibuf_get_n64 "struct ibuf *buf" "uint64_t *value" +.Ft int +.Fn ibuf_get_n8 "struct ibuf *buf" "uint8_t *value" +.Ft size_t +.Fn ibuf_left "const struct ibuf *buf" +.Ft "struct ibuf *" +.Fn ibuf_open "size_t len" +.Ft "void *" +.Fn ibuf_reserve "struct ibuf *buf" "size_t len" +.Ft void +.Fn ibuf_rewind "struct ibuf *buf" +.Ft "void *" +.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len" +.Ft int +.Fn ibuf_set "struct ibuf *buf" "size_t pos" "const void *data" \ + "size_t len" +.Ft int +.Fn ibuf_set_h16 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft int +.Fn ibuf_set_h32 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft int +.Fn ibuf_set_h64 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft int +.Fn ibuf_set_n16 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft int +.Fn ibuf_set_n32 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft int +.Fn ibuf_set_n64 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft int +.Fn ibuf_set_n8 "struct ibuf *buf" "size_t pos" "uint64_t value" +.Ft size_t +.Fn ibuf_size "const struct ibuf *buf" +.Ft int +.Fn ibuf_skip "struct ibuf *buf" "size_t len" +.Ft int +.Fn ibuf_truncate "struct ibuf *buf" "size_t len" +.Ft int +.Fn ibuf_write "struct msgbuf *msgbuf" +.Ft void +.Fn msgbuf_init "struct msgbuf *msgbuf" +.Ft void +.Fn msgbuf_clear "struct msgbuf *msgbuf" +.Ft uint32_t +.Fn msgbuf_queuelen "struct msgbuf *msgbuf" +.Ft int +.Fn msgbuf_write "struct msgbuf *msgbuf" +.Sh DESCRIPTION +The ibuf API defines functions to manipulate buffers, used for example to +construct imsgs with +.Xr imsg_create 3 . +A +.Vt struct ibuf +is a single buffer. +It has a maximum size, a read and a write position. +Buffers should be either constructed with the various +.Fn ibuf_add +and +.Fn ibuf_set +functions or consumed with the various +.Fn ibuf_get +functions. +A +.Vt struct msgbuf +is used to queue the output buffers for transmission. +.Pp +.Fn ibuf_add +appends a block of data to +.Fa buf . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_add_ibuf +appends the buffer +.Fa from +to +.Fa buf . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_add_h16 , +.Fn ibuf_add_h32 , +and +.Fn ibuf_add_h64 +add a 2-byte, 4-byte, and 8-byte +.Fa value +to +.Fa buf +in host byte order. +This function checks +.Fa value +to not overflow. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_add_n8 , +.Fn ibuf_add_n16 , +.Fn ibuf_add_n32 , +and +.Fn ibuf_add_n64 +add a 1-byte, 2-byte, 4-byte, and 8-byte +.Fa value +to +.Fa buf +in network byte order. +This function checks +.Fa value +to not overflow. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_add_zero +appends a block of zeros to +.Fa buf . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_close +appends +.Fa buf +to +.Fa msgbuf +ready to be sent. +.Pp +.Fn ibuf_data +returns the pointer to the internal buffer. +This function should only be used together with +.Fn ibuf_size +to process a previously generated buffer. +.Pp +.Fn ibuf_dynamic +allocates a resizeable buffer of initial length +.Fa len +and maximum size +.Fa max . +Buffers allocated with +.Fn ibuf_dynamic +are automatically grown if necessary when data is added. +.Pp +.Fn ibuf_fd_avail , +.Fn ibuf_fd_get +and +.Fn ibuf_fd_set +are functions to check, get and set the file descriptor assigned to +.Fa buf . +After calling +.Fn ibuf_fd_set +the file descriptor is part of the +.Fa buf +and will be transmitted or closed by the ibuf API. +Any previously set file descriptor will be closed before assigning a +new descriptor. +.Fn ibuf_fd_get +returns the file descriptor and passes the responsibility to track the +descriptor back to the program. +.Fn ibuf_fd_avail +returns true if there is a file descriptor set on +.Fa buf . +.Pp +.Fn ibuf_free +frees +.Fa buf +and any associated storage, and closes any file descriptor set with +.Fn ibuf_fd_set . +If +.Fa buf +is a NULL pointer, no action occurs. +.Pp +.Fn ibuf_from_buffer +initializes the passed +.Fa buf +to point at +.Fa data +and spanning +.Fa len +bytes. +The returned buffer can be read using the various +.Fn ibuf_get +functions . +.Fn ibuf_from_ibuf +duplicates the +.Fa from +ibuf into +.Fa buf +without modifying +.Fa from . +This allows safely peeking into an ibuf without consuming data. +.Pp +.Fn ibuf_get +consumes a block of data from +.Fa buf +spanning +.Fa len +bytes. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_get_ibuf +consumes +.Fa len +bytes from the buffer +.Fa buf +and returns it in +.Fa new +covering this region. +The data in this buffer is only valid as long as +.Fa buf +remains valid . +There is no need to deallocate +.Fa new +using +.Fn ibuf_free . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_get_h16 , +.Fn ibuf_get_h32 , +and +.Fn ibuf_get_h64 +get a 2-byte, 4-byte, and 8-byte +.Fa value +from +.Fa buf +without altering byte order. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_get_n8 , +.Fn ibuf_get_n16 , +.Fn ibuf_get_n32 , +and +.Fn ibuf_get_n64 +get a 1-byte, 2-byte, 4-byte, and 8-byte +.Fa value +from +.Fa buf +converting the value from network to host byte order. +0 is returned on success and \-1 on failure. +.Pp +The +.Fn ibuf_open +function allocates a fixed-length buffer. +The buffer may not be resized and may contain a maximum of +.Fa len +bytes. +On success +.Fn ibuf_open +returns a pointer to the buffer; on failure it returns NULL. +.Pp +.Fn ibuf_reserve +is used to reserve +.Fa len +bytes in +.Fa buf . +A pointer to the start of the reserved space is returned, or NULL on error. +.Pp +.Fn ibuf_rewind +resets the read offset to the start of the buffer. +.Pp +.Fn ibuf_seek +returns a pointer to the part of the buffer at offset +.Fa pos +and of extent +.Fa len . +NULL is returned if the requested range is outside the part of the buffer +in use. +.Pp +.Fn ibuf_set +replaces a part of +.Fa buf +at offset +.Fa pos +with the +.Fa data +of extent +.Fa len . +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_set_h16 , +.Fn ibuf_set_h32 +and +.Fn ibuf_set_h64 +replace a 2-byte, 4-byte or 8-byte +.Fa value +at offset +.Fa pos +in the buffer +.Fa buf +in host byte order. +This function checks +.Fa value +to not overflow. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_set_n8 , +.Fn ibuf_set_n16 , +.Fn ibuf_set_n32 +and +.Fn ibuf_set_n64 +replace a 1-byte, 2-byte, 4-byte or 8-byte +.Fa value +at offset +.Fa pos +in the buffer +.Fa buf +in network byte order. +This function checks +.Fa value +to not overflow. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_size +and +.Fn ibuf_left +are functions which return the total bytes used and available in +.Fa buf , +respectively. +.Pp +.Fn ibuf_skip +advances the read position in +.Fa buf +by +.Fa len +bytes. +0 is returned on success and \-1 on failure. +.Pp +.Fn ibuf_truncate +truncates the buffer to +.Fa len +bytes if necessary zero extending the buffer. +0 is returned on success and \-1 on failure. +.Pp +The +.Fn ibuf_write +routine transmits as many pending buffers as possible from +.Fa msgbuf +using +.Xr writev 2 . +It returns 1 if it succeeds, \-1 on error and 0 when no buffers were +pending or an EOF condition on the socket is detected. +Temporary resource shortages are returned with errno +.Er EAGAIN +and require the application to retry again in the future. +.Pp +The +.Fn msgbuf_init +function initializes +.Fa msgbuf +so that buffers may be appended to it. +The +.Fa fd +member should also be set directly before +.Fn msgbuf_write +is used. +.Pp +.Fn msgbuf_clear +empties a msgbuf, removing and discarding any queued buffers. +.Pp +.Fn msgbuf_queuelen +returns the number of messages queued in +.Fa msgbuf . +This function returns 0 if no messages are pending for transmission. +.Pp +The +.Fn msgbuf_write +routine calls +.Xr sendmsg 2 +to transmit buffers queued in +.Fa msgbuf . +It returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty +or an EOF condition on the socket is detected. +Temporary resource shortages are returned with errno +.Er EAGAIN +and require the application to retry again in the future. +.Sh SEE ALSO +.Xr socketpair 2 , +.Xr imsg_init 3 , +.Xr unix 4 diff --git a/lib/libutil/imsg-buffer.c b/lib/libutil/imsg-buffer.c index e54904226..0708f486e 100644 --- a/lib/libutil/imsg-buffer.c +++ b/lib/libutil/imsg-buffer.c @@ -1,6 +1,7 @@ -/* $OpenBSD: imsg-buffer.c,v 1.17 2023/10/24 14:05:23 claudio Exp $ */ +/* $OpenBSD: imsg-buffer.c,v 1.18 2023/12/12 15:47:41 claudio Exp $ */ /* + * Copyright (c) 2023 Claudio Jeker * Copyright (c) 2003, 2004 Henning Brauer * * Permission to use, copy, modify, and distribute this software for any @@ -24,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -61,7 +63,7 @@ ibuf_dynamic(size_t len, size_t max) { struct ibuf *buf; - if (max < len) { + if (max == 0 || max < len) { errno = EINVAL; return (NULL); } @@ -106,7 +108,7 @@ ibuf_reserve(struct ibuf *buf, size_t len) { void *b; - if (len > SIZE_MAX - buf->wpos) { + if (len > SIZE_MAX - buf->wpos || buf->max == 0) { errno = ERANGE; return (NULL); } @@ -117,7 +119,6 @@ ibuf_reserve(struct ibuf *buf, size_t len) b = buf->buf + buf->wpos; buf->wpos += len; - memset(b, 0, len); return (b); } @@ -133,10 +134,17 @@ ibuf_add(struct ibuf *buf, const void *data, size_t len) return (0); } +int +ibuf_add_ibuf(struct ibuf *buf, const struct ibuf *from) +{ + return ibuf_add(buf, ibuf_data(from), ibuf_size(from)); +} + +/* remove after tree is converted */ int ibuf_add_buf(struct ibuf *buf, const struct ibuf *from) { - return ibuf_add(buf, from->buf, from->wpos); + return ibuf_add_ibuf(buf, from); } int @@ -185,6 +193,38 @@ ibuf_add_n64(struct ibuf *buf, uint64_t value) return ibuf_add(buf, &value, sizeof(value)); } +int +ibuf_add_h16(struct ibuf *buf, uint64_t value) +{ + uint16_t v; + + if (value > UINT16_MAX) { + errno = EINVAL; + return (-1); + } + v = value; + return ibuf_add(buf, &v, sizeof(v)); +} + +int +ibuf_add_h32(struct ibuf *buf, uint64_t value) +{ + uint32_t v; + + if (value > UINT32_MAX) { + errno = EINVAL; + return (-1); + } + v = value; + return ibuf_add(buf, &v, sizeof(v)); +} + +int +ibuf_add_h64(struct ibuf *buf, uint64_t value) +{ + return ibuf_add(buf, &value, sizeof(value)); +} + int ibuf_add_zero(struct ibuf *buf, size_t len) { @@ -192,19 +232,21 @@ ibuf_add_zero(struct ibuf *buf, size_t len) if ((b = ibuf_reserve(buf, len)) == NULL) return (-1); + memset(b, 0, len); return (0); } void * ibuf_seek(struct ibuf *buf, size_t pos, size_t len) { - /* only allowed to seek in already written parts */ - if (len > SIZE_MAX - pos || pos + len > buf->wpos) { + /* only allow seeking between rpos and wpos */ + if (ibuf_size(buf) < pos || SIZE_MAX - pos < len || + ibuf_size(buf) < pos + len) { errno = ERANGE; return (NULL); } - return (buf->buf + pos); + return (buf->buf + buf->rpos + pos); } int @@ -265,35 +307,199 @@ ibuf_set_n64(struct ibuf *buf, size_t pos, uint64_t value) return (ibuf_set(buf, pos, &value, sizeof(value))); } +int +ibuf_set_h16(struct ibuf *buf, size_t pos, uint64_t value) +{ + uint16_t v; + + if (value > UINT16_MAX) { + errno = EINVAL; + return (-1); + } + v = value; + return (ibuf_set(buf, pos, &v, sizeof(v))); +} + +int +ibuf_set_h32(struct ibuf *buf, size_t pos, uint64_t value) +{ + uint32_t v; + + if (value > UINT32_MAX) { + errno = EINVAL; + return (-1); + } + v = value; + return (ibuf_set(buf, pos, &v, sizeof(v))); +} + +int +ibuf_set_h64(struct ibuf *buf, size_t pos, uint64_t value) +{ + return (ibuf_set(buf, pos, &value, sizeof(value))); +} + void * -ibuf_data(struct ibuf *buf) +ibuf_data(const struct ibuf *buf) { - return (buf->buf); + return (buf->buf + buf->rpos); } size_t -ibuf_size(struct ibuf *buf) +ibuf_size(const struct ibuf *buf) { - return (buf->wpos); + return (buf->wpos - buf->rpos); } size_t -ibuf_left(struct ibuf *buf) +ibuf_left(const struct ibuf *buf) { + if (buf->max == 0) + return (0); return (buf->max - buf->wpos); } +int +ibuf_truncate(struct ibuf *buf, size_t len) +{ + if (ibuf_size(buf) >= len) { + buf->wpos = buf->rpos + len; + return (0); + } + if (buf->max == 0) { + /* only allow to truncate down */ + errno = ERANGE; + return (-1); + } + return ibuf_add_zero(buf, len - ibuf_size(buf)); +} + +void +ibuf_rewind(struct ibuf *buf) +{ + buf->rpos = 0; +} + void ibuf_close(struct msgbuf *msgbuf, struct ibuf *buf) { ibuf_enqueue(msgbuf, buf); } +void +ibuf_from_buffer(struct ibuf *buf, void *data, size_t len) +{ + memset(buf, 0, sizeof(*buf)); + buf->buf = data; + buf->size = buf->wpos = len; + buf->fd = -1; +} + +void +ibuf_from_ibuf(struct ibuf *buf, const struct ibuf *from) +{ + ibuf_from_buffer(buf, ibuf_data(from), ibuf_size(from)); +} + +int +ibuf_get(struct ibuf *buf, void *data, size_t len) +{ + if (ibuf_size(buf) < len) { + errno = EBADMSG; + return (-1); + } + + memcpy(data, ibuf_data(buf), len); + buf->rpos += len; + return (0); +} + +int +ibuf_get_ibuf(struct ibuf *buf, size_t len, struct ibuf *new) +{ + if (ibuf_size(buf) < len) { + errno = EBADMSG; + return (-1); + } + + ibuf_from_buffer(new, ibuf_data(buf), len); + buf->rpos += len; + return (0); +} + +int +ibuf_get_n8(struct ibuf *buf, uint8_t *value) +{ + return ibuf_get(buf, value, sizeof(*value)); +} + +int +ibuf_get_n16(struct ibuf *buf, uint16_t *value) +{ + int rv; + + rv = ibuf_get(buf, value, sizeof(*value)); + *value = be16toh(*value); + return (rv); +} + +int +ibuf_get_n32(struct ibuf *buf, uint32_t *value) +{ + int rv; + + rv = ibuf_get(buf, value, sizeof(*value)); + *value = be32toh(*value); + return (rv); +} + +int +ibuf_get_n64(struct ibuf *buf, uint64_t *value) +{ + int rv; + + rv = ibuf_get(buf, value, sizeof(*value)); + *value = be64toh(*value); + return (rv); +} + +int +ibuf_get_h16(struct ibuf *buf, uint16_t *value) +{ + return ibuf_get(buf, value, sizeof(*value)); +} + +int +ibuf_get_h32(struct ibuf *buf, uint32_t *value) +{ + return ibuf_get(buf, value, sizeof(*value)); +} + +int +ibuf_get_h64(struct ibuf *buf, uint64_t *value) +{ + return ibuf_get(buf, value, sizeof(*value)); +} + +int +ibuf_skip(struct ibuf *buf, size_t len) +{ + if (ibuf_size(buf) < len) { + errno = EBADMSG; + return (-1); + } + + buf->rpos += len; + return (0); +} + void ibuf_free(struct ibuf *buf) { if (buf == NULL) return; + if (buf->max == 0) /* if buf lives on the stack */ + abort(); /* abort before causing more harm */ if (buf->fd != -1) close(buf->fd); freezero(buf->buf, buf->size); @@ -319,6 +525,8 @@ ibuf_fd_get(struct ibuf *buf) void ibuf_fd_set(struct ibuf *buf, int fd) { + if (buf->max == 0) /* if buf lives on the stack */ + abort(); /* abort before causing more harm */ if (buf->fd != -1) close(buf->fd); buf->fd = fd; @@ -336,8 +544,8 @@ ibuf_write(struct msgbuf *msgbuf) TAILQ_FOREACH(buf, &msgbuf->bufs, entry) { if (i >= IOV_MAX) break; - iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->wpos - buf->rpos; + iov[i].iov_base = ibuf_data(buf); + iov[i].iov_len = ibuf_size(buf); i++; } @@ -376,8 +584,8 @@ msgbuf_drain(struct msgbuf *msgbuf, size_t n) for (buf = TAILQ_FIRST(&msgbuf->bufs); buf != NULL && n > 0; buf = next) { next = TAILQ_NEXT(buf, entry); - if (n >= buf->wpos - buf->rpos) { - n -= buf->wpos - buf->rpos; + if (n >= ibuf_size(buf)) { + n -= ibuf_size(buf); ibuf_dequeue(msgbuf, buf); } else { buf->rpos += n; @@ -417,8 +625,8 @@ msgbuf_write(struct msgbuf *msgbuf) break; if (i > 0 && buf->fd != -1) break; - iov[i].iov_base = buf->buf + buf->rpos; - iov[i].iov_len = buf->wpos - buf->rpos; + iov[i].iov_base = ibuf_data(buf); + iov[i].iov_len = ibuf_size(buf); i++; if (buf->fd != -1) buf0 = buf; @@ -465,9 +673,17 @@ again: return (1); } +uint32_t +msgbuf_queuelen(struct msgbuf *msgbuf) +{ + return (msgbuf->queued); +} + static void ibuf_enqueue(struct msgbuf *msgbuf, struct ibuf *buf) { + if (buf->max == 0) /* if buf lives on the stack */ + abort(); /* abort before causing more harm */ TAILQ_INSERT_TAIL(&msgbuf->bufs, buf, entry); msgbuf->queued++; } @@ -476,7 +692,6 @@ static void ibuf_dequeue(struct msgbuf *msgbuf, struct ibuf *buf) { TAILQ_REMOVE(&msgbuf->bufs, buf, entry); - msgbuf->queued--; ibuf_free(buf); } diff --git a/lib/libutil/imsg.c b/lib/libutil/imsg.c index b6cc37ee1..0aff226bf 100644 --- a/lib/libutil/imsg.c +++ b/lib/libutil/imsg.c @@ -1,6 +1,7 @@ -/* $OpenBSD: imsg.c,v 1.22 2023/11/18 07:14:13 claudio Exp $ */ +/* $OpenBSD: imsg.c,v 1.23 2023/12/12 15:47:41 claudio Exp $ */ /* + * Copyright (c) 2023 Claudio Jeker * Copyright (c) 2003, 2004 Henning Brauer * * Permission to use, copy, modify, and distribute this software for any @@ -28,6 +29,11 @@ #include "imsg.h" +struct imsg_fd { + TAILQ_ENTRY(imsg_fd) entry; + int fd; +}; + int imsg_fd_overhead = 0; static int imsg_dequeue_fd(struct imsgbuf *); @@ -123,6 +129,7 @@ fail: ssize_t imsg_get(struct imsgbuf *imsgbuf, struct imsg *imsg) { + struct imsg m; size_t av, left, datalen; av = imsgbuf->r.wpos; @@ -130,42 +137,108 @@ imsg_get(struct imsgbuf *imsgbuf, struct imsg *imsg) if (IMSG_HEADER_SIZE > av) return (0); - memcpy(&imsg->hdr, imsgbuf->r.buf, sizeof(imsg->hdr)); - if (imsg->hdr.len < IMSG_HEADER_SIZE || - imsg->hdr.len > MAX_IMSGSIZE) { + memcpy(&m.hdr, imsgbuf->r.buf, sizeof(m.hdr)); + if (m.hdr.len < IMSG_HEADER_SIZE || + m.hdr.len > MAX_IMSGSIZE) { errno = ERANGE; return (-1); } - if (imsg->hdr.len > av) + if (m.hdr.len > av) return (0); - datalen = imsg->hdr.len - IMSG_HEADER_SIZE; + + m.fd = -1; + m.buf = NULL; + m.data = NULL; + + datalen = m.hdr.len - IMSG_HEADER_SIZE; imsgbuf->r.rptr = imsgbuf->r.buf + IMSG_HEADER_SIZE; - if (datalen == 0) - imsg->data = NULL; - else if ((imsg->data = malloc(datalen)) == NULL) - return (-1); + if (datalen != 0) { + if ((m.buf = ibuf_open(datalen)) == NULL) + return (-1); + if (ibuf_add(m.buf, imsgbuf->r.rptr, datalen) == -1) { + /* this should never fail */ + ibuf_free(m.buf); + return (-1); + } + m.data = ibuf_data(m.buf); + } - if (imsg->hdr.flags & IMSGF_HASFD) - imsg->fd = imsg_dequeue_fd(imsgbuf); - else - imsg->fd = -1; + if (m.hdr.flags & IMSGF_HASFD) + m.fd = imsg_dequeue_fd(imsgbuf); - if (datalen != 0) - memcpy(imsg->data, imsgbuf->r.rptr, datalen); - - if (imsg->hdr.len < av) { - left = av - imsg->hdr.len; - memmove(&imsgbuf->r.buf, imsgbuf->r.buf + imsg->hdr.len, left); + if (m.hdr.len < av) { + left = av - m.hdr.len; + memmove(&imsgbuf->r.buf, imsgbuf->r.buf + m.hdr.len, left); imsgbuf->r.wpos = left; } else imsgbuf->r.wpos = 0; + *imsg = m; return (datalen + IMSG_HEADER_SIZE); } +int +imsg_get_ibuf(struct imsg *imsg, struct ibuf *ibuf) +{ + if (imsg->buf == NULL) { + errno = EBADMSG; + return (-1); + } + return ibuf_get_ibuf(imsg->buf, ibuf_size(imsg->buf), ibuf); +} + +int +imsg_get_data(struct imsg *imsg, void *data, size_t len) +{ + if (len == 0) { + errno = EINVAL; + return (-1); + } + if (imsg->buf == NULL || ibuf_size(imsg->buf) != len) { + errno = EBADMSG; + return (-1); + } + return ibuf_get(imsg->buf, data, len); +} + +int +imsg_get_fd(struct imsg *imsg) +{ + int fd = imsg->fd; + + imsg->fd = -1; + return fd; +} + +uint32_t +imsg_get_id(struct imsg *imsg) +{ + return (imsg->hdr.peerid); +} + +size_t +imsg_get_len(struct imsg *imsg) +{ + if (imsg->buf == NULL) + return 0; + return ibuf_size(imsg->buf); +} + +pid_t +imsg_get_pid(struct imsg *imsg) +{ + return (imsg->hdr.pid); +} + +uint32_t +imsg_get_type(struct imsg *imsg) +{ + return (imsg->hdr.type); +} + int imsg_compose(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid, - int fd, const void *data, uint16_t datalen) + int fd, const void *data, size_t datalen) { struct ibuf *wbuf; @@ -186,7 +259,8 @@ imsg_composev(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid, int fd, const struct iovec *iov, int iovcnt) { struct ibuf *wbuf; - int i, datalen = 0; + int i; + size_t datalen = 0; for (i = 0; i < iovcnt; i++) datalen += iov[i].iov_len; @@ -204,11 +278,15 @@ imsg_composev(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid, return (1); } +/* + * Enqueue imsg with payload from ibuf buf. fd passing is not possible + * with this function. + */ int imsg_compose_ibuf(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid, struct ibuf *buf) { - struct ibuf *wbuf = NULL; + struct ibuf *hdrbuf = NULL; struct imsg_hdr hdr; int save_errno; @@ -224,26 +302,60 @@ imsg_compose_ibuf(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, if ((hdr.pid = pid) == 0) hdr.pid = imsgbuf->pid; - if ((wbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL) + if ((hdrbuf = ibuf_open(IMSG_HEADER_SIZE)) == NULL) goto fail; - if (imsg_add(wbuf, &hdr, sizeof(hdr)) == -1) + if (imsg_add(hdrbuf, &hdr, sizeof(hdr)) == -1) goto fail; - ibuf_close(&imsgbuf->w, wbuf); + ibuf_close(&imsgbuf->w, hdrbuf); ibuf_close(&imsgbuf->w, buf); return (1); fail: save_errno = errno; ibuf_free(buf); - ibuf_free(wbuf); + ibuf_free(hdrbuf); errno = save_errno; return (-1); } +/* + * Forward imsg to another channel. Any attached fd is closed. + */ +int +imsg_forward(struct imsgbuf *imsgbuf, struct imsg *msg) +{ + struct ibuf *wbuf; + size_t len = 0; + + if (msg->fd != -1) { + close(msg->fd); + msg->fd = -1; + } + + if (msg->buf != NULL) { + ibuf_rewind(msg->buf); + len = ibuf_size(msg->buf); + } + + if ((wbuf = imsg_create(imsgbuf, msg->hdr.type, msg->hdr.peerid, + msg->hdr.pid, len)) == NULL) + return (-1); + + if (msg->buf != NULL) { + if (ibuf_add_buf(wbuf, msg->buf) == -1) { + ibuf_free(wbuf); + return (-1); + } + } + + imsg_close(imsgbuf, wbuf); + return (1); +} + struct ibuf * imsg_create(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid, - uint16_t datalen) + size_t datalen) { struct ibuf *wbuf; struct imsg_hdr hdr; @@ -269,7 +381,7 @@ imsg_create(struct imsgbuf *imsgbuf, uint32_t type, uint32_t id, pid_t pid, } int -imsg_add(struct ibuf *msg, const void *data, uint16_t datalen) +imsg_add(struct ibuf *msg, const void *data, size_t datalen) { if (datalen) if (ibuf_add(msg, data, datalen) == -1) { @@ -297,7 +409,7 @@ imsg_close(struct imsgbuf *imsgbuf, struct ibuf *msg) void imsg_free(struct imsg *imsg) { - freezero(imsg->data, imsg->hdr.len - IMSG_HEADER_SIZE); + ibuf_free(imsg->buf); } static int diff --git a/lib/libutil/imsg.h b/lib/libutil/imsg.h index fb516e302..dd47b1889 100644 --- a/lib/libutil/imsg.h +++ b/lib/libutil/imsg.h @@ -1,6 +1,7 @@ -/* $OpenBSD: imsg.h,v 1.7 2023/06/19 17:19:50 claudio Exp $ */ +/* $OpenBSD: imsg.h,v 1.8 2023/12/12 15:47:41 claudio Exp $ */ /* + * Copyright (c) 2023 Claudio Jeker * Copyright (c) 2006, 2007 Pierre-Yves Ritschard * Copyright (c) 2006, 2007, 2008 Reyk Floeter * Copyright (c) 2003, 2004 Henning Brauer @@ -21,7 +22,7 @@ #ifndef _IMSG_H_ #define _IMSG_H_ -#include +#include #define IBUF_READ_SIZE 65535 #define IMSG_HEADER_SIZE sizeof(struct imsg_hdr) @@ -49,11 +50,7 @@ struct ibuf_read { size_t wpos; }; -struct imsg_fd { - TAILQ_ENTRY(imsg_fd) entry; - int fd; -}; - +struct imsg_fd; struct imsgbuf { TAILQ_HEAD(, imsg_fd) fds; struct ibuf_read r; @@ -76,6 +73,7 @@ struct imsg { struct imsg_hdr hdr; int fd; void *data; + struct ibuf *buf; }; struct iovec; @@ -85,11 +83,15 @@ struct ibuf *ibuf_open(size_t); struct ibuf *ibuf_dynamic(size_t, size_t); int ibuf_add(struct ibuf *, const void *, size_t); int ibuf_add_buf(struct ibuf *, const struct ibuf *); +int ibuf_add_ibuf(struct ibuf *, const struct ibuf *); int ibuf_add_zero(struct ibuf *, size_t); int ibuf_add_n8(struct ibuf *, uint64_t); int ibuf_add_n16(struct ibuf *, uint64_t); int ibuf_add_n32(struct ibuf *, uint64_t); int ibuf_add_n64(struct ibuf *, uint64_t); +int ibuf_add_h16(struct ibuf *, uint64_t); +int ibuf_add_h32(struct ibuf *, uint64_t); +int ibuf_add_h64(struct ibuf *, uint64_t); void *ibuf_reserve(struct ibuf *, size_t); void *ibuf_seek(struct ibuf *, size_t, size_t); int ibuf_set(struct ibuf *, size_t, const void *, size_t); @@ -97,10 +99,27 @@ int ibuf_set_n8(struct ibuf *, size_t, uint64_t); int ibuf_set_n16(struct ibuf *, size_t, uint64_t); int ibuf_set_n32(struct ibuf *, size_t, uint64_t); int ibuf_set_n64(struct ibuf *, size_t, uint64_t); -void *ibuf_data(struct ibuf *); -size_t ibuf_size(struct ibuf *); -size_t ibuf_left(struct ibuf *); +int ibuf_set_h16(struct ibuf *, size_t, uint64_t); +int ibuf_set_h32(struct ibuf *, size_t, uint64_t); +int ibuf_set_h64(struct ibuf *, size_t, uint64_t); +void *ibuf_data(const struct ibuf *); +size_t ibuf_size(const struct ibuf *); +size_t ibuf_left(const struct ibuf *); +int ibuf_truncate(struct ibuf *, size_t); +void ibuf_rewind(struct ibuf *); void ibuf_close(struct msgbuf *, struct ibuf *); +void ibuf_from_buffer(struct ibuf *, void *, size_t); +void ibuf_from_ibuf(struct ibuf *, const struct ibuf *); +int ibuf_get(struct ibuf *, void *, size_t); +int ibuf_get_ibuf(struct ibuf *, size_t, struct ibuf *); +int ibuf_get_n8(struct ibuf *, uint8_t *); +int ibuf_get_n16(struct ibuf *, uint16_t *); +int ibuf_get_n32(struct ibuf *, uint32_t *); +int ibuf_get_n64(struct ibuf *, uint64_t *); +int ibuf_get_h16(struct ibuf *, uint16_t *); +int ibuf_get_h32(struct ibuf *, uint32_t *); +int ibuf_get_h64(struct ibuf *, uint64_t *); +int ibuf_skip(struct ibuf *, size_t); void ibuf_free(struct ibuf *); int ibuf_fd_avail(struct ibuf *); int ibuf_fd_get(struct ibuf *); @@ -108,20 +127,29 @@ void ibuf_fd_set(struct ibuf *, int); int ibuf_write(struct msgbuf *); void msgbuf_init(struct msgbuf *); void msgbuf_clear(struct msgbuf *); +uint32_t msgbuf_queuelen(struct msgbuf *); int msgbuf_write(struct msgbuf *); /* imsg.c */ void imsg_init(struct imsgbuf *, int); ssize_t imsg_read(struct imsgbuf *); ssize_t imsg_get(struct imsgbuf *, struct imsg *); +int imsg_get_ibuf(struct imsg *, struct ibuf *); +int imsg_get_data(struct imsg *, void *, size_t); +int imsg_get_fd(struct imsg *); +uint32_t imsg_get_id(struct imsg *); +size_t imsg_get_len(struct imsg *); +pid_t imsg_get_pid(struct imsg *); +uint32_t imsg_get_type(struct imsg *); +int imsg_forward(struct imsgbuf *, struct imsg *); int imsg_compose(struct imsgbuf *, uint32_t, uint32_t, pid_t, int, - const void *, uint16_t); + const void *, size_t); int imsg_composev(struct imsgbuf *, uint32_t, uint32_t, pid_t, int, const struct iovec *, int); int imsg_compose_ibuf(struct imsgbuf *, uint32_t, uint32_t, pid_t, struct ibuf *); -struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, uint16_t); -int imsg_add(struct ibuf *, const void *, uint16_t); +struct ibuf *imsg_create(struct imsgbuf *, uint32_t, uint32_t, pid_t, size_t); +int imsg_add(struct ibuf *, const void *, size_t); void imsg_close(struct imsgbuf *, struct ibuf *); void imsg_free(struct imsg *); int imsg_flush(struct imsgbuf *); diff --git a/lib/libutil/imsg_init.3 b/lib/libutil/imsg_init.3 index 3c6b96222..5b02f5a4a 100644 --- a/lib/libutil/imsg_init.3 +++ b/lib/libutil/imsg_init.3 @@ -1,5 +1,6 @@ -.\" $OpenBSD: imsg_init.3,v 1.30 2023/09/28 17:00:21 schwarze Exp $ +.\" $OpenBSD: imsg_init.3,v 1.31 2023/12/12 15:49:21 claudio Exp $ .\" +.\" Copyright (c) 2023 Claudio Jeker .\" Copyright (c) 2010 Nicholas Marriott .\" .\" Permission to use, copy, modify, and distribute this software for any @@ -14,50 +15,30 @@ .\" IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING .\" OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. .\" -.Dd $Mdocdate: September 28 2023 $ +.Dd $Mdocdate: December 12 2023 $ .Dt IMSG_INIT 3 .Os .Sh NAME .Nm imsg_init , .Nm imsg_read , .Nm imsg_get , +.Nm imsg_get_ibuf , +.Nm imsg_get_data , +.Nm imsg_get_fd , +.Nm imsg_get_id , +.Nm imsg_get_len , +.Nm imsg_get_pid , +.Nm imsg_get_type , .Nm imsg_compose , .Nm imsg_composev , .Nm imsg_compose_ibuf , .Nm imsg_create , .Nm imsg_add , .Nm imsg_close , +.Nm imsg_forward , .Nm imsg_free , .Nm imsg_flush , -.Nm imsg_clear , -.Nm ibuf_open , -.Nm ibuf_dynamic , -.Nm ibuf_add , -.Nm ibuf_add_buf , -.Nm ibuf_add_n8 , -.Nm ibuf_add_n16 , -.Nm ibuf_add_n32 , -.Nm ibuf_add_n64 , -.Nm ibuf_add_zero , -.Nm ibuf_reserve , -.Nm ibuf_seek , -.Nm ibuf_set , -.Nm ibuf_set_n8 , -.Nm ibuf_set_n16 , -.Nm ibuf_set_n32 , -.Nm ibuf_set_n64 , -.Nm ibuf_data , -.Nm ibuf_size , -.Nm ibuf_left , -.Nm ibuf_close , -.Nm ibuf_free , -.Nm ibuf_fd_avail , -.Nm ibuf_fd_get , -.Nm ibuf_fd_set , -.Nm ibuf_write , -.Nm msgbuf_init , -.Nm msgbuf_clear , -.Nm msgbuf_write +.Nm imsg_clear .Nd IPC messaging functions .Sh SYNOPSIS .In sys/types.h @@ -66,90 +47,49 @@ .In stdint.h .In imsg.h .Ft void -.Fn imsg_init "struct imsgbuf *ibuf" "int fd" +.Fn imsg_init "struct imsgbuf *imsgbuf" "int fd" .Ft ssize_t -.Fn imsg_read "struct imsgbuf *ibuf" +.Fn imsg_read "struct imsgbuf *imsgbuf" .Ft ssize_t -.Fn imsg_get "struct imsgbuf *ibuf" "struct imsg *imsg" +.Fn imsg_get "struct imsgbuf *imsgbuf" "struct imsg *imsg" .Ft int -.Fn imsg_compose "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \ - "pid_t pid" "int fd" "const void *data" "uint16_t datalen" +.Fn imsg_get_ibuf "struct imsg *imsg" "struct ibuf *ibuf" .Ft int -.Fn imsg_composev "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \ +.Fn imsg_get_data "struct imsg *imsg" "void *data" "size_t len" +.Ft int +.Fn imsg_get_fd "struct imsg *imsg" +.Ft uint32_t +.Fn imsg_get_id "struct imsg *imsg" +.Ft size_t +.Fn imsg_get_len "struct imsg *imsg" +.Ft pid_t +.Fn imsg_get_pid "struct imsg *imsg" +.Ft uint32_t +.Fn imsg_get_type "struct imsg *imsg" +.Ft int +.Fn imsg_compose "struct imsgbuf *imsgbuf" "uint32_t type" "uint32_t id" \ + "pid_t pid" "int fd" "const void *data" "size_t datalen" +.Ft int +.Fn imsg_composev "struct imsgbuf *imsgbuf" "uint32_t type" "uint32_t id" \ "pid_t pid" "int fd" "const struct iovec *iov" "int iovcnt" .Ft int -.Fn imsg_compose_ibuf "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \ - "pid_t pid" "struct ibuf *buf" +.Fn imsg_compose_ibuf "struct imsgbuf *imsgbuf" "uint32_t type" \ + "uint32_t id" "pid_t pid" "struct ibuf *buf" .Ft "struct ibuf *" -.Fn imsg_create "struct imsgbuf *ibuf" "uint32_t type" "uint32_t peerid" \ - "pid_t pid" "uint16_t datalen" +.Fn imsg_create "struct imsgbuf *imsgbuf" "uint32_t type" "uint32_t id" \ + "pid_t pid" "size_t datalen" .Ft int -.Fn imsg_add "struct ibuf *msg" "const void *data" "uint16_t datalen" +.Fn imsg_add "struct ibuf *msg" "const void *data" "size_t datalen" .Ft void -.Fn imsg_close "struct imsgbuf *ibuf" "struct ibuf *msg" +.Fn imsg_close "struct imsgbuf *imsgbuf" "struct ibuf *msg" .Ft void .Fn imsg_free "struct imsg *imsg" .Ft int -.Fn imsg_flush "struct imsgbuf *ibuf" +.Fn imsg_forward "struct imsgbuf *imsgbuf" "struct imsg *msg" +.Ft int +.Fn imsg_flush "struct imsgbuf *imsgbuf" .Ft void -.Fn imsg_clear "struct imsgbuf *ibuf" -.Ft "struct ibuf *" -.Fn ibuf_open "size_t len" -.Ft "struct ibuf *" -.Fn ibuf_dynamic "size_t len" "size_t max" -.Ft int -.Fn ibuf_add "struct ibuf *buf" "const void *data" "size_t len" -.Ft int -.Fn ibuf_add_buf "struct ibuf *buf" "const struct ibuf *from" -.Ft int -.Fn ibuf_add_n8 "struct ibuf *buf" "uint64_t value" -.Ft int -.Fn ibuf_add_n16 "struct ibuf *buf" "uint64_t value" -.Ft int -.Fn ibuf_add_n32 "struct ibuf *buf" "uint64_t value" -.Ft int -.Fn ibuf_add_n64 "struct ibuf *buf" "uint64_t value" -.Ft int -.Fn ibuf_add_zero "struct ibuf *buf" "size_t len" -.Ft "void *" -.Fn ibuf_reserve "struct ibuf *buf" "size_t len" -.Ft "void *" -.Fn ibuf_seek "struct ibuf *buf" "size_t pos" "size_t len" -.Ft int -.Fn ibuf_set "struct ibuf *buf" "size_t pos" "const void *data" \ - "size_t len" -.Ft int -.Fn ibuf_set_n8 "struct ibuf *buf" "size_t pos" "uint64_t value" -.Ft int -.Fn ibuf_set_n16 "struct ibuf *buf" "size_t pos" "uint64_t value" -.Ft int -.Fn ibuf_set_n32 "struct ibuf *buf" "size_t pos" "uint64_t value" -.Ft int -.Fn ibuf_set_n64 "struct ibuf *buf" "size_t pos" "uint64_t value" -.Ft "void *" -.Fn ibuf_data "struct ibuf *buf" -.Ft size_t -.Fn ibuf_size "struct ibuf *buf" -.Ft size_t -.Fn ibuf_left "struct ibuf *buf" -.Ft void -.Fn ibuf_close "struct msgbuf *msgbuf" "struct ibuf *buf" -.Ft void -.Fn ibuf_free "struct ibuf *buf" -.Ft int -.Fn ibuf_fd_avail "struct ibuf *buf" -.Ft int -.Fn ibuf_fd_get "struct ibuf *buf" -.Ft void -.Fn ibuf_fd_set "struct ibuf *buf" "int fd" -.Ft int -.Fn ibuf_write "struct msgbuf *msgbuf" -.Ft void -.Fn msgbuf_init "struct msgbuf *msgbuf" -.Ft void -.Fn msgbuf_clear "struct msgbuf *msgbuf" -.Ft int -.Fn msgbuf_write "struct msgbuf *msgbuf" +.Fn imsg_clear "struct imsgbuf *imsgbuf" .Sh DESCRIPTION The .Nm imsg @@ -181,7 +121,7 @@ struct imsgbuf { .Pp .Fn imsg_init initializes -.Fa ibuf +.Fa imsgbuf as one side of a channel associated with .Fa fd . The file descriptor is used to send and receive messages, @@ -208,7 +148,7 @@ imsgbuf. .Fn imsg_create creates a new message with header specified by .Fa type , -.Fa peerid +.Fa id and .Fa pid . A @@ -216,7 +156,7 @@ A of zero uses the process ID returned by .Xr getpid 2 when -.Fa ibuf +.Fa imsgbuf was initialized. In addition to this common imsg header, .Fa datalen @@ -242,7 +182,7 @@ is freed and \-1 is returned. completes creation of .Fa msg by adding it to -.Fa ibuf +.Fa imsgbuf output buffer. .Pp .Fn imsg_compose @@ -281,6 +221,13 @@ In either case the buffer .Fa buf is consumed by the function. .Pp +.Fn imsg_forward +forwards a just received +.Fa msg +unaltered on +.Fa imsgbuf . +Any attached filedescriptor is closed. +.Pp .Fn imsg_flush calls .Fn msgbuf_write @@ -313,268 +260,54 @@ Received messages are returned as a which must be freed by .Fn imsg_free when no longer required. -.Em struct imsg -has this form: -.Bd -literal -offset indent -struct imsg { - struct imsg_hdr hdr; - int fd; - void *data; -}; - -struct imsg_hdr { - uint32_t type; - uint16_t len; - uint16_t flags; - uint32_t peerid; - uint32_t pid; -}; -.Ed .Pp -The header members are: -.Bl -tag -width Ds -offset indent -.It type -A integer identifier, typically used to express the meaning of the message. -.It len -The total length of the imsg, including the header and any ancillary data -transmitted with the message (pointed to by the -.Em data -member of the message itself). -.It flags -Flags used internally by the imsg functions: should not be used by application -programs. -.It peerid, pid -32-bit values specified on message creation and free for any use by the -caller, normally used to identify the message sender. -.El +The accessors +.Fn imsg_get_type , +.Fn imsg_get_pid , +.Fn imsg_get_id , +and +.Fn imsg_get_len , +return the +.Fa type , +.Fa pid , +.Fa id , +and payload length used in +.Fn imsg_create +to build the +.Fa imsg . +If there is no payload +.Fn imsg_get_len +returns 0. .Pp -In addition, -.Em struct imsg -has the following: -.Bl -tag -width Ds -offset indent -.It fd -The file descriptor specified when the message was created and passed using the -socket control message API, or \-1 if no file descriptor was sent. -.It data -A pointer to the ancillary data transmitted with the imsg. -.El +.Fn imsg_get_fd +returns the file descriptor and passes the responsibility to track the +descriptor back to the program. .Pp -The IMSG_HEADER_SIZE define is the size of the imsg message header, which -may be subtracted from the -.Fa len -member of -.Em struct imsg_hdr -to obtain the length of any additional data passed with the message. +.Fn imsg_get_data +and +.Fn imsg_get_ibuf +are used to extract the payload of an +.Fa imsg . +.Fn imsg_get_data +can be used if the structure of the payload is known and can be extracted +in one go. +0 is returned on success and \-1 on failure. +.Fn imsg_get_ibuf +initializes the passed +.Fa ibuf +to hold the payload which can be read using +.Xr ibuf_get 3 . +The +.Fa ibuf +remains valid until +.Fn imsg_free +is called and there is no need to call +.Fn ibuf_free +on this stack based buffer. +The function returns 0 on success, \-1 otherwise. .Pp MAX_IMSGSIZE is defined as the maximum size of a single imsg, currently 16384 bytes. -.Sh BUFFERS -The imsg API defines functions to manipulate buffers, used internally and during -construction of imsgs with -.Fn imsg_create . -A -.Em struct ibuf -is a single buffer and a -.Em struct msgbuf -a queue of output buffers for transmission: -.Bd -literal -offset indent -struct ibuf { - TAILQ_ENTRY(ibuf) entry; - unsigned char *buf; - size_t size; - size_t max; - size_t wpos; - size_t rpos; - int fd; -}; - -struct msgbuf { - TAILQ_HEAD(, ibuf) bufs; - uint32_t queued; - int fd; -}; -.Ed -.Pp -The -.Fn ibuf_open -function allocates a fixed-length buffer. -The buffer may not be resized and may contain a maximum of -.Fa len -bytes. -On success -.Fn ibuf_open -returns a pointer to the buffer; on failure it returns NULL. -.Pp -.Fn ibuf_dynamic -allocates a resizeable buffer of initial length -.Fa len -and maximum size -.Fa max . -Buffers allocated with -.Fn ibuf_dynamic -are automatically grown if necessary when data is added. -.Pp -.Fn ibuf_add -appends a block of data to -.Fa buf . -0 is returned on success and \-1 on failure. -.Pp -.Fn ibuf_add_buf -appends the buffer -.Fa from -to -.Fa buf . -0 is returned on success and \-1 on failure. -.Pp -.Fn ibuf_add_n8 , -.Fn ibuf_add_n16 , -.Fn ibuf_add_n32 , -and -.Fn ibuf_add_n64 -add a 1-byte, 2-byte, 4-byte, and 8-byte -.Fa value -to -.Fa buf -in network byte order. -This function checks -.Fa value -to not overflow. -0 is returned on success and \-1 on failure. -.Pp -.Fn ibuf_add_zero -appends a block of zeros to -.Fa buf . -0 is returned on success and \-1 on failure. -.Pp -.Fn ibuf_reserve -is used to reserve -.Fa len -bytes in -.Fa buf . -A pointer to the start of the reserved space is returned, or NULL on error. -.Pp -.Fn ibuf_seek -returns a pointer to the part of the buffer at offset -.Fa pos -and of extent -.Fa len . -NULL is returned if the requested range is outside the part of the buffer -in use. -.Pp -.Fn ibuf_set -replaces a part of -.Fa buf -at offset -.Fa pos -with the -.Fa data -of extent -.Fa len . -0 is returned on success and \-1 on failure. -.Pp -.Fn ibuf_set_n8 , -.Fn ibuf_set_n16 , -.Fn ibuf_set_n32 -and -.Fn ibuf_set_n64 -replace a 1-byte, 2-byte, 4-byte or 8-byte -.Fa value -at offset -.Fa pos -in the buffer -.Fa buf -in network byte order. -This function checks -.Fa value -to not overflow. -0 is returned on success and \-1 on failure. -.Pp -.Fn ibuf_data -returns the pointer to the internal buffer. -This function should only be used together with -.Fn ibuf_size -to process a previously generated buffer. -.Pp -.Fn ibuf_size -and -.Fn ibuf_left -are functions which return the total bytes used and available in -.Fa buf -respectively. -.Pp -.Fn ibuf_close -appends -.Fa buf -to -.Fa msgbuf -ready to be sent. -.Pp -.Fn ibuf_fd_avail , -.Fn ibuf_fd_get -and -.Fn ibuf_fd_set -are functions to check, get and set the file descriptor assigned to -.Fa buf . -After calling -.Fn ibuf_fd_set -the file descriptor is part of the -.Fa buf -and will be transmitted or closed by the ibuf API. -Any previously set file descriptor will be closed before assigning a -new descriptor. -.Fn ibuf_fd_get -returns the file descriptor and passes the responsibility to track the -descriptor back to the program. -.Fn ibuf_fd_avail -returns true if there is a file descriptor set on -.Fa buf . -.Pp -.Fn ibuf_free -frees -.Fa buf -and any associated storage, and closes any file descriptor set with -.Fn ibuf_fd_set . -If -.Fa buf -is a NULL pointer, no action occurs. -.Pp -The -.Fn ibuf_write -routine transmits as many pending buffers as possible from -.Fa msgbuf -using -.Xr writev 2 . -It returns 1 if it succeeds, \-1 on error and 0 when no buffers were -pending or an EOF condition on the socket is detected. -Temporary resource shortages are returned with errno -.Er EAGAIN -and require the application to retry again in the future. -.Pp -The -.Fn msgbuf_init -function initializes -.Fa msgbuf -so that buffers may be appended to it. -The -.Em fd -member should also be set directly before -.Fn msgbuf_write -is used. -.Pp -.Fn msgbuf_clear -empties a msgbuf, removing and discarding any queued buffers. -.Pp -The -.Fn msgbuf_write -routine calls -.Xr sendmsg 2 -to transmit buffers queued in -.Fa msgbuf . -It returns 1 if it succeeds, \-1 on error, and 0 when the queue was empty -or an EOF condition on the socket is detected. -Temporary resource shortages are returned with errno -.Er EAGAIN -and require the application to retry again in the future. .Sh EXAMPLES In a typical program, a channel between two processes is created with .Xr socketpair 2 , @@ -616,12 +349,12 @@ enum imsg_type { }; int -child_main(struct imsgbuf *ibuf) +child_main(struct imsgbuf *imsgbuf) { int idata; ... idata = 42; - imsg_compose(ibuf, IMSG_A_MESSAGE, + imsg_compose(imsgbuf, IMSG_A_MESSAGE, 0, 0, -1, &idata, sizeof idata); ... } @@ -635,7 +368,7 @@ library is used to monitor the socket file descriptor. When the socket is ready for writing, queued messages are transmitted with .Fn msgbuf_write : .Bd -literal -offset indent - if ((n = msgbuf_write(&ibuf-\*(Gtw)) == -1 && errno != EAGAIN) { + if ((n = msgbuf_write(&imsgbuf-\*(Gtw)) == -1 && errno != EAGAIN) { /* handle write failure */ } if (n == 0) { @@ -649,13 +382,13 @@ and then extracted with .Fn imsg_get : .Bd -literal -offset indent void -dispatch_imsg(struct imsgbuf *ibuf) +dispatch_imsg(struct imsgbuf *imsgbuf) { struct imsg imsg; - ssize_t n, datalen; + ssize_t n; int idata; - if ((n = imsg_read(ibuf)) == -1 && errno != EAGAIN) { + if ((n = imsg_read(imsgbuf)) == -1 && errno != EAGAIN) { /* handle read error */ } if (n == 0) { @@ -663,19 +396,18 @@ dispatch_imsg(struct imsgbuf *ibuf) } for (;;) { - if ((n = imsg_get(ibuf, &imsg)) == -1) { + if ((n = imsg_get(imsgbuf, &imsg)) == -1) { /* handle read error */ } if (n == 0) /* no more messages */ return; - datalen = imsg.hdr.len - IMSG_HEADER_SIZE; - switch (imsg.hdr.type) { + switch (imsg_get_type(&imsg)) { case IMSG_A_MESSAGE: - if (datalen \*(Lt sizeof idata) { + if (imsg_get_data(&imsg, &idata, + sizeof(idata)) == -1) { /* handle corrupt message */ } - memcpy(&idata, imsg.data, sizeof idata); /* handle message received */ break; ... @@ -687,4 +419,5 @@ dispatch_imsg(struct imsgbuf *ibuf) .Ed .Sh SEE ALSO .Xr socketpair 2 , +.Xr ibuf_add 3 , .Xr unix 4 diff --git a/lib/libutil/shlib_version b/lib/libutil/shlib_version index ffdd3d2d5..94727e17b 100644 --- a/lib/libutil/shlib_version +++ b/lib/libutil/shlib_version @@ -1,2 +1,2 @@ -major=17 +major=18 minor=0 diff --git a/libexec/ld.so/loader.c b/libexec/ld.so/loader.c index 52e7b03e9..016bfa336 100644 --- a/libexec/ld.so/loader.c +++ b/libexec/ld.so/loader.c @@ -1,4 +1,4 @@ -/* $OpenBSD: loader.c,v 1.214 2023/08/15 06:26:34 guenther Exp $ */ +/* $OpenBSD: loader.c,v 1.215 2023/12/12 15:44:00 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -466,6 +466,29 @@ _dl_self_relro(long loff) (((X) & PF_W) ? PROT_WRITE : 0) | \ (((X) & PF_X) ? PROT_EXEC : 0)) +/* + * To avoid kbind(2) becoming a powerful gadget, it is called inline to a + * function. Therefore we cannot create a precise pinsyscall label. Instead + * create a duplicate entry to force the kernel's pinsyscall code to skip + * validation, rather than labelling it illegal. kbind(2) remains safe + * because it self-protects by checking its calling address. + */ +#define __STRINGIFY(x) #x +#define STRINGIFY(x) __STRINGIFY(x) +#ifdef __arm__ +__asm__(".pushsection openbsd.syscalls,\"\",%progbits;" + ".p2align 2;" + ".long 0;" + ".long " STRINGIFY(SYS_kbind) ";" + ".popsection"); +#else +__asm__(".pushsection openbsd.syscalls,\"\",@progbits;" + ".long 0;" + ".p2align 2;" + ".long " STRINGIFY(SYS_kbind) ";" + ".popsection"); +#endif + /* * This is the dynamic loader entrypoint. When entering here, depending * on architecture type, the stack and registers are set up according diff --git a/libexec/ld.so/syscall.h b/libexec/ld.so/syscall.h index 6e9394d07..649fc240e 100644 --- a/libexec/ld.so/syscall.h +++ b/libexec/ld.so/syscall.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.h,v 1.4 2023/02/18 01:22:50 deraadt Exp $ */ +/* $OpenBSD: syscall.h,v 1.5 2023/12/12 17:39:14 deraadt Exp $ */ /* * Copyright (c) 1998 Per Fogelstrom, Opsycon AB @@ -56,7 +56,7 @@ int _dl_munmap(const void *, size_t); int _dl_mimmutable(const void *, size_t); int _dl_open(const char *, int); int _dl_pledge(const char *, const char **); -ssize_t _dl_read(int, const char *, size_t); +ssize_t _dl_read(int, void *, size_t); int _dl_sendsyslog(const char *, size_t, int); void _dl___set_tcb(void *); int _dl_sysctl(const int *, u_int, void *, size_t *, void *, size_t); diff --git a/sbin/iked/imsg_util.c b/sbin/iked/imsg_util.c index bf97af6f8..a008872cd 100644 --- a/sbin/iked/imsg_util.c +++ b/sbin/iked/imsg_util.c @@ -1,4 +1,4 @@ -/* $OpenBSD: imsg_util.c,v 1.21 2023/07/18 15:07:41 claudio Exp $ */ +/* $OpenBSD: imsg_util.c,v 1.22 2023/12/12 15:52:58 claudio Exp $ */ /* * Copyright (c) 2010-2013 Reyk Floeter @@ -80,13 +80,12 @@ ibuf_length(struct ibuf *buf) struct ibuf * ibuf_getdata(struct ibuf *buf, size_t len) { - void *data; + struct ibuf tmp; - if ((data = ibuf_seek(buf, buf->rpos, len)) == NULL) + if (ibuf_get_ibuf(buf, len, &tmp) == -1) return (NULL); - buf->rpos += len; - return (ibuf_new(data, len)); + return (ibuf_new(ibuf_data(&tmp), ibuf_size(&tmp))); } struct ibuf * diff --git a/sys/arch/amd64/amd64/locore.S b/sys/arch/amd64/amd64/locore.S index d1cc97d0a..a5f159561 100644 --- a/sys/arch/amd64/amd64/locore.S +++ b/sys/arch/amd64/amd64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.142 2023/12/10 16:56:01 deraadt Exp $ */ +/* $OpenBSD: locore.S,v 1.144 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: locore.S,v 1.13 2004/03/25 18:33:17 drochner Exp $ */ /* @@ -181,13 +181,10 @@ sigcodecall: syscall .globl sigcoderet sigcoderet: - movq $SYS_exit,%rax - syscall - _ALIGN_TRAPS + int3 1: JMP_RETPOLINE(rax) .globl esigcode esigcode: - .globl sigfill sigfill: int3 @@ -510,6 +507,7 @@ ENTRY(savectx) lfence END(savectx) +// XXX this should not behave like a nop IDTVEC(syscall32) sysret /* go away please */ END(Xsyscall32) diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c index 8fc51b396..bccc016f7 100644 --- a/sys/arch/amd64/amd64/trap.c +++ b/sys/arch/amd64/amd64/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.101 2023/07/05 12:58:55 kn Exp $ */ +/* $OpenBSD: trap.c,v 1.102 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: trap.c,v 1.2 2003/05/04 23:51:56 fvdl Exp $ */ /*- @@ -553,7 +553,7 @@ syscall(struct trapframe *frame) caddr_t params; const struct sysent *callp; struct proc *p; - int error, indirect = -1; + int error = ENOSYS; size_t argsize, argoff; register_t code, args[9], rval[2], *argp; @@ -570,26 +570,9 @@ syscall(struct trapframe *frame) argp = &args[0]; argoff = 0; - switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - indirect = code; - code = frame->tf_rdi; - argp = &args[1]; - argoff = 1; - break; - default: - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; - + if (code <= 0 || code >= SYS_MAXSYSCALL) + goto bad; + callp = sysent + code; argsize = (callp->sy_argsize >> 3) + argoff; if (argsize) { switch (MIN(argsize, 6)) { @@ -620,7 +603,7 @@ syscall(struct trapframe *frame) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, argp, rval); + error = mi_syscall(p, code, callp, argp, rval); switch (error) { case 0: diff --git a/sys/arch/arm/arm/sigcode.S b/sys/arch/arm/arm/sigcode.S index 35442f8f9..19995468e 100644 --- a/sys/arch/arm/arm/sigcode.S +++ b/sys/arch/arm/arm/sigcode.S @@ -1,4 +1,4 @@ -/* $OpenBSD: sigcode.S,v 1.13 2023/12/10 16:56:01 deraadt Exp $ */ +/* $OpenBSD: sigcode.S,v 1.14 2023/12/12 07:37:20 deraadt Exp $ */ /* $NetBSD: sigcode.S,v 1.6 2003/10/05 19:44:58 matt Exp $ */ /* @@ -63,14 +63,9 @@ sigcodecall: isb .globl sigcoderet sigcoderet: - /* Well if that failed we better exit quick ! */ - mov r12, #SYS_exit - swi 0 - dsb nsh - isb .global esigcode esigcode: - + /* FALLTHROUGH */ .globl sigfill sigfill: udf #0 diff --git a/sys/arch/arm/arm/syscall.c b/sys/arch/arm/arm/syscall.c index bf3bf2d2f..3879834e2 100644 --- a/sys/arch/arm/arm/syscall.c +++ b/sys/arch/arm/arm/syscall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.c,v 1.26 2023/02/11 23:07:26 deraadt Exp $ */ +/* $OpenBSD: syscall.c,v 1.27 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: syscall.c,v 1.24 2003/11/14 19:03:17 scw Exp $ */ /*- @@ -93,8 +93,8 @@ void swi_handler(trapframe_t *frame) { struct proc *p = curproc; - const struct sysent *callp; - int code, error, indirect = -1; + const struct sysent *callp = sysent; + int code, error; u_int nap = 4, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; @@ -103,31 +103,18 @@ swi_handler(trapframe_t *frame) /* Before enabling interrupts, save FPU state */ vfp_save(); - /* Re-enable interrupts if they were enabled previously */ - if (__predict_true((frame->tf_spsr & PSR_I) == 0)) - enable_interrupts(PSR_I); + enable_interrupts(PSR_I); p->p_addr->u_pcb.pcb_tf = frame; /* Skip over speculation-blocking barrier. */ frame->tf_pc += 8; - code = frame->tf_r12; - ap = &frame->tf_r0; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else + code = frame->tf_r12; + // XXX out of range stays on syscall0, which we assume is enosys + if (code >= 0 || code <= SYS_MAXSYSCALL) callp += code; nargs = callp->sy_argsize / sizeof(register_t); @@ -145,27 +132,23 @@ swi_handler(trapframe_t *frame) rval[0] = 0; rval[1] = frame->tf_r1; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_r0 = rval[0]; frame->tf_r1 = rval[1]; - frame->tf_spsr &= ~PSR_C; /* carry bit */ break; - case ERESTART: /* * Reconstruct the pc to point at the swi. */ frame->tf_pc -= 12; break; - case EJUSTRETURN: /* nothing to do */ break; - default: bad: frame->tf_r0 = error; diff --git a/sys/arch/arm64/arm64/locore.S b/sys/arch/arm64/arm64/locore.S index 51fbfff4f..6a5e76d4c 100644 --- a/sys/arch/arm64/arm64/locore.S +++ b/sys/arch/arm64/arm64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.44 2023/12/10 16:56:01 deraadt Exp $ */ +/* $OpenBSD: locore.S,v 1.45 2023/12/12 07:37:20 deraadt Exp $ */ /*- * Copyright (c) 2012-2014 Andrew Turner * All rights reserved. @@ -372,16 +372,10 @@ sigcodecall: isb .globl sigcoderet sigcoderet: - - /* sigreturn failed, exit */ - mov x8, #SYS_exit - svc 0 - dsb nsh - isb END(sigcode) .global esigcode esigcode: - + /* FALLTHROUGH */ .globl sigfill sigfill: udf #0 diff --git a/sys/arch/arm64/arm64/syscall.c b/sys/arch/arm64/arm64/syscall.c index 6efecdcc7..eec3777d2 100644 --- a/sys/arch/arm64/arm64/syscall.c +++ b/sys/arch/arm64/arm64/syscall.c @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall.c,v 1.14 2023/04/13 02:19:04 jsg Exp $ */ +/* $OpenBSD: syscall.c,v 1.15 2023/12/12 15:30:55 deraadt Exp $ */ /* * Copyright (c) 2015 Dale Rahn * @@ -33,7 +33,7 @@ svc_handler(trapframe_t *frame) { struct proc *p = curproc; const struct sysent *callp; - int code, error, indirect = -1; + int code, error = ENOSYS, indirect = -1; u_int nap = 8, nargs; register_t *ap, *args, copyargs[MAXARGS], rval[2]; @@ -50,20 +50,10 @@ svc_handler(trapframe_t *frame) ap = &frame->tf_x[0]; - switch (code) { - case SYS_syscall: - indirect = code; - code = *ap++; - nap--; - break; - } - - callp = sysent; if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else - callp += code; + goto bad; + callp = sysent + code; nargs = callp->sy_argsize / sizeof(register_t); if (nargs <= nap) { args = ap; @@ -79,25 +69,22 @@ svc_handler(trapframe_t *frame) rval[0] = 0; rval[1] = 0; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: frame->tf_x[0] = rval[0]; frame->tf_spsr &= ~PSR_C; /* carry bit */ break; - case ERESTART: /* * Reconstruct the pc to point at the svc. */ frame->tf_elr -= 12; break; - case EJUSTRETURN: /* nothing to do */ break; - default: bad: frame->tf_x[0] = error; diff --git a/sys/arch/i386/i386/locore.s b/sys/arch/i386/i386/locore.s index c3a749702..b25acfaab 100644 --- a/sys/arch/i386/i386/locore.s +++ b/sys/arch/i386/i386/locore.s @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.s,v 1.203 2023/12/10 16:56:01 deraadt Exp $ */ +/* $OpenBSD: locore.s,v 1.204 2023/12/12 07:37:20 deraadt Exp $ */ /* $NetBSD: locore.s,v 1.145 1996/05/03 19:41:19 christos Exp $ */ /*- @@ -346,11 +346,9 @@ sigcodecall: int $0x80 # enter kernel with args on stack .globl sigcoderet sigcoderet: - movl $SYS_exit,%eax - int $0x80 # exit if sigreturn fails .globl esigcode esigcode: - + /* FALLTHROUGH */ .globl sigfill sigfill: int3 diff --git a/sys/arch/i386/i386/trap.c b/sys/arch/i386/i386/trap.c index 8208c89ff..69860df90 100644 --- a/sys/arch/i386/i386/trap.c +++ b/sys/arch/i386/i386/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.162 2023/04/16 06:43:49 jsg Exp $ */ +/* $OpenBSD: trap.c,v 1.163 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: trap.c,v 1.95 1996/05/05 06:50:02 mycroft Exp $ */ /*- @@ -516,9 +516,9 @@ void syscall(struct trapframe *frame) { caddr_t params; - const struct sysent *callp; - struct proc *p; - int error, indirect = -1; + const struct sysent *callp = sysent; + struct proc *p = curproc; + int error; register_t code, args[8], rval[2]; #ifdef DIAGNOSTIC int ocpl = lapic_tpr; @@ -540,38 +540,22 @@ syscall(struct trapframe *frame) } #endif - p = curproc; p->p_md.md_regs = frame; + code = frame->tf_eax; - - params = (caddr_t)frame->tf_esp + sizeof(int); - - switch (code) { - case SYS_syscall: - /* - * Code is first argument, followed by actual args. - */ - indirect = code; - copyin(params, &code, sizeof(int)); - params += sizeof(int); - break; - default: - break; - } - - callp = sysent; - if (code < 0 || code >= SYS_MAXSYSCALL) - callp += SYS_syscall; - else + // XXX out of range stays on syscall0, which we assume is enosys + if (code >= 0 || code <= SYS_MAXSYSCALL) callp += code; + argsize = callp->sy_argsize; + params = (caddr_t)frame->tf_esp + sizeof(int); if (argsize && (error = copyin(params, args, argsize))) goto bad; rval[0] = 0; rval[1] = frame->tf_edx; - error = mi_syscall(p, code, indirect, callp, args, rval); + error = mi_syscall(p, code, callp, args, rval); switch (error) { case 0: diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index e06170a9a..4d6e0ff72 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,10 +1,10 @@ -/* $OpenBSD: init_sysent.c,v 1.271 2023/12/10 16:59:51 deraadt Exp $ */ +/* $OpenBSD: init_sysent.c,v 1.272 2023/12/12 15:32:59 deraadt Exp $ */ /* * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.253 2023/12/10 16:59:09 deraadt Exp + * created from; OpenBSD: syscalls.master,v 1.254 2023/12/12 15:30:55 deraadt Exp */ #include @@ -18,7 +18,7 @@ const struct sysent sysent[] = { { 0, 0, 0, - sys_nosys }, /* 0 = syscall (indir) */ + sys_nosys }, /* 0 = unimplemented syscall */ { 1, s(struct sys_exit_args), 0, sys_exit }, /* 1 = exit */ { 0, 0, 0, diff --git a/sys/kern/kern_ktrace.c b/sys/kern/kern_ktrace.c index 9108277af..fa7aeeb9f 100644 --- a/sys/kern/kern_ktrace.c +++ b/sys/kern/kern_ktrace.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_ktrace.c,v 1.112 2023/05/11 09:51:33 bluhm Exp $ */ +/* $OpenBSD: kern_ktrace.c,v 1.113 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: kern_ktrace.c,v 1.23 1996/02/09 18:59:36 christos Exp $ */ /* @@ -160,7 +160,7 @@ ktrsyscall(struct proc *p, register_t code, size_t argsize, register_t args[]) u_int nargs = 0; int i; - if ((code & KTRC_CODE_MASK) == SYS_sysctl) { + if (code == SYS_sysctl) { /* * The sysctl encoding stores the mib[] * array because it is interesting. diff --git a/sys/kern/kern_pledge.c b/sys/kern/kern_pledge.c index 2099db42f..deb254245 100644 --- a/sys/kern/kern_pledge.c +++ b/sys/kern/kern_pledge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kern_pledge.c,v 1.309 2023/09/29 12:47:34 claudio Exp $ */ +/* $OpenBSD: kern_pledge.c,v 1.310 2023/12/12 17:43:10 deraadt Exp $ */ /* * Copyright (c) 2015 Nicholas Marriott @@ -113,6 +113,7 @@ const uint64_t pledge_syscalls[SYS_MAXSYSCALL] = { [SYS_thrkill] = PLEDGE_ALWAYS, /* raise, abort, stack pro */ [SYS_utrace] = PLEDGE_ALWAYS, /* ltrace(1) from ld.so */ [SYS_pinsyscall] = PLEDGE_ALWAYS, + [SYS_pinsyscalls] = PLEDGE_ALWAYS, /* "getting" information about self is considered safe */ [SYS_getuid] = PLEDGE_STDIO, diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index b009ec93c..8fbbaf11d 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,14 +1,14 @@ -/* $OpenBSD: syscalls.c,v 1.269 2023/12/10 16:59:51 deraadt Exp $ */ +/* $OpenBSD: syscalls.c,v 1.270 2023/12/12 15:32:59 deraadt Exp $ */ /* * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.253 2023/12/10 16:59:09 deraadt Exp + * created from; OpenBSD: syscalls.master,v 1.254 2023/12/12 15:30:55 deraadt Exp */ const char *const syscallnames[] = { - "syscall", /* 0 = syscall */ + "#0 (unimplemented syscall)", /* 0 = unimplemented syscall */ "exit", /* 1 = exit */ "fork", /* 2 = fork */ "read", /* 3 = read */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index ac0b924b8..31c051c94 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.253 2023/12/10 16:59:09 deraadt Exp $ +; $OpenBSD: syscalls.master,v 1.254 2023/12/12 15:30:55 deraadt Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -48,7 +48,7 @@ ; redistributions should be placed in the reserved range at the end ; of the current calls. -0 INDIR { int sys_syscall(int number, ...); } +0 UNIMPL syscall 1 STD { void sys_exit(int rval); } 2 STD { int sys_fork(void); } 3 STD NOLOCK { ssize_t sys_read(int fd, void *buf, size_t nbyte); } diff --git a/sys/net/if_pflow.c b/sys/net/if_pflow.c index 4fa69b9d6..f8b19735a 100644 --- a/sys/net/if_pflow.c +++ b/sys/net/if_pflow.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_pflow.c,v 1.104 2023/12/12 00:03:31 mvs Exp $ */ +/* $OpenBSD: if_pflow.c,v 1.105 2023/12/12 12:38:52 mvs Exp $ */ /* * Copyright (c) 2011 Florian Obser @@ -832,11 +832,11 @@ export_pflow(struct pf_state *st) mtx_enter(&sc->sc_mtx); switch (sc->sc_version) { case PFLOW_PROTO_5: - if( sk->af == AF_INET ) + if (sk->af == AF_INET) export_pflow_if(st, sk, sc); break; case PFLOW_PROTO_10: - if( sk->af == AF_INET || sk->af == AF_INET6 ) + if (sk->af == AF_INET || sk->af == AF_INET6) export_pflow_if(st, sk, sc); break; default: /* NOTREACHED */ diff --git a/sys/sys/ktrace.h b/sys/sys/ktrace.h index e76652efa..19eb541ed 100644 --- a/sys/sys/ktrace.h +++ b/sys/sys/ktrace.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ktrace.h,v 1.46 2023/02/23 01:33:20 deraadt Exp $ */ +/* $OpenBSD: ktrace.h,v 1.47 2023/12/12 15:30:55 deraadt Exp $ */ /* $NetBSD: ktrace.h,v 1.12 1996/02/04 02:12:29 christos Exp $ */ /* @@ -76,8 +76,6 @@ struct ktr_header { #define KTR_SYSCALL 1 struct ktr_syscall { int ktr_code; /* syscall number */ -#define KTRC_CODE_MASK 0x0000ffff -#define KTRC_CODE_SYSCALL 0x20000000 int ktr_argsize; /* size of arguments */ /* * followed by ktr_argsize/sizeof(register_t) "register_t"s diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index c013e0dc1..3248b6ecf 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -1,15 +1,12 @@ -/* $OpenBSD: syscall.h,v 1.268 2023/12/10 16:59:51 deraadt Exp $ */ +/* $OpenBSD: syscall.h,v 1.269 2023/12/12 15:32:58 deraadt Exp $ */ /* * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.253 2023/12/10 16:59:09 deraadt Exp + * created from; OpenBSD: syscalls.master,v 1.254 2023/12/12 15:30:55 deraadt Exp */ -/* syscall: "syscall" ret: "int" args: "int" "..." */ -#define SYS_syscall 0 - /* syscall: "exit" ret: "void" args: "int" */ #define SYS_exit 1 diff --git a/sys/sys/syscall_mi.h b/sys/sys/syscall_mi.h index 693742750..b9cf7bc07 100644 --- a/sys/sys/syscall_mi.h +++ b/sys/sys/syscall_mi.h @@ -1,4 +1,4 @@ -/* $OpenBSD: syscall_mi.h,v 1.28 2023/02/11 23:07:23 deraadt Exp $ */ +/* $OpenBSD: syscall_mi.h,v 1.29 2023/12/12 15:30:55 deraadt Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1993 @@ -51,8 +51,8 @@ * The MD setup for a system call has been done; here's the MI part. */ static inline int -mi_syscall(struct proc *p, register_t code, int indirect, - const struct sysent *callp, register_t *argp, register_t retval[2]) +mi_syscall(struct proc *p, register_t code, const struct sysent *callp, + register_t *argp, register_t retval[2]) { uint64_t tval; int lock = !(callp->sy_flags & SY_NOLOCK); @@ -73,15 +73,8 @@ mi_syscall(struct proc *p, register_t code, int indirect, #ifdef KTRACE if (KTRPOINT(p, KTR_SYSCALL)) { /* convert to mask, then include with code */ - switch (indirect) { - case SYS_syscall: - indirect = KTRC_CODE_SYSCALL; - break; - default: - indirect = 0; - } KERNEL_LOCK(); - ktrsyscall(p, code | indirect, callp->sy_argsize, argp); + ktrsyscall(p, code, callp->sy_argsize, argp); KERNEL_UNLOCK(); } #endif diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index 25d648c66..7a71382c2 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -1,10 +1,10 @@ -/* $OpenBSD: syscallargs.h,v 1.271 2023/12/10 16:59:51 deraadt Exp $ */ +/* $OpenBSD: syscallargs.h,v 1.272 2023/12/12 15:32:58 deraadt Exp $ */ /* * System call argument lists. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.253 2023/12/10 16:59:09 deraadt Exp + * created from; OpenBSD: syscalls.master,v 1.254 2023/12/12 15:30:55 deraadt Exp */ #ifdef syscallarg diff --git a/usr.bin/kdump/kdump.c b/usr.bin/kdump/kdump.c index 3411f7a33..9632afdce 100644 --- a/usr.bin/kdump/kdump.c +++ b/usr.bin/kdump/kdump.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kdump.c,v 1.159 2023/11/09 15:43:28 kn Exp $ */ +/* $OpenBSD: kdump.c,v 1.160 2023/12/12 15:30:55 deraadt Exp $ */ /*- * Copyright (c) 1988, 1993 @@ -933,9 +933,7 @@ ktrsyscall(struct ktr_syscall *ktr, size_t ktrlen) narg = ktr->ktr_argsize / sizeof(register_t); sep = '\0'; - if (ktr->ktr_code & KTRC_CODE_SYSCALL) - (void)printf("(via syscall) "); - code = ktr->ktr_code & KTRC_CODE_MASK; + code = ktr->ktr_code; if (code >= SYS_MAXSYSCALL || code < 0) (void)printf("[%d]", code); else diff --git a/usr.sbin/rpki-client/io.c b/usr.sbin/rpki-client/io.c index a3b988ef0..3d8b79deb 100644 --- a/usr.sbin/rpki-client/io.c +++ b/usr.sbin/rpki-client/io.c @@ -1,4 +1,4 @@ -/* $OpenBSD: io.c,v 1.23 2023/06/20 15:15:14 claudio Exp $ */ +/* $OpenBSD: io.c,v 1.24 2023/12/12 15:54:18 claudio Exp $ */ /* * Copyright (c) 2021 Claudio Jeker * Copyright (c) 2019 Kristaps Dzonsons @@ -100,15 +100,10 @@ io_close_buffer(struct msgbuf *msgbuf, struct ibuf *b) void io_read_buf(struct ibuf *b, void *res, size_t sz) { - char *tmp; - if (sz == 0) return; - tmp = ibuf_seek(b, b->rpos, sz); - if (tmp == NULL) - errx(1, "bad internal framing, buffer too short"); - b->rpos += sz; - memcpy(res, tmp, sz); + if (ibuf_get(b, res, sz) == -1) + err(1, "bad internal framing"); } /* diff --git a/usr.sbin/snmpd/application_internal.c b/usr.sbin/snmpd/application_internal.c index 9553a1489..11fec82d6 100644 --- a/usr.sbin/snmpd/application_internal.c +++ b/usr.sbin/snmpd/application_internal.c @@ -1,4 +1,4 @@ -/* $OpenBSD: application_internal.c,v 1.8 2023/11/12 16:03:41 martijn Exp $ */ +/* $OpenBSD: application_internal.c,v 1.9 2023/12/12 20:15:49 martijn Exp $ */ /* * Copyright (c) 2023 Martijn van Duren @@ -206,8 +206,7 @@ appl_internal_init(void) oid.bo_id[oid.bo_n++] = 0; if (appl_register(NULL, 150, 1, &oid, 1, 1, 0, 0, &appl_config) != APPL_ERROR_NOERROR) { - if (obj->stringval != NULL) - free(obj->stringval); + free(obj->stringval); free(obj); } else RB_INSERT(appl_internal_objects, &appl_internal_objects, @@ -223,10 +222,12 @@ appl_internal_shutdown(void) while ((object = RB_ROOT(&appl_internal_objects)) != NULL) { RB_REMOVE(appl_internal_objects, &appl_internal_objects, object); + free(object->stringval); free(object); } appl_close(&appl_internal); + appl_close(&appl_config); } void @@ -258,6 +259,7 @@ appl_internal_object(struct ber_oid *oid, obj->oid = *oid; obj->get = get; obj->getnext = getnext; + obj->stringval = NULL; RB_INSERT(appl_internal_objects, &appl_internal_objects, obj); } diff --git a/usr.sbin/snmpd/trap.c b/usr.sbin/snmpd/trap.c index ec967100e..043799a39 100644 --- a/usr.sbin/snmpd/trap.c +++ b/usr.sbin/snmpd/trap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: trap.c,v 1.39 2023/11/12 20:02:05 martijn Exp $ */ +/* $OpenBSD: trap.c,v 1.40 2023/12/12 20:18:39 martijn Exp $ */ /* * Copyright (c) 2008 Reyk Floeter @@ -46,7 +46,7 @@ trap_init(void) * Send a coldStart to notify that the daemon has been * started and re-initialized. */ - trap_send(&OID(MIB_coldStart, 0), NULL); + trap_send(&OID(MIB_coldStart), NULL); } int