--- sys/netinet/libalias/alias_smedia.c.orig
+++ sys/netinet/libalias/alias_smedia.c
@@ -104,8 +104,9 @@
 #include <sys/kernel.h>
 #include <sys/module.h>
 #else
-#include <errno.h>
 #include <sys/types.h>
+#include <errno.h>
+#include <stdbool.h>
 #include <stdio.h>
 #include <string.h>
 #endif
@@ -128,9 +129,9 @@
 #define RTSP_CONTROL_PORT_NUMBER_2 7070
 #define TFTP_PORT_NUMBER 69
 
-static void
-AliasHandleRtspOut(struct libalias *, struct ip *, struct alias_link *,
-    int maxpacketsize);
+static void AliasHandleRtspOut(struct libalias *, struct ip *,
+    struct alias_link *, size_t);
+
 static int
 fingerprint(struct libalias *la, struct alias_data *ah)
 {
@@ -154,7 +155,8 @@
 	if (ntohs(*ah->dport) == TFTP_PORT_NUMBER)
 		FindRtspOut(la, pip->ip_src, pip->ip_dst,
 		    *ah->sport, *ah->aport, IPPROTO_UDP);
-	else AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize);
+	else
+		AliasHandleRtspOut(la, pip, ah->lnk, ah->maxpktsize);
 	return (0);
 }
 
@@ -208,13 +210,15 @@
 
 #define ISDIGIT(a) (((a) >= '0') && ((a) <= '9'))
 
