git: ec2aaa9c7053 - stable/14 - fwcontrol: Allocate full fw_asyreq structures passed to the kernel

From: John Baldwin <jhb_at_FreeBSD.org>
Date: Sat, 30 Nov 2024 16:51:24 UTC
The branch stable/14 has been updated by jhb:

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

commit ec2aaa9c705392c8f419b51aeb6daa12bdaa3435
Author:     John Baldwin <jhb@FreeBSD.org>
AuthorDate: 2024-07-19 17:08:14 +0000
Commit:     John Baldwin <jhb@FreeBSD.org>
CommitDate: 2024-11-30 13:55:58 +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
    
    (cherry picked from commit 9494dfe1b3faf5c48abaa9be4ec87e4669963942)
---
 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;