From: Marc Kleine-Budde Date: Wed, 1 Feb 2023 16:33:51 +0000 (+0100) Subject: can: netlink: can_validate(): validate sample point for CAN and CAN-FD X-Git-Tag: io_uring-6.3-2023-03-03~13^2~124^2^2~10 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=73335cfab7fd7c2bfd1696730733b8b952545951;p=linux-2.6-block.git 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.de Signed-off-by: Marc Kleine-Budde --- diff --git a/drivers/net/can/dev/netlink.c b/drivers/net/can/dev/netlink.c index 8efa22d9f214..02f5c00c521f 100644 --- a/drivers/net/can/dev/netlink.c +++ b/drivers/net/can/dev/netlink.c @@ -36,10 +36,24 @@ static const struct nla_policy can_tdc_policy[IFLA_CAN_TDC_MAX + 1] = { [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[], struct netlink_ext_ack *extack) { bool is_can_fd = false; + int err; /* Make sure that valid CAN FD configurations always consist of * - nominal/arbitration bittiming @@ -51,6 +65,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[], if (!data) 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]) { struct can_ctrlmode *cm = nla_data(data[IFLA_CAN_CTRLMODE]); u32 tdc_flags = cm->flags & CAN_CTRLMODE_TDC_MASK; @@ -71,7 +94,6 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[], */ if (data[IFLA_CAN_TDC]) { struct nlattr *tb_tdc[IFLA_CAN_TDC_MAX + 1]; - int err; err = nla_parse_nested(tb_tdc, IFLA_CAN_TDC_MAX, data[IFLA_CAN_TDC], @@ -102,6 +124,15 @@ static int can_validate(struct nlattr *tb[], struct nlattr *data[], 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; }