Received: by 2002:a25:31c3:0:0:0:0:0 with SMTP id x186csp6554250ybx; Mon, 11 Nov 2019 10:51:58 -0800 (PST) X-Google-Smtp-Source: APXvYqyUVQrv5KG05gsx+Inw54lC9HajNZUg0qffM6mih+F4qY7qhA5QPOE61BtbV+d02ytZNNKB X-Received: by 2002:a05:6402:512:: with SMTP id m18mr28477604edv.250.1573498318895; Mon, 11 Nov 2019 10:51:58 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1573498318; cv=none; d=google.com; s=arc-20160816; b=WvWkE7qIosK4+H6sHWEz50e0/5jKMf8Tq4MQDKNOMqB0PgYuM+59PCVXXyXihuS4La wa2oFsgl6dcy2kPW5hyFtCaGxb3PyrKO8aod9ZZYGoLf1CWnwL6lPODB+g3PDsrJH9IY ssO0K6ZyGjndFDJXmuAkLUyLbcylAxwN1lOCy6ax0uUDfSlgT0iFqhXGSTQXm8w8Om9z 5U4e0F3FXUFIBSFf76KQlibDmehr2COS2dFFU33AVzqQjLtSsO1nwAMu+0ex1tR1STfK kowwK16Sh8SnrlhScECLdQWWI2xLjwbOImY3HKaPCHABGfm82bn7AtFoxLCNAXH3yFIp GiCw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :user-agent:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature; bh=+PGqAcajxzqa9gBOMeuFWHxMSuwTLI074yVVuhifaJ8=; b=tqY6ZqUS+O1h6rn/MK4txzPf8YVxxNOLDWgZpxRkaoF+t5QDacHfFyaxNLH2YOXwof 7HibQGFw+mL6//E4h7AAhxfBnnu5O+7AiBRnmu4t9gPG7IOI7e+fiazXCegEWOOmi2Yt EMlUyVjLcJjcblqDj/zSa25afftdV2C5eGTWBZWMWyKLU26spsJW8bs/AjTL41gl6OeY STyh1Ti8AAFDZJ9p1wG+9pX9nnGlXtZKZTF3ay3fQFgiOaMaxP7/bsZYVAfhB+RRhiQ8 hejKqLilmA+108gJJksD+v0MHvFWUUh/hb6/Rzv3EEmflizhEz1p7cfCC+ZRhsB9DN9I nR8g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=OlnafMFr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id v4si11592407edm.299.2019.11.11.10.51.35; Mon, 11 Nov 2019 10:51:58 -0800 (PST) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=default header.b=OlnafMFr; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730270AbfKKSsh (ORCPT + 99 others); Mon, 11 Nov 2019 13:48:37 -0500 Received: from mail.kernel.org ([198.145.29.99]:41664 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729600AbfKKSsg (ORCPT ); Mon, 11 Nov 2019 13:48:36 -0500 Received: from localhost (83-86-89-107.cable.dynamic.v4.ziggo.nl [83.86.89.107]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPSA id 23AE120674; Mon, 11 Nov 2019 18:48:33 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=default; t=1573498114; bh=vNa/ksUXJnBe6vrWo5uDxUVxHyDz6ZLyD+1YZGbDsIc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=OlnafMFrWn2qzkByeDuOUKQlyZhAVdjdowwLeyYKWnJ+I/S5rmqm4+9b32/1VkewK Wo7kZ4M0+hqHgtNr5PwI4iZnuattOuIkAfbb7pq9rdL9EmyU4WMJJs2fKEykbH1SlS SsF0NrVHcWJ73vWKBlird3hm2CePvq6bME1dbfuQ= From: Greg Kroah-Hartman To: linux-kernel@vger.kernel.org Cc: Greg Kroah-Hartman , stable@vger.kernel.org, syzbot+f8495bff23a879a6d0bd@syzkaller.appspotmail.com, syzbot+6f50c99e8f6194bf363f@syzkaller.appspotmail.com, Jakub Kicinski , John Fastabend , "David S. Miller" Subject: [PATCH 5.3 007/193] net/tls: fix sk_msg trim on fallback to copy mode Date: Mon, 11 Nov 2019 19:26:29 +0100 Message-Id: <20191111181500.382685090@linuxfoundation.org> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191111181459.850623879@linuxfoundation.org> References: <20191111181459.850623879@linuxfoundation.org> User-Agent: quilt/0.66 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jakub Kicinski [ Upstream commit 683916f6a84023407761d843048f1aea486b2612 ] sk_msg_trim() tries to only update curr pointer if it falls into the trimmed region. The logic, however, does not take into the account pointer wrapping that sk_msg_iter_var_prev() does nor (as John points out) the fact that msg->sg is a ring buffer. This means that when the message was trimmed completely, the new curr pointer would have the value of MAX_MSG_FRAGS - 1, which is neither smaller than any other value, nor would it actually be correct. Special case the trimming to 0 length a little bit and rework the comparison between curr and end to take into account wrapping. This bug caused the TLS code to not copy all of the message, if zero copy filled in fewer sg entries than memcopy would need. Big thanks to Alexander Potapenko for the non-KMSAN reproducer. v2: - take into account that msg->sg is a ring buffer (John). Link: https://lore.kernel.org/netdev/20191030160542.30295-1-jakub.kicinski@netronome.com/ (v1) Fixes: d829e9c4112b ("tls: convert to generic sk_msg interface") Reported-by: syzbot+f8495bff23a879a6d0bd@syzkaller.appspotmail.com Reported-by: syzbot+6f50c99e8f6194bf363f@syzkaller.appspotmail.com Co-developed-by: John Fastabend Signed-off-by: Jakub Kicinski Signed-off-by: John Fastabend Signed-off-by: David S. Miller Signed-off-by: Greg Kroah-Hartman --- include/linux/skmsg.h | 9 ++++++--- net/core/skmsg.c | 20 +++++++++++++++----- 2 files changed, 21 insertions(+), 8 deletions(-) --- a/include/linux/skmsg.h +++ b/include/linux/skmsg.h @@ -139,6 +139,11 @@ static inline void sk_msg_apply_bytes(st } } +static inline u32 sk_msg_iter_dist(u32 start, u32 end) +{ + return end >= start ? end - start : end + (MAX_MSG_FRAGS - start); +} + #define sk_msg_iter_var_prev(var) \ do { \ if (var == 0) \ @@ -198,9 +203,7 @@ static inline u32 sk_msg_elem_used(const if (sk_msg_full(msg)) return MAX_MSG_FRAGS; - return msg->sg.end >= msg->sg.start ? - msg->sg.end - msg->sg.start : - msg->sg.end + (MAX_MSG_FRAGS - msg->sg.start); + return sk_msg_iter_dist(msg->sg.start, msg->sg.end); } static inline struct scatterlist *sk_msg_elem(struct sk_msg *msg, int which) --- a/net/core/skmsg.c +++ b/net/core/skmsg.c @@ -271,18 +271,28 @@ void sk_msg_trim(struct sock *sk, struct msg->sg.data[i].length -= trim; sk_mem_uncharge(sk, trim); + /* Adjust copybreak if it falls into the trimmed part of last buf */ + if (msg->sg.curr == i && msg->sg.copybreak > msg->sg.data[i].length) + msg->sg.copybreak = msg->sg.data[i].length; out: - /* If we trim data before curr pointer update copybreak and current - * so that any future copy operations start at new copy location. + sk_msg_iter_var_next(i); + msg->sg.end = i; + + /* If we trim data a full sg elem before curr pointer update + * copybreak and current so that any future copy operations + * start at new copy location. * However trimed data that has not yet been used in a copy op * does not require an update. */ - if (msg->sg.curr >= i) { + if (!msg->sg.size) { + msg->sg.curr = msg->sg.start; + msg->sg.copybreak = 0; + } else if (sk_msg_iter_dist(msg->sg.start, msg->sg.curr) >= + sk_msg_iter_dist(msg->sg.start, msg->sg.end)) { + sk_msg_iter_var_prev(i); msg->sg.curr = i; msg->sg.copybreak = msg->sg.data[i].length; } - sk_msg_iter_var_next(i); - msg->sg.end = i; } EXPORT_SYMBOL_GPL(sk_msg_trim);