git: 800d5b7a8a4f - main - netmap: Fix driver name handling
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Fri, 07 Aug 2026 16:30:35 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=800d5b7a8a4f5665ced0453e090f8d563366bd47
commit 800d5b7a8a4f5665ced0453e090f8d563366bd47
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2026-08-07 14:46:52 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2026-08-07 16:30:24 +0000
netmap: Fix driver name handling
if_initname() requires the caller to ensure that the lifetime of the
interface's name buffer contains that of the ifnet itself.
netmap_vi_create() wasn't respecting that; we were instead passing the
stack-allocated buffer provided by the ioctl handler.
While here, add a check to avoid assuming that the caller-provided
buffer is nul-terminated.
Reported by: syzkaller
Reviewed by: vmaffione
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Differential Revision: https://reviews.freebsd.org/D58676
---
sys/dev/netmap/netmap_kern.h | 3 +++
sys/dev/netmap/netmap_vale.c | 24 ++++++++++++++++++------
2 files changed, 21 insertions(+), 6 deletions(-)
diff --git a/sys/dev/netmap/netmap_kern.h b/sys/dev/netmap/netmap_kern.h
index 931bf7cd332b..704b880b3232 100644
--- a/sys/dev/netmap/netmap_kern.h
+++ b/sys/dev/netmap/netmap_kern.h
@@ -1015,6 +1015,9 @@ struct netmap_vp_adapter { /* VALE software port */
u_int mfs;
/* Last source MAC on this port */
uint64_t last_smac;
+
+ /* Buffer for ifnet driver name */
+ char *name;
};
diff --git a/sys/dev/netmap/netmap_vale.c b/sys/dev/netmap/netmap_vale.c
index 21a067715814..df167912f96f 100644
--- a/sys/dev/netmap/netmap_vale.c
+++ b/sys/dev/netmap/netmap_vale.c
@@ -1352,6 +1352,7 @@ nm_vi_destroy(const char *name)
{
if_t ifp;
struct netmap_vp_adapter *vpna;
+ char *viname;
int error;
ifp = ifunit_ref(name);
@@ -1386,9 +1387,12 @@ nm_vi_destroy(const char *name)
/* Linux requires all the references are released
* before unregister
*/
+ viname = vpna->name;
+ vpna->name = NULL;
netmap_detach(ifp);
if_rele(ifp);
nm_os_vi_detach(ifp);
+ nm_os_free(viname);
return 0;
err:
@@ -1420,6 +1424,7 @@ netmap_vi_create(struct nmreq_header *hdr, int autodelete)
if_t ifp;
struct netmap_vp_adapter *vpna;
struct netmap_mem_d *nmd = NULL;
+ char *name;
int error;
if (hdr->nr_reqtype != NETMAP_REQ_REGISTER) {
@@ -1429,10 +1434,14 @@ netmap_vi_create(struct nmreq_header *hdr, int autodelete)
/* don't include VALE prefix */
if (!strncmp(hdr->nr_name, NM_BDG_NAME, strlen(NM_BDG_NAME)))
return EINVAL;
- if (strlen(hdr->nr_name) >= IFNAMSIZ) {
+ if (strnlen(hdr->nr_name, sizeof(hdr->nr_name)) >= IFNAMSIZ)
return EINVAL;
- }
- ifp = ifunit_ref(hdr->nr_name);
+ name = nm_os_malloc(strlen(hdr->nr_name) + 1);
+ if (name == NULL)
+ return ENOMEM;
+ strlcpy(name, hdr->nr_name, strlen(hdr->nr_name) + 1);
+
+ ifp = ifunit_ref(name);
if (ifp) { /* already exist, cannot create new one */
error = EEXIST;
NMG_LOCK();
@@ -1443,11 +1452,11 @@ netmap_vi_create(struct nmreq_header *hdr, int autodelete)
}
NMG_UNLOCK();
if_rele(ifp);
- return error;
+ goto err_0;
}
- error = nm_os_vi_persist(hdr->nr_name, &ifp);
+ error = nm_os_vi_persist(name, &ifp);
if (error)
- return error;
+ goto err_0;
NMG_LOCK();
if (req->nr_mem_id) {
@@ -1464,6 +1473,7 @@ netmap_vi_create(struct nmreq_header *hdr, int autodelete)
nm_prerr("error %d", error);
goto err_1;
}
+ vpna->name = name;
/* persist-specific routines */
vpna->up.nm_bdg_ctl = netmap_vp_bdg_ctl;
if (!autodelete) {
@@ -1491,6 +1501,8 @@ err_1:
netmap_mem_put(nmd);
NMG_UNLOCK();
nm_os_vi_detach(ifp);
+err_0:
+ nm_os_free(name);
return error;
}