Commit 73335cfa authored by Marc Kleine-Budde's avatar Marc Kleine-Budde

can: netlink: can_validate(): validate sample point for CAN and CAN-FD

The sample point is a value in tenths of a percent. Meaningful values
are between 0 and 1000. Invalid values are rejected and an error
message is returned to user space via netlink.

Link: https://lore.kernel.org/all/20230202110854.2318594-8-mkl@pengutronix.deSigned-off-by: default avatarMarc Kleine-Budde <mkl@pengutronix.de>
parent a3db5424
...@@ -36,10 +36,24 @@ static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] = { ...@@ -36,10 +36,24 @@ static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] = {
[IFLA_CAN_TDC_TDCF] = { .type = NLA_U32 }, [IFLA_CAN_TDC_TDCF] = { .type = NLA_U32 },
}; };
static int can_validate_bittiming(const struct can_bittiming *bt,
struct netlink_ext_ack *extack)
{
/* sample point is in one-tenth of a percent */
if (bt->sample_point >= 1000) {
NL_SET_ERR_MSG(extack, "sample point must be between 0 and 100%");
return -EINVAL;
}
return 0;
}
static int can_validate(struct nlattr *tb[], struct nlattr *data[], static int can_validate(struct nlattr *tb[], struct nlattr *data[],
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
bool is_can_fd = false; bool is_can_fd = false;
int err;
/* Make sure that valid CAN FD configurations always consist of /* Make sure that valid CAN FD configurations always consist of
* - nominal/arbitration bittiming * - nominal/arbitration bittiming
...@@ -51,6 +65,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[], ...@@ -51,6 +65,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
if (!data) if (!data)
return 0; return 0;
if (data[IFLA_CAN_BITTIMING]) {
struct can_bittiming bt;
memcpy(&bt, nla_data(data[IFLA_CAN_BITTIMING]), sizeof(bt));
err = can_validate_bittiming(&bt, extack);
if (err)
return err;
}
if (data[IFLA_CAN_CTRLMODE]) { if (data[IFLA_CAN_CTRLMODE]) {
struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]);
u32 tdc_flags = cm->flags & CAN_CTRLMODE_TDC_MASK; u32 tdc_flags = cm->flags & CAN_CTRLMODE_TDC_MASK;
...@@ -71,7 +94,6 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[], ...@@ -71,7 +94,6 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
*/ */
if (data[IFLA_CAN_TDC]) { if (data[IFLA_CAN_TDC]) {
struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1]; struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1];
int err;
err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX, err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX,
data[IFLA_CAN_TDC], data[IFLA_CAN_TDC],
...@@ -102,6 +124,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[], ...@@ -102,6 +124,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[],
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (data[IFLA_CAN_DATA_BITTIMING]) {
struct can_bittiming bt;
memcpy(&bt, nla_data(data[IFLA_CAN_DATA_BITTIMING]), sizeof(bt));
err = can_validate_bittiming(&bt, extack);
if (err)
return err;
}
return 0; return 0;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment