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
This commit is contained in:
John Baldwin 2024-07-19 13:08:14 -04:00
parent 2ba12978f6
commit 9494dfe1b3

View File

@ -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;