From patchwork Wed Sep 13 21:44:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yuxuan Luo X-Patchwork-Id: 1833727 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ubuntu.com (client-ip=185.125.189.65; helo=lists.ubuntu.com; envelope-from=kernel-team-bounces@lists.ubuntu.com; receiver=patchwork.ozlabs.org) Received: from lists.ubuntu.com (lists.ubuntu.com [185.125.189.65]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4RmDW30vmvz1yhn for ; Thu, 14 Sep 2023 07:44:30 +1000 (AEST) Received: from localhost ([127.0.0.1] helo=lists.ubuntu.com) by lists.ubuntu.com with esmtp (Exim 4.86_2) (envelope-from ) id 1qgXeg-0003MD-8y; Wed, 13 Sep 2023 21:44:14 +0000 Received: from smtp-relay-internal-0.internal ([10.131.114.225] helo=smtp-relay-internal-0.canonical.com) by lists.ubuntu.com with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.86_2) (envelope-from ) id 1qgXeX-0003LD-Q0 for kernel-team@lists.ubuntu.com; Wed, 13 Sep 2023 21:44:05 +0000 Received: from mail-qv1-f71.google.com (mail-qv1-f71.google.com [209.85.219.71]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by smtp-relay-internal-0.canonical.com (Postfix) with ESMTPS id 7DF4C3F673 for ; Wed, 13 Sep 2023 21:44:05 +0000 (UTC) Received: by mail-qv1-f71.google.com with SMTP id 6a1803df08f44-64f3be16f48so3409726d6.3 for ; Wed, 13 Sep 2023 14:44:05 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1694641444; x=1695246244; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/4z2D4Ojwf0JiDHI1kxSzZThVxVR+bYzKPPiTQmEzsI=; b=ftSwF8pTGnzUpi6ocgwDEG7q4jYuhq8Q5vEwhdSNJjFAo17BMSgTLucj1q6tTaw2/B KmhU0XZmiO8GZihE53ySAOiWn6eygNYy9K87s+ayaXtXZqiHNotTN7w4+pln/RdEFlsS dOdFLsd/SH9DIoGMOx0U2nA2jzXMvTf4rRJZU3A1Gy93CUlxyLi8YdkKXk9KkEZABB7X fPvCpEBTWv7+D+7hOiVZQlbdjB37pZKvQr3hjEtwNtJO8JY8h1F0QMsj6eHsKjcM9+59 TCm50SKPbfT8MGAP2ZNDIl34oeshVn9K1QUOJ2L41wf5Z9qg2Qs3ViXkzPc0nhsEzn/4 TRsA== X-Gm-Message-State: AOJu0Yymn9IXTJic1IHdOpeaKGouhBOrnUHqoVN7CeUZgFlk7US6UHRS uAOnZQjqzG8tP9Gp++HAUQfEWDwcHWr+krhsgDisKaejLV8PZ4rBjzTtept0iLNUVKcZAmkSo3F ZF/5s4pzcHfekFVCD781kv69NZ7mKmCzPGG33qYxX8dJbfeTTPA== X-Received: by 2002:a0c:cd0e:0:b0:63d:651e:4133 with SMTP id b14-20020a0ccd0e000000b0063d651e4133mr3362049qvm.37.1694641443936; Wed, 13 Sep 2023 14:44:03 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHMoPSFNOWZazWwEvLAXoLCleOnAxT1UBJpCB2NC8QU0aZMe72VSBaDs5EWaQyZVXbK/EY9pw== X-Received: by 2002:a0c:cd0e:0:b0:63d:651e:4133 with SMTP id b14-20020a0ccd0e000000b0063d651e4133mr3362039qvm.37.1694641443622; Wed, 13 Sep 2023 14:44:03 -0700 (PDT) Received: from cache-ubuntu.hsd1.nj.comcast.net ([2601:86:200:98b0:648e:df48:8a4a:64d1]) by smtp.gmail.com with ESMTPSA id b10-20020a0cc98a000000b006560eea8a7esm42075qvk.132.2023.09.13.14.44.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 Sep 2023 14:44:03 -0700 (PDT) From: Yuxuan Luo To: kernel-team@lists.ubuntu.com Subject: [SRU][F/J/L][PATCH 1/1] af_unix: Fix null-ptr-deref in unix_stream_sendpage(). Date: Wed, 13 Sep 2023 17:44:00 -0400 Message-Id: <20230913214400.66802-2-yuxuan.luo@canonical.com> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20230913214400.66802-1-yuxuan.luo@canonical.com> References: <20230913214400.66802-1-yuxuan.luo@canonical.com> MIME-Version: 1.0 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: , Errors-To: kernel-team-bounces@lists.ubuntu.com Sender: "kernel-team" From: Kuniyuki Iwashima Bing-Jhong Billy Jheng reported null-ptr-deref in unix_stream_sendpage() with detailed analysis and a nice repro. unix_stream_sendpage() tries to add data to the last skb in the peer's recv queue without locking the queue. If the peer's FD is passed to another socket and the socket's FD is passed to the peer, there is a loop between them. If we close both sockets without receiving FD, the sockets will be cleaned up by garbage collection. The garbage collection iterates such sockets and unlinks skb with FD from the socket's receive queue under the queue's lock. So, there is a race where unix_stream_sendpage() could access an skb locklessly that is being released by garbage collection, resulting in use-after-free. To avoid the issue, unix_stream_sendpage() must lock the peer's recv queue. Note the issue does not exist in 6.5+ thanks to the recent sendpage() refactoring. This patch is originally written by Linus Torvalds. BUG: unable to handle page fault for address: ffff988004dd6870 PF: supervisor read access in kernel mode PF: error_code(0x0000) - not-present page PGD 0 P4D 0 PREEMPT SMP PTI CPU: 4 PID: 297 Comm: garbage_uaf Not tainted 6.1.46 #1 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 RIP: 0010:kmem_cache_alloc_node+0xa2/0x1e0 Code: c0 0f 84 32 01 00 00 41 83 fd ff 74 10 48 8b 00 48 c1 e8 3a 41 39 c5 0f 85 1c 01 00 00 41 8b 44 24 28 49 8b 3c 24 48 8d 4a 40 <49> 8b 1c 06 4c 89 f0 65 48 0f c7 0f 0f 94 c0 84 c0 74 a1 41 8b 44 RSP: 0018:ffffc9000079fac0 EFLAGS: 00000246 RAX: 0000000000000070 RBX: 0000000000000005 RCX: 000000000001a284 RDX: 000000000001a244 RSI: 0000000000400cc0 RDI: 000000000002eee0 RBP: 0000000000400cc0 R08: 0000000000400cc0 R09: 0000000000000003 R10: 0000000000000001 R11: 0000000000000000 R12: ffff888003970f00 R13: 00000000ffffffff R14: ffff988004dd6800 R15: 00000000000000e8 FS: 00007f174d6f3600(0000) GS:ffff88807db00000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: ffff988004dd6870 CR3: 00000000092be000 CR4: 00000000007506e0 PKRU: 55555554 Call Trace: ? __die_body.cold+0x1a/0x1f ? page_fault_oops+0xa9/0x1e0 ? fixup_exception+0x1d/0x310 ? exc_page_fault+0xa8/0x150 ? asm_exc_page_fault+0x22/0x30 ? kmem_cache_alloc_node+0xa2/0x1e0 ? __alloc_skb+0x16c/0x1e0 __alloc_skb+0x16c/0x1e0 alloc_skb_with_frags+0x48/0x1e0 sock_alloc_send_pskb+0x234/0x270 unix_stream_sendmsg+0x1f5/0x690 sock_sendmsg+0x5d/0x60 ____sys_sendmsg+0x210/0x260 ___sys_sendmsg+0x83/0xd0 ? kmem_cache_alloc+0xc6/0x1c0 ? avc_disable+0x20/0x20 ? percpu_counter_add_batch+0x53/0xc0 ? alloc_empty_file+0x5d/0xb0 ? alloc_file+0x91/0x170 ? alloc_file_pseudo+0x94/0x100 ? __fget_light+0x9f/0x120 __sys_sendmsg+0x54/0xa0 do_syscall_64+0x3b/0x90 entry_SYSCALL_64_after_hwframe+0x69/0xd3 RIP: 0033:0x7f174d639a7d Code: 28 89 54 24 1c 48 89 74 24 10 89 7c 24 08 e8 8a c1 f4 ff 8b 54 24 1c 48 8b 74 24 10 41 89 c0 8b 7c 24 08 b8 2e 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 33 44 89 c7 48 89 44 24 08 e8 de c1 f4 ff 48 RSP: 002b:00007ffcb563ea50 EFLAGS: 00000293 ORIG_RAX: 000000000000002e RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 00007f174d639a7d RDX: 0000000000000000 RSI: 00007ffcb563eab0 RDI: 0000000000000007 RBP: 00007ffcb563eb10 R08: 0000000000000000 R09: 00000000ffffffff R10: 00000000004040a0 R11: 0000000000000293 R12: 00007ffcb563ec28 R13: 0000000000401398 R14: 0000000000403e00 R15: 00007f174d72c000 Fixes: 869e7c62486e ("net: af_unix: implement stream sendpage support") Reported-by: Bing-Jhong Billy Jheng Reviewed-by: Bing-Jhong Billy Jheng Co-developed-by: Linus Torvalds Signed-off-by: Linus Torvalds Signed-off-by: Kuniyuki Iwashima Signed-off-by: Greg Kroah-Hartman (cherry picked from commit 790c2f9d15b594350ae9bca7b236f2b1859de02c stable/linux-6.1.y) CVE-2023-4622 Signed-off-by: Yuxuan Luo --- net/unix/af_unix.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index 5b19b6c53a2cb..94d079d1c0b63 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -2290,6 +2290,7 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, if (false) { alloc_skb: + spin_unlock(&other->sk_receive_queue.lock); unix_state_unlock(other); mutex_unlock(&unix_sk(other)->iolock); newskb = sock_alloc_send_pskb(sk, 0, 0, flags & MSG_DONTWAIT, @@ -2329,6 +2330,7 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, init_scm = false; } + spin_lock(&other->sk_receive_queue.lock); skb = skb_peek_tail(&other->sk_receive_queue); if (tail && tail == skb) { skb = newskb; @@ -2359,14 +2361,11 @@ static ssize_t unix_stream_sendpage(struct socket *socket, struct page *page, refcount_add(size, &sk->sk_wmem_alloc); if (newskb) { - err = unix_scm_to_skb(&scm, skb, false); - if (err) - goto err_state_unlock; - spin_lock(&other->sk_receive_queue.lock); + unix_scm_to_skb(&scm, skb, false); __skb_queue_tail(&other->sk_receive_queue, newskb); - spin_unlock(&other->sk_receive_queue.lock); } + spin_unlock(&other->sk_receive_queue.lock); unix_state_unlock(other); mutex_unlock(&unix_sk(other)->iolock);