git: 12bd1341d2aa - stable/13 - if_vxlan(4): Plug a memory leak

From: Zhenlei Huang <zlei_at_FreeBSD.org>
Date: Wed, 10 Jul 2024 11:45:21 UTC
The branch stable/13 has been updated by zlei:

URL: https://cgit.FreeBSD.org/src/commit/?id=12bd1341d2aa8eea34d858727c295ed5703de4f1

commit 12bd1341d2aa8eea34d858727c295ed5703de4f1
Author:     Zhenlei Huang <zlei@FreeBSD.org>
AuthorDate: 2024-07-02 04:57:02 +0000
Commit:     Zhenlei Huang <zlei@FreeBSD.org>
CommitDate: 2024-07-10 11:43:37 +0000

    if_vxlan(4): Plug a memory leak
    
    On clone creating, either failure from vxlan_set_user_config() or
    ifc_copyin() will result in leaking previous allocated counters.
    
    Since counter_u64_alloc(M_WAITOK) never fails, make vxlan_stats_alloc()
    void and move the allocation for counters below checking ifd->params to
    avoid memory leak.
    
    Reviewed by:    kp, glebius
    Fixes:  b092fd6c973d if_vxlan(4): add support for hardware assisted checksumming, TSO, and RSS
    MFC after:      1 week
    Differential Revision:  https://reviews.freebsd.org/D45822
    
    (cherry picked from commit 087f5e08ab5f0384163f76f73b9a91c98a3ba450)
    (cherry picked from commit e729e750806d3873d5de24cce3b47cc054145985)
---
 sys/net/if_vxlan.c | 36 ++++++------------------------------
 1 file changed, 6 insertions(+), 30 deletions(-)

diff --git a/sys/net/if_vxlan.c b/sys/net/if_vxlan.c
index 34816ede13a3..2cc9f60cba87 100644
--- a/sys/net/if_vxlan.c
+++ b/sys/net/if_vxlan.c
@@ -367,7 +367,7 @@ static void	vxlan_rcv_udp_packet(struct mbuf *, int, struct inpcb *,
 static int	vxlan_input(struct vxlan_socket *, uint32_t, struct mbuf **,
 		    const struct sockaddr *);
 
-static int	vxlan_stats_alloc(struct vxlan_softc *);
+static void	vxlan_stats_alloc(struct vxlan_softc *);
 static void	vxlan_stats_free(struct vxlan_softc *);
 static void	vxlan_set_default_config(struct vxlan_softc *);
 static int	vxlan_set_user_config(struct vxlan_softc *,
@@ -2918,27 +2918,14 @@ out:
 	return (error);
 }
 
-static int
+static void
 vxlan_stats_alloc(struct vxlan_softc *sc)
 {
 	struct vxlan_statistics *stats = &sc->vxl_stats;
 
 	stats->txcsum = counter_u64_alloc(M_WAITOK);
-	if (stats->txcsum == NULL)
-		goto failed;
-
 	stats->tso = counter_u64_alloc(M_WAITOK);
-	if (stats->tso == NULL)
-		goto failed;
-
 	stats->rxcsum = counter_u64_alloc(M_WAITOK);
-	if (stats->rxcsum == NULL)
-		goto failed;
-
-	return (0);
-failed:
-	vxlan_stats_free(sc);
-	return (ENOMEM);
 }
 
 static void
@@ -2946,18 +2933,9 @@ vxlan_stats_free(struct vxlan_softc *sc)
 {
 	struct vxlan_statistics *stats = &sc->vxl_stats;
 
-	if (stats->txcsum != NULL) {
-		counter_u64_free(stats->txcsum);
-		stats->txcsum = NULL;
-	}
-	if (stats->tso != NULL) {
-		counter_u64_free(stats->tso);
-		stats->tso = NULL;
-	}
-	if (stats->rxcsum != NULL) {
-		counter_u64_free(stats->rxcsum);
-		stats->rxcsum = NULL;
-	}
+	counter_u64_free(stats->txcsum);
+	counter_u64_free(stats->tso);
+	counter_u64_free(stats->rxcsum);
 }
 
 static void
@@ -3227,9 +3205,6 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 	sc->vxl_unit = unit;
 	sc->vxl_fibnum = curthread->td_proc->p_fibnum;
 	vxlan_set_default_config(sc);
-	error = vxlan_stats_alloc(sc);
-	if (error != 0)
-		goto fail;
 
 	if (params != 0) {
 		error = copyin(params, &vxlp, sizeof(vxlp));
@@ -3241,6 +3216,7 @@ vxlan_clone_create(struct if_clone *ifc, int unit, caddr_t params)
 			goto fail;
 	}
 
+	vxlan_stats_alloc(sc);
 	ifp = if_alloc(IFT_ETHER);
 	if (ifp == NULL) {
 		error = ENOSPC;