proxy: Validate retarget write length

_write() copies a caller-controlled length into a fixed-size stack
buffer without checking that the RPC header and payload fit. Negative
lengths also become large unsigned memcpy() sizes, and the stdout NUL
terminator is written one byte beyond its intended position.

Reject invalid lengths before constructing the request. Include the
optional terminator in the capacity check and place the terminator
immediately after the copied payload.

Signed-off-by: Ben Levinsky <ben.levinsky@amd.com>
Assisted-by: Codex:GPT-5
This commit is contained in:
Ben Levinsky
2026-09-21 09:54:50 +02:00
committed by Arnaud Pouliquen
parent 372048d49d
commit 2b7013e733
+8 -6
View File
@@ -271,16 +271,20 @@ int _write(int fd, const char *ptr, int len)
int ret;
struct rpmsg_rpc_syscall *syscall;
struct rpmsg_rpc_syscall resp;
int payload_size = sizeof(*syscall) + len;
size_t payload_size;
struct rpmsg_rpc_data *rpc = rpmsg_default_rpc;
unsigned char tmpbuf[MAX_BUF_LEN];
unsigned char *tmpptr;
int null_term = 0;
if (!rpc)
if (!rpc || !ptr || len < 0)
return -EINVAL;
if (fd == 1)
null_term = 1;
/* Reserve space for the payload and stdout's trailing NUL byte. */
if ((size_t)len > MAX_BUF_LEN - sizeof(*syscall) - null_term)
return -EINVAL;
payload_size = sizeof(*syscall) + (size_t)len + null_term;
syscall = (void *)tmpbuf;
syscall->id = WRITE_SYSCALL_ID;
@@ -289,10 +293,8 @@ int _write(int fd, const char *ptr, int len)
syscall->args.data_len = len + null_term;
tmpptr = tmpbuf + sizeof(*syscall);
memcpy(tmpptr, ptr, len);
if (null_term == 1) {
*(char *)(tmpptr + len + null_term) = 0;
payload_size += 1;
}
if (null_term == 1)
tmpptr[len] = '\0';
resp.id = 0;
ret = rpmsg_rpc_send(rpc, tmpbuf, payload_size,
(void *)&resp, sizeof(resp));