From patchwork Wed May 29 00:22:57 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ioanna Alifieraki X-Patchwork-Id: 1106663 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from huckleberry.canonical.com (huckleberry.canonical.com [91.189.94.19]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 45DBJG18FQz9sBb; Wed, 29 May 2019 10:23:09 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=huckleberry.canonical.com) by huckleberry.canonical.com with esmtp (Exim 4.86_2) (envelope-from ) id 1hVmMw-000435-Gs; Wed, 29 May 2019 00:23:02 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.0:DHE_RSA_AES_128_CBC_SHA1:128) (Exim 4.86_2) (envelope-from ) id 1hVmMu-00042B-Vh for kernel-team@lists.ubuntu.com; Wed, 29 May 2019 00:23:00 +0000 Received: from mail-wm1-f71.google.com ([209.85.128.71]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1hVmMu-0006vl-KO for kernel-team@lists.ubuntu.com; Wed, 29 May 2019 00:23:00 +0000 Received: by mail-wm1-f71.google.com with SMTP id q5so253448wmc.8 for ; Tue, 28 May 2019 17:23:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references; bh=K6IpIVCjqM4U9ZawQnWUNL/e8Wszw5nEhPIKoDID9EY=; b=SgF/6haESu2rmZNWuHMO63O5QwVCDIpEHsH/u//CgrMgjrhecCdAKRqXDdiggbJRVu EuBC/18fsBGAvfc72djv0hTpwTQOAdRFX2k5Dq+maf99fjiXH/MUD1bOwbfZJqf1Dlnf +SW5lhVzoLAh3sujzdFLJo31dheaV5on3H6/fDHE1APoq2QIYsbshsxbs2/ss8OggOZt 6pEObj8Q2nB+O1VJKc/n+fCpXJyEkoWFzceatyALztZVFb/oLBubDiTl6SiI6SRWMh1W gD16FsdHQR8kISkAbadMsZBixmMhpJ1Bn/S9uomDoi0y2hHmRUr2Eth78e73XVzW9s0j 1Irg== X-Gm-Message-State: APjAAAXAGk4TJgEP3Eiv88c/u9Ef2UqotcOu0EIzCjpiJX7Y1u6ceYmi Wo85OJLg92hIgXmGEoPu5pAfJTnatJFXLn0qqEapnRTfNFf2mOh4VCGUWjScN286kqCZN0nRkf9 RmovMMpjU68/YgSWPV76Qki5cMcqTE00kacHYkPcprg== X-Received: by 2002:a1c:7a15:: with SMTP id v21mr4869377wmc.82.1559089380184; Tue, 28 May 2019 17:23:00 -0700 (PDT) X-Google-Smtp-Source: APXvYqy2ReI6Bo6vW/SYMXDdeK+mwtkzWzxIbZQn+FHwxiNbjl6oESRPjjcv60XLKpyXCrZRntQwSw== X-Received: by 2002:a1c:7a15:: with SMTP id v21mr4869370wmc.82.1559089380027; Tue, 28 May 2019 17:23:00 -0700 (PDT) Received: from localhost ([2a02:c7d:31d6:7200:8157:b437:1818:6632]) by smtp.gmail.com with ESMTPSA id w2sm9359131wru.16.2019.05.28.17.22.59 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Tue, 28 May 2019 17:22:59 -0700 (PDT) From: Ioanna Alifieraki To: kernel-team@lists.ubuntu.com Subject: [SRU][Bionic][Cosmic][PATCH 1/1] tcp: do not release socket ownership in tcp_close() Date: Wed, 29 May 2019 01:22:57 +0100 Message-Id: <20190529002257.4100-2-ioanna-maria.alifieraki@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190529002257.4100-1-ioanna-maria.alifieraki@canonical.com> References: <20190529002257.4100-1-ioanna-maria.alifieraki@canonical.com> X-BeenThere: kernel-team@lists.ubuntu.com X-Mailman-Version: 2.1.20 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" From: Eric Dumazet BugLink: https://bugs.launchpad.net/bugs/1830813 syzkaller was able to hit the WARN_ON(sock_owned_by_user(sk)); in tcp_close() While a socket is being closed, it is very possible other threads find it in rtnetlink dump. tcp_get_info() will acquire the socket lock for a short amount of time (slow = lock_sock_fast(sk)/unlock_sock_fast(sk, slow);), enough to trigger the warning. Fixes: 67db3e4bfbc9 ("tcp: no longer hold ehash lock while calling tcp_get_info()") Signed-off-by: Eric Dumazet Reported-by: syzbot Signed-off-by: David S. Miller (cherry picked from commit 8873c064d1de579ea23412a6d3eee972593f142b) Signed-off-by: Ioanna Alifieraki Acked-by: Connor Kuehl --- include/net/sock.h | 1 + net/core/sock.c | 2 +- net/ipv4/tcp.c | 11 +++-------- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/include/net/sock.h b/include/net/sock.h index 7a7b14e9628a..5fcdd5b7b47c 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -1461,6 +1461,7 @@ static inline void lock_sock(struct sock *sk) lock_sock_nested(sk, 0); } +void __release_sock(struct sock *sk); void release_sock(struct sock *sk); /* BH context may only use the following locking interface. */ diff --git a/net/core/sock.c b/net/core/sock.c index 1039cb1fdcff..050dba776f75 100644 --- a/net/core/sock.c +++ b/net/core/sock.c @@ -2242,7 +2242,7 @@ static void __lock_sock(struct sock *sk) finish_wait(&sk->sk_lock.wq, &wait); } -static void __release_sock(struct sock *sk) +void __release_sock(struct sock *sk) __releases(&sk->sk_lock.slock) __acquires(&sk->sk_lock.slock) { diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c index ba6255d934a4..8a9ea72c82fa 100644 --- a/net/ipv4/tcp.c +++ b/net/ipv4/tcp.c @@ -2242,16 +2242,10 @@ void tcp_close(struct sock *sk, long timeout) sock_hold(sk); sock_orphan(sk); - /* It is the last release_sock in its life. It will remove backlog. */ - release_sock(sk); - - - /* Now socket is owned by kernel and we acquire BH lock - * to finish close. No need to check for user refs. - */ local_bh_disable(); bh_lock_sock(sk); - WARN_ON(sock_owned_by_user(sk)); + /* remove backlog if any, without releasing ownership. */ + __release_sock(sk); percpu_counter_inc(sk->sk_prot->orphan_count); @@ -2320,6 +2314,7 @@ void tcp_close(struct sock *sk, long timeout) out: bh_unlock_sock(sk); local_bh_enable(); + release_sock(sk); sock_put(sk); } EXPORT_SYMBOL(tcp_close);