|
@@ -298,7 +298,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
|
|
|
|
|
|
if (head->nframes) {
|
|
if (head->nframes) {
|
|
/* can_frames starting here */
|
|
/* can_frames starting here */
|
|
- firstframe = (struct can_frame *) skb_tail_pointer(skb);
|
|
|
|
|
|
+ firstframe = (struct can_frame *)skb_tail_pointer(skb);
|
|
|
|
|
|
memcpy(skb_put(skb, datalen), frames, datalen);
|
|
memcpy(skb_put(skb, datalen), frames, datalen);
|
|
|
|
|
|
@@ -826,6 +826,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
|
for (i = 0; i < msg_head->nframes; i++) {
|
|
for (i = 0; i < msg_head->nframes; i++) {
|
|
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
|
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
|
msg->msg_iov, CFSIZ);
|
|
msg->msg_iov, CFSIZ);
|
|
|
|
+
|
|
|
|
+ if (op->frames[i].can_dlc > 8)
|
|
|
|
+ err = -EINVAL;
|
|
|
|
+
|
|
if (err < 0)
|
|
if (err < 0)
|
|
return err;
|
|
return err;
|
|
|
|
|
|
@@ -858,6 +862,10 @@ static int bcm_tx_setup(struct bcm_msg_head *msg_head, struct msghdr *msg,
|
|
for (i = 0; i < msg_head->nframes; i++) {
|
|
for (i = 0; i < msg_head->nframes; i++) {
|
|
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
|
err = memcpy_fromiovec((u8 *)&op->frames[i],
|
|
msg->msg_iov, CFSIZ);
|
|
msg->msg_iov, CFSIZ);
|
|
|
|
+
|
|
|
|
+ if (op->frames[i].can_dlc > 8)
|
|
|
|
+ err = -EINVAL;
|
|
|
|
+
|
|
if (err < 0) {
|
|
if (err < 0) {
|
|
if (op->frames != &op->sframe)
|
|
if (op->frames != &op->sframe)
|
|
kfree(op->frames);
|
|
kfree(op->frames);
|
|
@@ -1164,9 +1172,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
|
|
|
|
|
|
skb->dev = dev;
|
|
skb->dev = dev;
|
|
skb->sk = sk;
|
|
skb->sk = sk;
|
|
- can_send(skb, 1); /* send with loopback */
|
|
|
|
|
|
+ err = can_send(skb, 1); /* send with loopback */
|
|
dev_put(dev);
|
|
dev_put(dev);
|
|
|
|
|
|
|
|
+ if (err)
|
|
|
|
+ return err;
|
|
|
|
+
|
|
return CFSIZ + MHSIZ;
|
|
return CFSIZ + MHSIZ;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -1185,6 +1196,10 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|
if (!bo->bound)
|
|
if (!bo->bound)
|
|
return -ENOTCONN;
|
|
return -ENOTCONN;
|
|
|
|
|
|
|
|
+ /* check for valid message length from userspace */
|
|
|
|
+ if (size < MHSIZ || (size - MHSIZ) % CFSIZ)
|
|
|
|
+ return -EINVAL;
|
|
|
|
+
|
|
/* check for alternative ifindex for this bcm_op */
|
|
/* check for alternative ifindex for this bcm_op */
|
|
|
|
|
|
if (!ifindex && msg->msg_name) {
|
|
if (!ifindex && msg->msg_name) {
|
|
@@ -1259,8 +1274,8 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
|
|
break;
|
|
break;
|
|
|
|
|
|
case TX_SEND:
|
|
case TX_SEND:
|
|
- /* we need at least one can_frame */
|
|
|
|
- if (msg_head.nframes < 1)
|
|
|
|
|
|
+ /* we need exactly one can_frame behind the msg head */
|
|
|
|
+ if ((msg_head.nframes != 1) || (size != CFSIZ + MHSIZ))
|
|
ret = -EINVAL;
|
|
ret = -EINVAL;
|
|
else
|
|
else
|
|
ret = bcm_tx_send(msg, ifindex, sk);
|
|
ret = bcm_tx_send(msg, ifindex, sk);
|