can: add sanity checks

Even though the CAN netlayer only deals with CAN netdevices, the 
netlayer interface to the userspace and to the device layer should 
perform some sanity checks.

This patch adds several sanity checks that mainly prevent userspace apps 
to send broken content into the system that may be misinterpreted by 
some other userspace application.

Signed-off-by: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
Signed-off-by: Urs Thuermann <urs.thuermann@volkswagen.de>
Acked-by: Andre Naujoks <nautsch@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Oliver Hartkopp
2008-07-05 23:38:43 -07:00
committed by David S. Miller
parent c5a78ac00c
commit 7f2d38eb7a
3 changed files with 32 additions and 4 deletions

View File

@@ -298,7 +298,7 @@ static void bcm_send_to_user(struct bcm_op *op, struct bcm_msg_head *head,
if (head->nframes) {
/* 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);
@@ -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++) {
err = memcpy_fromiovec((u8 *)&op->frames[i],
msg->msg_iov, CFSIZ);
if (op->frames[i].can_dlc > 8)
err = -EINVAL;
if (err < 0)
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++) {
err = memcpy_fromiovec((u8 *)&op->frames[i],
msg->msg_iov, CFSIZ);
if (op->frames[i].can_dlc > 8)
err = -EINVAL;
if (err < 0) {
if (op->frames != &op->sframe)
kfree(op->frames);
@@ -1164,9 +1172,12 @@ static int bcm_tx_send(struct msghdr *msg, int ifindex, struct sock *sk)
skb->dev = dev;
skb->sk = sk;
can_send(skb, 1); /* send with loopback */
err = can_send(skb, 1); /* send with loopback */
dev_put(dev);
if (err)
return err;
return CFSIZ + MHSIZ;
}
@@ -1185,6 +1196,10 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
if (!bo->bound)
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 */
if (!ifindex && msg->msg_name) {
@@ -1259,8 +1274,8 @@ static int bcm_sendmsg(struct kiocb *iocb, struct socket *sock,
break;
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;
else
ret = bcm_tx_send(msg, ifindex, sk);