From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,FREEMAIL_FORGED_FROMDOMAIN,FREEMAIL_FROM, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_PASS,URIBL_BLOCKED,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 78E16C43381 for ; Wed, 20 Mar 2019 06:49:48 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 3D4EE2184D for ; Wed, 20 Mar 2019 06:49:48 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="a++Ea6F0" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727109AbfCTGtr (ORCPT ); Wed, 20 Mar 2019 02:49:47 -0400 Received: from mail-pg1-f194.google.com ([209.85.215.194]:38755 "EHLO mail-pg1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726123AbfCTGtr (ORCPT ); Wed, 20 Mar 2019 02:49:47 -0400 Received: by mail-pg1-f194.google.com with SMTP id v1so1054080pgi.5; Tue, 19 Mar 2019 23:49:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=grFYzCl0a/jvLznChjfhtZM8unUrkMkwpQiAJo9OAKw=; b=a++Ea6F0AInumJHmsblBxyC/6ukaeTxEYOfg82ZbABI3Y/nRtsu3N9JaFYqeiUiiml l9xQMCIcetoTIrJfNao95MK0r3iP2Jd/dtcHEfO+Q4ZaU7NFZPFrmGprGarfhGrnVsG8 MQ02FV3wGrfX2T3bFqwuJKnoMrYoDjj5I54oQW/N27gWLdqtniPf975bRpj8sSbL8fKo oO+HYxQ7AXoYAvYdWrQ1EnLQaulJp4RQ7mfw4Dgc+b7lXDj7FqCqtFKw2spiI2MUzPmk pxKxgaEzJXJ1a6yCwnfegNL+ZhgDKKrBxr018Y0i3A+lSPG1JcNwCbiG/fcgpK94HZuR Fisw== 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; bh=grFYzCl0a/jvLznChjfhtZM8unUrkMkwpQiAJo9OAKw=; b=o4qenW9fv5wx+MFjpD5GTcaKXYEDW/wuNelvZIbNXT+6fDgSUtHI17XOyMO88zNfic C73iIpnpBWcvyLDGtmdd0EeCF1hYc5NX4QV6tjN5UEi+8kZuX+RtGP1My9MOD8tyWESX 2xbhexUo0tyImqLPvBkBb8ibBG3Tym3JT6gG7L9/Iz1WCycKcJNM8b+rNvBs96vFZFLS 89qPsDdX2woZfmIIU5Je2dd8oh4skHVJeI4SvYzuHzKJ52ymEAUiF4fnotPKy3QaRq6V 0J+WknFDf9WclAAfJ5ZqAWxCZ9HiDyG/0WVRMbF2nyUuRJZXx2E1fGZRne5zZaYmUhoC e21w== X-Gm-Message-State: APjAAAXvNmW3m+Ue5ols3iJ/MvZtLi5dNJH7H9Ijo9Di6Ooe6teUBX+0 fKkHRYSOc9ggVqJ7Qp3lmZn/j2ArVCI= X-Google-Smtp-Source: APXvYqx2NvD8JRlyZcRRzv66VI1OwfM8RqCiW1ZgbHumTRLRdtcUmjPCoff+HcwxnR0zgX5gPXmS2g== X-Received: by 2002:a17:902:5992:: with SMTP id p18mr6312623pli.231.1553064586208; Tue, 19 Mar 2019 23:49:46 -0700 (PDT) Received: from localhost ([209.132.188.80]) by smtp.gmail.com with ESMTPSA id g6sm1410932pgq.54.2019.03.19.23.49.44 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Tue, 19 Mar 2019 23:49:45 -0700 (PDT) From: Xin Long To: network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, Marcelo Ricardo Leitner , Neil Horman , syzkaller@googlegroups.com Subject: [PATCH net] sctp: use memdup_user instead of vmemdup_user Date: Wed, 20 Mar 2019 14:49:38 +0800 Message-Id: <94e635135533b7469c84b0aa4df59ea7818a486a.1553064578.git.lucien.xin@gmail.com> X-Mailer: git-send-email 2.1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org In sctp_setsockopt_bindx()/__sctp_setsockopt_connectx(), it allocates memory with addrs_size which is passed from userspace. We used flag GFP_USER to put some more restrictions on it in Commit cacc06215271 ("sctp: use GFP_USER for user-controlled kmalloc"). However, since Commit c981f254cc82 ("sctp: use vmemdup_user() rather than badly open-coding memdup_user()"), vmemdup_user() has been used, which doesn't check GFP_USER flag when goes to vmalloc_*(). So when addrs_size is a huge value, it could exhaust memory and even trigger oom killer. This patch is to use memdup_user() instead, in which GFP_USER would work to limit the memory allocation with a huge addrs_size. Note we can't fix it by limiting 'addrs_size', as there's no demand for it from RFC. Reported-by: syzbot+ec1b7575afef85a0e5ca@syzkaller.appspotmail.com Fixes: c981f254cc82 ("sctp: use vmemdup_user() rather than badly open-coding memdup_user()") Signed-off-by: Xin Long --- net/sctp/socket.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6140471..09ad5b2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -999,7 +999,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, if (unlikely(addrs_size <= 0)) return -EINVAL; - kaddrs = vmemdup_user(addrs, addrs_size); + kaddrs = memdup_user(addrs, addrs_size); if (unlikely(IS_ERR(kaddrs))) return PTR_ERR(kaddrs); @@ -1007,7 +1007,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, addr_buf = kaddrs; while (walk_size < addrs_size) { if (walk_size + sizeof(sa_family_t) > addrs_size) { - kvfree(kaddrs); + kfree(kaddrs); return -EINVAL; } @@ -1018,7 +1018,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, * causes the address buffer to overflow return EINVAL. */ if (!af || (walk_size + af->sockaddr_len) > addrs_size) { - kvfree(kaddrs); + kfree(kaddrs); return -EINVAL; } addrcnt++; @@ -1054,7 +1054,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, } out: - kvfree(kaddrs); + kfree(kaddrs); return err; } @@ -1329,7 +1329,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk, if (unlikely(addrs_size <= 0)) return -EINVAL; - kaddrs = vmemdup_user(addrs, addrs_size); + kaddrs = memdup_user(addrs, addrs_size); if (unlikely(IS_ERR(kaddrs))) return PTR_ERR(kaddrs); @@ -1349,7 +1349,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk, err = __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id); out_free: - kvfree(kaddrs); + kfree(kaddrs); return err; } -- 2.1.0 From mboxrd@z Thu Jan 1 00:00:00 1970 From: Xin Long Date: Wed, 20 Mar 2019 06:49:38 +0000 Subject: [PATCH net] sctp: use memdup_user instead of vmemdup_user Message-Id: <94e635135533b7469c84b0aa4df59ea7818a486a.1553064578.git.lucien.xin@gmail.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: network dev , linux-sctp@vger.kernel.org Cc: davem@davemloft.net, Marcelo Ricardo Leitner , Neil Horman , syzkaller@googlegroups.com In sctp_setsockopt_bindx()/__sctp_setsockopt_connectx(), it allocates memory with addrs_size which is passed from userspace. We used flag GFP_USER to put some more restrictions on it in Commit cacc06215271 ("sctp: use GFP_USER for user-controlled kmalloc"). However, since Commit c981f254cc82 ("sctp: use vmemdup_user() rather than badly open-coding memdup_user()"), vmemdup_user() has been used, which doesn't check GFP_USER flag when goes to vmalloc_*(). So when addrs_size is a huge value, it could exhaust memory and even trigger oom killer. This patch is to use memdup_user() instead, in which GFP_USER would work to limit the memory allocation with a huge addrs_size. Note we can't fix it by limiting 'addrs_size', as there's no demand for it from RFC. Reported-by: syzbot+ec1b7575afef85a0e5ca@syzkaller.appspotmail.com Fixes: c981f254cc82 ("sctp: use vmemdup_user() rather than badly open-coding memdup_user()") Signed-off-by: Xin Long --- net/sctp/socket.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/net/sctp/socket.c b/net/sctp/socket.c index 6140471..09ad5b2 100644 --- a/net/sctp/socket.c +++ b/net/sctp/socket.c @@ -999,7 +999,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, if (unlikely(addrs_size <= 0)) return -EINVAL; - kaddrs = vmemdup_user(addrs, addrs_size); + kaddrs = memdup_user(addrs, addrs_size); if (unlikely(IS_ERR(kaddrs))) return PTR_ERR(kaddrs); @@ -1007,7 +1007,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, addr_buf = kaddrs; while (walk_size < addrs_size) { if (walk_size + sizeof(sa_family_t) > addrs_size) { - kvfree(kaddrs); + kfree(kaddrs); return -EINVAL; } @@ -1018,7 +1018,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, * causes the address buffer to overflow return EINVAL. */ if (!af || (walk_size + af->sockaddr_len) > addrs_size) { - kvfree(kaddrs); + kfree(kaddrs); return -EINVAL; } addrcnt++; @@ -1054,7 +1054,7 @@ static int sctp_setsockopt_bindx(struct sock *sk, } out: - kvfree(kaddrs); + kfree(kaddrs); return err; } @@ -1329,7 +1329,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk, if (unlikely(addrs_size <= 0)) return -EINVAL; - kaddrs = vmemdup_user(addrs, addrs_size); + kaddrs = memdup_user(addrs, addrs_size); if (unlikely(IS_ERR(kaddrs))) return PTR_ERR(kaddrs); @@ -1349,7 +1349,7 @@ static int __sctp_setsockopt_connectx(struct sock *sk, err = __sctp_connect(sk, kaddrs, addrs_size, flags, assoc_id); out_free: - kvfree(kaddrs); + kfree(kaddrs); return err; } -- 2.1.0