From patchwork Tue Jun 20 17:27:29 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marcelo Henrique Cerri X-Patchwork-Id: 778433 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) by ozlabs.org (Postfix) with ESMTP id 3wsZZV1Rf1z9s7v; Wed, 21 Jun 2017 03:28:50 +1000 (AEST) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=canonical-com.20150623.gappssmtp.com header.i=@canonical-com.20150623.gappssmtp.com header.b="FCGoYDAu"; dkim-atps=neutral Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.76) (envelope-from ) id 1dNMxL-0001zQ-IN; Tue, 20 Jun 2017 17:28:47 +0000 Received: from mail-ua0-f173.google.com ([209.85.217.173]) by huckleberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1dNMwb-0001fV-P1 for kernel-team@lists.ubuntu.com; Tue, 20 Jun 2017 17:28:01 +0000 Received: by mail-ua0-f173.google.com with SMTP id g40so88659648uaa.3 for ; Tue, 20 Jun 2017 10:28:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=canonical-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=BAdWdnqCHXM+Fbexg9A6tBXZg/UjLBu6xwFLUe/7Pj8=; b=FCGoYDAuSFQK1Eo8MTTacq8oO/oLWt3XQUXaY7aPeZgn+nfh3CeBvKa05yo1LD6ibL db/ID/Oaz/m2JIn/O9IJ/Dvn9sxocuTvyzyCdPxdTbOHKH+6jppmKQsJXBn0JL/lfOcP FBd7QOA8++VK4bDOztaiLlP3twsGOSw+6JPjwrci+FXSu+J7VJjUzfHSvQT3JfXau6HX ZdD9FxaYevK01BlhlgG2Q1IBgc/j/SATzs5D4hhggagkcQ4vcXhABnBFDlTwgdkNXYqk 1DcD6u6+0Hz9EznsjOR/CAJkHU2tfzaRVgXGSzBMCJmTJNuSL8WLMP8d6OIZ0fhRkA2N dAEA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=BAdWdnqCHXM+Fbexg9A6tBXZg/UjLBu6xwFLUe/7Pj8=; b=Zzb9N6fosUZiodjbrYJio0syieKoJdOpstD4ZcsqvDzvx85yLNgAHatEr/KOVJMeUe zDZSN0BoYdeKnXCM+trWUXVGiy/3mrfUUwBFnn2VgNY4w71KX4Ctxq3YEA9LeWjVFbwY xQxST4YbR07CZr+Pk/9Fe6mdzoAyPiiHatlLNDSvAiSzzxu6kh5upGksv8QvRiK3Wh1C qbIb1hw4IpsD5VWHb/Gp9WKpgYeahngxBksqA57U6mGNtuLZZG8PVlEqcEu2oW8kuBYU P5TqRInRJlxRbkce385VZAVG9LByOoONc39Btl5kKjetqRwJdeakCMaFzYaCHXPF0UHV RoBw== X-Gm-Message-State: AKS2vOx+YvW5by9zk8qnCjXFP9bya8z/8JPaIrAwBh2sQj9K7EM4soTb vuOsHQqjp0kNMbenwwU= X-Received: by 10.176.71.3 with SMTP id h3mr6744172uac.140.1497979680528; Tue, 20 Jun 2017 10:28:00 -0700 (PDT) Received: from localhost.localdomain ([191.8.96.73]) by smtp.gmail.com with ESMTPSA id x2sm4922955vkd.35.2017.06.20.10.27.58 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Tue, 20 Jun 2017 10:27:59 -0700 (PDT) From: Marcelo Henrique Cerri To: kernel-team@lists.ubuntu.com Subject: [azure][PATCH 09/14] UBUNTU: SAUCE: hvsock: fix a race in hvs_stream_dequeue() Date: Tue, 20 Jun 2017 14:27:29 -0300 Message-Id: <1497979654-27251-10-git-send-email-marcelo.cerri@canonical.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1497979654-27251-1-git-send-email-marcelo.cerri@canonical.com> References: <1497979654-27251-1-git-send-email-marcelo.cerri@canonical.com> Cc: "K . Y . Srinivasan" , Dexuan Cui , Cheng-mean Liu X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.14 Precedence: list List-Id: Kernel team discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: kernel-team-bounces@lists.ubuntu.com From: Dexuan Cui BugLink: http://bugs.launchpad.net/bugs/1698425 If hv_pkt_iter_next() returns a non-NULL pointer, we must update the recv_data_len/data_off info, otherwise the received data will be silently dropped, and let's fix hvs_stream_has_data() accordingly. Thank Rolf for finding this! Reported-by: Rolf Neugebauer Signed-off-by: Dexuan Cui Signed-off-by: Marcelo Henrique Cerri --- net/vmw_vsock/hyperv_transport.c | 50 +++++++++++++++++++++++++++++----------- 1 file changed, 36 insertions(+), 14 deletions(-) diff --git a/net/vmw_vsock/hyperv_transport.c b/net/vmw_vsock/hyperv_transport.c index f465b0b662df..30154836acd0 100644 --- a/net/vmw_vsock/hyperv_transport.c +++ b/net/vmw_vsock/hyperv_transport.c @@ -476,13 +476,33 @@ static bool hvs_dgram_allow(u32 cid, u32 port) return false; } +static int hvs_update_recv_data(struct hvsock *hvs) +{ + struct hvs_recv_buf *recv_buf; + u32 payload_len; + + recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1); + payload_len = recv_buf->hdr.data_size; + + if (payload_len > HVS_MTU_SIZE) + return -EIO; + + if (payload_len == 0) + hvs->vsk->peer_shutdown |= SEND_SHUTDOWN; + + hvs->recv_data_len = payload_len; + hvs->recv_data_off = 0; + + return 0; +} + static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg, size_t len, int flags) { struct hvsock *hvs = vsk->trans; bool need_refill = !hvs->recv_desc; struct hvs_recv_buf *recv_buf; - u32 payload_len, to_read; + u32 to_read; int ret; if (flags & MSG_PEEK) @@ -490,29 +510,28 @@ static ssize_t hvs_stream_dequeue(struct vsock_sock *vsk, struct msghdr *msg, if (need_refill) { hvs->recv_desc = hv_pkt_iter_first(hvs->chan); - recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1); - - payload_len = recv_buf->hdr.data_size; - if (payload_len == 0 || payload_len > HVS_MTU_SIZE) - return -EIO; - - hvs->recv_data_len = payload_len; - hvs->recv_data_off = 0; - } else { - recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1); + ret = hvs_update_recv_data(hvs); + if (ret) + return ret; } + recv_buf = (struct hvs_recv_buf *)(hvs->recv_desc + 1); to_read = min_t(u32, len, hvs->recv_data_len); ret = memcpy_to_msg(msg, recv_buf->data + hvs->recv_data_off, to_read); if (ret != 0) return ret; hvs->recv_data_len -= to_read; - - if (hvs->recv_data_len == 0) + if (hvs->recv_data_len == 0) { hvs->recv_desc = hv_pkt_iter_next(hvs->chan, hvs->recv_desc); - else + if (hvs->recv_desc) { + ret = hvs_update_recv_data(hvs); + if (ret) + return ret; + } + } else { hvs->recv_data_off += to_read; + } return to_read; } @@ -554,6 +573,9 @@ static s64 hvs_stream_has_data(struct vsock_sock *vsk) struct hvsock *hvs = vsk->trans; s64 ret; + if (hvs->recv_data_len > 0) + return 1; + switch (hvs_channel_readable_payload(hvs->chan)) { case 1: ret = 1;