Re: [PATCH v3] can: ensure an initialized headroom in outgoing CAN sk_buffs

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 





On 16/12/2019 18.17, Oliver Hartkopp wrote:


On 10/12/2019 11.31, Marc Kleine-Budde wrote:
From: Oliver Hartkopp <socketcan@xxxxxxxxxxxx>

KMSAN sysbot detected a read access to an untinitialized value in the
headroom of an outgoing CAN related sk_buff. When using CAN sockets this
area is filled appropriately - but when using a packet socket this
initialization is missing.

The problematic read access occurs in the CAN receive path which can
only be triggered when the sk_buff is sent through a (virtual) CAN
interface. So we check in the sending path whether we need to perform
the missing initializations.

Fixes: d3b58c47d330d ("can: replace timestamp as unique skb attribute")
Reported-by: syzbot+b02ff0707a97e4e79ebb@xxxxxxxxxxxxxxxxxxxxxxxxx
Signed-off-by: Oliver Hartkopp <socketcan@xxxxxxxxxxxx>
Signed-off-by: Marc Kleine-Budde <mkl@xxxxxxxxxxxxxx>

When do you want to push it upstream?

... together with the hint for the stable trees

Cc: linux-stable <stable@xxxxxxxxxxxxxxx> # >= v4.1

The patch is ok for me.
Do you need another Acked-by or Tested-by tag?

Tested-by: Oliver Hartkopp <socketcan@xxxxxxxxxxxx>

Just for the record:

With this patch for vcan.c

diff --git a/drivers/net/can/vcan.c b/drivers/net/can/vcan.c
index 39ca14b0585d..eb7023043385 100644
--- a/drivers/net/can/vcan.c
+++ b/drivers/net/can/vcan.c
@@ -83,15 +83,32 @@ static void vcan_rx(struct sk_buff *skb, struct net_device *dev)
 	netif_rx_ni(skb);
 }

+static void vcan_print_skb(struct sk_buff *skb)
+{
+ printk("len: %d, end-data: %ld, tail-data %ld, data-head %ld, ifindex = %d, skbcnt = %d, pkt_type = %d, ip_summed = %d\n",
+	      skb->len,
+	      skb_end_pointer(skb) - skb->data,
+	      skb_tail_pointer(skb) - skb->data,
+	      skb->data - skb->head,
+	      can_skb_prv(skb)->ifindex,
+	      can_skb_prv(skb)->skbcnt,
+	      skb->pkt_type,
+	      skb->ip_summed);
+}
+
 static netdev_tx_t vcan_tx(struct sk_buff *skb, struct net_device *dev)
 {
 	struct canfd_frame *cfd = (struct canfd_frame *)skb->data;
 	struct net_device_stats *stats = &dev->stats;
 	int loop;

+	vcan_print_skb(skb);
+
 	if (can_dropped_invalid_skb(dev, skb))
 		return NETDEV_TX_OK;

+	vcan_print_skb(skb);
+
 	stats->tx_packets++;
 	stats->tx_bytes += cfd->len;


And then starting
cansend vcan0 12345678#112233

dmesg:
[ 95.567858] len: 16, end-data: 184, tail-data 16, data-head 8, ifindex = 8, skbcnt = 0, pkt_type = 5, ip_summed = 1 [ 95.567862] len: 16, end-data: 184, tail-data 16, data-head 8, ifindex = 8, skbcnt = 0, pkt_type = 5, ip_summed = 1

Alternatively
linux-can/can-tests/netlayer# ./tst-packet -s

dmesg:
[ 124.740592] len: 16, end-data: 176, tail-data 16, data-head 16, ifindex = 0, skbcnt = 0, pkt_type = 0, ip_summed = 0 [ 124.740596] len: 16, end-data: 176, tail-data 16, data-head 16, ifindex = 10, skbcnt = 0, pkt_type = 5, ip_summed = 1

So ifindex, skbcnt, pkt_type, ip_summed have been set correctly - even for skb's that have not been created by the CAN subsystem (e.g. packet socket).

Regards,
Oliver




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux