sync with OpenBSD -current

This commit is contained in:
purplerain 2024-04-17 02:49:09 +00:00
parent 382ecd9441
commit 1b576c8ddf
Signed by: purplerain
GPG Key ID: F42C07F07E2E35B7
25 changed files with 517 additions and 395 deletions

View File

@ -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 *);
/*

View File

@ -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);
}

View File

@ -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 .

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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)
{

View File

@ -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,

View File

@ -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 <jsing@openbsd.org>
* Copyright (c) 2017 Doug Hogan <doug@openbsd.org>
@ -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.

View File

@ -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 <fcambus@openbsd.org>
* Copyright (c) 2018-2024 Frederic Cambus <fcambus@openbsd.org>
* 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, /* ................................ */

View File

@ -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

View File

@ -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);

View File

@ -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)) {

View File

@ -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,

View File

@ -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);

View File

@ -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;
}

View File

@ -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)

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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.
*/

View File

@ -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)) {

View File

@ -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 <reyk@openbsd.org>
@ -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;