git: 9494dfe1b3fa - main - fwcontrol: Allocate full fw_asyreq structures passed to the kernel

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Fri, 19 Jul 2024 17:11:31 UTC
The branch main has been updated by jhb:

URL: https://cgit.FreeBSD.org/src/commit/?id=9494dfe1b3faf5c48abaa9be4ec87e4669963942

commit 9494dfe1b3faf5c48abaa9be4ec87e4669963942
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-07-19 17:08:14 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-07-19 17:09:32 +0000

    fwcontrol: Allocate full fw_asyreq structures passed to the kernel
    
    The FW_ASYREQ ioctl accepts a struct fw_asyreq object as its argument,
    meaning that the kernel always copies in the full structure in
    sys_ioctl before passing the request down to the driver.  However,
    fwcontrol was allocating smaller objects that contained only the
    request header and a variable-sized payload.  This means that the
    kernel copy in sys_ioctl was reading off the end of this buffer.  On
    current architectures this happened to be ok, but it is UB.
    
    Instead, allocate a full structure.
    
    Reported by:    GCC 14 -Walloc-size
    Reviewed by:    rlibby, brooks
    Differential Revision:  https://reviews.freebsd.org/D46014
---
 usr.sbin/fwcontrol/fwcontrol.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/usr.sbin/fwcontrol/fwcontrol.c b/usr.sbin/fwcontrol/fwcontrol.c
index 94478259606d..ce908341a42a 100644
--- a/usr.sbin/fwcontrol/fwcontrol.c
+++ b/usr.sbin/fwcontrol/fwcontrol.c
@@ -207,7 +207,7 @@ read_write_quad(int fd, struct fw_eui64 eui, u_int32_t addr_lo, int readmode, u_
         struct fw_asyreq *asyreq;
 	u_int32_t *qld, res;
 
-        asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16);
+	asyreq = malloc(sizeof(*asyreq));
 	if (asyreq == NULL)
 		err(EX_SOFTWARE, "%s:asyreq malloc", __func__);
 	asyreq->req.len = 16;
@@ -262,7 +262,7 @@ send_phy_config(int fd, int root_node, int gap_count)
 {
         struct fw_asyreq *asyreq;
 
-	asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12);
+	asyreq = malloc(sizeof(*asyreq));
 	if (asyreq == NULL)
 		err(EX_SOFTWARE, "%s:asyreq malloc", __func__);
 	asyreq->req.len = 12;
@@ -289,7 +289,7 @@ link_on(int fd, int node)
 {
         struct fw_asyreq *asyreq;
 
-	asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 12);
+	asyreq = malloc(sizeof(*asyreq));
 	if (asyreq == NULL)
 		err(EX_SOFTWARE, "%s:asyreq malloc", __func__);
 	asyreq->req.len = 12;
@@ -308,7 +308,7 @@ reset_start(int fd, int node)
 {
         struct fw_asyreq *asyreq;
 
-	asyreq = (struct fw_asyreq *)malloc(sizeof(struct fw_asyreq_t) + 16);
+	asyreq = malloc(sizeof(*asyreq));
 	if (asyreq == NULL)
 		err(EX_SOFTWARE, "%s:asyreq malloc", __func__);
 	asyreq->req.len = 16;