From 79a53c77f9ab624a2bf67f6bf760e6435b3ea979 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Tue, 11 Jul 2023 22:39:39 +0200 Subject: [PATCH] 5.10-stable patches added patches: block-change-all-__u32-annotations-to-__be32-in-affs_hardblocks.h.patch block-fix-signed-int-overflow-in-amiga-partition-support.patch sunrpc-fix-uaf-in-svc_tcp_listen_data_ready.patch --- ...tions-to-__be32-in-affs_hardblocks.h.patch | 142 ++++++++++++++++++ ...-overflow-in-amiga-partition-support.patch | 68 +++++++++ queue-5.10/series | 3 + ...fix-uaf-in-svc_tcp_listen_data_ready.patch | 138 +++++++++++++++++ 4 files changed, 351 insertions(+) create mode 100644 queue-5.10/block-change-all-__u32-annotations-to-__be32-in-affs_hardblocks.h.patch create mode 100644 queue-5.10/block-fix-signed-int-overflow-in-amiga-partition-support.patch create mode 100644 queue-5.10/sunrpc-fix-uaf-in-svc_tcp_listen_data_ready.patch diff --git a/queue-5.10/block-change-all-__u32-annotations-to-__be32-in-affs_hardblocks.h.patch b/queue-5.10/block-change-all-__u32-annotations-to-__be32-in-affs_hardblocks.h.patch new file mode 100644 index 00000000000..ca54e71c9d2 --- /dev/null +++ b/queue-5.10/block-change-all-__u32-annotations-to-__be32-in-affs_hardblocks.h.patch @@ -0,0 +1,142 @@ +From 95a55437dc49fb3342c82e61f5472a71c63d9ed0 Mon Sep 17 00:00:00 2001 +From: Michael Schmitz +Date: Wed, 21 Jun 2023 08:17:24 +1200 +Subject: block: change all __u32 annotations to __be32 in affs_hardblocks.h + +From: Michael Schmitz + +commit 95a55437dc49fb3342c82e61f5472a71c63d9ed0 upstream. + +The Amiga partition parser module uses signed int for partition sector +address and count, which will overflow for disks larger than 1 TB. + +Use u64 as type for sector address and size to allow using disks up to +2 TB without LBD support, and disks larger than 2 TB with LBD. The RBD +format allows to specify disk sizes up to 2^128 bytes (though native +OS limitations reduce this somewhat, to max 2^68 bytes), so check for +u64 overflow carefully to protect against overflowing sector_t. + +This bug was reported originally in 2012, and the fix was created by +the RDB author, Joanne Dow . A patch had been +discussed and reviewed on linux-m68k at that time but never officially +submitted (now resubmitted as patch 1 of this series). + +Patch 3 (this series) adds additional error checking and warning +messages. One of the error checks now makes use of the previously +unused rdb_CylBlocks field, which causes a 'sparse' warning +(cast to restricted __be32). + +Annotate all 32 bit fields in affs_hardblocks.h as __be32, as the +on-disk format of RDB and partition blocks is always big endian. + +Reported-by: Martin Steigerwald +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Message-ID: <201206192146.09327.Martin@lichtvoll.de> +Cc: # 5.2 +Signed-off-by: Michael Schmitz +Reviewed-by: Christoph Hellwig +Reviewed-by: Geert Uytterhoeven +Link: https://lore.kernel.org/r/20230620201725.7020-3-schmitzmic@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + include/uapi/linux/affs_hardblocks.h | 68 +++++++++++++++++------------------ + 1 file changed, 34 insertions(+), 34 deletions(-) + +--- a/include/uapi/linux/affs_hardblocks.h ++++ b/include/uapi/linux/affs_hardblocks.h +@@ -7,42 +7,42 @@ + /* Just the needed definitions for the RDB of an Amiga HD. */ + + struct RigidDiskBlock { +- __u32 rdb_ID; ++ __be32 rdb_ID; + __be32 rdb_SummedLongs; +- __s32 rdb_ChkSum; +- __u32 rdb_HostID; ++ __be32 rdb_ChkSum; ++ __be32 rdb_HostID; + __be32 rdb_BlockBytes; +- __u32 rdb_Flags; +- __u32 rdb_BadBlockList; ++ __be32 rdb_Flags; ++ __be32 rdb_BadBlockList; + __be32 rdb_PartitionList; +- __u32 rdb_FileSysHeaderList; +- __u32 rdb_DriveInit; +- __u32 rdb_Reserved1[6]; +- __u32 rdb_Cylinders; +- __u32 rdb_Sectors; +- __u32 rdb_Heads; +- __u32 rdb_Interleave; +- __u32 rdb_Park; +- __u32 rdb_Reserved2[3]; +- __u32 rdb_WritePreComp; +- __u32 rdb_ReducedWrite; +- __u32 rdb_StepRate; +- __u32 rdb_Reserved3[5]; +- __u32 rdb_RDBBlocksLo; +- __u32 rdb_RDBBlocksHi; +- __u32 rdb_LoCylinder; +- __u32 rdb_HiCylinder; +- __u32 rdb_CylBlocks; +- __u32 rdb_AutoParkSeconds; +- __u32 rdb_HighRDSKBlock; +- __u32 rdb_Reserved4; ++ __be32 rdb_FileSysHeaderList; ++ __be32 rdb_DriveInit; ++ __be32 rdb_Reserved1[6]; ++ __be32 rdb_Cylinders; ++ __be32 rdb_Sectors; ++ __be32 rdb_Heads; ++ __be32 rdb_Interleave; ++ __be32 rdb_Park; ++ __be32 rdb_Reserved2[3]; ++ __be32 rdb_WritePreComp; ++ __be32 rdb_ReducedWrite; ++ __be32 rdb_StepRate; ++ __be32 rdb_Reserved3[5]; ++ __be32 rdb_RDBBlocksLo; ++ __be32 rdb_RDBBlocksHi; ++ __be32 rdb_LoCylinder; ++ __be32 rdb_HiCylinder; ++ __be32 rdb_CylBlocks; ++ __be32 rdb_AutoParkSeconds; ++ __be32 rdb_HighRDSKBlock; ++ __be32 rdb_Reserved4; + char rdb_DiskVendor[8]; + char rdb_DiskProduct[16]; + char rdb_DiskRevision[4]; + char rdb_ControllerVendor[8]; + char rdb_ControllerProduct[16]; + char rdb_ControllerRevision[4]; +- __u32 rdb_Reserved5[10]; ++ __be32 rdb_Reserved5[10]; + }; + + #define IDNAME_RIGIDDISK 0x5244534B /* "RDSK" */ +@@ -50,16 +50,16 @@ struct RigidDiskBlock { + struct PartitionBlock { + __be32 pb_ID; + __be32 pb_SummedLongs; +- __s32 pb_ChkSum; +- __u32 pb_HostID; ++ __be32 pb_ChkSum; ++ __be32 pb_HostID; + __be32 pb_Next; +- __u32 pb_Flags; +- __u32 pb_Reserved1[2]; +- __u32 pb_DevFlags; ++ __be32 pb_Flags; ++ __be32 pb_Reserved1[2]; ++ __be32 pb_DevFlags; + __u8 pb_DriveName[32]; +- __u32 pb_Reserved2[15]; ++ __be32 pb_Reserved2[15]; + __be32 pb_Environment[17]; +- __u32 pb_EReserved[15]; ++ __be32 pb_EReserved[15]; + }; + + #define IDNAME_PARTITION 0x50415254 /* "PART" */ diff --git a/queue-5.10/block-fix-signed-int-overflow-in-amiga-partition-support.patch b/queue-5.10/block-fix-signed-int-overflow-in-amiga-partition-support.patch new file mode 100644 index 00000000000..a0de27ed372 --- /dev/null +++ b/queue-5.10/block-fix-signed-int-overflow-in-amiga-partition-support.patch @@ -0,0 +1,68 @@ +From fc3d092c6bb48d5865fec15ed5b333c12f36288c Mon Sep 17 00:00:00 2001 +From: Michael Schmitz +Date: Wed, 21 Jun 2023 08:17:23 +1200 +Subject: block: fix signed int overflow in Amiga partition support + +From: Michael Schmitz + +commit fc3d092c6bb48d5865fec15ed5b333c12f36288c upstream. + +The Amiga partition parser module uses signed int for partition sector +address and count, which will overflow for disks larger than 1 TB. + +Use sector_t as type for sector address and size to allow using disks +up to 2 TB without LBD support, and disks larger than 2 TB with LBD. + +This bug was reported originally in 2012, and the fix was created by +the RDB author, Joanne Dow . A patch had been +discussed and reviewed on linux-m68k at that time but never officially +submitted. This patch differs from Joanne's patch only in its use of +sector_t instead of unsigned int. No checking for overflows is done +(see patch 3 of this series for that). + +Reported-by: Martin Steigerwald +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=43511 +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Message-ID: <201206192146.09327.Martin@lichtvoll.de> +Cc: # 5.2 +Signed-off-by: Michael Schmitz +Tested-by: Martin Steigerwald +Reviewed-by: Geert Uytterhoeven +Reviewed-by: Christoph Hellwig +Link: https://lore.kernel.org/r/20230620201725.7020-2-schmitzmic@gmail.com +Signed-off-by: Jens Axboe +Signed-off-by: Greg Kroah-Hartman +--- + block/partitions/amiga.c | 9 +++++---- + 1 file changed, 5 insertions(+), 4 deletions(-) + +--- a/block/partitions/amiga.c ++++ b/block/partitions/amiga.c +@@ -31,7 +31,8 @@ int amiga_partition(struct parsed_partit + unsigned char *data; + struct RigidDiskBlock *rdb; + struct PartitionBlock *pb; +- int start_sect, nr_sects, blk, part, res = 0; ++ sector_t start_sect, nr_sects; ++ int blk, part, res = 0; + int blksize = 1; /* Multiplier for disk block size */ + int slot = 1; + char b[BDEVNAME_SIZE]; +@@ -97,14 +98,14 @@ int amiga_partition(struct parsed_partit + + /* Tell Kernel about it */ + +- nr_sects = (be32_to_cpu(pb->pb_Environment[10]) + 1 - +- be32_to_cpu(pb->pb_Environment[9])) * ++ nr_sects = ((sector_t)be32_to_cpu(pb->pb_Environment[10]) + 1 - ++ be32_to_cpu(pb->pb_Environment[9])) * + be32_to_cpu(pb->pb_Environment[3]) * + be32_to_cpu(pb->pb_Environment[5]) * + blksize; + if (!nr_sects) + continue; +- start_sect = be32_to_cpu(pb->pb_Environment[9]) * ++ start_sect = (sector_t)be32_to_cpu(pb->pb_Environment[9]) * + be32_to_cpu(pb->pb_Environment[3]) * + be32_to_cpu(pb->pb_Environment[5]) * + blksize; diff --git a/queue-5.10/series b/queue-5.10/series index cef83081403..42e9094a6fd 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -215,3 +215,6 @@ io_uring-ensure-iopoll-locks-around-deferred-work.patch usb-serial-option-add-lara-r6-01b-pids.patch usb-dwc3-gadget-propagate-core-init-errors-to-udc-during-pullup.patch phy-tegra-xusb-clear-the-driver-reference-in-usb-phy-dev.patch +block-fix-signed-int-overflow-in-amiga-partition-support.patch +block-change-all-__u32-annotations-to-__be32-in-affs_hardblocks.h.patch +sunrpc-fix-uaf-in-svc_tcp_listen_data_ready.patch diff --git a/queue-5.10/sunrpc-fix-uaf-in-svc_tcp_listen_data_ready.patch b/queue-5.10/sunrpc-fix-uaf-in-svc_tcp_listen_data_ready.patch new file mode 100644 index 00000000000..bc896864a21 --- /dev/null +++ b/queue-5.10/sunrpc-fix-uaf-in-svc_tcp_listen_data_ready.patch @@ -0,0 +1,138 @@ +From fc80fc2d4e39137869da3150ee169b40bf879287 Mon Sep 17 00:00:00 2001 +From: Ding Hui +Date: Mon, 15 May 2023 10:13:07 +0800 +Subject: SUNRPC: Fix UAF in svc_tcp_listen_data_ready() + +From: Ding Hui + +commit fc80fc2d4e39137869da3150ee169b40bf879287 upstream. + +After the listener svc_sock is freed, and before invoking svc_tcp_accept() +for the established child sock, there is a window that the newsock +retaining a freed listener svc_sock in sk_user_data which cloning from +parent. In the race window, if data is received on the newsock, we will +observe use-after-free report in svc_tcp_listen_data_ready(). + +Reproduce by two tasks: + +1. while :; do rpc.nfsd 0 ; rpc.nfsd; done +2. while :; do echo "" | ncat -4 127.0.0.1 2049 ; done + +KASAN report: + + ================================================================== + BUG: KASAN: slab-use-after-free in svc_tcp_listen_data_ready+0x1cf/0x1f0 [sunrpc] + Read of size 8 at addr ffff888139d96228 by task nc/102553 + CPU: 7 PID: 102553 Comm: nc Not tainted 6.3.0+ #18 + Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 11/12/2020 + Call Trace: + + dump_stack_lvl+0x33/0x50 + print_address_description.constprop.0+0x27/0x310 + print_report+0x3e/0x70 + kasan_report+0xae/0xe0 + svc_tcp_listen_data_ready+0x1cf/0x1f0 [sunrpc] + tcp_data_queue+0x9f4/0x20e0 + tcp_rcv_established+0x666/0x1f60 + tcp_v4_do_rcv+0x51c/0x850 + tcp_v4_rcv+0x23fc/0x2e80 + ip_protocol_deliver_rcu+0x62/0x300 + ip_local_deliver_finish+0x267/0x350 + ip_local_deliver+0x18b/0x2d0 + ip_rcv+0x2fb/0x370 + __netif_receive_skb_one_core+0x166/0x1b0 + process_backlog+0x24c/0x5e0 + __napi_poll+0xa2/0x500 + net_rx_action+0x854/0xc90 + __do_softirq+0x1bb/0x5de + do_softirq+0xcb/0x100 + + + ... + + + Allocated by task 102371: + kasan_save_stack+0x1e/0x40 + kasan_set_track+0x21/0x30 + __kasan_kmalloc+0x7b/0x90 + svc_setup_socket+0x52/0x4f0 [sunrpc] + svc_addsock+0x20d/0x400 [sunrpc] + __write_ports_addfd+0x209/0x390 [nfsd] + write_ports+0x239/0x2c0 [nfsd] + nfsctl_transaction_write+0xac/0x110 [nfsd] + vfs_write+0x1c3/0xae0 + ksys_write+0xed/0x1c0 + do_syscall_64+0x38/0x90 + entry_SYSCALL_64_after_hwframe+0x72/0xdc + + Freed by task 102551: + kasan_save_stack+0x1e/0x40 + kasan_set_track+0x21/0x30 + kasan_save_free_info+0x2a/0x50 + __kasan_slab_free+0x106/0x190 + __kmem_cache_free+0x133/0x270 + svc_xprt_free+0x1e2/0x350 [sunrpc] + svc_xprt_destroy_all+0x25a/0x440 [sunrpc] + nfsd_put+0x125/0x240 [nfsd] + nfsd_svc+0x2cb/0x3c0 [nfsd] + write_threads+0x1ac/0x2a0 [nfsd] + nfsctl_transaction_write+0xac/0x110 [nfsd] + vfs_write+0x1c3/0xae0 + ksys_write+0xed/0x1c0 + do_syscall_64+0x38/0x90 + entry_SYSCALL_64_after_hwframe+0x72/0xdc + +Fix the UAF by simply doing nothing in svc_tcp_listen_data_ready() +if state != TCP_LISTEN, that will avoid dereferencing svsk for all +child socket. + +Link: https://lore.kernel.org/lkml/20230507091131.23540-1-dinghui@sangfor.com.cn/ +Fixes: fa9251afc33c ("SUNRPC: Call the default socket callbacks instead of open coding") +Signed-off-by: Ding Hui +Cc: +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/svcsock.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -692,12 +692,6 @@ static void svc_tcp_listen_data_ready(st + { + struct svc_sock *svsk = (struct svc_sock *)sk->sk_user_data; + +- if (svsk) { +- /* Refer to svc_setup_socket() for details. */ +- rmb(); +- svsk->sk_odata(sk); +- } +- + /* + * This callback may called twice when a new connection + * is established as a child socket inherits everything +@@ -706,13 +700,18 @@ static void svc_tcp_listen_data_ready(st + * when one of child sockets become ESTABLISHED. + * 2) data_ready method of the child socket may be called + * when it receives data before the socket is accepted. +- * In case of 2, we should ignore it silently. ++ * In case of 2, we should ignore it silently and DO NOT ++ * dereference svsk. + */ +- if (sk->sk_state == TCP_LISTEN) { +- if (svsk) { +- set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); +- svc_xprt_enqueue(&svsk->sk_xprt); +- } ++ if (sk->sk_state != TCP_LISTEN) ++ return; ++ ++ if (svsk) { ++ /* Refer to svc_setup_socket() for details. */ ++ rmb(); ++ svsk->sk_odata(sk); ++ set_bit(XPT_CONN, &svsk->sk_xprt.xpt_flags); ++ svc_xprt_enqueue(&svsk->sk_xprt); + } + } + -- 2.47.3