-static int
-search_string(char *data, int dlen, const char *search_str)
+static ssize_t
+search_string(char *data, size_t dlen, const char *search_str)
 {
-	int i, j, k;
-	int search_str_len;
+	size_t i, j, k;
+	size_t search_str_len;
 
 	search_str_len = strlen(search_str);
+	if (search_str_len > dlen)
+		return (-1);
 	for (i = 0; i < dlen - search_str_len; i++) {
 		for (j = i, k = 0; j < dlen - search_str_len; j++, k++) {
 			if (data[j] != search_str[k] &&
@@ -230,18 +234,21 @@
 static int
 alias_rtsp_out(struct libalias *la, struct ip *pip,
     struct alias_link *lnk,
-    char *data,
+    char *data, size_t maxlen,
     const char *port_str)
 {
-	int hlen, tlen, dlen;
+	size_t hlen, tlen, dlen;
+	size_t i, j;
 	struct tcphdr *tc;
-	int i, j, pos, state, port_dlen, new_dlen, delta;
+	int delta, state;
+	ssize_t pos, slen;
+	size_t new_dlen, port_dlen, port_slen;
 	u_short p[2], new_len;
 	u_short sport, eport, base_port;
 	u_short salias = 0, ealias = 0, base_alias = 0;
 	const char *transport_str = "transport:";
-	char newdata[2048], *port_data, *port_newdata, stemp[80];
-	int links_created = 0, pkt_updated = 0;
+	char *newdata, *port_data;
+	bool links_created = false, pkt_updated = false;
 	struct alias_link *rtsp_lnk = NULL;
 	struct in_addr null_addr;
 
@@ -250,6 +257,9 @@
 	hlen = (pip->ip_hl + tc->th_off) << 2;
 	tlen = ntohs(pip->ip_len);
 	dlen = tlen - hlen;
+	if (hlen > tlen || tlen > maxlen)
+		return (-1);
+	port_slen = strlen(port_str);
 
 	/* Find keyword, "Transport: " */
 	pos = search_string(data, dlen, transport_str);
@@ -259,17 +269,21 @@
 	port_data = data + pos;
 	port_dlen = dlen - pos;
 
+	/* Allocate temporary buffer */
+	maxlen -= hlen;
+	if ((newdata = malloc(maxlen)) == NULL)
+		return (-1);
 	memcpy(newdata, data, pos);
-	port_newdata = newdata + pos;
+	new_dlen = pos;
 
-	while (port_dlen > (int)strlen(port_str)) {
+	while (port_dlen > port_slen) {
 		/* Find keyword, appropriate port string */
 		pos = search_string(port_data, port_dlen, port_str);
-		if (pos < 0)
+		if (pos < 0 || (size_t)pos + 1 > maxlen - new_dlen)
 			break;
 
-		memcpy(port_newdata, port_data, pos + 1);
-		port_newdata += (pos + 1);
+		memcpy(newdata + new_dlen, port_data, pos + 1);
+		new_dlen += pos + 1;
 
 		p[0] = p[1] = 0;
 		sport = eport = 0;
@@ -300,7 +314,7 @@
 				eport = htons(p[1]);
 
 				if (!links_created) {
-					links_created = 1;
+					links_created = true;
 					/*
 					 * Find an even numbered port
 					 * number base that satisfies the
@@ -349,24 +363,30 @@
 					ealias = htons(base_alias + (RTSP_PORT_GROUP - 1));
 				}
 				if (salias && rtsp_lnk) {
-					pkt_updated = 1;
+					pkt_updated = true;
 
 					/* Copy into IP packet */
-					sprintf(stemp, "%d", ntohs(salias));
-					memcpy(port_newdata, stemp, strlen(stemp));
-					port_newdata += strlen(stemp);
+					slen = snprintf(newdata + new_dlen,
+					    maxlen - new_dlen, "%d", ntohs(salias));
+					if (slen < 0 || slen >= maxlen - new_dlen)
+						goto fail;
+					new_dlen += slen;
 
 					if (eport != 0) {
-						*port_newdata = '-';
-						port_newdata++;
+						if (new_dlen == maxlen)
+							goto fail;
+						newdata[new_dlen++] = '-';
 
 						/* Copy into IP packet */
-						sprintf(stemp, "%d", ntohs(ealias));
-						memcpy(port_newdata, stemp, strlen(stemp));
-						port_newdata += strlen(stemp);
+						slen = snprintf(newdata + new_dlen,
+						    maxlen - new_dlen, "%d", ntohs(ealias));
+						if (slen < 0 || slen >= maxlen - new_dlen)
+							goto fail;
+						new_dlen += slen;
 					}
-					*port_newdata = ';';
-					port_newdata++;
+					if (new_dlen == maxlen)
+						goto fail;
+					newdata[new_dlen++] = ';';
 				}
 				state++;
 				break;
@@ -380,20 +400,20 @@
 	}
 
 	if (!pkt_updated)
-		return (-1);
-
-	memcpy(port_newdata, port_data, port_dlen);
-	port_newdata += port_dlen;
-	*port_newdata = '\0';
+		goto fail;
 
 	/* Create new packet */
-	new_dlen = port_newdata - newdata;
+	if (new_dlen + port_dlen > maxlen)
+		goto fail;
+	memmove(data + new_dlen, port_data, port_dlen);
 	memcpy(data, newdata, new_dlen);
+	new_dlen += port_dlen;
+	free(newdata);
 
 	SetAckModified(lnk);
 	tc = (struct tcphdr *)ip_next(pip);
 	delta = GetDeltaSeqOut(tc->th_seq, lnk);
-	AddSeq(lnk, delta + new_dlen - dlen, pip->ip_hl, pip->ip_len,
+	AddSeq(lnk, delta + (int)(new_dlen - dlen), pip->ip_hl, pip->ip_len,
 	    tc->th_seq, tc->th_off);
 
 	new_len = htons(hlen + new_dlen);
@@ -407,6 +427,9 @@
 	tc->th_sum = TcpChecksum(pip);
 #endif
 	return (0);
+fail:
+	free(newdata);
+	return (-1);
 }
 
 /* Support the protocol used by early versions of RealPlayer */
@@ -415,13 +438,13 @@
 alias_pna_out(struct libalias *la, struct ip *pip,
     struct alias_link *lnk,
     char *data,
-    int dlen)
+    size_t dlen)
 {
 	struct alias_link *pna_links;
-	u_short msg_id, msg_len;
 	char *work;
-	u_short alias_port, port;
 	struct tcphdr *tc;
+	u_short msg_id, msg_len;
+	u_short alias_port, port;
 
 	work = data;
 	work += 5;
@@ -433,7 +456,7 @@
 		if (ntohs(msg_id) == 0) /* end of options */
 			return (0);
 
-		if ((ntohs(msg_id) == 1) || (ntohs(msg_id) == 7)) {
+		if (ntohs(msg_id) == 1 || ntohs(msg_id) == 7) {
 			memcpy(&port, work, 2);
 			pna_links = FindUdpTcpOut(la, pip->ip_src, GetDestAddress(lnk),
 			    port, 0, IPPROTO_UDP, 1);
@@ -462,22 +485,23 @@
 }
 
 static void
-AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk, int maxpacketsize)
+AliasHandleRtspOut(struct libalias *la, struct ip *pip, struct alias_link *lnk,
+    size_t maxlen)
 {
-	int hlen, tlen, dlen;
 	struct tcphdr *tc;
 	char *data;
 	const char *setup = "SETUP", *pna = "PNA", *str200 = "200";
 	const char *okstr = "OK", *client_port_str = "client_port";
 	const char *server_port_str = "server_port";
-	int i, parseOk;
-
-	(void)maxpacketsize;
+	size_t hlen, tlen, dlen;
+	size_t i;
 
 	tc = (struct tcphdr *)ip_next(pip);
 	hlen = (pip->ip_hl + tc->th_off) << 2;
 	tlen = ntohs(pip->ip_len);
 	dlen = tlen - hlen;
+	if (hlen > tlen || tlen > maxlen)
+		return;
 
 	data = (char *)pip;
 	data += hlen;
@@ -485,13 +509,14 @@
 	/* When aliasing a client, check for the SETUP request */
 	if ((ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_1) ||
 	    (ntohs(tc->th_dport) == RTSP_CONTROL_PORT_NUMBER_2)) {
-		if (dlen >= (int)strlen(setup) &&
+		if (dlen >= strlen(setup) &&
 		    memcmp(data, setup, strlen(setup)) == 0) {
-			alias_rtsp_out(la, pip, lnk, data, client_port_str);
+			alias_rtsp_out(la, pip, lnk, data, maxlen,
+			    client_port_str);
 			return;
 		}
 
-		if (dlen >= (int)strlen(pna) &&
+		if (dlen >= strlen(pna) &&
 		    memcmp(data, pna, strlen(pna)) == 0)
 			alias_pna_out(la, pip, lnk, data, dlen);
 	} else {
@@ -499,24 +524,21 @@
 		 * When aliasing a server, check for the 200 reply
 		 * Accommodate varying number of blanks between 200 & OK
 		 */
-
-		if (dlen >= (int)strlen(str200)) {
-			for (parseOk = 0, i = 0;
-			    i <= dlen - (int)strlen(str200);
-			    i++)
-				if (memcmp(&data[i], str200, strlen(str200)) == 0) {
-					parseOk = 1;
-					break;
-				}
-
-			if (parseOk) {
-				i += strlen(str200);	/* skip string found */
-				while (data[i] == ' ')	/* skip blank(s) */
+		if (dlen < strlen(str200) + 1 + strlen(okstr))
+			return;
+		for (i = 0; i <= dlen - strlen(str200) - 1; i++) {
+			if (memcmp(&data[i], str200, strlen(str200)) == 0 &&
+			    data[i + strlen(str200)] == ' ') {
+				i += strlen(str200);	/* skip 200 */
+				while (i < dlen && data[i] == ' ')	/* skip blank(s) */
 					i++;
-
-				if ((dlen - i) >= (int)strlen(okstr))
-					if (memcmp(&data[i], okstr, strlen(okstr)) == 0)
-						alias_rtsp_out(la, pip, lnk, data, server_port_str);
+				if (dlen - i >= strlen(okstr)) {
+					if (memcmp(&data[i], okstr, strlen(okstr)) == 0) {
+						alias_rtsp_out(la, pip, lnk, data,
+						    maxlen, server_port_str);
+						break;
+					}
+				}
 			}
 		}
 	}
--- tests/sys/netinet/libalias/Makefile.orig
+++ tests/sys/netinet/libalias/Makefile
@@ -4,6 +4,10 @@
 TESTSDIR=	${TESTSBASE}/sys/netinet/libalias
 BINDIR=		${TESTSDIR}
 
+PLAIN_TESTS_C+=	smedia
+
+LIBADD.smedia+=	sbuf
+
 ATF_TESTS_C+=	1_instance	\
 		2_natout	\
 		3_natin		\
--- /dev/null
+++ tests/sys/netinet/libalias/smedia.c
@@ -0,0 +1,74 @@
+/*
+ * Copyright (c) 2026 The FreeBSD Foundation
+ *
+ * This software was developed by Mark Johnston under sponsorship from
+ * the FreeBSD Foundation.
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+/*
+ * A minimal regression test for a buffer overflow in alias_rtsp_out().
+ */
+
+#include <sys/types.h>
+#include <sys/sbuf.h>
+
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/tcp_var.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <alias.h>
+
+int
+main(void)
+{
+	uint8_t *packet;
+	struct ip ip;
+	struct tcphdr tcp;
+	struct sbuf sb;
+	struct libalias *la;
+
+	sbuf_new(&sb, NULL, 0, SBUF_AUTOEXTEND);
+	sbuf_printf(&sb, "SETUP rtsp://example.com/media.mp4 RTSP/1.0\r\n");
+	sbuf_printf(&sb, "CSeq: 1\r\n");
+	sbuf_printf(&sb, "Transport: RTP/AVP;unicast;");
+	for (int i = 0; i < 200; i++)
+		sbuf_printf(&sb, "client_port=%d-%d;", 2 * i, 2 * i + 1);
+	sbuf_printf(&sb, "\r\n\r\n");
+	sbuf_finish(&sb);
+
+	memset(&tcp, 0, sizeof(tcp));
+	tcp.th_sport = htons(1234);
+	tcp.th_dport = htons(554);
+	tcp.th_off = 5;
+
+	memset(&ip, 0, sizeof(ip));
+	ip.ip_v = IPVERSION;
+	ip.ip_hl = sizeof(ip) / 4;
+	ip.ip_len = htons(sizeof(ip) + sizeof(tcp) + sbuf_len(&sb));
+	ip.ip_id = htons(1);
+	ip.ip_ttl = 64;
+	ip.ip_p = IPPROTO_TCP;
+	ip.ip_src.s_addr = inet_addr("127.0.0.1");
+	ip.ip_dst.s_addr = inet_addr("127.0.0.2");
+
+	packet = malloc(sizeof(ip) + sizeof(tcp) + sbuf_len(&sb));
+	memcpy(packet, &ip, sizeof(ip));
+	memcpy(packet + sizeof(ip), &tcp, sizeof(tcp));
+	memcpy(packet + sizeof(ip) + sizeof(tcp), sbuf_data(&sb),
+	    sbuf_len(&sb));
+
+	la = LibAliasInit(NULL);
+	LibAliasSetAddress(la,
+	    (struct in_addr){.s_addr = inet_addr("127.0.0.1")});
+	if (LibAliasOut(la, packet, sizeof(ip) + sizeof(tcp) + sbuf_len(&sb)) !=
+	    PKT_ALIAS_OK)
+		return (1);
+	LibAliasUninit(la);
+	return (0);
+}
