From patchwork Tue Apr 6 21:13:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Khalid Elmously X-Patchwork-Id: 1463022 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (no SPF record) smtp.mailfrom=lists.ubuntu.com (client-ip=91.189.94.19; helo=huckleberry.canonical.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=) 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 4FFKyh67ppz9sRR; Wed, 7 Apr 2021 07:14:03 +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 1lTt1L-0001gW-2w; Tue, 06 Apr 2021 21:13:59 +0000 Received: from youngberry.canonical.com ([91.189.89.112]) by huckleberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1lTt1I-0001gD-AM for kernel-team@lists.ubuntu.com; Tue, 06 Apr 2021 21:13:56 +0000 Received: from mail-qv1-f72.google.com ([209.85.219.72]) by youngberry.canonical.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1lTt1H-0008F1-V3 for kernel-team@lists.ubuntu.com; Tue, 06 Apr 2021 21:13:56 +0000 Received: by mail-qv1-f72.google.com with SMTP id i7so5433686qvj.1 for ; Tue, 06 Apr 2021 14:13:55 -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:cc:subject:date:message-id:in-reply-to :references; bh=OM+5iChGHTqjZJRoug3Ud3xW1xA0WHN6hp9rJlTfYMU=; b=bv2ee/PAmYs0OZJTRAPMxs+RmejTO36qTJJF+REQ9+/hXr4qPVXFotx3Q47nHcNiEu ZEcHrP2nVvqfIg+3nbA9K2E2DOYakLr75EOA5wqFYt2UqnH+1dzus0mHzXNacFfYuBMN FNLpwXI/vw4ZmS5Wq6Mf2bMhXSDxFCAKdhwfCALhdzn+p/+/eWzFQIHNZi/6djgBzZLA LqiRUEKpajv3zhxzO9zdI00koVhQf98EJTr4T3sQIi7LOeWzrkMl8gpRFrnaQuX8vunG lpEJ7OYfIk/7reLo3tHFv55dbLYe0H9MnDMhENxfPen++1VSn8Xs+i73yz48jHbK+Nsj IWdQ== X-Gm-Message-State: AOAM532uZKHSaOU5IhKBJ5h2k1f34lZpZ2RRG8GEOVUZC4q7CdU2ft6/ 6rzfdMO86ITjaVzioOFQ9ayqCsuuX6QozaISXiEgn0b/nsyPeJUYGIrspldZMRItd5wPQThStFG JigdcfUyr9wpVHSkeurSeC/u8+lc9UgwSW33V8be9jQ== X-Received: by 2002:a05:622a:3c8:: with SMTP id k8mr29475737qtx.101.1617743635054; Tue, 06 Apr 2021 14:13:55 -0700 (PDT) X-Google-Smtp-Source: ABdhPJxoAGfciR0p7OkowzYhjzZLUpjN9vYl4YX/EtPWTkzN9xElNuY+PtQGaI8hKyruWSEVNC46RQ== X-Received: by 2002:a05:622a:3c8:: with SMTP id k8mr29475717qtx.101.1617743634803; Tue, 06 Apr 2021 14:13:54 -0700 (PDT) Received: from kbuntu2.fuzzbuzz.org (dhcp-24-53-240-22.cable.user.start.ca. [24.53.240.22]) by smtp.gmail.com with ESMTPSA id o7sm17069715qkb.104.2021.04.06.14.13.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 06 Apr 2021 14:13:54 -0700 (PDT) From: Khalid Elmously To: kernel-team@lists.ubuntu.com Subject: [SRU][F/gke][F/gkeop][PATCH v3 1/1] scsi: iscsi: iscsi_tcp: Avoid holding spinlock while calling getpeername() Date: Tue, 6 Apr 2021 17:13:46 -0400 Message-Id: <20210406211346.17091-2-khalid.elmously@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20210406211346.17091-1-khalid.elmously@canonical.com> References: <20210406211346.17091-1-khalid.elmously@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: Mark Mielke BugLink: https://bugs.launchpad.net/bugs/1921825 The kernel may fail to boot or devices may fail to come up when initializing iscsi_tcp devices starting with Linux 5.8. Commit a79af8a64d39 ("[SCSI] iscsi_tcp: use iscsi_conn_get_addr_param libiscsi function") introduced getpeername() within the session spinlock. Commit 1b66d253610c ("bpf: Add get{peer, sock}name attach types for sock_addr") introduced BPF_CGROUP_RUN_SA_PROG_LOCK() within getpeername(), which acquires a mutex and when used from iscsi_tcp devices can now lead to "BUG: scheduling while atomic:" and subsequent damage. Ensure that the spinlock is released before calling getpeername() or getsockname(). sock_hold() and sock_put() are used to ensure that the socket reference is preserved until after the getpeername() or getsockname() complete. Link: https://bugzilla.redhat.com/show_bug.cgi?id=1877345 Link: https://lkml.org/lkml/2020/7/28/1085 Link: https://lkml.org/lkml/2020/8/31/459 Link: https://lore.kernel.org/r/20200928043329.606781-1-mark.mielke@gmail.com Fixes: a79af8a64d39 ("[SCSI] iscsi_tcp: use iscsi_conn_get_addr_param libiscsi function") Fixes: 1b66d253610c ("bpf: Add get{peer, sock}name attach types for sock_addr") Cc: stable@vger.kernel.org Reported-by: Marc Dionne Tested-by: Marc Dionne Reviewed-by: Mike Christie Signed-off-by: Mark Mielke Signed-off-by: Martin K. Petersen (cherry picked from commit bcf3a2953d36bbfb9bd44ccb3db0897d935cc485) Signed-off-by: Khalid Elmously --- drivers/scsi/iscsi_tcp.c | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/drivers/scsi/iscsi_tcp.c b/drivers/scsi/iscsi_tcp.c index b5dd1caae5e9..d10efb66cf19 100644 --- a/drivers/scsi/iscsi_tcp.c +++ b/drivers/scsi/iscsi_tcp.c @@ -736,6 +736,7 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, struct iscsi_tcp_conn *tcp_conn = conn->dd_data; struct iscsi_sw_tcp_conn *tcp_sw_conn = tcp_conn->dd_data; struct sockaddr_in6 addr; + struct socket *sock; int rc; switch(param) { @@ -747,13 +748,17 @@ static int iscsi_sw_tcp_conn_get_param(struct iscsi_cls_conn *cls_conn, spin_unlock_bh(&conn->session->frwd_lock); return -ENOTCONN; } + sock = tcp_sw_conn->sock; + sock_hold(sock->sk); + spin_unlock_bh(&conn->session->frwd_lock); + if (param == ISCSI_PARAM_LOCAL_PORT) - rc = kernel_getsockname(tcp_sw_conn->sock, + rc = kernel_getsockname(sock, (struct sockaddr *)&addr); else - rc = kernel_getpeername(tcp_sw_conn->sock, + rc = kernel_getpeername(sock, (struct sockaddr *)&addr); - spin_unlock_bh(&conn->session->frwd_lock); + sock_put(sock->sk); if (rc < 0) return rc; @@ -775,6 +780,7 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, struct iscsi_tcp_conn *tcp_conn; struct iscsi_sw_tcp_conn *tcp_sw_conn; struct sockaddr_in6 addr; + struct socket *sock; int rc; switch (param) { @@ -789,16 +795,18 @@ static int iscsi_sw_tcp_host_get_param(struct Scsi_Host *shost, return -ENOTCONN; } tcp_conn = conn->dd_data; - tcp_sw_conn = tcp_conn->dd_data; - if (!tcp_sw_conn->sock) { + sock = tcp_sw_conn->sock; + if (!sock) { spin_unlock_bh(&session->frwd_lock); return -ENOTCONN; } + sock_hold(sock->sk); + spin_unlock_bh(&session->frwd_lock); - rc = kernel_getsockname(tcp_sw_conn->sock, + rc = kernel_getsockname(sock, (struct sockaddr *)&addr); - spin_unlock_bh(&session->frwd_lock); + sock_put(sock->sk); if (rc < 0) return rc;