sync with OpenBSD -current
This commit is contained in:
parent
caabca1cee
commit
aaa686b79e
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: radius.h,v 1.4 2024/02/25 06:22:45 yasuoka Exp $ */
|
/* $OpenBSD: radius.h,v 1.6 2024/06/29 07:19:18 yasuoka Exp $ */
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
* Copyright (c) 2009 Internet Initiative Japan Inc.
|
||||||
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
#define RADIUS_DEFAULT_PORT 1812
|
#define RADIUS_DEFAULT_PORT 1812
|
||||||
#define RADIUS_ACCT_DEFAULT_PORT 1813
|
#define RADIUS_ACCT_DEFAULT_PORT 1813
|
||||||
|
#define RADIUS_DAE_DEFAULT_PORT 3799
|
||||||
|
|
||||||
/* RADIUS codes */
|
/* RADIUS codes */
|
||||||
#define RADIUS_CODE_ACCESS_REQUEST 1
|
#define RADIUS_CODE_ACCESS_REQUEST 1
|
||||||
@ -42,6 +43,12 @@
|
|||||||
#define RADIUS_CODE_STATUS_SERVER 12
|
#define RADIUS_CODE_STATUS_SERVER 12
|
||||||
#define RADIUS_CODE_STATUS_CLIENT 13
|
#define RADIUS_CODE_STATUS_CLIENT 13
|
||||||
|
|
||||||
|
#define RADIUS_CODE_DISCONNECT_REQUEST 40
|
||||||
|
#define RADIUS_CODE_DISCONNECT_ACK 41
|
||||||
|
#define RADIUS_CODE_DISCONNECT_NACK 42
|
||||||
|
#define RADIUS_CODE_COA_REQUEST 43
|
||||||
|
#define RADIUS_CODE_COA_ACK 44
|
||||||
|
#define RADIUS_CODE_COA_NACK 45
|
||||||
|
|
||||||
/* RADIUS attributes */
|
/* RADIUS attributes */
|
||||||
#define RADIUS_TYPE_USER_NAME 1
|
#define RADIUS_TYPE_USER_NAME 1
|
||||||
@ -143,6 +150,9 @@
|
|||||||
#define RADIUS_TYPE_FRAMED_IPV6_ROUTE 99
|
#define RADIUS_TYPE_FRAMED_IPV6_ROUTE 99
|
||||||
#define RADIUS_TYPE_FRAMED_IPV6_POOL 100
|
#define RADIUS_TYPE_FRAMED_IPV6_POOL 100
|
||||||
|
|
||||||
|
/* RFC 5176 3.5. Error-Cause */
|
||||||
|
#define RADIUS_TYPE_ERROR_CAUSE 101
|
||||||
|
|
||||||
/* RFC 6911 3. Attributes */
|
/* RFC 6911 3. Attributes */
|
||||||
#define RADIUS_TYPE_FRAMED_IPV6_ADDRESS 168
|
#define RADIUS_TYPE_FRAMED_IPV6_ADDRESS 168
|
||||||
#define RADIUS_TYPE_DNS_SERVER_IPV6_ADDRESS 169
|
#define RADIUS_TYPE_DNS_SERVER_IPV6_ADDRESS 169
|
||||||
@ -320,6 +330,42 @@
|
|||||||
#define RADIUS_TUNNEL_MEDIUM_TYPE_E163 7 /* E.163 (POTS) */
|
#define RADIUS_TUNNEL_MEDIUM_TYPE_E163 7 /* E.163 (POTS) */
|
||||||
#define RADIUS_TUNNEL_MEDIUM_TYPE_E164 8 /* E.164 (SMDS, Frame
|
#define RADIUS_TUNNEL_MEDIUM_TYPE_E164 8 /* E.164 (SMDS, Frame
|
||||||
* Relay, ATM) */
|
* Relay, ATM) */
|
||||||
|
/* RFC 5167 3.5. Error-Cause */
|
||||||
|
/* Residual Session Context Removed */
|
||||||
|
#define RADIUS_ERROR_CAUSE_RESIDUAL_SESSION_REMOVED 201
|
||||||
|
/* Invalid EAP Packet (Ignored) */
|
||||||
|
#define RADIUS_ERROR_CAUSE_INVALID_EAP_PACKET 202
|
||||||
|
/* Unsupported Attribute */
|
||||||
|
#define RADIUS_ERROR_CAUSE_UNSUPPORTED_ATTRIBUTE 401
|
||||||
|
/* Missing Attribute */
|
||||||
|
#define RADIUS_ERROR_CAUSE_MISSING_ATTRIBUTE 402
|
||||||
|
/* NAS Identification Mismatch */
|
||||||
|
#define RADIUS_ERROR_CAUSE_NAS_IDENTIFICATION_MISMATCH 403
|
||||||
|
/* Invalid Request */
|
||||||
|
#define RADIUS_ERROR_CAUSE_INVALID_REQUEST 404
|
||||||
|
/* Unsupported Service */
|
||||||
|
#define RADIUS_ERROR_CAUSE_UNSUPPORTED_SERVICE 405
|
||||||
|
/* Unsupported Extension */
|
||||||
|
#define RADIUS_ERROR_CAUSE_UNSUPPORTED_EXTENSION 406
|
||||||
|
/* Invalid Attribute Valu */
|
||||||
|
#define RADIUS_ERROR_CAUSE_INVALID_ATTRIBUTE_VALUE 407
|
||||||
|
/* Administratively Prohibited */
|
||||||
|
#define RADIUS_ERROR_CAUSE_ADMINISTRATIVELY_PROHIBITED 501
|
||||||
|
/* Request Not Routable (Proxy) */
|
||||||
|
#define RADIUS_ERROR_CAUSE_REQUEST_NOT_ROUTABLE 502
|
||||||
|
/* Session Context Not Found */
|
||||||
|
#define RADIUS_ERROR_CAUSE_SESSION_NOT_FOUND 503
|
||||||
|
/* Session Context Not Removable */
|
||||||
|
#define RADIUS_ERROR_CAUSE_SESSION_NOT_REMOVABLE 504
|
||||||
|
/* Other Proxy Processing Error */
|
||||||
|
#define RADIUS_ERROR_CAUSE_OTHER_PROXY_PROCESSING_ERROR 505
|
||||||
|
/* Resources Unavailable */
|
||||||
|
#define RADIUS_ERROR_CAUSE_RESOURCES_UNAVAILABLE 506
|
||||||
|
/* Request Initiated */
|
||||||
|
#define RADIUS_ERROR_CAUSE_REQUEST_INITIATED 507
|
||||||
|
/* Multiple Session Selection Unsupported */
|
||||||
|
#define RADIUS_ERROR_CAUSE_MULTI_SELECTION_UNSUPPORTED 508
|
||||||
|
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#include <sys/cdefs.h>
|
#include <sys/cdefs.h>
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
.\" $OpenBSD: SSL_CTX_set_alpn_select_cb.3,v 1.8 2021/09/10 09:25:29 tb Exp $
|
.\" $OpenBSD: SSL_CTX_set_alpn_select_cb.3,v 1.9 2024/06/28 14:48:43 tb Exp $
|
||||||
.\" OpenSSL 87b81496 Apr 19 12:38:27 2017 -0400
|
.\" OpenSSL 87b81496 Apr 19 12:38:27 2017 -0400
|
||||||
.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100
|
.\" OpenSSL b97fdb57 Nov 11 09:33:09 2016 +0100
|
||||||
.\"
|
.\"
|
||||||
@ -49,7 +49,7 @@
|
|||||||
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
|
||||||
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
.\" OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
.\"
|
.\"
|
||||||
.Dd $Mdocdate: September 10 2021 $
|
.Dd $Mdocdate: June 28 2024 $
|
||||||
.Dt SSL_CTX_SET_ALPN_SELECT_CB 3
|
.Dt SSL_CTX_SET_ALPN_SELECT_CB 3
|
||||||
.Os
|
.Os
|
||||||
.Sh NAME
|
.Sh NAME
|
||||||
@ -153,6 +153,15 @@ It implements the standard protocol selection.
|
|||||||
It is expected that this function is called from the application
|
It is expected that this function is called from the application
|
||||||
callback
|
callback
|
||||||
.Fa cb .
|
.Fa cb .
|
||||||
|
If
|
||||||
|
.Fn SSL_select_next_proto
|
||||||
|
returns
|
||||||
|
.Dv OPENSSL_NPN_NO_OVERLAP ,
|
||||||
|
.Fa cb
|
||||||
|
should ignore
|
||||||
|
.Fa out
|
||||||
|
and fail by returning
|
||||||
|
.Dv SSL_TLSEXT_ERR_ALERT_FATAL .
|
||||||
The protocol data in
|
The protocol data in
|
||||||
.Fa server ,
|
.Fa server ,
|
||||||
.Fa server_len
|
.Fa server_len
|
||||||
@ -175,7 +184,8 @@ value will point into either
|
|||||||
.Fa server
|
.Fa server
|
||||||
or
|
or
|
||||||
.Fa client ,
|
.Fa client ,
|
||||||
so it should be copied immediately.
|
so it must not be modified and
|
||||||
|
should be copied immediately.
|
||||||
If no match is found, the first item in
|
If no match is found, the first item in
|
||||||
.Fa client ,
|
.Fa client ,
|
||||||
.Fa client_len
|
.Fa client_len
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssl_lib.c,v 1.323 2024/04/15 16:00:05 tb Exp $ */
|
/* $OpenBSD: ssl_lib.c,v 1.325 2024/06/29 07:34:12 tb Exp $ */
|
||||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
@ -1785,45 +1785,70 @@ LSSL_ALIAS(SSL_get_servername_type);
|
|||||||
* It returns either:
|
* It returns either:
|
||||||
* OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
|
* OPENSSL_NPN_NEGOTIATED if a common protocol was found, or
|
||||||
* OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
|
* OPENSSL_NPN_NO_OVERLAP if the fallback case was reached.
|
||||||
|
*
|
||||||
|
* XXX - the out argument points into server_list or client_list and should
|
||||||
|
* therefore really be const. We can't fix that without breaking the callers.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
|
SSL_select_next_proto(unsigned char **out, unsigned char *outlen,
|
||||||
const unsigned char *server, unsigned int server_len,
|
const unsigned char *server_list, unsigned int server_list_len,
|
||||||
const unsigned char *client, unsigned int client_len)
|
const unsigned char *client_list, unsigned int client_list_len)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
CBS client, client_proto, server, server_proto;
|
||||||
const unsigned char *result;
|
|
||||||
int status = OPENSSL_NPN_UNSUPPORTED;
|
*out = NULL;
|
||||||
|
*outlen = 0;
|
||||||
|
|
||||||
|
/* First check that the client list is well-formed. */
|
||||||
|
CBS_init(&client, client_list, client_list_len);
|
||||||
|
if (!tlsext_alpn_check_format(&client))
|
||||||
|
goto err;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For each protocol in server preference order,
|
* Use first client protocol as fallback. This is one way of doing NPN's
|
||||||
* see if we support it.
|
* "opportunistic" protocol selection (see security considerations in
|
||||||
|
* draft-agl-tls-nextprotoneg-04), and it is the documented behavior of
|
||||||
|
* this API. For ALPN it's the callback's responsibility to fail on
|
||||||
|
* OPENSSL_NPN_NO_OVERLAP.
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < server_len; ) {
|
|
||||||
for (j = 0; j < client_len; ) {
|
if (!CBS_get_u8_length_prefixed(&client, &client_proto))
|
||||||
if (server[i] == client[j] &&
|
goto err;
|
||||||
memcmp(&server[i + 1],
|
|
||||||
&client[j + 1], server[i]) == 0) {
|
*out = (unsigned char *)CBS_data(&client_proto);
|
||||||
/* We found a match */
|
*outlen = CBS_len(&client_proto);
|
||||||
result = &server[i];
|
|
||||||
status = OPENSSL_NPN_NEGOTIATED;
|
/* Now check that the server list is well-formed. */
|
||||||
goto found;
|
CBS_init(&server, server_list, server_list_len);
|
||||||
|
if (!tlsext_alpn_check_format(&server))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Walk the server list and select the first protocol that appears in
|
||||||
|
* the client list.
|
||||||
|
*/
|
||||||
|
while (CBS_len(&server) > 0) {
|
||||||
|
if (!CBS_get_u8_length_prefixed(&server, &server_proto))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
CBS_init(&client, client_list, client_list_len);
|
||||||
|
|
||||||
|
while (CBS_len(&client) > 0) {
|
||||||
|
if (!CBS_get_u8_length_prefixed(&client, &client_proto))
|
||||||
|
goto err;
|
||||||
|
|
||||||
|
if (CBS_mem_equal(&client_proto,
|
||||||
|
CBS_data(&server_proto), CBS_len(&server_proto))) {
|
||||||
|
*out = (unsigned char *)CBS_data(&server_proto);
|
||||||
|
*outlen = CBS_len(&server_proto);
|
||||||
|
|
||||||
|
return OPENSSL_NPN_NEGOTIATED;
|
||||||
}
|
}
|
||||||
j += client[j];
|
|
||||||
j++;
|
|
||||||
}
|
}
|
||||||
i += server[i];
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There's no overlap between our protocols and the server's list. */
|
err:
|
||||||
result = client;
|
return OPENSSL_NPN_NO_OVERLAP;
|
||||||
status = OPENSSL_NPN_NO_OVERLAP;
|
|
||||||
|
|
||||||
found:
|
|
||||||
*out = (unsigned char *) result + 1;
|
|
||||||
*outlen = result[0];
|
|
||||||
return (status);
|
|
||||||
}
|
}
|
||||||
LSSL_ALIAS(SSL_select_next_proto);
|
LSSL_ALIAS(SSL_select_next_proto);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssl_packet.c,v 1.15 2022/11/26 16:08:56 tb Exp $ */
|
/* $OpenBSD: ssl_packet.c,v 1.16 2024/06/28 13:37:49 jsing Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
|
* Copyright (c) 2016, 2017 Joel Sing <jsing@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -18,34 +18,6 @@
|
|||||||
#include "bytestring.h"
|
#include "bytestring.h"
|
||||||
#include "ssl_local.h"
|
#include "ssl_local.h"
|
||||||
|
|
||||||
static int
|
|
||||||
ssl_is_sslv2_client_hello(CBS *header)
|
|
||||||
{
|
|
||||||
uint16_t record_length;
|
|
||||||
uint8_t message_type;
|
|
||||||
CBS cbs;
|
|
||||||
|
|
||||||
CBS_dup(header, &cbs);
|
|
||||||
|
|
||||||
if (!CBS_get_u16(&cbs, &record_length) ||
|
|
||||||
!CBS_get_u8(&cbs, &message_type))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The SSLv2 record length field uses variable length (2 or 3 byte)
|
|
||||||
* encoding. Given the size of a client hello, we expect/require the
|
|
||||||
* 2-byte form which is indicated by a one in the most significant bit.
|
|
||||||
*/
|
|
||||||
if ((record_length & 0x8000) == 0)
|
|
||||||
return 0;
|
|
||||||
if ((record_length & ~0x8000) < 3)
|
|
||||||
return 0;
|
|
||||||
if (message_type != SSL2_MT_CLIENT_HELLO)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
static int
|
||||||
ssl_is_sslv3_handshake(CBS *header)
|
ssl_is_sslv3_handshake(CBS *header)
|
||||||
{
|
{
|
||||||
@ -67,164 +39,6 @@ ssl_is_sslv3_handshake(CBS *header)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
ssl_convert_sslv2_client_hello(SSL *s)
|
|
||||||
{
|
|
||||||
CBB cbb, handshake, client_hello, cipher_suites, compression, session_id;
|
|
||||||
CBS cbs, challenge, cipher_specs, session;
|
|
||||||
uint16_t record_length, client_version, cipher_specs_length;
|
|
||||||
uint16_t session_id_length, challenge_length;
|
|
||||||
unsigned char *client_random = NULL, *data = NULL;
|
|
||||||
size_t data_len, pad_len, len;
|
|
||||||
uint32_t cipher_spec;
|
|
||||||
uint8_t message_type;
|
|
||||||
unsigned char *pad;
|
|
||||||
int ret = -1;
|
|
||||||
int n;
|
|
||||||
|
|
||||||
memset(&cbb, 0, sizeof(cbb));
|
|
||||||
|
|
||||||
CBS_init(&cbs, s->packet, SSL3_RT_HEADER_LENGTH);
|
|
||||||
|
|
||||||
if (!CBS_get_u16(&cbs, &record_length) ||
|
|
||||||
!CBS_get_u8(&cbs, &message_type) ||
|
|
||||||
!CBS_get_u16(&cbs, &client_version))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* The SSLv2 record length field uses variable length (2 or 3 byte)
|
|
||||||
* encoding. Given the size of a client hello, we expect/require the
|
|
||||||
* 2-byte form which is indicated by a one in the most significant bit.
|
|
||||||
* Also note that the record length value does not include the bytes
|
|
||||||
* used for the record length field.
|
|
||||||
*/
|
|
||||||
if ((record_length & 0x8000) == 0)
|
|
||||||
return -1;
|
|
||||||
record_length &= ~0x8000;
|
|
||||||
if (record_length < SSL3_RT_HEADER_LENGTH - 2)
|
|
||||||
return -1;
|
|
||||||
if (message_type != SSL2_MT_CLIENT_HELLO)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
if (record_length < 9) {
|
|
||||||
SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (record_length > 4096) {
|
|
||||||
SSLerror(s, SSL_R_RECORD_TOO_LARGE);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = ssl3_packet_extend(s, record_length + 2);
|
|
||||||
if (n != record_length + 2)
|
|
||||||
return n;
|
|
||||||
|
|
||||||
tls1_transcript_record(s, s->packet + 2,
|
|
||||||
s->packet_length - 2);
|
|
||||||
s->mac_packet = 0;
|
|
||||||
|
|
||||||
if (s->msg_callback)
|
|
||||||
s->msg_callback(0, SSL2_VERSION, 0,
|
|
||||||
s->packet + 2, s->packet_length - 2, s,
|
|
||||||
s->msg_callback_arg);
|
|
||||||
|
|
||||||
/* Decode the SSLv2 record containing the client hello. */
|
|
||||||
CBS_init(&cbs, s->packet, s->packet_length);
|
|
||||||
|
|
||||||
if (!CBS_get_u16(&cbs, &record_length))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_u8(&cbs, &message_type))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_u16(&cbs, &client_version))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_u16(&cbs, &cipher_specs_length))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_u16(&cbs, &session_id_length))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_u16(&cbs, &challenge_length))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_bytes(&cbs, &cipher_specs, cipher_specs_length))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_bytes(&cbs, &session, session_id_length))
|
|
||||||
return -1;
|
|
||||||
if (!CBS_get_bytes(&cbs, &challenge, challenge_length))
|
|
||||||
return -1;
|
|
||||||
if (CBS_len(&cbs) != 0) {
|
|
||||||
SSLerror(s, SSL_R_RECORD_LENGTH_MISMATCH);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Convert SSLv2 challenge to SSLv3/TLS client random, by truncating or
|
|
||||||
* left-padding with zero bytes.
|
|
||||||
*/
|
|
||||||
if ((client_random = malloc(SSL3_RANDOM_SIZE)) == NULL)
|
|
||||||
goto err;
|
|
||||||
if (!CBB_init_fixed(&cbb, client_random, SSL3_RANDOM_SIZE))
|
|
||||||
goto err;
|
|
||||||
if ((len = CBS_len(&challenge)) > SSL3_RANDOM_SIZE)
|
|
||||||
len = SSL3_RANDOM_SIZE;
|
|
||||||
pad_len = SSL3_RANDOM_SIZE - len;
|
|
||||||
if (!CBB_add_space(&cbb, &pad, pad_len))
|
|
||||||
goto err;
|
|
||||||
memset(pad, 0, pad_len);
|
|
||||||
if (!CBB_add_bytes(&cbb, CBS_data(&challenge), len))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_finish(&cbb, NULL, NULL))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
/* Build SSLv3/TLS record with client hello. */
|
|
||||||
if (!CBB_init(&cbb, SSL3_RT_MAX_PLAIN_LENGTH))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u8(&cbb, SSL3_RT_HANDSHAKE))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u16(&cbb, 0x0301))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u16_length_prefixed(&cbb, &handshake))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u8(&handshake, SSL3_MT_CLIENT_HELLO))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u24_length_prefixed(&handshake, &client_hello))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u16(&client_hello, client_version))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_bytes(&client_hello, client_random, SSL3_RANDOM_SIZE))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u8_length_prefixed(&client_hello, &session_id))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u16_length_prefixed(&client_hello, &cipher_suites))
|
|
||||||
goto err;
|
|
||||||
while (CBS_len(&cipher_specs) > 0) {
|
|
||||||
if (!CBS_get_u24(&cipher_specs, &cipher_spec))
|
|
||||||
goto err;
|
|
||||||
if ((cipher_spec & 0xff0000) != 0)
|
|
||||||
continue;
|
|
||||||
if (!CBB_add_u16(&cipher_suites, cipher_spec & 0xffff))
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
if (!CBB_add_u8_length_prefixed(&client_hello, &compression))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_add_u8(&compression, 0))
|
|
||||||
goto err;
|
|
||||||
if (!CBB_finish(&cbb, &data, &data_len))
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
if (data_len > s->s3->rbuf.len)
|
|
||||||
goto err;
|
|
||||||
|
|
||||||
s->packet = s->s3->rbuf.buf;
|
|
||||||
s->packet_length = data_len;
|
|
||||||
memcpy(s->packet, data, data_len);
|
|
||||||
ret = 1;
|
|
||||||
|
|
||||||
err:
|
|
||||||
CBB_cleanup(&cbb);
|
|
||||||
free(client_random);
|
|
||||||
free(data);
|
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Potentially do legacy processing on the first packet received by a TLS
|
* Potentially do legacy processing on the first packet received by a TLS
|
||||||
* server. We return 1 if we want SSLv3/TLS record processing to continue
|
* server. We return 1 if we want SSLv3/TLS record processing to continue
|
||||||
@ -233,7 +47,6 @@ ssl_convert_sslv2_client_hello(SSL *s)
|
|||||||
int
|
int
|
||||||
ssl_server_legacy_first_packet(SSL *s)
|
ssl_server_legacy_first_packet(SSL *s)
|
||||||
{
|
{
|
||||||
uint16_t min_version;
|
|
||||||
const char *data;
|
const char *data;
|
||||||
CBS header;
|
CBS header;
|
||||||
|
|
||||||
@ -249,23 +62,6 @@ ssl_server_legacy_first_packet(SSL *s)
|
|||||||
if (s->method->min_tls_version == s->method->max_tls_version)
|
if (s->method->min_tls_version == s->method->max_tls_version)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
if (ssl_is_sslv2_client_hello(&header) == 1) {
|
|
||||||
/* Only permit SSLv2 client hellos if TLSv1.0 is enabled. */
|
|
||||||
if (ssl_enabled_tls_version_range(s, &min_version, NULL) != 1) {
|
|
||||||
SSLerror(s, SSL_R_NO_PROTOCOLS_AVAILABLE);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (min_version > TLS1_VERSION)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
if (ssl_convert_sslv2_client_hello(s) != 1) {
|
|
||||||
SSLerror(s, SSL_R_BAD_PACKET_LENGTH);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
|
/* Ensure that we have SSL3_RT_HEADER_LENGTH (5 bytes) of the packet. */
|
||||||
if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
|
if (CBS_len(&header) != SSL3_RT_HEADER_LENGTH) {
|
||||||
SSLerror(s, ERR_R_INTERNAL_ERROR);
|
SSLerror(s, ERR_R_INTERNAL_ERROR);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: ssl_set_alpn_protos.c,v 1.2 2022/07/21 03:59:04 tb Exp $ */
|
/* $OpenBSD: ssl_set_alpn_protos.c,v 1.3 2024/06/28 14:50:37 tb Exp $ */
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
|
* Copyright (c) 2022 Theo Buehler <tb@openbsd.org>
|
||||||
*
|
*
|
||||||
@ -20,6 +20,21 @@
|
|||||||
|
|
||||||
#include <openssl/ssl.h>
|
#include <openssl/ssl.h>
|
||||||
|
|
||||||
|
static void
|
||||||
|
hexdump(const unsigned char *buf, size_t len)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
|
||||||
|
if (buf == NULL) {
|
||||||
|
fprintf(stderr, "(null), len %zu\n", len);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
for (i = 1; i <= len; i++)
|
||||||
|
fprintf(stderr, " 0x%02hhx,%s", buf[i - 1], i % 8 ? "" : "\n");
|
||||||
|
if (len % 8)
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
struct alpn_test {
|
struct alpn_test {
|
||||||
const char *description;
|
const char *description;
|
||||||
const uint8_t protocols[24];
|
const uint8_t protocols[24];
|
||||||
@ -186,6 +201,279 @@ test_ssl_set_alpn_protos_edge_cases(void)
|
|||||||
return failed;
|
return failed;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static const struct select_next_proto_test {
|
||||||
|
const unsigned char *server_list;
|
||||||
|
size_t server_list_len;
|
||||||
|
const unsigned char *client_list;
|
||||||
|
size_t client_list_len;
|
||||||
|
int want_ret;
|
||||||
|
const unsigned char *want_out;
|
||||||
|
unsigned char want_out_len; /* yes, unsigned char */
|
||||||
|
} select_next_proto_tests[] = {
|
||||||
|
{
|
||||||
|
.server_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.server_list_len = 6,
|
||||||
|
.client_list = "\x01" "a",
|
||||||
|
.client_list_len = 2,
|
||||||
|
.want_ret = OPENSSL_NPN_NEGOTIATED,
|
||||||
|
.want_out = "a",
|
||||||
|
.want_out_len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.server_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.server_list_len = 6,
|
||||||
|
.client_list = "\x02" "aa" "\x01" "b" "\x01" "c",
|
||||||
|
.client_list_len = 7,
|
||||||
|
.want_ret = OPENSSL_NPN_NEGOTIATED,
|
||||||
|
.want_out = "b",
|
||||||
|
.want_out_len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Use server preference. */
|
||||||
|
.server_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.server_list_len = 6,
|
||||||
|
.client_list = "\x01" "c" "\x01" "b" "\x01" "a",
|
||||||
|
.client_list_len = 6,
|
||||||
|
.want_ret = OPENSSL_NPN_NEGOTIATED,
|
||||||
|
.want_out = "a",
|
||||||
|
.want_out_len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Again server preference wins. */
|
||||||
|
.server_list = "\x01" "a" "\x03" "bbb" "\x02" "cc",
|
||||||
|
.server_list_len = 9,
|
||||||
|
.client_list = "\x01" "z" "\x02" "cc" "\x03" "bbb",
|
||||||
|
.client_list_len = 9,
|
||||||
|
.want_ret = OPENSSL_NPN_NEGOTIATED,
|
||||||
|
.want_out = "bbb",
|
||||||
|
.want_out_len = 3,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* No overlap fails with first client protocol. */
|
||||||
|
.server_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.server_list_len = 6,
|
||||||
|
.client_list = "\x01" "z" "\x01" "y",
|
||||||
|
.client_list_len = 4,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
.want_out = "z",
|
||||||
|
.want_out_len = 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* No server protocols is a misconfiguration, but should fail
|
||||||
|
* cleanly.
|
||||||
|
*/
|
||||||
|
.server_list = "",
|
||||||
|
.server_list_len = 0,
|
||||||
|
.client_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.client_list_len = 6,
|
||||||
|
.want_out = "a",
|
||||||
|
.want_out_len = 1,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* NULL server protocols is a programming error that fails
|
||||||
|
* cleanly.
|
||||||
|
*/
|
||||||
|
.server_list = NULL,
|
||||||
|
.server_list_len = 0,
|
||||||
|
.client_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.client_list_len = 6,
|
||||||
|
.want_out = "a",
|
||||||
|
.want_out_len = 1,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Malformed server protocols is a misconfiguration, but it
|
||||||
|
* should fail cleanly.
|
||||||
|
*/
|
||||||
|
.server_list = "\x00",
|
||||||
|
.server_list_len = 1,
|
||||||
|
.client_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.client_list_len = 6,
|
||||||
|
.want_out = "a",
|
||||||
|
.want_out_len = 1,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Malformed server protocols is a misconfiguration, but it
|
||||||
|
* should fail cleanly.
|
||||||
|
*/
|
||||||
|
.server_list = "\x01" "a" "\x03" "bb",
|
||||||
|
.server_list_len = 5,
|
||||||
|
.client_list = "\x01" "a" "\x01" "b" "\x01" "c",
|
||||||
|
.client_list_len = 6,
|
||||||
|
.want_out = "a",
|
||||||
|
.want_out_len = 1,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Empty client protocols is not reachable from the ALPN
|
||||||
|
* callback. It fails cleanly with NULL protocol and 0 length.
|
||||||
|
*/
|
||||||
|
.server_list = "\x01" "a",
|
||||||
|
.server_list_len = 2,
|
||||||
|
.client_list = "",
|
||||||
|
.client_list_len = 0,
|
||||||
|
.want_out = NULL,
|
||||||
|
.want_out_len = 0,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* NULL client protocols is not reachable from the ALPN
|
||||||
|
* callback. It fails cleanly with NULL protocol and 0 length.
|
||||||
|
*/
|
||||||
|
.server_list = "\x01" "a",
|
||||||
|
.server_list_len = 2,
|
||||||
|
.client_list = NULL,
|
||||||
|
.client_list_len = 0,
|
||||||
|
.want_out = NULL,
|
||||||
|
.want_out_len = 0,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Malformed client list fails cleanly with NULL protocol and
|
||||||
|
* 0 length.
|
||||||
|
*/
|
||||||
|
.server_list = "\x01" "a",
|
||||||
|
.server_list_len = 2,
|
||||||
|
.client_list = "\x01" "a" "\x02" "bb" "\x03" "cc" "\x04" "ddd",
|
||||||
|
.client_list_len = 12,
|
||||||
|
.want_out = NULL,
|
||||||
|
.want_out_len = 0,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Malformed client list fails cleanly with NULL protocol and
|
||||||
|
* 0 length.
|
||||||
|
*/
|
||||||
|
.server_list = "\x01" "a",
|
||||||
|
.server_list_len = 2,
|
||||||
|
.client_list = "\x01" "a" "\x02" "bb" "\x00" "\x03" "ddd",
|
||||||
|
.client_list_len = 10,
|
||||||
|
.want_out = NULL,
|
||||||
|
.want_out_len = 0,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Some non-toy examples.
|
||||||
|
*/
|
||||||
|
|
||||||
|
{
|
||||||
|
.server_list = "\x08" "http/1.1" "\x06" "spdy/1",
|
||||||
|
.server_list_len = 16,
|
||||||
|
.client_list = "\x08" "http/2.0" "\x08" "http/1.1",
|
||||||
|
.client_list_len = 18,
|
||||||
|
.want_out = "http/1.1",
|
||||||
|
.want_out_len = 8,
|
||||||
|
.want_ret = OPENSSL_NPN_NEGOTIATED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.server_list = "\x08" "http/2.0" "\x06" "spdy/1",
|
||||||
|
.server_list_len = 16,
|
||||||
|
.client_list = "\x08" "http/1.0" "\x08" "http/1.1",
|
||||||
|
.client_list_len = 18,
|
||||||
|
.want_out = "http/1.0",
|
||||||
|
.want_out_len = 8,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.server_list = "\x08" "http/1.1" "\x08" "http/1.0",
|
||||||
|
.server_list_len = 18,
|
||||||
|
.client_list = "\x08" "http/1.0" "\x08" "http/1.1",
|
||||||
|
.client_list_len = 18,
|
||||||
|
.want_out = "http/1.1",
|
||||||
|
.want_out_len = 8,
|
||||||
|
.want_ret = OPENSSL_NPN_NEGOTIATED,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Server malformed. */
|
||||||
|
.server_list = "\x08" "http/1.1" "\x07" "http/1.0",
|
||||||
|
.server_list_len = 18,
|
||||||
|
.client_list = "\x08" "http/1.0" "\x08" "http/1.1",
|
||||||
|
.client_list_len = 18,
|
||||||
|
.want_out = "http/1.0",
|
||||||
|
.want_out_len = 8,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Server malformed. */
|
||||||
|
.server_list = "\x07" "http/1.1" "\x08" "http/1.0",
|
||||||
|
.server_list_len = 18,
|
||||||
|
.client_list = "\x08" "http/1.0" "\x08" "http/1.1",
|
||||||
|
.client_list_len = 18,
|
||||||
|
.want_out = "http/1.0",
|
||||||
|
.want_out_len = 8,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
/* Client has trailing bytes. */
|
||||||
|
.server_list = "\x08" "http/1.1" "\x08" "http/1.0",
|
||||||
|
.server_list_len = 18,
|
||||||
|
.client_list = "\x08" "http/1.0" "\x07" "http/1.1",
|
||||||
|
.client_list_len = 18,
|
||||||
|
.want_out = NULL,
|
||||||
|
.want_out_len = 0,
|
||||||
|
.want_ret = OPENSSL_NPN_NO_OVERLAP,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
#define N_SELECT_NEXT_PROTO_TESTS \
|
||||||
|
(sizeof(select_next_proto_tests) / sizeof(select_next_proto_tests[0]))
|
||||||
|
|
||||||
|
static int
|
||||||
|
select_next_proto_testcase(const struct select_next_proto_test *test)
|
||||||
|
{
|
||||||
|
unsigned char *out;
|
||||||
|
unsigned char out_len;
|
||||||
|
int ret;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
ret = SSL_select_next_proto(&out, &out_len, test->server_list,
|
||||||
|
test->server_list_len, test->client_list, test->client_list_len);
|
||||||
|
|
||||||
|
if (ret != test->want_ret || out_len != test->want_out_len ||
|
||||||
|
(out == NULL && test->want_out != NULL) ||
|
||||||
|
(out != NULL && test->want_out == NULL) ||
|
||||||
|
(out != NULL && test->want_out != NULL &&
|
||||||
|
memcmp(out, test->want_out, out_len) != 0)) {
|
||||||
|
fprintf(stderr, "FAIL: ret: %u (want %u), out_len: %u (want %u)\n",
|
||||||
|
ret, test->want_ret, out_len, test->want_out_len);
|
||||||
|
fprintf(stderr, "\ngot:\n");
|
||||||
|
hexdump(out, out_len);
|
||||||
|
fprintf(stderr, "\nwant:\n");
|
||||||
|
hexdump(test->want_out, test->want_out_len);
|
||||||
|
fprintf(stderr, "\nserver:\n");
|
||||||
|
hexdump(test->server_list, test->server_list_len);
|
||||||
|
fprintf(stderr, "\nclient:\n");
|
||||||
|
hexdump(test->client_list, test->client_list_len);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
failed = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
test_ssl_select_next_proto(void)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
int failed = 0;
|
||||||
|
|
||||||
|
for (i = 0; i < N_SELECT_NEXT_PROTO_TESTS; i++)
|
||||||
|
failed |= select_next_proto_testcase(&select_next_proto_tests[i]);
|
||||||
|
|
||||||
|
return failed;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main(void)
|
main(void)
|
||||||
{
|
{
|
||||||
@ -197,6 +485,8 @@ main(void)
|
|||||||
|
|
||||||
failed |= test_ssl_set_alpn_protos_edge_cases();
|
failed |= test_ssl_set_alpn_protos_edge_cases();
|
||||||
|
|
||||||
|
failed |= test_ssl_select_next_proto();
|
||||||
|
|
||||||
if (!failed)
|
if (!failed)
|
||||||
printf("PASS %s\n", __FILE__);
|
printf("PASS %s\n", __FILE__);
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# $OpenBSD: Makefile,v 1.105 2023/07/06 07:45:56 deraadt Exp $
|
# $OpenBSD: Makefile,v 1.106 2024/06/28 21:36:05 bluhm Exp $
|
||||||
|
|
||||||
SUBDIR+= accept access
|
SUBDIR+= accept access
|
||||||
SUBDIR+= bind
|
SUBDIR+= bind
|
||||||
@ -22,7 +22,7 @@ SUBDIR+= setuid
|
|||||||
.endif
|
.endif
|
||||||
SUBDIR+= signal sosplice stackjmp stackpivot syscall_segment
|
SUBDIR+= signal sosplice stackjmp stackpivot syscall_segment
|
||||||
SUBDIR+= sysvmsg sysvsem sysvshm
|
SUBDIR+= sysvmsg sysvsem sysvshm
|
||||||
SUBDIR+= unalign unfdpass unixsockets unveil unveil-unmount
|
SUBDIR+= unalign unfdpass unixsockets unp-write-closed unveil unveil-unmount
|
||||||
SUBDIR+= wait
|
SUBDIR+= wait
|
||||||
SUBDIR+= xonly
|
SUBDIR+= xonly
|
||||||
|
|
||||||
|
5
regress/sys/kern/unp-write-closed/Makefile
Normal file
5
regress/sys/kern/unp-write-closed/Makefile
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# $OpenBSD: Makefile,v 1.1.1.1 2024/06/28 21:07:27 bluhm Exp $
|
||||||
|
|
||||||
|
PROG= unp-write-closed
|
||||||
|
|
||||||
|
.include <bsd.regress.mk>
|
83
regress/sys/kern/unp-write-closed/unp-write-closed.c
Normal file
83
regress/sys/kern/unp-write-closed/unp-write-closed.c
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
/* $OpenBSD: unp-write-closed.c,v 1.1.1.1 2024/06/28 21:07:27 bluhm Exp $ */
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2024 Vitaliy Makkoveev <mvs@openbsd.org>
|
||||||
|
* Copyright (c) 2024 Alenander Bluhm <bluhm@openbsd.org>
|
||||||
|
*
|
||||||
|
* Permission to use, copy, modify, and distribute this software for any
|
||||||
|
* purpose with or without fee is hereby granted, provided that the above
|
||||||
|
* copyright notice and this permission notice appear in all copies.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||||
|
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||||
|
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||||
|
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||||
|
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/socket.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
|
||||||
|
#include <err.h>
|
||||||
|
#include <errno.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
sig_atomic_t done = 0;
|
||||||
|
|
||||||
|
void
|
||||||
|
handler(int sigraised)
|
||||||
|
{
|
||||||
|
done = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int
|
||||||
|
main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
int i, s[2], status;
|
||||||
|
pid_t pid;
|
||||||
|
|
||||||
|
if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
|
||||||
|
err(1, "signal pipe");
|
||||||
|
if (signal(SIGALRM, handler) == SIG_ERR)
|
||||||
|
err(1, "signal alrm");
|
||||||
|
alarm(30);
|
||||||
|
|
||||||
|
while (!done) {
|
||||||
|
if (socketpair(AF_UNIX, SOCK_STREAM, 0, s) < 0)
|
||||||
|
err(1, "socketpair");
|
||||||
|
|
||||||
|
switch ((pid = fork())) {
|
||||||
|
case -1:
|
||||||
|
err(1, "fork");
|
||||||
|
case 0:
|
||||||
|
if (close(s[0]) < 0)
|
||||||
|
err(1, "child close 0");
|
||||||
|
if (close(s[1]) < 0)
|
||||||
|
err(1, "child close 1");
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
if (close(s[1]) < 0)
|
||||||
|
err(1, "parent close 1");
|
||||||
|
for (i = 1000000; i > 0; i--) {
|
||||||
|
if (write(s[0], "1", 1) < 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (i <= 0)
|
||||||
|
errx(1, "write did not fail");
|
||||||
|
if (errno != EPIPE)
|
||||||
|
err(1, "write");
|
||||||
|
if (close(s[0]) < 0)
|
||||||
|
err(1, "parent close 1");
|
||||||
|
if (waitpid(pid, &status, 0) < 0)
|
||||||
|
err(1, "waitpid");
|
||||||
|
if (status != 0)
|
||||||
|
errx(1, "child status %d", status);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -164,6 +164,8 @@ static void sumo_construct_vid_mapping_table(struct amdgpu_device *adev,
|
|||||||
|
|
||||||
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
|
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
|
||||||
if (table[i].ulSupportedSCLK != 0) {
|
if (table[i].ulSupportedSCLK != 0) {
|
||||||
|
if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES)
|
||||||
|
continue;
|
||||||
vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
|
vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
|
||||||
table[i].usVoltageID;
|
table[i].usVoltageID;
|
||||||
vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
|
vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
|
||||||
|
@ -393,6 +393,10 @@ bool intel_dp_can_bigjoiner(struct intel_dp *intel_dp)
|
|||||||
struct intel_encoder *encoder = &intel_dig_port->base;
|
struct intel_encoder *encoder = &intel_dig_port->base;
|
||||||
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
struct drm_i915_private *dev_priv = to_i915(encoder->base.dev);
|
||||||
|
|
||||||
|
/* eDP MSO is not compatible with joiner */
|
||||||
|
if (intel_dp->mso_link_count)
|
||||||
|
return false;
|
||||||
|
|
||||||
return DISPLAY_VER(dev_priv) >= 12 ||
|
return DISPLAY_VER(dev_priv) >= 12 ||
|
||||||
(DISPLAY_VER(dev_priv) == 11 &&
|
(DISPLAY_VER(dev_priv) == 11 &&
|
||||||
encoder->port != PORT_A);
|
encoder->port != PORT_A);
|
||||||
|
@ -1621,6 +1621,8 @@ void sumo_construct_vid_mapping_table(struct radeon_device *rdev,
|
|||||||
|
|
||||||
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
|
for (i = 0; i < SUMO_MAX_HARDWARE_POWERLEVELS; i++) {
|
||||||
if (table[i].ulSupportedSCLK != 0) {
|
if (table[i].ulSupportedSCLK != 0) {
|
||||||
|
if (table[i].usVoltageIndex >= SUMO_MAX_NUMBER_VOLTAGES)
|
||||||
|
continue;
|
||||||
vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
|
vid_mapping_table->entries[table[i].usVoltageIndex].vid_7bit =
|
||||||
table[i].usVoltageID;
|
table[i].usVoltageID;
|
||||||
vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
|
vid_mapping_table->entries[table[i].usVoltageIndex].vid_2bit =
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: if_vio.c,v 1.41 2024/06/26 01:40:49 jsg Exp $ */
|
/* $OpenBSD: if_vio.c,v 1.42 2024/06/28 14:46:31 jan Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
|
* Copyright (c) 2012 Stefan Fritsch, Alexander Fiveg.
|
||||||
@ -419,7 +419,7 @@ vio_alloc_mem(struct vio_softc *sc)
|
|||||||
*/
|
*/
|
||||||
allocsize = sizeof(struct virtio_net_hdr) * txqsize;
|
allocsize = sizeof(struct virtio_net_hdr) * txqsize;
|
||||||
|
|
||||||
if (vsc->sc_nvqs == 3) {
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ)) {
|
||||||
allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1;
|
allocsize += sizeof(struct virtio_net_ctrl_cmd) * 1;
|
||||||
allocsize += sizeof(struct virtio_net_ctrl_status) * 1;
|
allocsize += sizeof(struct virtio_net_ctrl_status) * 1;
|
||||||
allocsize += sizeof(struct virtio_net_ctrl_rx) * 1;
|
allocsize += sizeof(struct virtio_net_ctrl_rx) * 1;
|
||||||
@ -436,7 +436,7 @@ vio_alloc_mem(struct vio_softc *sc)
|
|||||||
kva = sc->sc_dma_kva;
|
kva = sc->sc_dma_kva;
|
||||||
sc->sc_tx_hdrs = (struct virtio_net_hdr*)(kva + offset);
|
sc->sc_tx_hdrs = (struct virtio_net_hdr*)(kva + offset);
|
||||||
offset += sizeof(struct virtio_net_hdr) * txqsize;
|
offset += sizeof(struct virtio_net_hdr) * txqsize;
|
||||||
if (vsc->sc_nvqs == 3) {
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ)) {
|
||||||
sc->sc_ctrl_cmd = (void*)(kva + offset);
|
sc->sc_ctrl_cmd = (void*)(kva + offset);
|
||||||
offset += sizeof(*sc->sc_ctrl_cmd);
|
offset += sizeof(*sc->sc_ctrl_cmd);
|
||||||
sc->sc_ctrl_status = (void*)(kva + offset);
|
sc->sc_ctrl_status = (void*)(kva + offset);
|
||||||
@ -529,7 +529,7 @@ vio_needs_reset(struct vio_softc *sc)
|
|||||||
{
|
{
|
||||||
if (virtio_get_status(sc->sc_virtio) &
|
if (virtio_get_status(sc->sc_virtio) &
|
||||||
VIRTIO_CONFIG_DEVICE_STATUS_DEVICE_NEEDS_RESET) {
|
VIRTIO_CONFIG_DEVICE_STATUS_DEVICE_NEEDS_RESET) {
|
||||||
printf("%s: device needs reset", sc->sc_dev.dv_xname);
|
printf("%s: device needs reset\n", sc->sc_dev.dv_xname);
|
||||||
vio_ctrl_wakeup(sc, RESET);
|
vio_ctrl_wakeup(sc, RESET);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@ -604,8 +604,7 @@ vio_attach(struct device *parent, struct device *self, void *aux)
|
|||||||
virtio_postpone_intr_far(&sc->sc_vq[VQTX]);
|
virtio_postpone_intr_far(&sc->sc_vq[VQTX]);
|
||||||
else
|
else
|
||||||
virtio_stop_vq_intr(vsc, &sc->sc_vq[VQTX]);
|
virtio_stop_vq_intr(vsc, &sc->sc_vq[VQTX]);
|
||||||
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ) &&
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ)) {
|
||||||
virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_RX)) {
|
|
||||||
if (virtio_alloc_vq(vsc, &sc->sc_vq[VQCTL], 2, NBPG, 1,
|
if (virtio_alloc_vq(vsc, &sc->sc_vq[VQCTL], 2, NBPG, 1,
|
||||||
"control") == 0) {
|
"control") == 0) {
|
||||||
sc->sc_vq[VQCTL].vq_done = vio_ctrleof;
|
sc->sc_vq[VQCTL].vq_done = vio_ctrleof;
|
||||||
@ -760,7 +759,7 @@ vio_stop(struct ifnet *ifp, int disable)
|
|||||||
/* only way to stop I/O and DMA is resetting... */
|
/* only way to stop I/O and DMA is resetting... */
|
||||||
virtio_reset(vsc);
|
virtio_reset(vsc);
|
||||||
vio_rxeof(sc);
|
vio_rxeof(sc);
|
||||||
if (vsc->sc_nvqs >= 3)
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
|
||||||
vio_ctrl_wakeup(sc, RESET);
|
vio_ctrl_wakeup(sc, RESET);
|
||||||
vio_tx_drain(sc);
|
vio_tx_drain(sc);
|
||||||
if (disable)
|
if (disable)
|
||||||
@ -769,10 +768,10 @@ vio_stop(struct ifnet *ifp, int disable)
|
|||||||
virtio_reinit_start(vsc);
|
virtio_reinit_start(vsc);
|
||||||
virtio_start_vq_intr(vsc, &sc->sc_vq[VQRX]);
|
virtio_start_vq_intr(vsc, &sc->sc_vq[VQRX]);
|
||||||
virtio_stop_vq_intr(vsc, &sc->sc_vq[VQTX]);
|
virtio_stop_vq_intr(vsc, &sc->sc_vq[VQTX]);
|
||||||
if (vsc->sc_nvqs >= 3)
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
|
||||||
virtio_start_vq_intr(vsc, &sc->sc_vq[VQCTL]);
|
virtio_start_vq_intr(vsc, &sc->sc_vq[VQCTL]);
|
||||||
virtio_reinit_end(vsc);
|
virtio_reinit_end(vsc);
|
||||||
if (vsc->sc_nvqs >= 3)
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ))
|
||||||
vio_ctrl_wakeup(sc, FREE);
|
vio_ctrl_wakeup(sc, FREE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -959,7 +958,7 @@ vio_dump(struct vio_softc *sc)
|
|||||||
printf("rx tick active: %d\n", !timeout_triggered(&sc->sc_rxtick));
|
printf("rx tick active: %d\n", !timeout_triggered(&sc->sc_rxtick));
|
||||||
printf("RX virtqueue:\n");
|
printf("RX virtqueue:\n");
|
||||||
virtio_vq_dump(&vsc->sc_vqs[VQRX]);
|
virtio_vq_dump(&vsc->sc_vqs[VQRX]);
|
||||||
if (vsc->sc_nvqs == 3) {
|
if (virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_VQ)) {
|
||||||
printf("CTL virtqueue:\n");
|
printf("CTL virtqueue:\n");
|
||||||
virtio_vq_dump(&vsc->sc_vqs[VQCTL]);
|
virtio_vq_dump(&vsc->sc_vqs[VQCTL]);
|
||||||
printf("ctrl_inuse: %d\n", sc->sc_ctrl_inuse);
|
printf("ctrl_inuse: %d\n", sc->sc_ctrl_inuse);
|
||||||
@ -1530,7 +1529,7 @@ vio_wait_ctrl_done(struct vio_softc *sc)
|
|||||||
r = tsleep_nsec(&sc->sc_ctrl_inuse, PRIBIO, "viodone",
|
r = tsleep_nsec(&sc->sc_ctrl_inuse, PRIBIO, "viodone",
|
||||||
VIRTIO_NET_CTRL_TIMEOUT);
|
VIRTIO_NET_CTRL_TIMEOUT);
|
||||||
if (r == EWOULDBLOCK) {
|
if (r == EWOULDBLOCK) {
|
||||||
printf("%s: ctrl queue timeout", sc->sc_dev.dv_xname);
|
printf("%s: ctrl queue timeout\n", sc->sc_dev.dv_xname);
|
||||||
vio_ctrl_wakeup(sc, RESET);
|
vio_ctrl_wakeup(sc, RESET);
|
||||||
return ENXIO;
|
return ENXIO;
|
||||||
}
|
}
|
||||||
@ -1648,7 +1647,7 @@ vio_iff(struct vio_softc *sc)
|
|||||||
|
|
||||||
ifp->if_flags &= ~IFF_ALLMULTI;
|
ifp->if_flags &= ~IFF_ALLMULTI;
|
||||||
|
|
||||||
if (vsc->sc_nvqs < 3) {
|
if (!virtio_has_feature(vsc, VIRTIO_NET_F_CTRL_RX)) {
|
||||||
/* no ctrl vq; always promisc */
|
/* no ctrl vq; always promisc */
|
||||||
ifp->if_flags |= IFF_ALLMULTI | IFF_PROMISC;
|
ifp->if_flags |= IFF_ALLMULTI | IFF_PROMISC;
|
||||||
return;
|
return;
|
||||||
@ -1682,9 +1681,6 @@ vio_iff(struct vio_softc *sc)
|
|||||||
|
|
||||||
sc->sc_ctrl_mac_tbl_mc->nentries = rxfilter ? nentries : 0;
|
sc->sc_ctrl_mac_tbl_mc->nentries = rxfilter ? nentries : 0;
|
||||||
|
|
||||||
if (vsc->sc_nvqs < 3)
|
|
||||||
return;
|
|
||||||
|
|
||||||
r = vio_set_rx_filter(sc);
|
r = vio_set_rx_filter(sc);
|
||||||
if (r == EIO)
|
if (r == EIO)
|
||||||
allmulti = 1; /* fallback */
|
allmulti = 1; /* fallback */
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: uipc_socket2.c,v 1.155 2024/05/17 19:11:14 mvs Exp $ */
|
/* $OpenBSD: uipc_socket2.c,v 1.156 2024/06/28 21:30:24 mvs Exp $ */
|
||||||
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
|
/* $NetBSD: uipc_socket2.c,v 1.11 1996/02/04 02:17:55 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -160,8 +160,6 @@ void
|
|||||||
soisdisconnected(struct socket *so)
|
soisdisconnected(struct socket *so)
|
||||||
{
|
{
|
||||||
soassertlocked(so);
|
soassertlocked(so);
|
||||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
|
||||||
so->so_state |= SS_ISDISCONNECTED;
|
|
||||||
|
|
||||||
mtx_enter(&so->so_rcv.sb_mtx);
|
mtx_enter(&so->so_rcv.sb_mtx);
|
||||||
so->so_rcv.sb_state |= SS_CANTRCVMORE;
|
so->so_rcv.sb_state |= SS_CANTRCVMORE;
|
||||||
@ -171,6 +169,9 @@ soisdisconnected(struct socket *so)
|
|||||||
so->so_snd.sb_state |= SS_CANTSENDMORE;
|
so->so_snd.sb_state |= SS_CANTSENDMORE;
|
||||||
mtx_leave(&so->so_snd.sb_mtx);
|
mtx_leave(&so->so_snd.sb_mtx);
|
||||||
|
|
||||||
|
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||||
|
so->so_state |= SS_ISDISCONNECTED;
|
||||||
|
|
||||||
wakeup(&so->so_timeo);
|
wakeup(&so->so_timeo);
|
||||||
sowwakeup(so);
|
sowwakeup(so);
|
||||||
sorwakeup(so);
|
sorwakeup(so);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: uipc_usrreq.c,v 1.207 2024/06/26 12:23:36 mvs Exp $ */
|
/* $OpenBSD: uipc_usrreq.c,v 1.208 2024/06/28 21:30:24 mvs Exp $ */
|
||||||
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
|
/* $NetBSD: uipc_usrreq.c,v 1.18 1996/02/09 19:00:50 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -513,6 +513,14 @@ uipc_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We hold both solock() and `sb_mtx' mutex while modifying
|
||||||
|
* SS_CANTSENDMORE flag. solock() is enough to check it.
|
||||||
|
*/
|
||||||
|
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
|
||||||
|
error = EPIPE;
|
||||||
|
goto dispose;
|
||||||
|
}
|
||||||
if (unp->unp_conn == NULL) {
|
if (unp->unp_conn == NULL) {
|
||||||
error = ENOTCONN;
|
error = ENOTCONN;
|
||||||
goto dispose;
|
goto dispose;
|
||||||
@ -531,12 +539,6 @@ uipc_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
|
|||||||
*/
|
*/
|
||||||
mtx_enter(&so2->so_rcv.sb_mtx);
|
mtx_enter(&so2->so_rcv.sb_mtx);
|
||||||
mtx_enter(&so->so_snd.sb_mtx);
|
mtx_enter(&so->so_snd.sb_mtx);
|
||||||
if (so->so_snd.sb_state & SS_CANTSENDMORE) {
|
|
||||||
mtx_leave(&so->so_snd.sb_mtx);
|
|
||||||
mtx_leave(&so2->so_rcv.sb_mtx);
|
|
||||||
error = EPIPE;
|
|
||||||
goto dispose;
|
|
||||||
}
|
|
||||||
if (control) {
|
if (control) {
|
||||||
if (sbappendcontrol(so2, &so2->so_rcv, m, control)) {
|
if (sbappendcontrol(so2, &so2->so_rcv, m, control)) {
|
||||||
control = NULL;
|
control = NULL;
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
/* $OpenBSD: fifo_vnops.c,v 1.105 2024/05/03 17:43:09 mvs Exp $ */
|
/* $OpenBSD: fifo_vnops.c,v 1.106 2024/06/28 21:30:24 mvs Exp $ */
|
||||||
/* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
|
/* $NetBSD: fifo_vnops.c,v 1.18 1996/03/16 23:52:42 christos Exp $ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -174,10 +174,16 @@ fifo_open(void *v)
|
|||||||
return (error);
|
return (error);
|
||||||
}
|
}
|
||||||
fip->fi_readers = fip->fi_writers = 0;
|
fip->fi_readers = fip->fi_writers = 0;
|
||||||
|
/*
|
||||||
|
* Should take both solock() and `sb_mtx' mutex for
|
||||||
|
* SS_CANTSENDMORE flag modifications.
|
||||||
|
*/
|
||||||
|
solock(wso);
|
||||||
mtx_enter(&wso->so_snd.sb_mtx);
|
mtx_enter(&wso->so_snd.sb_mtx);
|
||||||
wso->so_snd.sb_state |= SS_CANTSENDMORE;
|
wso->so_snd.sb_state |= SS_CANTSENDMORE;
|
||||||
wso->so_snd.sb_lowat = PIPE_BUF;
|
wso->so_snd.sb_lowat = PIPE_BUF;
|
||||||
mtx_leave(&wso->so_snd.sb_mtx);
|
mtx_leave(&wso->so_snd.sb_mtx);
|
||||||
|
sounlock(wso);
|
||||||
} else {
|
} else {
|
||||||
rso = fip->fi_readsock;
|
rso = fip->fi_readsock;
|
||||||
wso = fip->fi_writesock;
|
wso = fip->fi_writesock;
|
||||||
@ -185,9 +191,11 @@ fifo_open(void *v)
|
|||||||
if (ap->a_mode & FREAD) {
|
if (ap->a_mode & FREAD) {
|
||||||
fip->fi_readers++;
|
fip->fi_readers++;
|
||||||
if (fip->fi_readers == 1) {
|
if (fip->fi_readers == 1) {
|
||||||
|
solock(wso);
|
||||||
mtx_enter(&wso->so_snd.sb_mtx);
|
mtx_enter(&wso->so_snd.sb_mtx);
|
||||||
wso->so_snd.sb_state &= ~SS_CANTSENDMORE;
|
wso->so_snd.sb_state &= ~SS_CANTSENDMORE;
|
||||||
mtx_leave(&wso->so_snd.sb_mtx);
|
mtx_leave(&wso->so_snd.sb_mtx);
|
||||||
|
sounlock(wso);
|
||||||
if (fip->fi_writers > 0)
|
if (fip->fi_writers > 0)
|
||||||
wakeup(&fip->fi_writers);
|
wakeup(&fip->fi_writers);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user