mirror of
https://github.com/linux-can/can-utils.git
synced 2026-11-04 07:21:13 +01:00
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 <socketcan@hartkopp.net>
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <stddef.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
@@ -473,8 +474,14 @@ static int isobusfs_srv_process_volume_status_request(struct isobusfs_srv_priv *
|
|||||||
|
|
||||||
req_name_len = le16toh(req->name_len);
|
req_name_len = le16toh(req->name_len);
|
||||||
|
|
||||||
pr_debug("< rx volume status request. mode: %x, length: %d, name: %s",
|
/* the volume name has to fit into the received message */
|
||||||
req->volume_mode, req_name_len, req->name);
|
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);
|
client = isobusfs_srv_get_client_by_msg(priv, msg);
|
||||||
if (!client) {
|
if (!client) {
|
||||||
|
|||||||
@@ -657,15 +657,22 @@ static int isobusfs_srv_dh_ccd_res(struct isobusfs_srv_priv *priv,
|
|||||||
uint8_t error_code = ISOBUSFS_ERR_SUCCESS;
|
uint8_t error_code = ISOBUSFS_ERR_SUCCESS;
|
||||||
struct isobusfs_srv_client *client;
|
struct isobusfs_srv_client *client;
|
||||||
struct isobusfs_dh_ccd_res res;
|
struct isobusfs_dh_ccd_res res;
|
||||||
|
uint16_t name_len = le16toh(req->name_len);
|
||||||
size_t abs_path_len;
|
size_t abs_path_len;
|
||||||
char *abs_path;
|
char *abs_path;
|
||||||
int ret;
|
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
|
* We assume, the relative path stored in res->name is not longer
|
||||||
* than absolute path
|
* 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");
|
pr_warn("path too long");
|
||||||
return -EINVAL;
|
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",
|
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 */
|
/* Normalize provided string and convert it to absolute ISOBUS FS path */
|
||||||
ret = isobusfs_convert_relative_to_absolute(priv, client->current_dir,
|
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);
|
abs_path, abs_path_len);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto process_error;
|
goto process_error;
|
||||||
|
|||||||
Reference in New Issue
Block a user