Commit 5b75c497 authored by Oliver Hartkopp's avatar Oliver Hartkopp Committed by David S. Miller

can: add limit for nframes and clean up signed/unsigned variables

This patch adds a limit for nframes as the number of frames in TX_SETUP and
RX_SETUP are derived from a single byte multiplex value by default.
Use-cases that would require to send/filter more than 256 CAN frames should
be implemented in userspace for complexity reasons anyway.

Additionally the assignments of unsigned values from userspace to signed
values in kernelspace and vice versa are fixed by using unsigned values in
kernelspace consistently.
Signed-off-by: default avatarOliver Hartkopp <socketcan@hartkopp.net>
Reported-by: default avatarBen Hawkes <hawkes@google.com>
Acked-by: default avatarUrs Thuermann <urs.thuermann@volkswagen.de>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 3e9e5a59
...@@ -60,6 +60,13 @@ ...@@ -60,6 +60,13 @@
#include <net/sock.h> #include <net/sock.h>
#include <net/net_namespace.h> #include <net/net_namespace.h>
/*
* To send multiple CAN frame content within TX_SETUP or to filter
* CAN messages with multiplex index within RX_SETUP, the number of
* different filters is limited to 256 due to the one byte index value.
*/
#define MAX_NFRAMES 256
/* use of last_frames[index].can_dlc */ /* use of last_frames[index].can_dlc */
#define RX_RECV 0x40 /* received data for this element */ #define RX_RECV 0x40 /* received data for this element */
#define RX_THR 0x80 /* element not been sent due to throttle feature */ #define RX_THR 0x80 /* element not been sent due to throttle feature */
...@@ -89,16 +96,16 @@ struct bcm_op { ...@@ -89,16 +96,16 @@ struct bcm_op {
struct list_head list; struct list_head list;
int ifindex; int ifindex;
canid_t can_id; canid_t can_id;
int flags; u32 flags;
unsigned long frames_abs, frames_filtered; unsigned long frames_abs, frames_filtered;
struct timeval ival1, ival2; struct timeval ival1, ival2;
struct hrtimer timer, thrtimer; struct hrtimer timer, thrtimer;
struct tasklet_struct tsklet, thrtsklet; struct tasklet_struct tsklet, thrtsklet;
ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg; ktime_t rx_stamp, kt_ival1, kt_ival2, kt_lastmsg;
int rx_ifindex; int rx_ifindex;
int count; u32 count;
int nframes; u32 nframes;
int currframe; u32 currframe;
struct can_frame *frames; struct can_frame *frames;
struct can_frame *last_frames; struct can_frame *last_frames;
struct can_frame sframe; struct can_frame sframe;
...@@ -175,7 +182,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) ...@@ -175,7 +182,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
seq_printf(m, "rx_op: %03X %-5s ", seq_printf(m, "rx_op: %03X %-5s ",
op->can_id, bcm_proc_getifname(ifname, op->ifindex)); op->can_id, bcm_proc_getifname(ifname, op->ifindex));
seq_printf(m, "[%d]%c ", op->nframes, seq_printf(m, "[%u]%c ", op->nframes,
(op->flags & RX_CHECK_DLC)?'d':' '); (op->flags & RX_CHECK_DLC)?'d':' ');
if (op->kt_ival1.tv64) if (op->kt_ival1.tv64)
seq_printf(m, "timeo=%lld ", seq_printf(m, "timeo=%lld ",
...@@ -198,7 +205,7 @@ static int bcm_proc_show(struct seq_file *m, void *v) ...@@ -198,7 +205,7 @@ static int bcm_proc_show(struct seq_file *m, void *v)
list_for_each_entry(op, &bo->tx_ops, list) { list_for_each_entry(op, &bo->tx_ops, list) {
seq_printf(m, "tx_op: %03X %s [%d] ", seq_printf(m, "tx_op: %03X %s [%u] ",
op->can_id, op->can_id,
bcm_proc_getifname(ifname, op->ifindex), bcm_proc_getifname(ifname, op->ifindex),
op->nframes); op->nframes);
...@@ -283,7 +290,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head, ...@@ -283,7 +290,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
struct can_frame *firstframe; struct can_frame *firstframe;
struct sockaddr_can *addr; struct sockaddr_can *addr;
struct sock *sk = op->sk; struct sock *sk = op->sk;
int datalen = head->nframes * CFSIZ; unsigned int datalen = head->nframes * CFSIZ;
int err; int err;
skb = alloc_skb(sizeof(*head) + datalen, gfp_any()); skb = alloc_skb(sizeof(*head) + datalen, gfp_any());
...@@ -468,7 +475,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op, ...@@ -468,7 +475,7 @@ static void bcm_rx_update_and_send(struct bcm_op *op,
* bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly * bcm_rx_cmp_to_index - (bit)compares the currently received data to formerly
* received data stored in op->last_frames[] * received data stored in op->last_frames[]
*/ */
static void bcm_rx_cmp_to_index(struct bcm_op *op, int index, static void bcm_rx_cmp_to_index(struct bcm_op *op, unsigned int index,
const struct can_frame *rxdata) const struct can_frame *rxdata)
{ {
/* /*
...@@ -554,7 +561,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer) ...@@ -554,7 +561,8 @@ static enum hrtimer_restart bcm_rx_timeout_handler(struct hrtimer *hrtimer)
/* /*
* bcm_rx_do_flush - helper for bcm_rx_thr_flush * bcm_rx_do_flush - helper for bcm_rx_thr_flush
*/ */
static inline int bcm_rx_do_flush(struct bcm_op *op, int update, int index) static inline int bcm_rx_do_flush(struct bcm_op *op, int update,
unsigned int index)
{ {
if ((op->last_frames) && (op->last_frames[index].can_dlc & RX_THR)) { if ((op->last_frames) && (op->last_frames[index].can_dlc & RX_THR)) {
if (update) if (update)
...@@ -575,7 +583,7 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update) ...@@ -575,7 +583,7 @@ static int bcm_rx_thr_flush(struct bcm_op *op, int update)
int updated = 0; int updated = 0;
if (op->nframes > 1) { if (op->nframes > 1) {
int i; unsigned int i;
/* for MUX filter we start at index 1 */ /* for MUX filter we start at index 1 */
for (i = 1; i < op->nframes; i++) for (i = 1; i < op->nframes; i++)
...@@ -624,7 +632,7 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data) ...@@ -624,7 +632,7 @@ static void bcm_rx_handler(struct sk_buff *skb, void *data)
{ {
struct bcm_op *op = (struct bcm_op *)data; struct bcm_op *op = (struct bcm_op *)data;
const struct can_frame *rxframe = (struct can_frame *)skb->data; const struct can_frame *rxframe = (struct can_frame *)skb->data;
int i; unsigned int i;
/* disable timeout */ /* disable timeout */
hrtimer_cancel(&op->timer); hrtimer_cancel(&op->timer);
...@@ -822,14 +830,15 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, ...@@ -822,14 +830,15 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
{ {
struct bcm_sock *bo = bcm_sk(sk); struct bcm_sock *bo = bcm_sk(sk);
struct bcm_op *op; struct bcm_op *op;
int i, err; unsigned int i;
int err;
/* we need a real device to send frames */ /* we need a real device to send frames */
if (!ifindex) if (!ifindex)
return -ENODEV; return -ENODEV;
/* we need at least one can_frame */ /* check nframes boundaries - we need at least one can_frame */
if (msg_head->nframes < 1) if (msg_head->nframes < 1 || msg_head->nframes > MAX_NFRAMES)
return -EINVAL; return -EINVAL;
/* check the given can_id */ /* check the given can_id */
...@@ -993,6 +1002,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg, ...@@ -993,6 +1002,10 @@ static int bcm_rx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
msg_head->nframes = 0; msg_head->nframes = 0;
} }
/* the first element contains the mux-mask => MAX_NFRAMES + 1 */
if (msg_head->nframes > MAX_NFRAMES + 1)
return -EINVAL;
if ((msg_head->flags & RX_RTR_FRAME) && if ((msg_head->flags & RX_RTR_FRAME) &&
((msg_head->nframes != 1) || ((msg_head->nframes != 1) ||
(!(msg_head->can_id & CAN_RTR_FLAG)))) (!(msg_head->can_id & CAN_RTR_FLAG))))
......
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