From 1b576c8ddfecd128e372da2dfbda08bb3fdb3b20 Mon Sep 17 00:00:00 2001 From: purplerain Date: Wed, 17 Apr 2024 02:49:09 +0000 Subject: [PATCH] sync with OpenBSD -current --- bin/pax/extern.h | 3 +- bin/pax/options.c | 47 +++++-- bin/pax/tar.1 | 80 ++++++++++- bin/pax/tar.c | 53 +++++++- lib/libcrypto/Symbols.list | 2 +- lib/libcrypto/bn/bn_convert.c | 109 +++++++++------ lib/libcrypto/bn/bn_lib.c | 20 ++- lib/libcrypto/bn/bn_local.h | 5 +- lib/libssl/ssl_tlsext.c | 41 +++++- sys/dev/wsfont/spleen32x64.h | 8 +- sys/netinet/ip_input.c | 63 ++++----- sys/netinet/ip_var.h | 4 +- sys/netinet6/in6.c | 17 ++- sys/netinet6/in6_proto.c | 6 +- sys/netinet6/ip6_forward.c | 54 ++++---- sys/netinet6/ip6_input.c | 20 ++- sys/netinet6/ip6_output.c | 4 +- sys/netinet6/ip6_var.h | 4 +- sys/netinet6/raw_ip6.c | 26 ++-- sys/ufs/mfs/mfs_vnops.c | 5 +- sys/uvm/uvm_amap.c | 9 +- sys/uvm/uvm_swap.c | 3 +- usr.bin/less/filename.c | 79 ----------- usr.bin/openssl/req.c | 3 +- usr.sbin/httpd/server_file.c | 247 ++++++++++++++++------------------ 25 files changed, 517 insertions(+), 395 deletions(-) diff --git a/bin/pax/extern.h b/bin/pax/extern.h index 9730b8db8..6e7031ab1 100644 --- a/bin/pax/extern.h +++ b/bin/pax/extern.h @@ -1,4 +1,4 @@ -/* $OpenBSD: extern.h,v 1.62 2023/12/09 23:00:11 jca Exp $ */ +/* $OpenBSD: extern.h,v 1.63 2024/04/16 18:52:43 jca Exp $ */ /* $NetBSD: extern.h,v 1.5 1996/03/26 23:54:16 mrg Exp $ */ /*- @@ -284,6 +284,7 @@ int tar_wr(ARCHD *); int ustar_id(char *, int); int ustar_rd(ARCHD *, char *); int ustar_wr(ARCHD *); +int pax_id(char *, int); int pax_wr(ARCHD *); /* diff --git a/bin/pax/options.c b/bin/pax/options.c index d8b1c0995..54c6b3050 100644 --- a/bin/pax/options.c +++ b/bin/pax/options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: options.c,v 1.109 2024/04/15 22:07:08 caspar Exp $ */ +/* $OpenBSD: options.c,v 1.112 2024/04/16 23:09:35 jca Exp $ */ /* $NetBSD: options.c,v 1.6 1996/03/26 23:54:18 mrg Exp $ */ /*- @@ -228,7 +228,7 @@ FSUB fsub[] = { /* 9: gzip, to detect failure to use -z */ {NULL, 0, 4, 0, 0, 0, 0, gzip_id}, /* 10: POSIX PAX */ - {"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, ustar_id, no_op, + {"pax", 5120, BLKMULT, 0, 1, BLKMULT, 0, pax_id, no_op, ustar_rd, tar_endrd, no_op, pax_wr, tar_endwr, tar_trail, tar_opt}, #endif @@ -237,10 +237,11 @@ FSUB fsub[] = { #define F_ACPIO 1 /* format when called as cpio -c */ #define F_CPIO 3 /* format when called as cpio */ #define F_OTAR 4 /* format when called as tar -o */ -#define F_TAR 5 /* format when called as tar */ #ifdef SMALL +# define F_TAR 5 /* default write format when called as tar: ustar */ # define DEFLT 5 /* default write format when called as pax: ustar */ #else +# define F_TAR 10 /* default write format when called as tar: ustar */ # define DEFLT 10 /* default write format when called as pax: pax */ #endif @@ -249,7 +250,7 @@ FSUB fsub[] = { * of archive we are dealing with. This helps to properly id archive formats * some formats may be subsets of others.... */ -int ford[] = {5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1}; +int ford[] = {10, 5, 4, 9, 8, 7, 6, 3, 2, 1, 0, -1}; /* * Do we have -C anywhere and what is it? @@ -725,9 +726,10 @@ static void tar_options(int argc, char **argv) { int c; - int Oflag = 0; int nincfiles = 0; int incfiles_max = 0; + unsigned int i; + unsigned int format = F_TAR; struct incfile { char *file; char *dir; @@ -743,7 +745,7 @@ tar_options(int argc, char **argv) * process option flags */ while ((c = getoldopt(argc, argv, - "b:cef:hjmopqruts:vwxzBC:HI:LNOPXZ014578")) != -1) { + "b:cef:hjmopqruts:vwxzBC:F:HI:LNOPXZ014578")) != -1) { switch (c) { case 'b': /* @@ -792,10 +794,10 @@ tar_options(int argc, char **argv) pmtime = 0; break; case 'O': - Oflag = 1; + format = F_OTAR; break; case 'o': - Oflag = 2; + format = F_OTAR; tar_nodir = 1; break; case 'p': @@ -868,6 +870,24 @@ tar_options(int argc, char **argv) havechd++; chdname = optarg; break; + case 'F': + for (i = 0; i < sizeof(fsub)/sizeof(FSUB); ++i) + if (fsub[i].name != NULL && + strcmp(fsub[i].name, optarg) == 0) + break; + if (i < sizeof(fsub)/sizeof(FSUB)) { + format = i; + break; + } + paxwarn(1, "Unknown -F format: %s", optarg); + (void)fputs("tar: Known -F formats are:", stderr); + for (i = 0; i < (sizeof(fsub)/sizeof(FSUB)); ++i) + if (fsub[i].name != NULL) + (void)fprintf(stderr, " %s", + fsub[i].name); + (void)fputs("\n\n", stderr); + tar_usage(); + break; case 'H': /* * follow command line symlinks only @@ -1042,7 +1062,7 @@ tar_options(int argc, char **argv) break; case ARCHIVE: case APPND: - frmt = &(fsub[Oflag ? F_OTAR : F_TAR]); + frmt = &fsub[format]; if (chdname != NULL) { /* initial chdir() */ if (ftree_add(chdname, 1) < 0) @@ -1704,11 +1724,12 @@ void tar_usage(void) { (void)fputs( - "usage: tar {crtux}[014578befHhjLmNOoPpqsvwXZz]\n" - " [blocking-factor | archive | replstr] [-C directory] [-I file]\n" - " [file ...]\n" + "usage: tar {crtux}[014578beFfHhjLmNOoPpqsvwXZz]\n" + " [blocking-factor | format | archive | replstr]\n" + " [-C directory] [-I file] [file ...]\n" " tar {-crtux} [-014578eHhjLmNOoPpqvwXZz] [-b blocking-factor]\n" - " [-C directory] [-f archive] [-I file] [-s replstr] [file ...]\n", + " [-C directory] [-F format] [-f archive] [-I file]\n" + " [-s replstr] [file ...]\n", stderr); exit(1); } diff --git a/bin/pax/tar.1 b/bin/pax/tar.1 index 5b37487ba..9e4906a83 100644 --- a/bin/pax/tar.1 +++ b/bin/pax/tar.1 @@ -1,4 +1,4 @@ -.\" $OpenBSD: tar.1,v 1.65 2023/08/03 18:17:54 aisha Exp $ +.\" $OpenBSD: tar.1,v 1.67 2024/04/16 23:09:35 jca Exp $ .\" .\" Copyright (c) 1996 SigmaSoft, Th. Lockert .\" All rights reserved. @@ -23,7 +23,7 @@ .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. .\" -.Dd $Mdocdate: August 3 2023 $ +.Dd $Mdocdate: April 16 2024 $ .Dt TAR 1 .Os .Sh NAME @@ -32,10 +32,10 @@ .Sh SYNOPSIS .Nm tar .Sm off -.No { Cm crtux No } Op Cm 014578befHhjLmNOoPpqsvwXZz +.No { Cm crtux No } Op Cm 014578beFfHhjLmNOoPpqsvwXZz .Sm on .Bk -words -.Op Ar blocking-factor | archive | replstr +.Op Ar blocking-factor | format | archive | replstr .Op Fl C Ar directory .Op Fl I Ar file .Op Ar @@ -46,6 +46,7 @@ .Op Fl 014578eHhjLmNOoPpqvwXZz .Op Fl b Ar blocking-factor .Op Fl C Ar directory +.Op Fl F Ar format .Op Fl f Ar archive .Op Fl I Ar file .Op Fl s Ar replstr @@ -141,6 +142,77 @@ the specified directory; when creating, the specified files will be matched from the directory. .It Fl e Stop after the first error. +.It Fl F Ar format +Specify the output archive format, with the default format being +.Cm pax . +.Nm +currently supports the following formats: +.Bl -tag -width "sv4cpio" +.It Cm bcpio +The old binary cpio format. +The default blocksize for this format is 5120 bytes. +This format is not very portable and should not be used when other formats +are available. +Inode and device information about a file (used for detecting file hard links +by this format), which may be truncated by this format, is detected by +.Nm +and is repaired. +.It Cm cpio +The extended cpio interchange format specified in the +.St -p1003.2 +standard. +The default blocksize for this format is 5120 bytes. +Inode and device information about a file (used for detecting file hard links +by this format), which may be truncated by this format, is detected by +.Nm +and is repaired. +.It Cm sv4cpio +The System V release 4 cpio. +The default blocksize for this format is 5120 bytes. +Inode and device information about a file (used for detecting file hard links +by this format), which may be truncated by this format, is detected by +.Nm +and is repaired. +.It Cm sv4crc +The System V release 4 cpio with file CRC checksums. +The default blocksize for this format is 5120 bytes. +Inode and device information about a file (used for detecting file hard links +by this format), which may be truncated by this format, is detected by +.Nm +and is repaired. +.It Cm tar +The old +.Bx +tar format as found in +.Bx 4.3 . +The default blocksize for this format is 10240 bytes. +Pathnames stored by this format must be 100 characters or less in length. +Only regular files, hard links, soft links, and directories +will be archived (other file system types are not supported). +For backwards compatibility with even older tar formats, see the +description for +.Fl o . +.It Cm ustar +The extended tar interchange format specified in the +.St -p1003.2 +standard. +The default blocksize for this format is 10240 bytes. +Filenames stored by this format must be 100 characters or less in length; +the total pathname must be 256 characters or less. +.It Cm pax +The pax interchange format specified in the +.St -p1003.1-2001 +standard. +The default blocksize for this format is 5120 bytes. +.El +.Pp +.Nm +will detect and report any file that it is unable to store or extract +as the result of any specific archive format restrictions. +The individual archive formats may impose additional restrictions on use. +Typical archive format restrictions include (but are not limited to): +file pathname length, file size, link pathname length, and the type of the +file. .It Fl f Ar archive Read from or write to .Ar archive . diff --git a/bin/pax/tar.c b/bin/pax/tar.c index cd64ec7ba..01f4491ac 100644 --- a/bin/pax/tar.c +++ b/bin/pax/tar.c @@ -1,4 +1,4 @@ -/* $OpenBSD: tar.c,v 1.79 2024/01/20 17:34:50 jca Exp $ */ +/* $OpenBSD: tar.c,v 1.84 2024/04/16 22:58:10 jca Exp $ */ /* $NetBSD: tar.c,v 1.5 1995/03/21 09:07:49 cgd Exp $ */ /*- @@ -62,9 +62,6 @@ struct xheader_record { /* shortest possible extended record: "5 a=\n" */ #define MINXHDRSZ 5 -/* longest record we'll accept */ -#define MAXXHDRSZ BLKMULT - /* * Routines for reading, writing and header identify of various versions of tar */ @@ -1135,7 +1132,7 @@ wr_ustar_or_pax(ARCHD *arcn, int ustar) return(1); } #ifndef SMALL - else if (xheader_add(&xhdr, "linkpath", arcn->name) == -1) { + else if (xheader_add(&xhdr, "linkpath", arcn->ln_name) == -1) { paxwarn(1, "Link name too long for pax %s", arcn->ln_name); xheader_free(&xhdr); @@ -1391,6 +1388,46 @@ ustar_wr(ARCHD *arcn) return wr_ustar_or_pax(arcn, 1); } +/* + * pax_id() + * determine if a block given to us is a valid pax header. + * Return: + * 0 if a pax header, -1 otherwise + */ +#ifndef SMALL +int +pax_id(char *blk, int size) +{ + HD_USTAR *hd; + + if (size < BLKMULT) + return(-1); + hd = (HD_USTAR *)blk; + + /* + * check for block of zero's first, a simple and fast test then check + * ustar magic cookie. We should use TMAGLEN, but some USTAR archive + * programs are fouled up and create archives missing the \0. Last we + * check the checksum and the type flag. If ok we have to assume it is + * a valid pax header. + */ + if (hd->prefix[0] == '\0' && hd->name[0] == '\0') + return(-1); + if (strncmp(hd->magic, TMAGIC, TMAGLEN - 1) != 0) + return(-1); + if (asc_ul(hd->chksum,sizeof(hd->chksum),OCT) != tar_chksm(blk,BLKMULT)) + return(-1); + /* + * It is valid for a pax formatted archive not to start with + * a global header nor with an extended header. In that case + * we'll fall back to ustar in append mode. + */ + if (hd->typeflag == XHDRTYPE || hd->typeflag == GHDRTYPE) + return(0); + return (-1); +} +#endif + /* * pax_wr() * Write out a pax format archive. @@ -1548,7 +1585,11 @@ rd_size(off_t *size, const char *keyword, char *p) static int rd_xheader(ARCHD *arcn, int global, off_t size) { - char buf[MAXXHDRSZ]; + /* + * The pax format supposedly supports arbitrarily sized extended + * record headers, this implementation doesn't. + */ + char buf[sizeof("30xx linkpath=") - 1 + PAXPATHLEN + sizeof("\n")]; long len; char *delim, *keyword; char *nextp, *p, *end; diff --git a/lib/libcrypto/Symbols.list b/lib/libcrypto/Symbols.list index aa3019905..dfe7ce492 100644 --- a/lib/libcrypto/Symbols.list +++ b/lib/libcrypto/Symbols.list @@ -2693,8 +2693,8 @@ X509_STORE_add_crl X509_STORE_add_lookup X509_STORE_free X509_STORE_get0_objects -X509_STORE_get1_objects X509_STORE_get0_param +X509_STORE_get1_objects X509_STORE_get_check_issued X509_STORE_get_ex_data X509_STORE_get_verify diff --git a/lib/libcrypto/bn/bn_convert.c b/lib/libcrypto/bn/bn_convert.c index f09c9091e..5c3c98b78 100644 --- a/lib/libcrypto/bn/bn_convert.c +++ b/lib/libcrypto/bn/bn_convert.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_convert.c,v 1.15 2023/07/09 18:37:58 tb Exp $ */ +/* $OpenBSD: bn_convert.c,v 1.18 2024/04/16 13:14:46 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -153,46 +153,69 @@ BN_bn2binpad(const BIGNUM *a, unsigned char *to, int tolen) } LCRYPTO_ALIAS(BN_bn2binpad); -BIGNUM * -BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret) +static int +bn_bin2bn_cbs(BIGNUM **bnp, CBS *cbs) { - unsigned int i, m; - unsigned int n; - BN_ULONG l; BIGNUM *bn = NULL; + BN_ULONG w; + uint8_t v; + int b, i; - if (len < 0) - return (NULL); - if (ret == NULL) - ret = bn = BN_new(); - if (ret == NULL) - return (NULL); - l = 0; - n = len; - if (n == 0) { - ret->top = 0; - return (ret); - } - i = ((n - 1) / BN_BYTES) + 1; - m = ((n - 1) % (BN_BYTES)); - if (!bn_wexpand(ret, (int)i)) { - BN_free(bn); - return NULL; - } - ret->top = i; - ret->neg = 0; - while (n--) { - l = (l << 8L) | *(s++); - if (m-- == 0) { - ret->d[--i] = l; - l = 0; - m = BN_BYTES - 1; + if ((bn = *bnp) == NULL) + bn = BN_new(); + if (bn == NULL) + goto err; + if (!bn_expand_bytes(bn, CBS_len(cbs))) + goto err; + + b = 0; + i = 0; + w = 0; + + while (CBS_len(cbs) > 0) { + if (!CBS_get_last_u8(cbs, &v)) + goto err; + + w |= (BN_ULONG)v << b; + b += 8; + + if (b == BN_BITS2 || CBS_len(cbs) == 0) { + b = 0; + bn->d[i++] = w; + w = 0; } } - /* need to call this due to clear byte at top if avoiding - * having the top bit set (-ve number) */ - bn_correct_top(ret); - return (ret); + + bn->neg = 0; + bn->top = i; + + bn_correct_top(bn); + + *bnp = bn; + + return 1; + + err: + if (*bnp == NULL) + BN_free(bn); + + return 0; +} + +BIGNUM * +BN_bin2bn(const unsigned char *d, int len, BIGNUM *bn) +{ + CBS cbs; + + if (len < 0) + return NULL; + + CBS_init(&cbs, d, len); + + if (!bn_bin2bn_cbs(&bn, &cbs)) + return NULL; + + return bn; } LCRYPTO_ALIAS(BN_bin2bn); @@ -431,7 +454,7 @@ bn_dec2bn_cbs(BIGNUM **bnp, CBS *cbs) bn = BN_new(); if (bn == NULL) goto err; - if (!bn_expand(bn, digits * 4)) + if (!bn_expand_bits(bn, digits * 4)) goto err; if ((d = digits % BN_DEC_NUM) == 0) @@ -628,13 +651,13 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs) bn = BN_new(); if (bn == NULL) goto err; - if (!bn_expand(bn, digits * 4)) + if (!bn_expand_bits(bn, digits * 4)) goto err; if (!CBS_get_bytes(cbs, cbs, digits)) goto err; - b = BN_BITS2; + b = 0; i = 0; w = 0; @@ -652,11 +675,11 @@ bn_hex2bn_cbs(BIGNUM **bnp, CBS *cbs) else goto err; - w |= (BN_ULONG)v << (BN_BITS2 - b); - b -= 4; + w |= (BN_ULONG)v << b; + b += 4; - if (b == 0 || digits == 0) { - b = BN_BITS2; + if (b == BN_BITS2 || digits == 0) { + b = 0; bn->d[i++] = w; w = 0; } diff --git a/lib/libcrypto/bn/bn_lib.c b/lib/libcrypto/bn/bn_lib.c index b59e65a1e..72b988650 100644 --- a/lib/libcrypto/bn/bn_lib.c +++ b/lib/libcrypto/bn/bn_lib.c @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_lib.c,v 1.91 2024/04/15 14:35:25 jsing Exp $ */ +/* $OpenBSD: bn_lib.c,v 1.93 2024/04/16 13:07:14 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -219,13 +219,10 @@ bn_expand_internal(BIGNUM *bn, int words) } int -bn_expand(BIGNUM *bn, int bits) +bn_expand_bits(BIGNUM *bn, size_t bits) { int words; - if (bits < 0) - return 0; - if (bits > (INT_MAX - BN_BITS2 + 1)) return 0; @@ -234,6 +231,19 @@ bn_expand(BIGNUM *bn, int bits) return bn_wexpand(bn, words); } +int +bn_expand_bytes(BIGNUM *bn, size_t bytes) +{ + int words; + + if (bytes > (INT_MAX - BN_BYTES + 1)) + return 0; + + words = (bytes + BN_BYTES - 1) / BN_BYTES; + + return bn_wexpand(bn, words); +} + int bn_wexpand(BIGNUM *bn, int words) { diff --git a/lib/libcrypto/bn/bn_local.h b/lib/libcrypto/bn/bn_local.h index 2c82e323f..58b5d5490 100644 --- a/lib/libcrypto/bn/bn_local.h +++ b/lib/libcrypto/bn/bn_local.h @@ -1,4 +1,4 @@ -/* $OpenBSD: bn_local.h,v 1.41 2024/04/10 15:09:03 tb Exp $ */ +/* $OpenBSD: bn_local.h,v 1.43 2024/04/16 13:07:14 jsing Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -259,7 +259,8 @@ int bn_mul_mont(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, const BN_ULONG *np, const BN_ULONG *n0, int num); void bn_correct_top(BIGNUM *a); -int bn_expand(BIGNUM *a, int bits); +int bn_expand_bits(BIGNUM *a, size_t bits); +int bn_expand_bytes(BIGNUM *a, size_t bytes); int bn_wexpand(BIGNUM *a, int words); BN_ULONG bn_add_words(BN_ULONG *rp, const BN_ULONG *ap, const BN_ULONG *bp, diff --git a/lib/libssl/ssl_tlsext.c b/lib/libssl/ssl_tlsext.c index 6d8f51833..64fa52e20 100644 --- a/lib/libssl/ssl_tlsext.c +++ b/lib/libssl/ssl_tlsext.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssl_tlsext.c,v 1.148 2024/04/04 08:02:21 tb Exp $ */ +/* $OpenBSD: ssl_tlsext.c,v 1.149 2024/04/16 17:46:30 tb Exp $ */ /* * Copyright (c) 2016, 2017, 2019 Joel Sing * Copyright (c) 2017 Doug Hogan @@ -1493,6 +1493,45 @@ tlsext_keyshare_server_process(SSL *s, uint16_t msg_type, CBS *cbs, int *alert) return 0; } + if (s->s3->hs.tls13.hrr) { + if (!CBS_get_u16_length_prefixed(cbs, &client_shares)) + return 0; + + /* Unpack client share. */ + if (!CBS_get_u16(&client_shares, &group)) + return 0; + if (!CBS_get_u16_length_prefixed(&client_shares, &key_exchange)) + return 0; + + /* There should only be one share. */ + if (CBS_len(&client_shares) != 0) + return 0; + + if (group != s->s3->hs.tls13.server_group) { + *alert = SSL_AD_ILLEGAL_PARAMETER; + return 0; + } + + if (s->s3->hs.key_share != NULL) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + /* Decode and store the selected key share. */ + if ((s->s3->hs.key_share = tls_key_share_new(group)) == NULL) { + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + if (!tls_key_share_peer_public(s->s3->hs.key_share, + &key_exchange, &decode_error, NULL)) { + if (!decode_error) + *alert = SSL_AD_INTERNAL_ERROR; + return 0; + } + + return 1; + } + /* * XXX similar to tls1_get_supported_group, but client pref * only - consider deduping later. diff --git a/sys/dev/wsfont/spleen32x64.h b/sys/dev/wsfont/spleen32x64.h index 1470730f1..a229340ee 100644 --- a/sys/dev/wsfont/spleen32x64.h +++ b/sys/dev/wsfont/spleen32x64.h @@ -1,7 +1,7 @@ -/* $OpenBSD: spleen32x64.h,v 1.9 2020/07/31 20:14:47 fcambus Exp $ */ +/* $OpenBSD: spleen32x64.h,v 1.10 2024/04/16 17:15:15 fcambus Exp $ */ /* - * Copyright (c) 2018-2020 Frederic Cambus + * Copyright (c) 2018-2024 Frederic Cambus * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -5616,11 +5616,11 @@ static u_char spleen32x64_data[] = { 0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */ 0x0f, 0x00, 0x00, 0xf0, /* ....****................****.... */ 0x0f, 0x80, 0x00, 0xf0, /* ....*****...............****.... */ - 0x0f, 0xc0, 0x00, 0xf0, /* ....******..............****.... */ + 0x07, 0xc0, 0x00, 0xf0, /* .....*****..............****.... */ 0x07, 0xff, 0xff, 0xf0, /* .....***********************.... */ 0x03, 0xff, 0xff, 0xf0, /* ......**********************.... */ 0x01, 0xff, 0xff, 0xf0, /* .......*********************.... */ - 0x00, 0xff, 0xff, 0xf0, /* ........********************.... */ + 0x00, 0x7f, 0xff, 0xf0, /* .........*******************.... */ 0x00, 0x00, 0x00, 0x00, /* ................................ */ 0x00, 0x00, 0x00, 0x00, /* ................................ */ 0x00, 0x00, 0x00, 0x00, /* ................................ */ diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 25f9cc5eb..1d1510470 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.392 2024/04/14 20:46:27 bluhm Exp $ */ +/* $OpenBSD: ip_input.c,v 1.393 2024/04/16 12:56:39 bluhm Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -138,7 +138,7 @@ extern struct niqueue arpinq; int ip_ours(struct mbuf **, int *, int, int); int ip_dooptions(struct mbuf *, struct ifnet *); -int in_ouraddr(struct mbuf *, struct ifnet *, struct rtentry **); +int in_ouraddr(struct mbuf *, struct ifnet *, struct route *); int ip_fragcheck(struct mbuf **, int *); struct mbuf * ip_reass(struct ipqent *, struct ipq *); @@ -424,9 +424,9 @@ bad: int ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) { - struct mbuf *m; - struct rtentry *rt = NULL; - struct ip *ip; + struct route ro; + struct mbuf *m; + struct ip *ip; int hlen; #if NPF > 0 struct in_addr odst; @@ -435,6 +435,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) KASSERT(*offp == 0); + ro.ro_rt = NULL; ipstat_inc(ips_total); m = *mp = ipv4_check(ifp, *mp); if (m == NULL) @@ -482,7 +483,7 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) goto out; } - switch(in_ouraddr(m, ifp, &rt)) { + switch(in_ouraddr(m, ifp, &ro)) { case 2: goto bad; case 1: @@ -584,14 +585,14 @@ ip_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) } #endif /* IPSEC */ - ip_forward(m, ifp, rt, pfrdr); + ip_forward(m, ifp, &ro, pfrdr); *mp = NULL; return IPPROTO_DONE; bad: nxt = IPPROTO_DONE; m_freemp(mp); out: - rtfree(rt); + rtfree(ro.ro_rt); return nxt; } @@ -805,11 +806,10 @@ ip_deliver(struct mbuf **mp, int *offp, int nxt, int af, int shared) #undef IPSTAT_INC int -in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt) +in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct route *ro) { struct rtentry *rt; struct ip *ip; - struct sockaddr_in sin; int match = 0; #if NPF > 0 @@ -826,13 +826,8 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt) ip = mtod(m, struct ip *); - memset(&sin, 0, sizeof(sin)); - sin.sin_len = sizeof(sin); - sin.sin_family = AF_INET; - sin.sin_addr = ip->ip_dst; - rt = rtalloc_mpath(sintosa(&sin), &ip->ip_src.s_addr, - m->m_pkthdr.ph_rtableid); - if (rtisvalid(rt)) { + rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); + if (rt != NULL) { if (ISSET(rt->rt_flags, RTF_LOCAL)) match = 1; @@ -848,7 +843,6 @@ in_ouraddr(struct mbuf *m, struct ifnet *ifp, struct rtentry **prt) m->m_flags |= M_BCAST; } } - *prt = rt; if (!match) { struct ifaddr *ifa; @@ -1527,11 +1521,12 @@ const u_char inetctlerrmap[PRC_NCMDS] = { * via a source route. */ void -ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) +ip_forward(struct mbuf *m, struct ifnet *ifp, struct route *ro, int srcrt) { struct mbuf mfake, *mcopy; struct ip *ip = mtod(m, struct ip *); - struct route ro; + struct route iproute; + struct rtentry *rt; int error = 0, type = 0, code = 0, destmtu = 0, fake = 0, len; u_int32_t dest; @@ -1546,19 +1541,16 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) goto done; } - ro.ro_rt = NULL; - route_cache(&ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); - if (!rtisvalid(rt)) { - rtfree(rt); - rt = rtalloc_mpath(&ro.ro_dstsa, &ip->ip_src.s_addr, - m->m_pkthdr.ph_rtableid); - if (rt == NULL) { - ipstat_inc(ips_noroute); - icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0); - return; - } + if (ro == NULL) { + ro = &iproute; + ro->ro_rt = NULL; + } + rt = route_mpath(ro, &ip->ip_dst, &ip->ip_src, m->m_pkthdr.ph_rtableid); + if (rt == NULL) { + ipstat_inc(ips_noroute); + icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_HOST, dest, 0); + goto done; } - ro.ro_rt = rt; /* * Save at most 68 bytes of the packet in case @@ -1609,10 +1601,10 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) } } - error = ip_output(m, NULL, &ro, + error = ip_output(m, NULL, ro, (IP_FORWARDING | (ip_directedbcast ? IP_ALLOWBROADCAST : 0)), NULL, NULL, 0); - rt = ro.ro_rt; + rt = ro->ro_rt; if (error) ipstat_inc(ips_cantforward); else { @@ -1680,9 +1672,10 @@ ip_forward(struct mbuf *m, struct ifnet *ifp, struct rtentry *rt, int srcrt) icmp_error(mcopy, type, code, dest, destmtu); done: + if (ro == &iproute) + rtfree(ro->ro_rt); if (fake) m_tag_delete_chain(&mfake); - rtfree(rt); } int diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index c5b928475..cdbdd2d43 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_var.h,v 1.115 2024/04/14 20:46:27 bluhm Exp $ */ +/* $OpenBSD: ip_var.h,v 1.116 2024/04/16 12:56:39 bluhm Exp $ */ /* $NetBSD: ip_var.h,v 1.16 1996/02/13 23:43:20 christos Exp $ */ /* @@ -260,7 +260,7 @@ void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *, struct mbuf *); int ip_input_if(struct mbuf **, int *, int, int, struct ifnet *); int ip_deliver(struct mbuf **, int *, int, int, int); -void ip_forward(struct mbuf *, struct ifnet *, struct rtentry *, int); +void ip_forward(struct mbuf *, struct ifnet *, struct route *, int); int rip_ctloutput(int, struct socket *, int, int, struct mbuf *); void rip_init(void); int rip_input(struct mbuf **, int *, int, int); diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 1266354e2..244fb26e0 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6.c,v 1.262 2023/06/28 11:49:49 kn Exp $ */ +/* $OpenBSD: in6.c,v 1.263 2024/04/16 14:37:49 florian Exp $ */ /* $KAME: in6.c,v 1.372 2004/06/14 08:14:21 itojun Exp $ */ /* @@ -565,7 +565,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, * The destination address for a p2p link must have a family * of AF_UNSPEC or AF_INET6. */ - if ((ifp->if_flags & IFF_POINTOPOINT) != 0 && + if ((ifp->if_flags & IFF_POINTOPOINT) && ifra->ifra_dstaddr.sin6_family != AF_INET6 && ifra->ifra_dstaddr.sin6_family != AF_UNSPEC) return (EAFNOSUPPORT); @@ -603,19 +603,18 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, * zone identifier. */ dst6 = ifra->ifra_dstaddr; - if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) != 0 && + if ((ifp->if_flags & IFF_POINTOPOINT) && (dst6.sin6_family == AF_INET6)) { error = in6_check_embed_scope(&dst6, ifp->if_index); if (error) return error; } /* - * The destination address can be specified only for a p2p or a - * loopback interface. If specified, the corresponding prefix length - * must be 128. + * The destination address can be specified only for a p2p interface. + * If specified, the corresponding prefix length must be 128. */ if (ifra->ifra_dstaddr.sin6_family == AF_INET6) { - if ((ifp->if_flags & (IFF_POINTOPOINT|IFF_LOOPBACK)) == 0) + if (!(ifp->if_flags & IFF_POINTOPOINT)) return (EINVAL); if (plen != 128) return (EINVAL); @@ -652,7 +651,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, ia6->ia_addr.sin6_family = AF_INET6; ia6->ia_addr.sin6_len = sizeof(ia6->ia_addr); ia6->ia6_updatetime = getuptime(); - if ((ifp->if_flags & (IFF_POINTOPOINT | IFF_LOOPBACK)) != 0) { + if (ifp->if_flags & IFF_POINTOPOINT) { /* * XXX: some functions expect that ifa_dstaddr is not * NULL for p2p interfaces. @@ -687,7 +686,7 @@ in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, /* * If a new destination address is specified, scrub the old one and * install the new destination. Note that the interface must be - * p2p or loopback (see the check above.) + * p2p (see the check above.) */ if ((ifp->if_flags & IFF_POINTOPOINT) && dst6.sin6_family == AF_INET6 && !IN6_ARE_ADDR_EQUAL(&dst6.sin6_addr, &ia6->ia_dstaddr.sin6_addr)) { diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c index db218af06..f73e00b4d 100644 --- a/sys/netinet6/in6_proto.c +++ b/sys/netinet6/in6_proto.c @@ -1,4 +1,4 @@ -/* $OpenBSD: in6_proto.c,v 1.113 2024/01/11 14:15:12 bluhm Exp $ */ +/* $OpenBSD: in6_proto.c,v 1.114 2024/04/16 12:40:40 bluhm Exp $ */ /* $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $ */ /* @@ -158,7 +158,7 @@ const struct protosw inet6sw[] = { .pr_type = SOCK_RAW, .pr_domain = &inet6domain, .pr_protocol = IPPROTO_RAW, - .pr_flags = PR_ATOMIC|PR_ADDR, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT, .pr_input = rip6_input, .pr_ctlinput = rip6_ctlinput, .pr_ctloutput = rip6_ctloutput, @@ -322,7 +322,7 @@ const struct protosw inet6sw[] = { /* raw wildcard */ .pr_type = SOCK_RAW, .pr_domain = &inet6domain, - .pr_flags = PR_ATOMIC|PR_ADDR, + .pr_flags = PR_ATOMIC|PR_ADDR|PR_MPINPUT, .pr_input = rip6_input, .pr_ctloutput = rip6_ctloutput, .pr_usrreqs = &rip6_usrreqs, diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index 84c872a19..913fb6430 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.116 2024/02/28 10:57:20 bluhm Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.117 2024/04/16 12:56:39 bluhm Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -82,11 +82,12 @@ */ void -ip6_forward(struct mbuf *m, struct rtentry *rt, int srcrt) +ip6_forward(struct mbuf *m, struct route *ro, int srcrt) { struct ip6_hdr *ip6 = mtod(m, struct ip6_hdr *); + struct route iproute; + struct rtentry *rt; struct sockaddr *dst; - struct route ro; struct ifnet *ifp = NULL; int error = 0, type = 0, code = 0, destmtu = 0; struct mbuf *mcopy; @@ -165,25 +166,22 @@ reroute: } #endif /* IPSEC */ - ro.ro_rt = NULL; - route6_cache(&ro, &ip6->ip6_dst, &ip6->ip6_src, - m->m_pkthdr.ph_rtableid); - dst = &ro.ro_dstsa; - if (!rtisvalid(rt)) { - rtfree(rt); - rt = rtalloc_mpath(dst, &ip6->ip6_src.s6_addr32[0], - m->m_pkthdr.ph_rtableid); - if (rt == NULL) { - ip6stat_inc(ip6s_noroute); - if (mcopy != NULL) { - icmp6_error(mcopy, ICMP6_DST_UNREACH, - ICMP6_DST_UNREACH_NOROUTE, 0); - } - m_freem(m); - goto done; - } + if (ro == NULL) { + ro = &iproute; + ro->ro_rt = NULL; } - ro.ro_rt = rt; + rt = route6_mpath(ro, &ip6->ip6_dst, &ip6->ip6_src, + m->m_pkthdr.ph_rtableid); + if (rt == NULL) { + ip6stat_inc(ip6s_noroute); + if (mcopy != NULL) { + icmp6_error(mcopy, ICMP6_DST_UNREACH, + ICMP6_DST_UNREACH_NOROUTE, 0); + } + m_freem(m); + goto done; + } + dst = &ro->ro_dstsa; /* * Scope check: if a packet can't be delivered to its destination @@ -225,8 +223,8 @@ reroute: */ if (tdb != NULL) { /* Callee frees mbuf */ - error = ip6_output_ipsec_send(tdb, m, &ro, 0, 1); - rt = ro.ro_rt; + error = ip6_output_ipsec_send(tdb, m, ro, 0, 1); + rt = ro->ro_rt; if (error) goto senderr; goto freecopy; @@ -254,7 +252,7 @@ reroute: ip6_sendredirects && (rt->rt_flags & (RTF_DYNAMIC|RTF_MODIFIED)) == 0) { if ((ifp->if_flags & IFF_POINTOPOINT) && - nd6_is_addr_neighbor(&ro.ro_dstsin6, ifp)) { + nd6_is_addr_neighbor(&ro->ro_dstsin6, ifp)) { /* * If the incoming interface is equal to the outgoing * one, the link attached to the interface is @@ -308,8 +306,9 @@ reroute: /* tag as generated to skip over pf_test on rerun */ m->m_pkthdr.pf.flags |= PF_TAG_GENERATED; srcrt = 1; - rtfree(rt); - rt = NULL; + if (ro == &iproute) + rtfree(ro->ro_rt); + ro = NULL; if_put(ifp); ifp = NULL; goto reroute; @@ -388,7 +387,8 @@ senderr: freecopy: m_freem(mcopy); done: - rtfree(rt); + if (ro == &iproute) + rtfree(ro->ro_rt); if_put(ifp); #ifdef IPSEC tdb_unref(tdb); diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index 5f4e991e0..e389bc0aa 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.260 2024/04/14 20:46:27 bluhm Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.261 2024/04/16 12:56:39 bluhm Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -356,10 +356,10 @@ bad: int ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) { + struct route ro; struct mbuf *m; struct ip6_hdr *ip6; - struct sockaddr_in6 sin6; - struct rtentry *rt = NULL; + struct rtentry *rt; int ours = 0; u_int16_t src_scope, dst_scope; #if NPF > 0 @@ -369,8 +369,8 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) KASSERT(*offp == 0); + ro.ro_rt = NULL; ip6stat_inc(ip6s_total); - m = *mp = ipv6_check(ifp, *mp); if (m == NULL) goto bad; @@ -516,18 +516,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) /* * Unicast check */ - memset(&sin6, 0, sizeof(struct sockaddr_in6)); - sin6.sin6_len = sizeof(struct sockaddr_in6); - sin6.sin6_family = AF_INET6; - sin6.sin6_addr = ip6->ip6_dst; - rt = rtalloc_mpath(sin6tosa(&sin6), &ip6->ip6_src.s6_addr32[0], + rt = route6_mpath(&ro, &ip6->ip6_dst, &ip6->ip6_src, m->m_pkthdr.ph_rtableid); /* * Accept the packet if the route to the destination is marked * as local. */ - if (rtisvalid(rt) && ISSET(rt->rt_flags, RTF_LOCAL)) { + if (rt != NULL && ISSET(rt->rt_flags, RTF_LOCAL)) { struct in6_ifaddr *ia6 = ifatoia6(rt->rt_ifa); if (ip6_forwarding == 0 && rt->rt_ifidx != ifp->if_index && @@ -617,14 +613,14 @@ ip6_input_if(struct mbuf **mp, int *offp, int nxt, int af, struct ifnet *ifp) } #endif /* IPSEC */ - ip6_forward(m, rt, pfrdr); + ip6_forward(m, &ro, pfrdr); *mp = NULL; return IPPROTO_DONE; bad: nxt = IPPROTO_DONE; m_freemp(mp); out: - rtfree(rt); + rtfree(ro.ro_rt); return nxt; } diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index a2ba550fa..99d494df5 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.289 2024/04/09 11:05:05 bluhm Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.290 2024/04/16 12:56:39 bluhm Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -391,7 +391,7 @@ reroute: /* initialize cached route */ if (ro == NULL) { ro = &iproute; - bzero((caddr_t)ro, sizeof(*ro)); + ro->ro_rt = NULL; } ro_pmtu = ro; if (opt && opt->ip6po_rthdr) diff --git a/sys/netinet6/ip6_var.h b/sys/netinet6/ip6_var.h index c1249f797..1b9ae82c4 100644 --- a/sys/netinet6/ip6_var.h +++ b/sys/netinet6/ip6_var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_var.h,v 1.114 2024/02/14 13:18:21 claudio Exp $ */ +/* $OpenBSD: ip6_var.h,v 1.115 2024/04/16 12:56:39 bluhm Exp $ */ /* $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $ */ /* @@ -320,7 +320,7 @@ int ip6_process_hopopts(struct mbuf **, u_int8_t *, int, u_int32_t *, void ip6_savecontrol(struct inpcb *, struct mbuf *, struct mbuf **); int ip6_sysctl(int *, u_int, void *, size_t *, void *, size_t); -void ip6_forward(struct mbuf *, struct rtentry *, int); +void ip6_forward(struct mbuf *, struct route *, int); void ip6_mloopback(struct ifnet *, struct mbuf *, struct sockaddr_in6 *); int ip6_output(struct mbuf *, struct ip6_pktopts *, struct route *, int, diff --git a/sys/netinet6/raw_ip6.c b/sys/netinet6/raw_ip6.c index 177eeb8e8..5804af262 100644 --- a/sys/netinet6/raw_ip6.c +++ b/sys/netinet6/raw_ip6.c @@ -1,4 +1,4 @@ -/* $OpenBSD: raw_ip6.c,v 1.182 2024/02/13 12:22:09 bluhm Exp $ */ +/* $OpenBSD: raw_ip6.c,v 1.183 2024/04/16 12:40:40 bluhm Exp $ */ /* $KAME: raw_ip6.c,v 1.69 2001/03/04 15:55:44 itojun Exp $ */ /* @@ -155,9 +155,9 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) } else rip6stat_inc(rip6s_ipackets); - bzero(&rip6src, sizeof(rip6src)); - rip6src.sin6_len = sizeof(struct sockaddr_in6); + memset(&rip6src, 0, sizeof(rip6src)); rip6src.sin6_family = AF_INET6; + rip6src.sin6_len = sizeof(rip6src); /* KAME hack: recover scopeid */ in6_recoverscope(&rip6src, &ip6->ip6_src); @@ -186,7 +186,13 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) TAILQ_FOREACH(inp, &rawin6pcbtable.inpt_queue, inp_queue) { KASSERT(ISSET(inp->inp_flags, INP_IPV6)); - if (inp->inp_socket->so_rcv.sb_state & SS_CANTRCVMORE) + /* + * Packet must not be inserted after disconnected wakeup + * call. To avoid race, check again when holding receive + * buffer mutex. + */ + if (ISSET(READ_ONCE(inp->inp_socket->so_rcv.sb_state), + SS_CANTRCVMORE)) continue; if (rtable_l2(inp->inp_rtableid) != rtable_l2(m->m_pkthdr.ph_rtableid)) @@ -264,7 +270,7 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) n = m_copym(m, 0, M_COPYALL, M_NOWAIT); if (n != NULL) { struct socket *so = inp->inp_socket; - int ret; + int ret = 0; if (inp->inp_flags & IN6P_CONTROLOPTS) ip6_savecontrol(inp, n, &opts); @@ -272,12 +278,14 @@ rip6_input(struct mbuf **mp, int *offp, int proto, int af) m_adj(n, *offp); mtx_enter(&so->so_rcv.sb_mtx); - ret = sbappendaddr(so, &so->so_rcv, - sin6tosa(&rip6src), n, opts); + if (!ISSET(inp->inp_socket->so_rcv.sb_state, + SS_CANTRCVMORE)) { + ret = sbappendaddr(so, &so->so_rcv, + sin6tosa(&rip6src), n, opts); + } mtx_leave(&so->so_rcv.sb_mtx); if (ret == 0) { - /* should notify about lost packet */ m_freem(n); m_freem(opts); rip6stat_inc(rip6s_fullsock); @@ -727,7 +735,7 @@ rip6_disconnect(struct socket *so) if ((so->so_state & SS_ISCONNECTED) == 0) return (ENOTCONN); - so->so_state &= ~SS_ISCONNECTED; /* XXX */ + soisdisconnected(so); mtx_enter(&rawin6pcbtable.inpt_mtx); inp->inp_faddr6 = in6addr_any; mtx_leave(&rawin6pcbtable.inpt_mtx); diff --git a/sys/ufs/mfs/mfs_vnops.c b/sys/ufs/mfs/mfs_vnops.c index c3d5ffe54..f238af203 100644 --- a/sys/ufs/mfs/mfs_vnops.c +++ b/sys/ufs/mfs/mfs_vnops.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mfs_vnops.c,v 1.60 2022/06/26 05:20:43 visa Exp $ */ +/* $OpenBSD: mfs_vnops.c,v 1.61 2024/04/16 10:04:41 claudio Exp $ */ /* $NetBSD: mfs_vnops.c,v 1.8 1996/03/17 02:16:32 christos Exp $ */ /* @@ -237,6 +237,9 @@ mfs_reclaim(void *v) { struct vop_reclaim_args *ap = v; struct vnode *vp = ap->a_vp; + struct mfsnode *mfsp = VTOMFS(vp); + + bufq_destroy(&mfsp->mfs_bufq); free(vp->v_data, M_MFSNODE, sizeof(struct mfsnode)); vp->v_data = NULL; diff --git a/sys/uvm/uvm_amap.c b/sys/uvm/uvm_amap.c index 440543f47..991f4ae90 100644 --- a/sys/uvm/uvm_amap.c +++ b/sys/uvm/uvm_amap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_amap.c,v 1.92 2023/04/11 00:45:09 jsg Exp $ */ +/* $OpenBSD: uvm_amap.c,v 1.93 2024/04/16 08:53:02 mpi Exp $ */ /* $NetBSD: uvm_amap.c,v 1.27 2000/11/25 06:27:59 chs Exp $ */ /* @@ -662,9 +662,10 @@ amap_copy(struct vm_map *map, struct vm_map_entry *entry, int waitf, chunk = amap_chunk_get(amap, lcv, 1, PR_NOWAIT); if (chunk == NULL) { - /* amap_wipeout() releases the lock. */ - amap->am_ref = 0; - amap_wipeout(amap); + amap_unlock(srcamap); + /* Destroy the new amap. */ + amap->am_ref--; + amap_free(amap); return; } diff --git a/sys/uvm/uvm_swap.c b/sys/uvm/uvm_swap.c index 4a1d59fff..2b74240e7 100644 --- a/sys/uvm/uvm_swap.c +++ b/sys/uvm/uvm_swap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: uvm_swap.c,v 1.169 2024/02/03 18:51:59 beck Exp $ */ +/* $OpenBSD: uvm_swap.c,v 1.170 2024/04/16 10:06:37 claudio Exp $ */ /* $NetBSD: uvm_swap.c,v 1.40 2000/11/17 11:39:39 mrg Exp $ */ /* @@ -1088,6 +1088,7 @@ swap_off(struct proc *p, struct swapdev *sdp) */ if (sdp->swd_vp->v_type == VREG) { crfree(sdp->swd_cred); + bufq_destroy(&sdp->swd_bufq); } vrele(sdp->swd_vp); if (sdp->swd_vp != rootvp) { diff --git a/usr.bin/less/filename.c b/usr.bin/less/filename.c index 0aaecac61..0f5e1840a 100644 --- a/usr.bin/less/filename.c +++ b/usr.bin/less/filename.c @@ -378,85 +378,6 @@ bin_file(int f) return (bin_count > 5); } -/* - * Read a string from a file. - * Return a pointer to the string in memory. - */ -static char * -readfd(FILE *fd) -{ - int len; - int ch; - char *buf; - char *p; - - /* - * Make a guess about how many chars in the string - * and allocate a buffer to hold it. - */ - len = 100; - buf = ecalloc(len, sizeof (char)); - for (p = buf; ; p++) { - if ((ch = getc(fd)) == '\n' || ch == EOF) - break; - if (p >= buf + len-1) { - /* - * The string is too big to fit in the buffer we have. - * Allocate a new buffer, twice as big. - */ - len *= 2; - *p = '\0'; - p = ecalloc(len, sizeof (char)); - strlcpy(p, buf, len); - free(buf); - buf = p; - p = buf + strlen(buf); - } - *p = (char)ch; - } - *p = '\0'; - return (buf); -} - -/* - * Execute a shell command. - * Return a pointer to a pipe connected to the shell command's standard output. - */ -static FILE * -shellcmd(char *cmd) -{ - FILE *fd; - - char *shell; - - shell = lgetenv("SHELL"); - if (shell != NULL && *shell != '\0') { - char *scmd; - char *esccmd; - - /* - * Read the output of <$SHELL -c cmd>. - * Escape any metacharacters in the command. - */ - esccmd = shell_quote(cmd); - if (esccmd == NULL) { - fd = popen(cmd, "r"); - } else { - scmd = easprintf("%s -c %s", shell, esccmd); - free(esccmd); - fd = popen(scmd, "r"); - free(scmd); - } - } else { - fd = popen(cmd, "r"); - } - /* - * Redirection in `popen' might have messed with the - * standard devices. Restore binary input mode. - */ - return (fd); -} - /* * Expand a filename, doing any system-specific metacharacter substitutions. */ diff --git a/usr.bin/openssl/req.c b/usr.bin/openssl/req.c index b75ba92f7..1044f145a 100644 --- a/usr.bin/openssl/req.c +++ b/usr.bin/openssl/req.c @@ -1,4 +1,4 @@ -/* $OpenBSD: req.c,v 1.28 2023/07/02 07:05:14 tb Exp $ */ +/* $OpenBSD: req.c,v 1.29 2024/04/17 01:24:43 tb Exp $ */ /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) * All rights reserved. * @@ -1697,6 +1697,7 @@ set_keygen_ctx(BIO * err, const char *gstr, int *pkey_type, if (EVP_PKEY_keygen_init(gctx) <= 0) { BIO_puts(err, "Error initializing keygen context\n"); ERR_print_errors(err); + EVP_PKEY_CTX_free(gctx); return NULL; } if ((*pkey_type == EVP_PKEY_RSA) && (keylen != -1)) { diff --git a/usr.sbin/httpd/server_file.c b/usr.sbin/httpd/server_file.c index ad024fc95..0a8a9bb8e 100644 --- a/usr.sbin/httpd/server_file.c +++ b/usr.sbin/httpd/server_file.c @@ -1,4 +1,4 @@ -/* $OpenBSD: server_file.c,v 1.78 2024/01/06 11:29:00 espie Exp $ */ +/* $OpenBSD: server_file.c,v 1.79 2024/04/16 17:15:50 florian Exp $ */ /* * Copyright (c) 2006 - 2017 Reyk Floeter @@ -43,12 +43,14 @@ int server_file_access(struct httpd *, struct client *, char *, size_t); int server_file_request(struct httpd *, struct client *, - char *, struct timespec *); + struct media_type *, int, const struct stat *); int server_partial_file_request(struct httpd *, struct client *, - char *, struct timespec *, char *); -int server_file_index(struct httpd *, struct client *); + struct media_type *, int, const struct stat *, + char *); +int server_file_index(struct httpd *, struct client *, int, + struct stat *); int server_file_modified_since(struct http_descriptor *, - struct timespec *); + const struct timespec *); int server_file_method(struct client *); int parse_range_spec(char *, size_t, struct range *); int parse_ranges(struct client *, char *, size_t); @@ -62,28 +64,42 @@ server_file_access(struct httpd *env, struct client *clt, struct server_config *srv_conf = clt->clt_srv_conf; struct stat st; struct kv *r, key; + struct media_type *media; char *newpath, *encodedpath; - int ret; + int ret, fd; - errno = 0; + if ((fd = open(path, O_RDONLY)) == -1) { + switch (errno) { + case ENOENT: + case ENOTDIR: + return (404); + case EACCES: + return (403); + default: + return (500); + } + } + if (fstat(fd, &st) == -1) { + close(fd); + return (500); + } - if (stat(path, &st) == -1) { - goto fail; - } else if (S_ISDIR(st.st_mode)) { + if (S_ISDIR(st.st_mode)) { /* Deny access if directory indexing is disabled */ if (srv_conf->flags & SRVFLAG_NO_INDEX) { - errno = EACCES; - goto fail; + close(fd); + return (403); } if (desc->http_path_alias != NULL) { /* Recursion - the index "file" is a directory? */ - errno = EINVAL; - goto fail; + close(fd); + return (500); } /* Redirect to path with trailing "/" */ if (path[strlen(path) - 1] != '/') { + close(fd); if ((encodedpath = url_encode(desc->http_path)) == NULL) return (500); if (asprintf(&newpath, "%s/", encodedpath) == -1) { @@ -101,18 +117,21 @@ server_file_access(struct httpd *env, struct client *clt, /* Append the default index file to the location */ if (asprintf(&newpath, "%s%s", desc->http_path, - srv_conf->index) == -1) + srv_conf->index) == -1) { + close(fd); return (500); + } desc->http_path_alias = newpath; if (server_getlocation(clt, newpath) != srv_conf) { /* The location has changed */ + close(fd); return (server_file(env, clt)); } /* Otherwise append the default index file to the path */ if (strlcat(path, srv_conf->index, len) >= len) { - errno = EACCES; - goto fail; + close(fd); + return (403); } ret = server_file_access(env, clt, path, len); @@ -124,39 +143,72 @@ server_file_access(struct httpd *env, struct client *clt, * stat. */ if ((srv_conf->flags & SRVFLAG_AUTO_INDEX) == 0) { - errno = EACCES; - goto fail; + close(fd); + return (403); } - return (server_file_index(env, clt)); + return (server_file_index(env, clt, fd, &st)); } + close(fd); return (ret); } else if (!S_ISREG(st.st_mode)) { /* Don't follow symlinks and ignore special files */ - errno = EACCES; - goto fail; - } - - key.kv_key = "Range"; - r = kv_find(&desc->http_headers, &key); - if (r != NULL) - return (server_partial_file_request(env, clt, path, - &st.st_mtim, r->kv_value)); - else - return (server_file_request(env, clt, path, &st.st_mtim)); - - fail: - switch (errno) { - case ENOENT: - case ENOTDIR: - return (404); - case EACCES: + close(fd); return (403); - default: - return (500); } - /* NOTREACHED */ + media = media_find_config(env, srv_conf, path); + + /* Only consider range requests for GET */ + if (desc->http_method == HTTP_METHOD_GET) { + key.kv_key = "Range"; + r = kv_find(&desc->http_headers, &key); + if (r != NULL) + return (server_partial_file_request(env, clt, media, + fd, &st, r->kv_value)); + } + + /* change path to path.gz if necessary. */ + if (srv_conf->flags & SRVFLAG_GZIP_STATIC) { + struct http_descriptor *req = clt->clt_descreq; + struct http_descriptor *resp = clt->clt_descresp; + struct stat gzst; + int gzfd; + char gzpath[PATH_MAX]; + + /* check Accept-Encoding header */ + key.kv_key = "Accept-Encoding"; + r = kv_find(&req->http_headers, &key); + + if (r != NULL && strstr(r->kv_value, "gzip") != NULL) { + /* append ".gz" to path and check existence */ + ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path); + if (ret < 0 || (size_t)ret >= sizeof(gzpath)) { + close(fd); + return (500); + } + + if ((gzfd = open(gzpath, O_RDONLY)) != -1) { + /* .gz must be a file, and not older */ + if (fstat(gzfd, &gzst) != -1 && + S_ISREG(gzst.st_mode) && + timespeccmp(&gzst.st_mtim, &st.st_mtim, + >=)) { + kv_add(&resp->http_headers, + "Content-Encoding", "gzip"); + /* Use original file timestamp */ + gzst.st_mtim = st.st_mtim; + st = gzst; + close(fd); + fd = gzfd; + } else { + close(gzfd); + } + } + } + } + + return (server_file_request(env, clt, media, fd, &st)); } int @@ -216,73 +268,30 @@ server_file_method(struct client *clt) } int -server_file_request(struct httpd *env, struct client *clt, char *path, - struct timespec *mtim) +server_file_request(struct httpd *env, struct client *clt, struct media_type + *media, int fd, const struct stat *st) { struct server_config *srv_conf = clt->clt_srv_conf; - struct media_type *media; const char *errstr = NULL; - int fd = -1, ret, code = 500; - struct stat st; + int ret, code = 500; size_t bufsiz; - char gzpath[PATH_MAX]; if ((ret = server_file_method(clt)) != 0) { code = ret; goto abort; } - media = media_find_config(env, srv_conf, path); - if ((ret = server_file_modified_since(clt->clt_descreq, mtim)) != -1) { + if ((ret = server_file_modified_since(clt->clt_descreq, &st->st_mtim)) + != -1) { /* send the header without a body */ if ((ret = server_response_http(clt, ret, media, -1, - MINIMUM(time(NULL), mtim->tv_sec))) == -1) + MINIMUM(time(NULL), st->st_mtim.tv_sec))) == -1) goto fail; goto done; } - /* change path to path.gz if necessary. */ - if (srv_conf->flags & SRVFLAG_GZIP_STATIC) { - struct http_descriptor *req = clt->clt_descreq; - struct http_descriptor *resp = clt->clt_descresp; - struct kv *r, key; - - /* check Accept-Encoding header */ - key.kv_key = "Accept-Encoding"; - r = kv_find(&req->http_headers, &key); - - if (r != NULL && strstr(r->kv_value, "gzip") != NULL) { - /* append ".gz" to path and check existence */ - ret = snprintf(gzpath, sizeof(gzpath), "%s.gz", path); - if (ret < 0 || (size_t)ret >= sizeof(gzpath)) - goto abort; - if ((fd = open(gzpath, O_RDONLY)) != -1) { - /* .gz must be a file, and not older */ - if (fstat(fd, &st) != -1 && - S_ISREG(st.st_mode) && - timespeccmp(&st.st_mtim, mtim, >=)) { - kv_add(&resp->http_headers, - "Content-Encoding", "gzip"); - /* Use original file timestamp */ - st.st_mtim = *mtim; - } else { - close(fd); - fd = -1; - } - } - } - } - - /* Now open the file, should be readable or we have another problem */ - if (fd == -1) { - if ((fd = open(path, O_RDONLY)) == -1) - goto abort; - if (fstat(fd, &st) == -1) - goto abort; - } - - ret = server_response_http(clt, 200, media, st.st_size, - MINIMUM(time(NULL), st.st_mtim.tv_sec)); + ret = server_response_http(clt, 200, media, st->st_size, + MINIMUM(time(NULL), st->st_mtim.tv_sec)); switch (ret) { case -1: goto fail; @@ -307,7 +316,7 @@ server_file_request(struct httpd *env, struct client *clt, char *path, } /* Adjust read watermark to the optimal file io size */ - bufsiz = MAXIMUM(st.st_blksize, 64 * 1024); + bufsiz = MAXIMUM(st->st_blksize, 64 * 1024); bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0, bufsiz); @@ -333,47 +342,34 @@ server_file_request(struct httpd *env, struct client *clt, char *path, } int -server_partial_file_request(struct httpd *env, struct client *clt, char *path, - struct timespec *mtim, char *range_str) +server_partial_file_request(struct httpd *env, struct client *clt, + struct media_type *media, int fd, const struct stat *st, char *range_str) { struct server_config *srv_conf = clt->clt_srv_conf; struct http_descriptor *resp = clt->clt_descresp; - struct http_descriptor *desc = clt->clt_descreq; - struct media_type *media, multipart_media; + struct media_type multipart_media; struct range_data *r = &clt->clt_ranges; struct range *range; size_t content_length = 0, bufsiz; - struct stat st; - int code = 500, fd = -1, i, nranges, ret; + int code = 500, i, nranges, ret; char content_range[64]; const char *errstr = NULL; - /* Ignore range request for methods other than GET */ - if (desc->http_method != HTTP_METHOD_GET) - return server_file_request(env, clt, path, mtim); - - /* Now open the file, should be readable or we have another problem */ - if ((fd = open(path, O_RDONLY)) == -1) - goto abort; - if (fstat(fd, &st) == -1) - goto abort; - - if ((nranges = parse_ranges(clt, range_str, st.st_size)) < 1) { + if ((nranges = parse_ranges(clt, range_str, st->st_size)) < 1) { code = 416; (void)snprintf(content_range, sizeof(content_range), - "bytes */%lld", st.st_size); + "bytes */%lld", st->st_size); errstr = content_range; goto abort; } - media = media_find_config(env, srv_conf, path); r->range_media = media; if (nranges == 1) { range = &r->range[0]; (void)snprintf(content_range, sizeof(content_range), "bytes %lld-%lld/%lld", range->start, range->end, - st.st_size); + st->st_size); if (kv_add(&resp->http_headers, "Content-Range", content_range) == NULL) goto abort; @@ -395,7 +391,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path, "Content-Range: bytes %lld-%lld/%lld\r\n\r\n", clt->clt_boundary, media->media_type, media->media_subtype, - range->start, range->end, st.st_size)) < 0) + range->start, range->end, st->st_size)) < 0) goto abort; /* Add data length */ @@ -420,7 +416,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path, r->range_toread = TOREAD_HTTP_RANGE; ret = server_response_http(clt, 206, media, content_length, - MINIMUM(time(NULL), st.st_mtim.tv_sec)); + MINIMUM(time(NULL), st->st_mtim.tv_sec)); switch (ret) { case -1: goto fail; @@ -445,7 +441,7 @@ server_partial_file_request(struct httpd *env, struct client *clt, char *path, } /* Adjust read watermark to the optimal file io size */ - bufsiz = MAXIMUM(st.st_blksize, 64 * 1024); + bufsiz = MAXIMUM(st->st_blksize, 64 * 1024); bufferevent_setwatermark(clt->clt_srvbev, EV_READ, 0, bufsiz); @@ -482,21 +478,21 @@ select_visible(const struct dirent *dp) } int -server_file_index(struct httpd *env, struct client *clt) +server_file_index(struct httpd *env, struct client *clt, int fd, + struct stat *st) { char path[PATH_MAX]; char tmstr[21]; struct http_descriptor *desc = clt->clt_descreq; struct server_config *srv_conf = clt->clt_srv_conf; struct dirent **namelist, *dp; - int namesize, i, ret, fd = -1, skip; + int namesize, i, ret, skip; int code = 500; struct evbuffer *evb = NULL; struct media_type *media; const char *stripped; char *escapeduri, *escapedhtml, *escapedpath; struct tm tm; - struct stat st; time_t t, dir_mtime; char human_size[FMT_SCALED_STRSIZE]; @@ -511,14 +507,8 @@ server_file_index(struct httpd *env, struct client *clt) srv_conf->root, stripped) >= sizeof(path)) goto abort; - /* Now open the file, should be readable or we have another problem */ - if ((fd = open(path, O_RDONLY)) == -1) - goto abort; - if (fstat(fd, &st) == -1) - goto abort; - /* Save last modification time */ - dir_mtime = MINIMUM(time(NULL), st.st_mtim.tv_sec); + dir_mtime = MINIMUM(time(NULL), st->st_mtim.tv_sec); if ((evb = evbuffer_new()) == NULL) goto abort; @@ -548,7 +538,7 @@ server_file_index(struct httpd *env, struct client *clt) free(escapedpath); - if ((namesize = scandir(path, &namelist, select_visible, + if ((namesize = scandirat(fd, ".", &namelist, select_visible, alphasort)) == -1) goto abort; @@ -722,7 +712,8 @@ server_file_error(struct bufferevent *bev, short error, void *arg) } int -server_file_modified_since(struct http_descriptor *desc, struct timespec *mtim) +server_file_modified_since(struct http_descriptor *desc, const struct timespec + *mtim) { struct kv key, *since; struct tm tm;