Re: [PATCH 2/2] can: gw: add support for CAN FD frames

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

 



On 8/9/19 7:29 PM, Oliver Hartkopp wrote:
>> Which race condition do you have in mind?
> 
> E.g. you create a can-gw job that forwards the incoming CAN frame to 10 
> different vcan's.
> 
> These 10 skb's have been cloned which means their skb->data points to 
> the exact same location. When now each vcan instance on a multicore 
> system reads and writes the length info you have a classical race on 
> that one memory location.

Thanks. I've totally missed the point that can-gw can forward CAN frames
to more than one interface.

>> For loopback ("can_put_echo_skb()"), I see a race condition in some CAN
>> drivers: They first do a can_put_echo_skb(), then keep using the skb to
>> write ->data into the hardware.
>>
>> If we modify the skb in can_put_echo_skb(), then the CAN driver will see
>> the sanitized struct canfd_frame::len. This means for dlc == 13, 14, 15
>> the driver will write more data into the hardware than needed. It
>> probably depends on the HW what the controller sends out if you have a
>> dlc == 14 (which means len up to 48 bytes) but only write 33 bytes into
>> the registers.
> 
> Then you have uninitialized content from the CAN registers and not from 
> the skb on the wire :-)

ACK.

>> While other drivers don't touch the skb after can_put_echo_skb().
>>
>> Can we modify the ->len in can_get_echo_skb() (or the __ variant) right
>> before pushing the skv into the networking stack? We have to look at the
>> data path for driver that cannot/don't use can_get_echo_skb() due to no
>> TX-complete interrupt.
>>
>> Looking at vcan, where's the race condition when modifying the skb in
>> vcan_tx()?
> 
> As written above. Additionally the echo is mostly done in can_send() in 
> af_can.c. And vcan_tx() is just a /dev/null from the packet flow 
> perspective.

With can-gw, the skb hitting vcan may be cloned and thus changing the
data is not allowed. But what about the loopback path? Are there
usecases where a cloned skb used?

>>> I tend to sanitize the CAN FD length values when they are introduced
>>> into the system (CAN_RAW, CAN_BCM, CAN FD drivers*) and when they are
>>> modified (CAN_GW).
>>>
>>> * = already done
>>
>> You miss the datapath that directly injects packets into the networking
>> stack with the mechanism that tcpdump uses but the sending into the
>> kernel instead of receiving (I don't remember the exact name). This path
>> skips all checks in CAN_RAW. This is why we have the
>> "can_dropped_invalid_skb()" in all drivers.
> 
> I don't know whether these tools can create ethertype CAN(FD) skbs which 
> is mandatory for the CAN stack to process skbs. But if so, you are right.

You can inject arbitrary packets into the kernel.

>> So from my point of view it makes no sense to sanitize the len value in
>> gw, as the drivers convert from len to dlc anyways.
>>
>> What do I see when I attach a candump to the src and another one to the
>> dst interface? I suspenct:
>>
>> src) the unmodified canfd_frame with sanitized len, as the controller
>> knowns only the dlc.
>>
>> dst) the modified-by-gw canfd_frame, _after_ the loopback by the driver?
>> If there's neither sanitation in the gw not in the loopback, it's the
>> unsanitized len.
>>
>> When I have another application sending on the dst interface, the
>> candump receives the un-sanitized, as there's no sanitation in the loopback.
>>
>> For me the loopback is and vcan is the part to modify, as gw is just a
>> another source of unsanitized len information.
>>
>>> My idea was to fix things up when someone manipulates the CAN or CAN FD
>>> length field with can-gw.
>>
>> For CAN you don't have to do any sanitization, only check if the len is
>> <= 8.
> 
> Mapping [0..8] to [0..8] is pointless but correct :-)

:p

>>> Or do you think I should just omit it and let the data flow as-is?
>>
>> ACK
> 
> Ok, will send a v2 with a removed sanitized CAN FD length. The 
> boundaries of the max length information (max 8 or 64) is tested anyway.

Tnx. It's in the linux-can-next-for-5.4-20190814 pull reqeust.

Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |

Attachment: signature.asc
Description: OpenPGP digital signature


[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