From 7c593bf97ef08b556da81f17c81b2b0e3645ab80 Mon Sep 17 00:00:00 2001 From: Nikolas Gauder Date: Thu, 24 Jul 2025 22:00:49 +0200 Subject: [PATCH] BIO_dgram: Fix BIO_CTRL_DGRAM_QUERY_MTU for IPv4-mapped IPv6 addresses Ensure the correct IP header size is subtracted by reusing dgram_get_mtu_overhead(), which handles address families properly. Reviewed-by: Matt Caswell Reviewed-by: Frederik Wedel-Heinen (Merged from https://github.com/openssl/openssl/pull/28088) (cherry picked from commit a71b4fae432796a49c3b9d32ae29354b23809c1f) --- crypto/bio/bss_dgram.c | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/crypto/bio/bss_dgram.c b/crypto/bio/bss_dgram.c index 8ca1cf64ed4..4292d805a16 100644 --- a/crypto/bio/bss_dgram.c +++ b/crypto/bio/bss_dgram.c @@ -1,5 +1,5 @@ /* - * Copyright 2005-2022 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2005-2025 The OpenSSL Project Authors. All Rights Reserved. * * Licensed under the Apache License 2.0 (the "License"). You may not use * this file except in compliance with the License. You can obtain a copy @@ -349,11 +349,11 @@ static int dgram_write(BIO *b, const char *in, int inl) return ret; } -static long dgram_get_mtu_overhead(bio_dgram_data *data) +static long dgram_get_mtu_overhead(BIO_ADDR *addr) { long ret; - switch (BIO_ADDR_family(&data->peer)) { + switch (BIO_ADDR_family(addr)) { case AF_INET: /* * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP @@ -365,7 +365,8 @@ static long dgram_get_mtu_overhead(bio_dgram_data *data) { # ifdef IN6_IS_ADDR_V4MAPPED struct in6_addr tmp_addr; - if (BIO_ADDR_rawaddress(&data->peer, &tmp_addr, NULL) + + if (BIO_ADDR_rawaddress(addr, &tmp_addr, NULL) && IN6_IS_ADDR_V4MAPPED(&tmp_addr)) /* * Assume this is UDP - 20 bytes for IP, 8 bytes for UDP @@ -492,11 +493,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) &sockopt_len)) < 0 || sockopt_val < 0) { ret = 0; } else { - /* - * we assume that the transport protocol is UDP and no IP - * options are used. - */ - data->mtu = sockopt_val - 8 - 20; + data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr); ret = data->mtu; } break; @@ -508,11 +505,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) || sockopt_val < 0) { ret = 0; } else { - /* - * we assume that the transport protocol is UDP and no IPV6 - * options are used. - */ - data->mtu = sockopt_val - 8 - 40; + data->mtu = sockopt_val - dgram_get_mtu_overhead(&addr); ret = data->mtu; } break; @@ -526,7 +519,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) # endif break; case BIO_CTRL_DGRAM_GET_FALLBACK_MTU: - ret = -dgram_get_mtu_overhead(data); + ret = -dgram_get_mtu_overhead(&data->peer); switch (BIO_ADDR_family(&data->peer)) { case AF_INET: ret += 576; @@ -760,7 +753,7 @@ static long dgram_ctrl(BIO *b, int cmd, long num, void *ptr) } break; case BIO_CTRL_DGRAM_GET_MTU_OVERHEAD: - ret = dgram_get_mtu_overhead(data); + ret = dgram_get_mtu_overhead(&data->peer); break; /* -- 2.47.3