From 13dc8e9cc5ffe949c68d56c57c0a3821d8bd6037 Mon Sep 17 00:00:00 2001 From: Oliver Hartkopp Date: Wed, 14 Oct 2026 09:54:43 +0000 Subject: [PATCH] isobusfs: srv: check name length against the received message length The Change Current Directory and Volume Status requests used the path and volume name length from the request without checking it against the received message length. Short messages with a big name length made the server process stale content of the receive buffer as path or volume name. Check the name length against the message length, use le16toh() for the CCD name length and fix the debug output of the volume name. Assisted-by: Claude:claude-opus-5-5 Signed-off-by: Oliver Hartkopp --- isobusfs/isobusfs_srv_cm.c | 11 +++++++++-- isobusfs/isobusfs_srv_dh.c | 13 ++++++++++--- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/isobusfs/isobusfs_srv_cm.c b/isobusfs/isobusfs_srv_cm.c index b5b8d1e..f8da238 100644 --- a/isobusfs/isobusfs_srv_cm.c +++ b/isobusfs/isobusfs_srv_cm.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include @@ -473,8 +474,14 @@ static int isobusfs_srv_process_volume_status_request(struct isobusfs_srv_priv * req_name_len = le16toh(req->name_len); - pr_debug("< rx volume status request. mode: %x, length: %d, name: %s", - req->volume_mode, req_name_len, req->name); + /* the volume name has to fit into the received message */ + if (req_name_len > msg->len - offsetof(struct isobusfs_cm_vol_stat_req, name)) { + pr_warn("volume name length exceeds message length"); + return ISOBUSFS_ERR_MALFORMED_REQUEST; + } + + pr_debug("< rx volume status request. mode: %x, length: %zu, name: %.*s", + req->volume_mode, req_name_len, (int)req_name_len, req->name); client = isobusfs_srv_get_client_by_msg(priv, msg); if (!client) { diff --git a/isobusfs/isobusfs_srv_dh.c b/isobusfs/isobusfs_srv_dh.c index d92abea..37cec21 100644 --- a/isobusfs/isobusfs_srv_dh.c +++ b/isobusfs/isobusfs_srv_dh.c @@ -657,15 +657,22 @@ static int isobusfs_srv_dh_ccd_res(struct isobusfs_srv_priv *priv, uint8_t error_code = ISOBUSFS_ERR_SUCCESS; struct isobusfs_srv_client *client; struct isobusfs_dh_ccd_res res; + uint16_t name_len = le16toh(req->name_len); size_t abs_path_len; char *abs_path; int ret; + /* the path name has to fit into the received message */ + if (name_len > msg->len - sizeof(*req)) { + pr_warn("path name length exceeds message length"); + return -EINVAL; + } + /* * We assume, the relative path stored in res->name is not longer * than absolute path */ - if (req->name_len > ISOBUSFS_SRV_MAX_PATH_LEN) { + if (name_len > ISOBUSFS_SRV_MAX_PATH_LEN) { pr_warn("path too long"); return -EINVAL; } @@ -684,10 +691,10 @@ static int isobusfs_srv_dh_ccd_res(struct isobusfs_srv_priv *priv, } pr_debug("< rx change current directory request from client 0x%2x: %.*s. Current directory: %s", - client->addr, req->name_len, req->name, client->current_dir); + client->addr, name_len, req->name, client->current_dir); /* Normalize provided string and convert it to absolute ISOBUS FS path */ ret = isobusfs_convert_relative_to_absolute(priv, client->current_dir, - (char *)req->name, req->name_len, + (char *)req->name, name_len, abs_path, abs_path_len); if (ret < 0) goto process_error;