diff --git a/etc/services b/etc/services index 8124a2a3f..0fed1cea8 100644 --- a/etc/services +++ b/etc/services @@ -1,4 +1,4 @@ -# $OpenBSD: services,v 1.105 2023/05/25 09:41:46 sthen Exp $ +# $OpenBSD: services,v 1.106 2023/12/07 14:53:31 sthen Exp $ # # Network services, Internet style # https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.txt @@ -249,6 +249,8 @@ mdnsresponder 5354/tcp # Multicast DNS Responder IPC mdnsresponder 5354/udp # Multicast DNS Responder IPC postgresql 5432/tcp # PostgreSQL postgresql 5432/udp # PostgreSQL +matter 5540/tcp # Matter IoT +matter 5540/udp # Matter IoT rfb 5900/tcp vnc # Remote Framebuffer syslog-tls 6514/tcp # syslog over TLS afs3-fileserver 7000/tcp # AFS fileserver diff --git a/etc/skel/dot.version b/etc/skel/dot.version index 2db7a434c..096149f4e 100644 --- a/etc/skel/dot.version +++ b/etc/skel/dot.version @@ -1 +1 @@ -# SecBSD 1.4-a5839ef: Fri Dec 1 14:35:24 UTC 2023 (Mictlantecuhtli) +# SecBSD 1.4-6dd7abc: Thu Dec 7 18:11:47 UTC 2023 (Mictlantecuhtli) diff --git a/gnu/usr.bin/binutils-2.17/bfd/elf.c b/gnu/usr.bin/binutils-2.17/bfd/elf.c index 01d3b3445..b23e3a66e 100644 --- a/gnu/usr.bin/binutils-2.17/bfd/elf.c +++ b/gnu/usr.bin/binutils-2.17/bfd/elf.c @@ -1105,6 +1105,7 @@ get_segment_type (unsigned int p_type) case PT_OPENBSD_NOBTCFI: pt = "OPENBSD_NOBTCFI"; break; case PT_OPENBSD_BOOTDATA: pt = "OPENBSD_BOOTDATA"; break; case PT_OPENBSD_MUTABLE: pt = "OPENBSD_MUTABLE"; break; + case PT_OPENBSD_SYSCALLS: pt = "OPENBSD_SYSCALLS"; break; default: pt = NULL; break; } return pt; @@ -2654,6 +2655,11 @@ bfd_section_from_phdr (bfd *abfd, Elf_Internal_Phdr *hdr, int index) case PT_OPENBSD_MUTABLE: return _bfd_elf_make_section_from_phdr (abfd, hdr, index, "openbsd_mutable"); + + case PT_OPENBSD_SYSCALLS: + return _bfd_elf_make_section_from_phdr (abfd, hdr, index, + "openbsd_syscalls"); + default: /* Check for any processor-specific program segment types. */ bed = get_elf_backend_data (abfd); @@ -3659,6 +3665,7 @@ map_sections_to_segments (bfd *abfd) int tls_count = 0; asection *first_tls = NULL; asection *dynsec, *eh_frame_hdr, *randomdata, *mutabledata; + asection *syscalls; bfd_size_type amt; if (elf_tdata (abfd)->segment_map != NULL) @@ -4044,6 +4051,24 @@ map_sections_to_segments (bfd *abfd) pm = &m->next; } + /* If there is a .openbsd.syscalls section, throw in a PT_OPENBSD_SYSCALLS + segment. */ + syscalls = bfd_get_section_by_name (abfd, ".openbsd.syscalls"); + if (syscalls != NULL && (syscalls->flags & SEC_LOAD) == 0) + { + amt = sizeof (struct elf_segment_map); + m = bfd_zalloc (abfd, amt); + if (m == NULL) + goto error_return; + m->next = NULL; + m->p_type = PT_OPENBSD_SYSCALLS; + m->count = 1; + m->sections[0] = syscalls->output_section; + + *pm = m; + pm = &m->next; + } + if (elf_tdata (abfd)->relro) { amt = sizeof (struct elf_segment_map); @@ -4594,6 +4619,12 @@ assign_file_positions_for_segments (bfd *abfd, struct bfd_link_info *link_info) else if (p->p_type == PT_NOTE && (flags & SEC_HAS_CONTENTS) != 0) p->p_filesz += sec->size; + else if (p->p_type == PT_OPENBSD_SYSCALLS) + { + sec->filepos = off; + off += sec->size; + p->p_filesz += sec->size; + } /* .tbss is special. It doesn't contribute to p_memsz of normal segments. */ @@ -4796,6 +4827,12 @@ get_program_header_size (bfd *abfd) ++segs; } + if (bfd_get_section_by_name (abfd, ".openbsd.syscalls") != NULL) + { + /* We need a PT_OPENBSD_SYSCALLS segment. */ + ++segs; + } + if (elf_tdata (abfd)->eh_frame_hdr) { /* We need a PT_GNU_EH_FRAME segment. */ diff --git a/gnu/usr.bin/binutils-2.17/binutils/readelf.c b/gnu/usr.bin/binutils-2.17/binutils/readelf.c index c947d9ba7..f67db474d 100644 --- a/gnu/usr.bin/binutils-2.17/binutils/readelf.c +++ b/gnu/usr.bin/binutils-2.17/binutils/readelf.c @@ -2714,6 +2714,8 @@ get_segment_type (unsigned long p_type) return "OPENBSD_MUTABLE"; case PT_OPENBSD_NOBTCFI: return "OPENBSD_NOBTCFI"; + case PT_OPENBSD_SYSCALLS: + return "OPENBSD_SYSCALLS"; default: if ((p_type >= PT_LOPROC) && (p_type <= PT_HIPROC)) diff --git a/gnu/usr.bin/binutils-2.17/include/elf/common.h b/gnu/usr.bin/binutils-2.17/include/elf/common.h index 98f8b1890..aa3f2a103 100644 --- a/gnu/usr.bin/binutils-2.17/include/elf/common.h +++ b/gnu/usr.bin/binutils-2.17/include/elf/common.h @@ -316,6 +316,7 @@ #define PT_OPENBSD_NOBTCFI 0x65a3dbe8 /* no branch target CFI */ #define PT_OPENBSD_BOOTDATA 0x65a41be6 /* Section for boot arguments */ #define PT_OPENBSD_MUTABLE 0x65a3dbe5 /* Like bss, but not immutable */ +#define PT_OPENBSD_SYSCALLS 0x65a3dbe9 /* System call sites */ /* Program segment permissions, in program header p_flags field. */ diff --git a/gnu/usr.bin/binutils-2.17/ld/ldgram.y b/gnu/usr.bin/binutils-2.17/ld/ldgram.y index 5ed2a5fc7..60097ab13 100644 --- a/gnu/usr.bin/binutils-2.17/ld/ldgram.y +++ b/gnu/usr.bin/binutils-2.17/ld/ldgram.y @@ -1101,6 +1101,8 @@ phdr_type: $$ = exp_intop (0x65a41be6); else if (strcmp (s, "PT_OPENBSD_MUTABLE") == 0) $$ = exp_intop (0x65a3dbe5); + else if (strcmp (s, "PT_OPENBSD_SYSCALLS") == 0) + $$ = exp_intop (0x65a3dbe9); else { einfo (_("\ diff --git a/regress/sys/netinet/bindconnect/Makefile b/regress/sys/netinet/bindconnect/Makefile index 2884042f6..e2cb3295e 100644 --- a/regress/sys/netinet/bindconnect/Makefile +++ b/regress/sys/netinet/bindconnect/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.1 2023/12/06 14:41:52 bluhm Exp $ +# $OpenBSD: Makefile,v 1.3 2023/12/07 23:47:48 bluhm Exp $ PROG= bindconnect LDADD= -lpthread @@ -7,22 +7,80 @@ WARNINGS= yes CLEANFILES= ktrace.out -${REGRESS_TARGETS}: ${PROG} +LOCAL_NET ?= +LOCAL_NET6 ?= + +REGRESS_ROOT_TARGETS += setup-maxfiles run-100000 run-localnet-connect-delete + +REGRESS_SETUP_ONCE += setup-maxfiles +setup-maxfiles: + [[ $$(sysctl -n kern.maxfiles) -ge 110000 ]] || \ + ${SUDO} sysctl kern.maxfiles=110000 + +REGRESS_SETUP += ${PROG} REGRESS_TARGETS += run-default run-default: - ${SUDO} time ${KTRACE} ./${PROG} + time ${KTRACE} ./${PROG} -REGRESS_TARGETS += run-bind -run-bind: - ${SUDO} time ${KTRACE} ./${PROG} -n 10 -s 2 -o 1 -b 5 -c 0 +NET_inet = ${LOCAL_NET} +NET_inet6 = ${LOCAL_NET6} -REGRESS_TARGETS += run-connect -run-connect: - ${SUDO} time ${KTRACE} ./${PROG} -n 10 -s 2 -o 1 -b 0 -c 5 +.for af in inet inet6 -REGRESS_TARGETS += run-bind-connect -run-bind-connect: - ${SUDO} time ${KTRACE} ./${PROG} -n 10 -s 2 -o 1 -b 3 -c 3 +.if ! empty(NET_${af}) +REGRESS_CLEANUP += cleanup-${af}-delete +.endif +cleanup-${af}-delete: + -${SUDO} time ./${PROG} \ + -f ${af} -s 0 -o 0 -b 0 -c 0 -d 1 -N ${NET_${af}} -t 1 + +REGRESS_TARGETS += run-${af}-bind +run-${af}-bind: + time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -b 6 -c 0 + +REGRESS_TARGETS += run-${af}-connect +run-${af}-connect: + time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -b 0 -c 6 + +REGRESS_TARGETS += run-${af}-bind-connect +run-${af}-bind-connect: + time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -b 3 -c 3 + +REGRESS_TARGETS += run-${af}-100000 +run-${af}-100000: + ${SUDO} time ${KTRACE} ./${PROG} \ + -f ${af} -n 100000 -s 2 -o 1 -b 3 -c 3 + +REGRESS_TARGETS += run-${af}-reuseport +run-${af}-reuseport: + time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -b 3 -c 3 -r + +.if empty(NET_${af}) +REGRESS_SKIP_TARGETS += run-${af}-localnet-connect \ + run-${af}-localnet-bind-connect \ + run-${af}-localnet-connect-delete +.endif + +REGRESS_TARGETS += run-${af}-localnet-connect +run-${af}-localnet-connect: + time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -c 6 -N ${NET_${af}} + +REGRESS_TARGETS += run-${af}-localnet-bind-connect +run-${af}-localnet-bind-connect: + time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -b 3 -c 3 -N ${NET_${af}} + +REGRESS_TARGETS += run-${af}-localnet-connect-delete +run-${af}-localnet-connect-delete: + ${SUDO} time ${KTRACE} ./${PROG} \ + -f ${af} -n 16 -s 2 -o 1 -b 0 -c 6 -d 3 -N ${NET_${af}} + +.endfor .include diff --git a/regress/sys/netinet/bindconnect/README b/regress/sys/netinet/bindconnect/README index b8a00ad2f..f42590877 100644 --- a/regress/sys/netinet/bindconnect/README +++ b/regress/sys/netinet/bindconnect/README @@ -1,12 +1,17 @@ Stress test bind(2) and connect(2) system calls in OpenBSD regress. -bindconnect [-b bind] [-c connect] [-n num] [-o close] [-s socket] [-t time] - -b bind threads binding sockets, default 1 - -c connect threads connecting sockets, default 1 - -n num number of file descriptors, default 100 - -o close threads closing sockets, default 1 - -s socket threads creating sockets, default 1 - -t time run time in seconds, default 10 +bindconnect [-r] [-b bind] [-c connect] [-d delroute] +[-N addr/net] [-n num] [-o close] [-s socket] [-t time] + -b bind threads binding sockets, default 1 + -c connect threads connecting sockets, default 1 + -d delroute threads deleting cloned routes, default 0 + -f family address family inet or inet6, default inet + -N addr/net connect to any address within network + -n num number of file descriptors, default 128 + -o close threads closing sockets, default 1 + -r set reuse port socket option + -s socket threads creating sockets, default 1 + -t time run time in seconds, default 10 Separate threads are started to run socket(2), close(2), bind(2), and connect(2) system calls concurrently. The number of sockets @@ -15,4 +20,9 @@ system calls operate on random file descriptors. By setting the number of threads for each system call and the number of available file descriptors, the focus for the stress test can be changed. -Currently only IPv4 UDP sockets with 127.0.0.1 are supported. +Currently IPv4 and IPv6 UDP sockets are supported. Per default the +address to bind and connect is 127.0.0.1 or ::1. LOCAL_NET or +LOCAL_NET6 environment variable allows to bind on a local address +and connect to all directly attached hosts. This triggers creation +of cloned routes during source address selection. To stress test +routing table, these routes can be deleted in another thread. diff --git a/regress/sys/netinet/bindconnect/bindconnect.c b/regress/sys/netinet/bindconnect/bindconnect.c index e94f80987..7ed5eaf12 100644 --- a/regress/sys/netinet/bindconnect/bindconnect.c +++ b/regress/sys/netinet/bindconnect/bindconnect.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bindconnect.c,v 1.1 2023/12/06 14:41:52 bluhm Exp $ */ +/* $OpenBSD: bindconnect.c,v 1.3 2023/12/07 23:47:48 bluhm Exp $ */ /* * Copyright (c) 2023 Alexander Bluhm @@ -19,7 +19,9 @@ #include #include +#include #include +#include #include #include @@ -31,31 +33,125 @@ #define MAX(a, b) ((a) > (b) ? (a) : (b)) +#define s6_addr8 __u6_addr.__u6_addr8 +#define s6_addr16 __u6_addr.__u6_addr16 +#define s6_addr32 __u6_addr.__u6_addr32 + +union sockaddr_union { + struct sockaddr su_sa; + struct sockaddr_in su_sin; + struct sockaddr_in6 su_sin6; +}; + +union inaddr_union { + struct in_addr au_inaddr; + struct in6_addr au_in6addr; +}; + int fd_base; -unsigned int fd_num = 100; +unsigned int fd_num = 128; unsigned int run_time = 10; -unsigned int socket_num = 1, close_num = 1, bind_num = 1, connect_num = 1; +unsigned int socket_num = 1, close_num = 1, bind_num = 1, connect_num = 1, + delroute_num = 0; +int reuse_port = 0; +const char *family = "inet"; +union inaddr_union addr, mask; +int af, prefix = -1, route_sock = -1; static void __dead usage(void) { fprintf(stderr, - "bindconnect [-b bind] [-c connect] [-n num] [-o close]\n" - "[-s socket] [-t time]\n" - " -b bind threads binding sockets, default %u\n" - " -c connect threads connecting sockets, default %u\n" - " -n num number of file descriptors, default %u\n" - " -o close threads closing sockets, default %u\n" - " -s socket threads creating sockets, default %u\n" - " -t time run time in seconds, default %u\n", - bind_num, connect_num, fd_num, close_num, socket_num, run_time); + "bindconnect [-r] [-b bind] [-c connect] [-d delroute]\n" + "[-N addr/net] [-n num] [-o close] [-s socket] [-t time]\n" + " -b bind threads binding sockets, default %u\n" + " -c connect threads connecting sockets, default %u\n" + " -d delroute threads deleting cloned routes, default %u\n" + " -f family address family inet or inet6, default %s\n" + " -N addr/net connect to any address within network\n" + " -n num number of file descriptors, default %u\n" + " -o close threads closing sockets, default %u\n" + " -r set reuse port socket option\n" + " -s socket threads creating sockets, default %u\n" + " -t time run time in seconds, default %u\n", + bind_num, connect_num, delroute_num, family, fd_num, close_num, + socket_num, run_time); exit(2); } -static inline struct sockaddr * -sintosa(struct sockaddr_in *sin) +static void +in_prefixlen2mask(struct in_addr *maskp, int plen) { - return ((struct sockaddr *)(sin)); + if (plen == 0) + maskp->s_addr = 0; + else + maskp->s_addr = htonl(0xffffffff << (32 - plen)); +} + +static void +in6_prefixlen2mask(struct in6_addr *maskp, int len) +{ + u_char maskarray[8] = {0x80, 0xc0, 0xe0, 0xf0, 0xf8, 0xfc, 0xfe, 0xff}; + int bytelen, bitlen, i; + + bzero(maskp, sizeof(*maskp)); + bytelen = len / 8; + bitlen = len % 8; + for (i = 0; i < bytelen; i++) + maskp->s6_addr[i] = 0xff; + /* len == 128 is ok because bitlen == 0 then */ + if (bitlen) + maskp->s6_addr[bytelen] = maskarray[bitlen - 1]; +} + +static void +fill_sockaddr(union sockaddr_union *su) +{ + memset(su, 0, sizeof(*su)); + su->su_sa.sa_family = af; + if (af == AF_INET) { + su->su_sin.sin_len = sizeof(su->su_sin); + if (prefix >= 0) + su->su_sin.sin_addr = addr.au_inaddr; + else + su->su_sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + } + if (af == AF_INET6) { + su->su_sin6.sin6_len = sizeof(su->su_sin6); + if (prefix >= 0) + su->su_sin6.sin6_addr = addr.au_in6addr; + else + su->su_sin6.sin6_addr = in6addr_loopback; + } +} + +static void +mask_sockaddr(union sockaddr_union *su) +{ + if (af == AF_INET) { + if (prefix >=0 && prefix != 32) { + su->su_sin.sin_addr.s_addr &= + mask.au_inaddr.s_addr; + /* do only 8 bits variation, routes should be reused */ + su->su_sin.sin_addr.s_addr |= htonl(255) & + ~mask.au_inaddr.s_addr & arc4random(); + } + } + if (af == AF_INET6) { + if (prefix >=0 && prefix != 128) { + su->su_sin6.sin6_addr.s6_addr32[0] &= + mask.au_in6addr.s6_addr32[0]; + su->su_sin6.sin6_addr.s6_addr32[1] &= + mask.au_in6addr.s6_addr32[1]; + su->su_sin6.sin6_addr.s6_addr32[2] &= + mask.au_in6addr.s6_addr32[2]; + su->su_sin6.sin6_addr.s6_addr32[3] &= + mask.au_in6addr.s6_addr32[3]; + /* do only 8 bits variation, routes should be reused */ + su->su_sin6.sin6_addr.s6_addr32[3] |= htonl(255) & + ~mask.au_in6addr.s6_addr32[3] & arc4random(); + } + } } static void * @@ -63,9 +159,16 @@ thread_socket(void *arg) { volatile int *run = arg; unsigned long count; + int fd; for (count = 0; *run; count++) { - socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + int opt; + + fd = socket(af, SOCK_DGRAM, IPPROTO_UDP); + if (fd < 0 || !reuse_port) + continue; + opt = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &opt, sizeof(opt)); } return (void *)count; @@ -92,16 +195,13 @@ thread_bind(void *arg) volatile int *run = arg; unsigned long count; int fd; - struct sockaddr_in sin; + union sockaddr_union su; - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); + fill_sockaddr(&su); for (count = 0; *run; count++) { fd = fd_base + arc4random_uniform(fd_num); - bind(fd, sintosa(&sin), sizeof(sin)); + bind(fd, &su.su_sa, su.su_sa.sa_len); } return (void *)count; @@ -113,37 +213,89 @@ thread_connect(void *arg) volatile int *run = arg; unsigned long count; int fd; - struct sockaddr_in sin; + union sockaddr_union su; - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_addr.s_addr = htonl(INADDR_LOOPBACK); - sin.sin_port = arc4random(); + fill_sockaddr(&su); for (count = 0; *run; count++) { fd = fd_base + arc4random_uniform(fd_num); - connect(fd, sintosa(&sin), sizeof(sin)); + mask_sockaddr(&su); + if (af == AF_INET) + su.su_sin.sin_port = arc4random(); + if (af == AF_INET6) + su.su_sin6.sin6_port = arc4random(); + connect(fd, &su.su_sa, su.su_sa.sa_len); } return (void *)count; } +static void * +thread_delroute(void *arg) +{ + volatile int *run = arg; + unsigned long count; + int seq = 0; + struct { + struct rt_msghdr m_rtm; + char m_space[512]; + } m_rtmsg; + union sockaddr_union su; + +#define rtm \ + m_rtmsg.m_rtm +#define ROUNDUP(a) \ + ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) +#define ADVANCE(x, n) \ + (x += ROUNDUP((n)->sa_len)) +#define NEXTADDR(w, sa) \ + if (rtm.rtm_addrs & (w)) { \ + int l = ROUNDUP((sa)->sa_len); \ + memcpy(cp, (sa), l); \ + cp += l; \ + } + + memset(&m_rtmsg, 0, sizeof(m_rtmsg)); + rtm.rtm_type = RTM_DELETE; + rtm.rtm_flags = RTF_HOST; + rtm.rtm_version = RTM_VERSION; + rtm.rtm_addrs = RTA_DST; + rtm.rtm_hdrlen = sizeof(rtm); + + fill_sockaddr(&su); + + for (count = 0; *run; count++) { + char *cp = m_rtmsg.m_space; + + rtm.rtm_seq = ++seq; + mask_sockaddr(&su); + NEXTADDR(RTA_DST, &su.su_sa); + rtm.rtm_msglen = cp - (char *)&m_rtmsg; + write(route_sock, &m_rtmsg, rtm.rtm_msglen); + } + +#undef rtm +#undef ROUNDUP +#undef ADVANCE +#undef NEXTADDR + + return (void *)count; +} + int main(int argc, char *argv[]) { struct rlimit rlim; - pthread_t *tsocket, *tclose, *tbind, *tconnect; - const char *errstr; + pthread_t *tsocket, *tclose, *tbind, *tconnect, *tdelroute; + const char *errstr, *addr_net = NULL; + char buf[128], *p; int ch, run; unsigned int n; - unsigned long socket_count, close_count, bind_count, connect_count; + unsigned long socket_count, close_count, bind_count, connect_count, + delroute_count; + union sockaddr_union su; - fd_base = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (fd_base < 0) - err(1, "socket fd_base"); - - while ((ch = getopt(argc, argv, "b:c:n:o:s:t:")) != -1) { + while ((ch = getopt(argc, argv, "b:c:d:f:N:n:o:rs:t:")) != -1) { switch (ch) { case 'b': bind_num = strtonum(optarg, 0, UINT_MAX, &errstr); @@ -155,9 +307,19 @@ main(int argc, char *argv[]) if (errstr != NULL) errx(1, "connect is %s: %s", errstr, optarg); break; + case 'd': + delroute_num = strtonum(optarg, 0, UINT_MAX, &errstr); + if (errstr != NULL) + errx(1, "delroute is %s: %s", errstr, optarg); + break; + case 'f': + family = optarg; + break; + case 'N': + addr_net = optarg; + break; case 'n': - fd_num = strtonum(optarg, 1, INT_MAX - fd_base, - &errstr); + fd_num = strtonum(optarg, 1, INT_MAX, &errstr); if (errstr != NULL) errx(1, "num is %s: %s", errstr, optarg); break; @@ -166,6 +328,9 @@ main(int argc, char *argv[]) if (errstr != NULL) errx(1, "close is %s: %s", errstr, optarg); break; + case 'r': + reuse_port = 1; + break; case 's': socket_num = strtonum(optarg, 0, UINT_MAX, &errstr); if (errstr != NULL) @@ -185,6 +350,58 @@ main(int argc, char *argv[]) if (argc > 0) usage(); + if (strcmp(family, "inet") == 0) + af = AF_INET; + else if (strcmp(family, "inet6") == 0) + af = AF_INET6; + else + errx(1, "bad address family %s", family); + + /* split addr/net into addr, mask, prefix */ + if (addr_net != NULL) { + prefix = inet_net_pton(af, addr_net, &addr, sizeof(addr)); + if (prefix < 0) + err(1, "inet_net_pton %s", addr_net); + if (af == AF_INET6) { + /* + * Man page says inet_net_pton() preserves lower + * bits. That is not true, call inet_pton() again. + */ + if (strlcpy(buf, addr_net, sizeof(buf)) >= sizeof(buf)) + err(1, "strlcpy %s", addr_net); + p = strchr(buf, '/'); + if (p != NULL ) { + *p = '\0'; + if (inet_pton(af, buf, &addr) < 0) + err(1, "inet_pton %s", buf); + } + } + if (af == AF_INET) + in_prefixlen2mask(&mask.au_inaddr, prefix); + if (af == AF_INET6) + in6_prefixlen2mask(&mask.au_in6addr, prefix); + } + + /* preopen route socket before file descriptor limits are set */ + if (delroute_num > 0) { + if (prefix < 0 || prefix == 32) + errx(1, "delroute %u needs addr/net", delroute_num); + route_sock = socket(AF_ROUTE, SOCK_RAW, af); + if (route_sock < 0) + err(1, "socket route"); + if (shutdown(route_sock, SHUT_RD) < 0) + err(1, "shutdown read route"); + } + + /* detect lowest file desciptor, test bind, close everything above */ + fd_base = socket(af, SOCK_DGRAM, IPPROTO_UDP); + if (fd_base < 0) + err(1, "socket fd_base"); + if (fd_base > INT_MAX - (int)fd_num) + err(1, "fd base %d and num %u overflow", fd_base, fd_num); + fill_sockaddr(&su); + if (bind(fd_base, &su.su_sa, su.su_sa.sa_len) < 0) + err(1, "bind %s", inet_ntop(af, &addr, buf, sizeof(buf))); if (closefrom(fd_base) < 0) err(1, "closefrom %d", fd_base); @@ -196,6 +413,7 @@ main(int argc, char *argv[]) err(1, "setrlimit %llu", rlim.rlim_cur); run = 1; + tsocket = calloc(socket_num, sizeof(pthread_t)); if (tsocket == NULL) err(1, "tsocket"); @@ -204,6 +422,7 @@ main(int argc, char *argv[]) if (errno) err(1, "pthread_create socket %u", n); } + tclose = calloc(close_num, sizeof(pthread_t)); if (tclose == NULL) err(1, "tclose"); @@ -212,6 +431,7 @@ main(int argc, char *argv[]) if (errno) err(1, "pthread_create close %u", n); } + tbind = calloc(bind_num, sizeof(pthread_t)); if (tbind == NULL) err(1, "tbind"); @@ -220,6 +440,7 @@ main(int argc, char *argv[]) if (errno) err(1, "pthread_create bind %u", n); } + tconnect = calloc(connect_num, sizeof(pthread_t)); if (tconnect == NULL) err(1, "tconnect"); @@ -230,6 +451,16 @@ main(int argc, char *argv[]) err(1, "pthread_create connect %u", n); } + tdelroute = calloc(delroute_num, sizeof(pthread_t)); + if (tdelroute == NULL) + err(1, "tdelroute"); + for (n = 0; n < delroute_num; n++) { + errno = pthread_create(&tdelroute[n], NULL, thread_delroute, + &run); + if (errno) + err(1, "pthread_create delroute %u", n); + } + if (run_time > 0) { if (sleep(run_time) < 0) err(1, "sleep %u", run_time); @@ -245,6 +476,8 @@ main(int argc, char *argv[]) err(1, "pthread_join socket %u", n); socket_count += count; } + free(tsocket); + close_count = 0; for (n = 0; n < close_num; n++) { unsigned long count; @@ -254,6 +487,8 @@ main(int argc, char *argv[]) err(1, "pthread_join close %u", n); close_count += count; } + free(tclose); + bind_count = 0; for (n = 0; n < bind_num; n++) { unsigned long count; @@ -263,6 +498,8 @@ main(int argc, char *argv[]) err(1, "pthread_join bind %u", n); bind_count += count; } + free(tbind); + connect_count = 0; for (n = 0; n < connect_num; n++) { unsigned long count; @@ -272,8 +509,23 @@ main(int argc, char *argv[]) err(1, "pthread_join connect %u", n); connect_count += count; } - printf("count: socket %lu, close %lu, bind %lu, connect %lu\n", - socket_count, close_count, bind_count, connect_count); + free(tconnect); + + delroute_count = 0; + for (n = 0; n < delroute_num; n++) { + unsigned long count; + + errno = pthread_join(tdelroute[n], (void **)&count); + if (errno) + err(1, "pthread_join delroute %u", n); + delroute_count += count; + } + free(tdelroute); + + printf("count: socket %lu, close %lu, bind %lu, connect %lu, " + "delroute %lu\n", + socket_count, close_count, bind_count, connect_count, + delroute_count); return 0; } diff --git a/sys/dev/mii/eephy.c b/sys/dev/mii/eephy.c index 080367d45..ca768f953 100644 --- a/sys/dev/mii/eephy.c +++ b/sys/dev/mii/eephy.c @@ -1,4 +1,4 @@ -/* $OpenBSD: eephy.c,v 1.61 2023/12/05 11:06:05 uwe Exp $ */ +/* $OpenBSD: eephy.c,v 1.62 2023/12/07 09:46:58 uwe Exp $ */ /* * Principal Author: Parag Patel * Copyright (c) 2001 @@ -276,10 +276,13 @@ eephy_reset(struct mii_softc *sc) PHY_WRITE(sc, E1000_SCR, reg); - /* 25 MHz TX_CLK should always work. */ - reg = PHY_READ(sc, E1000_ESCR); - reg |= E1000_ESCR_TX_CLK_25; - PHY_WRITE(sc, E1000_ESCR, reg); + if (sc->mii_model != MII_MODEL_MARVELL_E1512 && + sc->mii_model != MII_MODEL_MARVELL_E1545) { + /* 25 MHz TX_CLK should always work. */ + reg = PHY_READ(sc, E1000_ESCR); + reg |= E1000_ESCR_TX_CLK_25; + PHY_WRITE(sc, E1000_ESCR, reg); + } /* Configure LEDs if they were left unconfigured. */ if (sc->mii_model == MII_MODEL_MARVELL_E3016 && diff --git a/sys/dev/mii/eephyreg.h b/sys/dev/mii/eephyreg.h index 59c6c5678..593127a7b 100644 --- a/sys/dev/mii/eephyreg.h +++ b/sys/dev/mii/eephyreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: eephyreg.h,v 1.9 2022/01/09 05:42:44 jsg Exp $ */ +/* $OpenBSD: eephyreg.h,v 1.10 2023/12/07 09:46:58 uwe Exp $ */ /* * Principal Author: Parag Patel * Copyright (c) 2001 @@ -284,6 +284,7 @@ #define E1000_ISR_SPEED_CHANGED 0x4000 #define E1000_ISR_AUTO_NEG_ERR 0x8000 +/* page any */ #define E1000_ESCR 0x14 /* extended special control reg */ #define E1000_ESCR_FIBER_LOOPBACK 0x4000 #define E1000_ESCR_DOWN_NO_IDLE 0x8000 diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index ea59de069..a0934eb6f 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -1,10 +1,10 @@ -/* $OpenBSD: init_sysent.c,v 1.269 2023/11/29 20:46:23 bluhm Exp $ */ +/* $OpenBSD: init_sysent.c,v 1.270 2023/12/07 14:00:16 deraadt Exp $ */ /* * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.251 2023/11/29 20:40:06 bluhm Exp + * created from; OpenBSD: syscalls.master,v 1.252 2023/12/07 13:59:04 deraadt Exp */ #include @@ -353,8 +353,8 @@ const struct sysent sysent[] = { sys_nosys }, /* 156 = obsolete ogetdirentries */ { 0, 0, 0, sys_nosys }, /* 157 = obsolete statfs25 */ - { 0, 0, 0, - sys_nosys }, /* 158 = obsolete fstatfs25 */ + { 4, s(struct sys_pinsyscalls_args), 0, + sys_pinsyscalls }, /* 158 = pinsyscalls */ { 2, s(struct sys_mimmutable_args), 0, sys_mimmutable }, /* 159 = mimmutable */ { 4, s(struct sys_waitid_args), 0, diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 3d6ff51e2..e3d56d1c4 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -1,10 +1,10 @@ -/* $OpenBSD: syscalls.c,v 1.267 2023/11/29 20:46:23 bluhm Exp $ */ +/* $OpenBSD: syscalls.c,v 1.268 2023/12/07 14:00:16 deraadt Exp $ */ /* * System call names. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.251 2023/11/29 20:40:06 bluhm Exp + * created from; OpenBSD: syscalls.master,v 1.252 2023/12/07 13:59:04 deraadt Exp */ const char *const syscallnames[] = { @@ -182,7 +182,7 @@ const char *const syscallnames[] = { #endif "#156 (obsolete ogetdirentries)", /* 156 = obsolete ogetdirentries */ "#157 (obsolete statfs25)", /* 157 = obsolete statfs25 */ - "#158 (obsolete fstatfs25)", /* 158 = obsolete fstatfs25 */ + "pinsyscalls", /* 158 = pinsyscalls */ "mimmutable", /* 159 = mimmutable */ "waitid", /* 160 = waitid */ "getfh", /* 161 = getfh */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index 5c60c389f..20215e6a2 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.251 2023/11/29 20:40:06 bluhm Exp $ +; $OpenBSD: syscalls.master,v 1.252 2023/12/07 13:59:04 deraadt Exp $ ; $NetBSD: syscalls.master,v 1.32 1996/04/23 10:24:21 mycroft Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -306,7 +306,8 @@ #endif 156 OBSOL ogetdirentries 157 OBSOL statfs25 -158 OBSOL fstatfs25 +158 STD { int sys_pinsyscalls(void *base, size_t len, \ + void *pins, size_t pinslen); } 159 STD { int sys_mimmutable(void *addr, size_t len); } 160 STD { int sys_waitid(int idtype, id_t id, \ siginfo_t *info, int options); } diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 35cd333de..67e80baa7 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.c,v 1.281 2023/12/03 20:24:17 bluhm Exp $ */ +/* $OpenBSD: in_pcb.c,v 1.282 2023/12/07 16:08:30 bluhm Exp $ */ /* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */ /* @@ -131,6 +131,13 @@ uint64_t in_pcbhash(struct inpcbtable *, u_int, const struct in_addr *, u_short, const struct in_addr *, u_short); uint64_t in_pcblhash(struct inpcbtable *, u_int, u_short); +struct inpcb *in_pcblookup_lock(struct inpcbtable *, struct in_addr, u_int, + struct in_addr, u_int, u_int, int); +int in_pcbaddrisavail_lock(struct inpcb *, struct sockaddr_in *, int, + struct proc *, int); +int in_pcbpickport(u_int16_t *, const void *, int, const struct inpcb *, + struct proc *); + /* * in_pcb is used for inet and inet6. in6_pcb only contains special * IPv6 cases. So the internet initializer is used for both domains. @@ -269,9 +276,8 @@ in_pcballoc(struct socket *so, struct inpcbtable *table, int wait) } int -in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) +in_pcbbind_locked(struct inpcb *inp, struct mbuf *nam, struct proc *p) { - struct inpcbtable *table = inp->inp_table; struct socket *so = inp->inp_socket; u_int16_t lport = 0; int wild = 0; @@ -297,7 +303,8 @@ in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) if ((error = in6_nam2sin6(nam, &sin6))) return (error); - if ((error = in6_pcbaddrisavail(inp, sin6, wild, p))) + if ((error = in6_pcbaddrisavail_lock(inp, sin6, wild, + p, IN_PCBLOCK_HOLD))) return (error); laddr = &sin6->sin6_addr; lport = sin6->sin6_port; @@ -313,7 +320,8 @@ in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) if ((error = in_nam2sin(nam, &sin))) return (error); - if ((error = in_pcbaddrisavail(inp, sin, wild, p))) + if ((error = in_pcbaddrisavail_lock(inp, sin, wild, + p, IN_PCBLOCK_HOLD))) return (error); laddr = &sin->sin_addr; lport = sin->sin_port; @@ -337,16 +345,28 @@ in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) inp->inp_laddr = *(struct in_addr *)laddr; } inp->inp_lport = lport; - mtx_enter(&table->inpt_mtx); in_pcbrehash(inp); - mtx_leave(&table->inpt_mtx); return (0); } int -in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in *sin, int wild, - struct proc *p) +in_pcbbind(struct inpcb *inp, struct mbuf *nam, struct proc *p) +{ + struct inpcbtable *table = inp->inp_table; + int error; + + /* keep lookup, modification, and rehash in sync */ + mtx_enter(&table->inpt_mtx); + error = in_pcbbind_locked(inp, nam, p); + mtx_leave(&table->inpt_mtx); + + return error; +} + +int +in_pcbaddrisavail_lock(struct inpcb *inp, struct sockaddr_in *sin, int wild, + struct proc *p, int lock) { struct socket *so = inp->inp_socket; struct inpcbtable *table = inp->inp_table; @@ -393,19 +413,21 @@ in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in *sin, int wild, int error = 0; if (so->so_euid && !IN_MULTICAST(sin->sin_addr.s_addr)) { - t = in_pcblookup_local(table, &sin->sin_addr, lport, - INPLOOKUP_WILDCARD, inp->inp_rtableid); + t = in_pcblookup_local_lock(table, &sin->sin_addr, + lport, INPLOOKUP_WILDCARD, inp->inp_rtableid, lock); if (t && (so->so_euid != t->inp_socket->so_euid)) error = EADDRINUSE; - in_pcbunref(t); + if (lock == IN_PCBLOCK_GRAB) + in_pcbunref(t); if (error) return (error); } - t = in_pcblookup_local(table, &sin->sin_addr, lport, - wild, inp->inp_rtableid); + t = in_pcblookup_local_lock(table, &sin->sin_addr, lport, + wild, inp->inp_rtableid, lock); if (t && (reuseport & t->inp_socket->so_options) == 0) error = EADDRINUSE; - in_pcbunref(t); + if (lock == IN_PCBLOCK_GRAB) + in_pcbunref(t); if (error) return (error); } @@ -413,6 +435,13 @@ in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in *sin, int wild, return (0); } +int +in_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in *sin, int wild, + struct proc *p) +{ + return in_pcbaddrisavail_lock(inp, sin, wild, p, IN_PCBLOCK_GRAB); +} + int in_pcbpickport(u_int16_t *lport, const void *laddr, int wild, const struct inpcb *inp, struct proc *p) @@ -423,6 +452,8 @@ in_pcbpickport(u_int16_t *lport, const void *laddr, int wild, u_int16_t first, last, lower, higher, candidate, localport; int count; + MUTEX_ASSERT_LOCKED(&table->inpt_mtx); + if (inp->inp_flags & INP_HIGHPORT) { first = ipport_hifirstauto; /* sysctl */ last = ipport_hilastauto; @@ -451,9 +482,7 @@ in_pcbpickport(u_int16_t *lport, const void *laddr, int wild, count = higher - lower; candidate = lower + arc4random_uniform(count); - t = NULL; do { - in_pcbunref(t); do { if (count-- < 0) /* completely used? */ return (EADDRNOTAVAIL); @@ -462,8 +491,8 @@ in_pcbpickport(u_int16_t *lport, const void *laddr, int wild, candidate = lower; localport = htons(candidate); } while (in_baddynamic(candidate, so->so_proto->pr_protocol)); - t = in_pcblookup_local(table, laddr, localport, wild, - inp->inp_rtableid); + t = in_pcblookup_local_lock(table, laddr, localport, wild, + inp->inp_rtableid, IN_PCBLOCK_HOLD); } while (t != NULL); *lport = localport; @@ -498,10 +527,13 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam) if (error) return (error); - t = in_pcblookup(inp->inp_table, sin->sin_addr, sin->sin_port, - ina, inp->inp_lport, inp->inp_rtableid); + /* keep lookup, modification, and rehash in sync */ + mtx_enter(&table->inpt_mtx); + + t = in_pcblookup_lock(inp->inp_table, sin->sin_addr, sin->sin_port, + ina, inp->inp_lport, inp->inp_rtableid, IN_PCBLOCK_HOLD); if (t != NULL) { - in_pcbunref(t); + mtx_leave(&table->inpt_mtx); return (EADDRINUSE); } @@ -509,15 +541,17 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam) if (inp->inp_laddr.s_addr == INADDR_ANY) { if (inp->inp_lport == 0) { - error = in_pcbbind(inp, NULL, curproc); - if (error) + error = in_pcbbind_locked(inp, NULL, curproc); + if (error) { + mtx_leave(&table->inpt_mtx); return (error); - t = in_pcblookup(inp->inp_table, sin->sin_addr, + } + t = in_pcblookup_lock(inp->inp_table, sin->sin_addr, sin->sin_port, ina, inp->inp_lport, - inp->inp_rtableid); + inp->inp_rtableid, IN_PCBLOCK_HOLD); if (t != NULL) { inp->inp_lport = 0; - in_pcbunref(t); + mtx_leave(&table->inpt_mtx); return (EADDRINUSE); } } @@ -525,8 +559,8 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam) } inp->inp_faddr = sin->sin_addr; inp->inp_fport = sin->sin_port; - mtx_enter(&table->inpt_mtx); in_pcbrehash(inp); + mtx_leave(&table->inpt_mtx); #if NSTOEPLITZ > 0 @@ -539,6 +573,11 @@ in_pcbconnect(struct inpcb *inp, struct mbuf *nam) void in_pcbdisconnect(struct inpcb *inp) { + /* + * XXXSMP pf lock sleeps, so we cannot use table->inpt_mtx + * to keep inp_pf_sk in sync with pcb. Use net lock for now. + */ + NET_ASSERT_LOCKED_EXCLUSIVE(); #if NPF > 0 if (inp->inp_pf_sk) { pf_remove_divert_state(inp->inp_pf_sk); @@ -576,6 +615,12 @@ in_pcbdetach(struct inpcb *inp) } else #endif ip_freemoptions(inp->inp_moptions); + + /* + * XXXSMP pf lock sleeps, so we cannot use table->inpt_mtx + * to keep inp_pf_sk in sync with pcb. Use net lock for now. + */ + NET_ASSERT_LOCKED_EXCLUSIVE(); #if NPF > 0 if (inp->inp_pf_sk) { pf_remove_divert_state(inp->inp_pf_sk); @@ -791,8 +836,8 @@ in_rtchange(struct inpcb *inp, int errno) } struct inpcb * -in_pcblookup_local(struct inpcbtable *table, const void *laddrp, - u_int lport_arg, int flags, u_int rtable) +in_pcblookup_local_lock(struct inpcbtable *table, const void *laddrp, + u_int lport_arg, int flags, u_int rtable, int lock) { struct inpcb *inp, *match = NULL; int matchwild = 3, wildcard; @@ -808,7 +853,12 @@ in_pcblookup_local(struct inpcbtable *table, const void *laddrp, rdomain = rtable_l2(rtable); lhash = in_pcblhash(table, rdomain, lport); - mtx_enter(&table->inpt_mtx); + if (lock == IN_PCBLOCK_GRAB) { + mtx_enter(&table->inpt_mtx); + } else { + KASSERT(lock == IN_PCBLOCK_HOLD); + MUTEX_ASSERT_LOCKED(&table->inpt_mtx); + } head = &table->inpt_lhashtbl[lhash & table->inpt_lmask]; LIST_FOREACH(inp, head, inp_lhash) { if (rtable_l2(inp->inp_rtableid) != rdomain) @@ -859,8 +909,10 @@ in_pcblookup_local(struct inpcbtable *table, const void *laddrp, break; } } - in_pcbref(match); - mtx_leave(&table->inpt_mtx); + if (lock == IN_PCBLOCK_GRAB) { + in_pcbref(match); + mtx_leave(&table->inpt_mtx); + } return (match); } @@ -1029,10 +1081,6 @@ in_pcbselsrc(struct in_addr *insrc, struct sockaddr_in *sin, void in_pcbrehash(struct inpcb *inp) { - struct inpcbtable *table = inp->inp_table; - - MUTEX_ASSERT_LOCKED(&table->inpt_mtx); - LIST_REMOVE(inp, inp_lhash); LIST_REMOVE(inp, inp_hash); in_pcbhash_insert(inp); @@ -1154,8 +1202,8 @@ int in_pcbnotifymiss = 0; * After those two lookups no other are necessary. */ struct inpcb * -in_pcblookup(struct inpcbtable *table, struct in_addr faddr, - u_int fport, struct in_addr laddr, u_int lport, u_int rtable) +in_pcblookup_lock(struct inpcbtable *table, struct in_addr faddr, + u_int fport, struct in_addr laddr, u_int lport, u_int rtable, int lock) { struct inpcb *inp; uint64_t hash; @@ -1164,11 +1212,18 @@ in_pcblookup(struct inpcbtable *table, struct in_addr faddr, rdomain = rtable_l2(rtable); hash = in_pcbhash(table, rdomain, &faddr, fport, &laddr, lport); - mtx_enter(&table->inpt_mtx); + if (lock == IN_PCBLOCK_GRAB) { + mtx_enter(&table->inpt_mtx); + } else { + KASSERT(lock == IN_PCBLOCK_HOLD); + MUTEX_ASSERT_LOCKED(&table->inpt_mtx); + } inp = in_pcbhash_lookup(table, hash, rdomain, &faddr, fport, &laddr, lport); - in_pcbref(inp); - mtx_leave(&table->inpt_mtx); + if (lock == IN_PCBLOCK_GRAB) { + in_pcbref(inp); + mtx_leave(&table->inpt_mtx); + } #ifdef DIAGNOSTIC if (inp == NULL && in_pcbnotifymiss) { @@ -1180,6 +1235,14 @@ in_pcblookup(struct inpcbtable *table, struct in_addr faddr, return (inp); } +struct inpcb * +in_pcblookup(struct inpcbtable *table, struct in_addr faddr, + u_int fport, struct in_addr laddr, u_int lport, u_int rtable) +{ + return in_pcblookup_lock(table, faddr, fport, laddr, lport, rtable, + IN_PCBLOCK_GRAB); +} + /* * The in(6)_pcblookup_listen functions are used to locate listening * sockets quickly. This are sockets with unspecified foreign address diff --git a/sys/netinet/in_pcb.h b/sys/netinet/in_pcb.h index c300b8ab0..9c15b4138 100644 --- a/sys/netinet/in_pcb.h +++ b/sys/netinet/in_pcb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: in_pcb.h,v 1.142 2023/12/03 20:24:17 bluhm Exp $ */ +/* $OpenBSD: in_pcb.h,v 1.143 2023/12/07 16:08:30 bluhm Exp $ */ /* $NetBSD: in_pcb.h,v 1.14 1996/02/13 23:42:00 christos Exp $ */ /* @@ -268,6 +268,9 @@ struct baddynamicports { #ifdef _KERNEL +#define IN_PCBLOCK_HOLD 1 +#define IN_PCBLOCK_GRAB 2 + extern struct inpcbtable rawcbtable, rawin6pcbtable; extern struct baddynamicports baddynamicports; extern struct baddynamicports rootonlyports; @@ -276,6 +279,7 @@ extern int in_pcbnotifymiss; void in_init(void); void in_losing(struct inpcb *); int in_pcballoc(struct socket *, struct inpcbtable *, int); +int in_pcbbind_locked(struct inpcb *, struct mbuf *, struct proc *); int in_pcbbind(struct inpcb *, struct mbuf *, struct proc *); int in_pcbaddrisavail(struct inpcb *, struct sockaddr_in *, int, struct proc *); @@ -296,10 +300,12 @@ uint64_t in6_pcbhash(struct inpcbtable *, u_int, const struct in6_addr *, u_short, const struct in6_addr *, u_short); struct inpcb * in6_pcblookup(struct inpcbtable *, const struct in6_addr *, - u_int, const struct in6_addr *, u_int, u_int); + u_int, const struct in6_addr *, u_int, u_int); struct inpcb * in6_pcblookup_listen(struct inpcbtable *, struct in6_addr *, u_int, struct mbuf *, u_int); +int in6_pcbaddrisavail_lock(struct inpcb *, struct sockaddr_in6 *, int, + struct proc *, int); int in6_pcbaddrisavail(struct inpcb *, struct sockaddr_in6 *, int, struct proc *); int in6_pcbconnect(struct inpcb *, struct mbuf *); @@ -310,8 +316,8 @@ int in6_peeraddr(struct socket *, struct mbuf *); #endif /* INET6 */ void in_pcbinit(struct inpcbtable *, int); struct inpcb * - in_pcblookup_local(struct inpcbtable *, const void *, u_int, int, - u_int); + in_pcblookup_local_lock(struct inpcbtable *, const void *, u_int, int, + u_int, int); void in_pcbnotifyall(struct inpcbtable *, struct sockaddr *, u_int, int, void (*)(struct inpcb *, int)); void in_pcbrehash(struct inpcb *); @@ -331,8 +337,6 @@ void in6_pcbnotify(struct inpcbtable *, struct sockaddr_in6 *, u_int, const struct sockaddr_in6 *, u_int, u_int, int, void *, void (*)(struct inpcb *, int)); int in6_selecthlim(struct inpcb *); -int in_pcbpickport(u_int16_t *, const void *, int, const struct inpcb *, - struct proc *); int in_pcbset_rtableid(struct inpcb *, u_int); void in_pcbset_laddr(struct inpcb *, const struct sockaddr *, u_int); void in_pcbunset_faddr(struct inpcb *); diff --git a/sys/netinet6/in6_pcb.c b/sys/netinet6/in6_pcb.c index b0c30bfff..a1bd2bdd1 100644 --- a/sys/netinet6/in6_pcb.c +++ b/sys/netinet6/in6_pcb.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_pcb.c,v 1.130 2023/12/03 20:36:24 bluhm Exp $ */ +/* $OpenBSD: in6_pcb.c,v 1.131 2023/12/07 16:08:30 bluhm Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -129,6 +129,9 @@ const struct in6_addr zeroin6_addr; struct inpcb *in6_pcbhash_lookup(struct inpcbtable *, uint64_t, u_int, const struct in6_addr *, u_short, const struct in6_addr *, u_short); +struct inpcb * in6_pcblookup_lock(struct inpcbtable *, const struct in6_addr *, + u_int, const struct in6_addr *, u_int, u_int, int); + uint64_t in6_pcbhash(struct inpcbtable *table, u_int rdomain, const struct in6_addr *faddr, u_short fport, @@ -147,8 +150,8 @@ in6_pcbhash(struct inpcbtable *table, u_int rdomain, } int -in6_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in6 *sin6, int wild, - struct proc *p) +in6_pcbaddrisavail_lock(struct inpcb *inp, struct sockaddr_in6 *sin6, int wild, + struct proc *p, int lock) { struct socket *so = inp->inp_socket; struct inpcbtable *table = inp->inp_table; @@ -214,26 +217,35 @@ in6_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in6 *sin6, int wild, int error = 0; if (so->so_euid && !IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) { - t = in_pcblookup_local(table, &sin6->sin6_addr, lport, - INPLOOKUP_WILDCARD | INPLOOKUP_IPV6, - inp->inp_rtableid); + t = in_pcblookup_local_lock(table, &sin6->sin6_addr, + lport, INPLOOKUP_WILDCARD | INPLOOKUP_IPV6, + inp->inp_rtableid, lock); if (t && (so->so_euid != t->inp_socket->so_euid)) error = EADDRINUSE; - in_pcbunref(t); + if (lock == IN_PCBLOCK_GRAB) + in_pcbunref(t); if (error) return (error); } - t = in_pcblookup_local(table, &sin6->sin6_addr, lport, - wild, inp->inp_rtableid); + t = in_pcblookup_local_lock(table, &sin6->sin6_addr, lport, + wild, inp->inp_rtableid, lock); if (t && (reuseport & t->inp_socket->so_options) == 0) error = EADDRINUSE; - in_pcbunref(t); + if (lock == IN_PCBLOCK_GRAB) + in_pcbunref(t); if (error) return (error); } return (0); } +int +in6_pcbaddrisavail(struct inpcb *inp, struct sockaddr_in6 *sin6, int wild, + struct proc *p) +{ + return in6_pcbaddrisavail_lock(inp, sin6, wild, p, IN_PCBLOCK_GRAB); +} + /* * Connect from a socket to a specified address. * Both address and port must be specified in argument sin6. @@ -285,11 +297,15 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam) inp->inp_ipv6.ip6_hlim = (u_int8_t)in6_selecthlim(inp); - t = in6_pcblookup(inp->inp_table, &sin6->sin6_addr, sin6->sin6_port, + /* keep lookup, modification, and rehash in sync */ + mtx_enter(&table->inpt_mtx); + + t = in6_pcblookup_lock(inp->inp_table, &sin6->sin6_addr, + sin6->sin6_port, IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6) ? in6a : &inp->inp_laddr6, - inp->inp_lport, inp->inp_rtableid); + inp->inp_lport, inp->inp_rtableid, IN_PCBLOCK_HOLD); if (t != NULL) { - in_pcbunref(t); + mtx_leave(&table->inpt_mtx); return (EADDRINUSE); } @@ -297,15 +313,17 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam) if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_laddr6)) { if (inp->inp_lport == 0) { - error = in_pcbbind(inp, NULL, curproc); - if (error) + error = in_pcbbind_locked(inp, NULL, curproc); + if (error) { + mtx_leave(&table->inpt_mtx); return (error); - t = in6_pcblookup(inp->inp_table, &sin6->sin6_addr, + } + t = in6_pcblookup_lock(inp->inp_table, &sin6->sin6_addr, sin6->sin6_port, in6a, inp->inp_lport, - inp->inp_rtableid); + inp->inp_rtableid, IN_PCBLOCK_HOLD); if (t != NULL) { inp->inp_lport = 0; - in_pcbunref(t); + mtx_leave(&table->inpt_mtx); return (EADDRINUSE); } } @@ -313,8 +331,8 @@ in6_pcbconnect(struct inpcb *inp, struct mbuf *nam) } inp->inp_faddr6 = sin6->sin6_addr; inp->inp_fport = sin6->sin6_port; - mtx_enter(&table->inpt_mtx); in_pcbrehash(inp); + mtx_leave(&table->inpt_mtx); inp->inp_flowinfo &= ~IPV6_FLOWLABEL_MASK; @@ -580,8 +598,9 @@ in6_pcbhash_lookup(struct inpcbtable *table, uint64_t hash, u_int rdomain, } struct inpcb * -in6_pcblookup(struct inpcbtable *table, const struct in6_addr *faddr, - u_int fport, const struct in6_addr *laddr, u_int lport, u_int rtable) +in6_pcblookup_lock(struct inpcbtable *table, const struct in6_addr *faddr, + u_int fport, const struct in6_addr *laddr, u_int lport, u_int rtable, + int lock) { struct inpcb *inp; uint64_t hash; @@ -590,11 +609,18 @@ in6_pcblookup(struct inpcbtable *table, const struct in6_addr *faddr, rdomain = rtable_l2(rtable); hash = in6_pcbhash(table, rdomain, faddr, fport, laddr, lport); - mtx_enter(&table->inpt_mtx); + if (lock == IN_PCBLOCK_GRAB) { + mtx_enter(&table->inpt_mtx); + } else { + KASSERT(lock == IN_PCBLOCK_HOLD); + MUTEX_ASSERT_LOCKED(&table->inpt_mtx); + } inp = in6_pcbhash_lookup(table, hash, rdomain, faddr, fport, laddr, lport); - in_pcbref(inp); - mtx_leave(&table->inpt_mtx); + if (lock == IN_PCBLOCK_GRAB) { + in_pcbref(inp); + mtx_leave(&table->inpt_mtx); + } #ifdef DIAGNOSTIC if (inp == NULL && in_pcbnotifymiss) { @@ -605,6 +631,14 @@ in6_pcblookup(struct inpcbtable *table, const struct in6_addr *faddr, return (inp); } +struct inpcb * +in6_pcblookup(struct inpcbtable *table, const struct in6_addr *faddr, + u_int fport, const struct in6_addr *laddr, u_int lport, u_int rtable) +{ + return in6_pcblookup_lock(table, faddr, fport, laddr, lport, rtable, + IN_PCBLOCK_GRAB); +} + struct inpcb * in6_pcblookup_listen(struct inpcbtable *table, struct in6_addr *laddr, u_int lport, struct mbuf *m, u_int rtable) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 433493b1a..ceebcffd5 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -1,10 +1,10 @@ -/* $OpenBSD: syscall.h,v 1.266 2023/11/29 20:46:24 bluhm Exp $ */ +/* $OpenBSD: syscall.h,v 1.267 2023/12/07 14:00:15 deraadt Exp $ */ /* * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.251 2023/11/29 20:40:06 bluhm Exp + * created from; OpenBSD: syscalls.master,v 1.252 2023/12/07 13:59:04 deraadt Exp */ /* syscall: "syscall" ret: "int" args: "int" "..." */ @@ -446,7 +446,9 @@ /* 156 is obsolete ogetdirentries */ /* 157 is obsolete statfs25 */ - /* 158 is obsolete fstatfs25 */ +/* syscall: "pinsyscalls" ret: "int" args: "void *" "size_t" "void *" "size_t" */ +#define SYS_pinsyscalls 158 + /* syscall: "mimmutable" ret: "int" args: "void *" "size_t" */ #define SYS_mimmutable 159 diff --git a/sys/sys/syscallargs.h b/sys/sys/syscallargs.h index 81f890065..d91d1c745 100644 --- a/sys/sys/syscallargs.h +++ b/sys/sys/syscallargs.h @@ -1,10 +1,10 @@ -/* $OpenBSD: syscallargs.h,v 1.269 2023/11/29 20:46:24 bluhm Exp $ */ +/* $OpenBSD: syscallargs.h,v 1.270 2023/12/07 14:00:15 deraadt Exp $ */ /* * System call argument lists. * * DO NOT EDIT-- this file is automatically generated. - * created from; OpenBSD: syscalls.master,v 1.251 2023/11/29 20:40:06 bluhm Exp + * created from; OpenBSD: syscalls.master,v 1.252 2023/12/07 13:59:04 deraadt Exp */ #ifdef syscallarg @@ -750,6 +750,13 @@ struct sys_nfssvc_args { syscallarg(void *) argp; }; +struct sys_pinsyscalls_args { + syscallarg(void *) base; + syscallarg(size_t) len; + syscallarg(void *) pins; + syscallarg(size_t) pinslen; +}; + struct sys_mimmutable_args { syscallarg(void *) addr; syscallarg(size_t) len; @@ -1310,6 +1317,7 @@ int sys_ypconnect(struct proc *, void *, register_t *); int sys_nfssvc(struct proc *, void *, register_t *); #else #endif +int sys_pinsyscalls(struct proc *, void *, register_t *); int sys_mimmutable(struct proc *, void *, register_t *); int sys_waitid(struct proc *, void *, register_t *); int sys_getfh(struct proc *, void *, register_t *); diff --git a/sys/uvm/uvm_mmap.c b/sys/uvm/uvm_mmap.c index caea59be2..1ff2d3106 100644 --- a/sys/uvm/uvm_mmap.c +++ b/sys/uvm/uvm_mmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_mmap.c,v 1.182 2023/05/09 10:35:20 kn Exp $ */ +/* $OpenBSD: uvm_mmap.c,v 1.183 2023/12/07 13:59:05 deraadt Exp $ */ /* $NetBSD: uvm_mmap.c,v 1.49 2001/02/18 21:19:08 chs Exp $ */ /* @@ -644,6 +644,16 @@ sys_pinsyscall(struct proc *p, void *v, register_t *retval) return (0); } + /* + * sys_pinsyscalls + */ +int +sys_pinsyscalls(struct proc *p, void *v, register_t *retval) +{ + /* STUB until other parts are ready */ + return (0); +} + /* * sys_mimmutable: the mimmutable system call */ diff --git a/usr.bin/ssh/log.c b/usr.bin/ssh/log.c index dd704437a..57d7d166b 100644 --- a/usr.bin/ssh/log.c +++ b/usr.bin/ssh/log.c @@ -1,4 +1,4 @@ -/* $OpenBSD: log.c,v 1.60 2021/09/16 15:11:19 djm Exp $ */ +/* $OpenBSD: log.c,v 1.61 2023/12/06 21:06:48 djm Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -427,6 +427,10 @@ sshlogv(const char *file, const char *func, int line, int showfunc, const char *cp; size_t i; + /* short circuit processing early if we're not going to log anything */ + if (nlog_verbose == 0 && level > log_level) + return; + snprintf(tag, sizeof(tag), "%.48s:%.48s():%d (pid=%ld)", (cp = strrchr(file, '/')) == NULL ? file : cp + 1, func, line, (long)getpid());