lkml.org 
[lkml]   [2022]   [Feb]   [14]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.16 011/203] can: isotp: fix error path in isotp_sendmsg() to unlock wait queue
    Date
    From: Oliver Hartkopp <socketcan@hartkopp.net>

    commit 8375dfac4f683e1b2c5956d919d36aeedad46699 upstream.

    Commit 43a08c3bdac4 ("can: isotp: isotp_sendmsg(): fix TX buffer concurrent
    access in isotp_sendmsg()") introduced a new locking scheme that may render
    the userspace application in a locking state when an error is detected.
    This issue shows up under high load on simultaneously running isotp channels
    with identical configuration which is against the ISO specification and
    therefore breaks any reasonable PDU communication anyway.

    Fixes: 43a08c3bdac4 ("can: isotp: isotp_sendmsg(): fix TX buffer concurrent access in isotp_sendmsg()")
    Link: https://lore.kernel.org/all/20220209073601.25728-1-socketcan@hartkopp.net
    Cc: stable@vger.kernel.org
    Cc: Ziyang Xuan <william.xuanziyang@huawei.com>
    Signed-off-by: Oliver Hartkopp <socketcan@hartkopp.net>
    Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    ---
    net/can/isotp.c | 15 +++++++++------
    1 file changed, 9 insertions(+), 6 deletions(-)

    --- a/net/can/isotp.c
    +++ b/net/can/isotp.c
    @@ -887,7 +887,7 @@ static int isotp_sendmsg(struct socket *

    if (!size || size > MAX_MSG_LENGTH) {
    err = -EINVAL;
    - goto err_out;
    + goto err_out_drop;
    }

    /* take care of a potential SF_DL ESC offset for TX_DL > 8 */
    @@ -897,24 +897,24 @@ static int isotp_sendmsg(struct socket *
    if ((so->opt.flags & CAN_ISOTP_SF_BROADCAST) &&
    (size > so->tx.ll_dl - SF_PCI_SZ4 - ae - off)) {
    err = -EINVAL;
    - goto err_out;
    + goto err_out_drop;
    }

    err = memcpy_from_msg(so->tx.buf, msg, size);
    if (err < 0)
    - goto err_out;
    + goto err_out_drop;

    dev = dev_get_by_index(sock_net(sk), so->ifindex);
    if (!dev) {
    err = -ENXIO;
    - goto err_out;
    + goto err_out_drop;
    }

    skb = sock_alloc_send_skb(sk, so->ll.mtu + sizeof(struct can_skb_priv),
    msg->msg_flags & MSG_DONTWAIT, &err);
    if (!skb) {
    dev_put(dev);
    - goto err_out;
    + goto err_out_drop;
    }

    can_skb_reserve(skb);
    @@ -976,7 +976,7 @@ static int isotp_sendmsg(struct socket *
    if (err) {
    pr_notice_once("can-isotp: %s: can_send_ret %pe\n",
    __func__, ERR_PTR(err));
    - goto err_out;
    + goto err_out_drop;
    }

    if (wait_tx_done) {
    @@ -989,6 +989,9 @@ static int isotp_sendmsg(struct socket *

    return size;

    +err_out_drop:
    + /* drop this PDU and unlock a potential wait queue */
    + old_state = ISOTP_IDLE;
    err_out:
    so->tx.state = old_state;
    if (so->tx.state == ISOTP_IDLE)

    \
     
     \ /
      Last update: 2022-02-14 11:39    [W:4.069 / U:0.096 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site