lkml.org 
[lkml]   [2019]   [Nov]   [11]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.3 075/193] can: peak_usb: fix a potential out-of-sync while decoding packets
    Date
    From: Stephane Grosjean <s.grosjean@peak-system.com>

    commit de280f403f2996679e2607384980703710576fed upstream.

    When decoding a buffer received from PCAN-USB, the first timestamp read in
    a packet is a 16-bit coded time base, and the next ones are an 8-bit
    offset to this base, regardless of the type of packet read.

    This patch corrects a potential loss of synchronization by using a
    timestamp index read from the buffer, rather than an index of received
    data packets, to determine on the sizeof the timestamp to be read from the
    packet being decoded.

    Signed-off-by: Stephane Grosjean <s.grosjean@peak-system.com>
    Fixes: 46be265d3388 ("can: usb: PEAK-System Technik PCAN-USB specific part")
    Cc: linux-stable <stable@vger.kernel.org>
    Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/net/can/usb/peak_usb/pcan_usb.c | 17 ++++++++++++-----
    1 file changed, 12 insertions(+), 5 deletions(-)

    --- a/drivers/net/can/usb/peak_usb/pcan_usb.c
    +++ b/drivers/net/can/usb/peak_usb/pcan_usb.c
    @@ -100,7 +100,7 @@ struct pcan_usb_msg_context {
    u8 *end;
    u8 rec_cnt;
    u8 rec_idx;
    - u8 rec_data_idx;
    + u8 rec_ts_idx;
    struct net_device *netdev;
    struct pcan_usb *pdev;
    };
    @@ -547,10 +547,15 @@ static int pcan_usb_decode_status(struct
    mc->ptr += PCAN_USB_CMD_ARGS;

    if (status_len & PCAN_USB_STATUSLEN_TIMESTAMP) {
    - int err = pcan_usb_decode_ts(mc, !mc->rec_idx);
    + int err = pcan_usb_decode_ts(mc, !mc->rec_ts_idx);

    if (err)
    return err;
    +
    + /* Next packet in the buffer will have a timestamp on a single
    + * byte
    + */
    + mc->rec_ts_idx++;
    }

    switch (f) {
    @@ -632,10 +637,13 @@ static int pcan_usb_decode_data(struct p

    cf->can_dlc = get_can_dlc(rec_len);

    - /* first data packet timestamp is a word */
    - if (pcan_usb_decode_ts(mc, !mc->rec_data_idx))
    + /* Only first packet timestamp is a word */
    + if (pcan_usb_decode_ts(mc, !mc->rec_ts_idx))
    goto decode_failed;

    + /* Next packet in the buffer will have a timestamp on a single byte */
    + mc->rec_ts_idx++;
    +
    /* read data */
    memset(cf->data, 0x0, sizeof(cf->data));
    if (status_len & PCAN_USB_STATUSLEN_RTR) {
    @@ -688,7 +696,6 @@ static int pcan_usb_decode_msg(struct pe
    /* handle normal can frames here */
    } else {
    err = pcan_usb_decode_data(&mc, sl);
    - mc.rec_data_idx++;
    }
    }


    \
     
     \ /
      Last update: 2019-11-11 19:52    [W:4.231 / U:1.972 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site