From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: stable@vger.kernel.org
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
patches@lists.linux.dev, Al Viro <viro@zeniv.linux.org.uk>
Subject: [PATCH 4.19 08/98] fix bitmap corruption on close_range() with CLOSE_RANGE_UNSHARE
Date: Sun, 1 Sep 2024 18:15:38 +0200 [thread overview]
Message-ID: <20240901160803.999210410@linuxfoundation.org> (raw)
In-Reply-To: <20240901160803.673617007@linuxfoundation.org>
4.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <viro@zeniv.linux.org.uk>
commit 9a2fa1472083580b6c66bdaf291f591e1170123a upstream.
copy_fd_bitmaps(new, old, count) is expected to copy the first
count/BITS_PER_LONG bits from old->full_fds_bits[] and fill
the rest with zeroes. What it does is copying enough words
(BITS_TO_LONGS(count/BITS_PER_LONG)), then memsets the rest.
That works fine, *if* all bits past the cutoff point are
clear. Otherwise we are risking garbage from the last word
we'd copied.
For most of the callers that is true - expand_fdtable() has
count equal to old->max_fds, so there's no open descriptors
past count, let alone fully occupied words in ->open_fds[],
which is what bits in ->full_fds_bits[] correspond to.
The other caller (dup_fd()) passes sane_fdtable_size(old_fdt, max_fds),
which is the smallest multiple of BITS_PER_LONG that covers all
opened descriptors below max_fds. In the common case (copying on
fork()) max_fds is ~0U, so all opened descriptors will be below
it and we are fine, by the same reasons why the call in expand_fdtable()
is safe.
Unfortunately, there is a case where max_fds is less than that
and where we might, indeed, end up with junk in ->full_fds_bits[] -
close_range(from, to, CLOSE_RANGE_UNSHARE) with
* descriptor table being currently shared
* 'to' being above the current capacity of descriptor table
* 'from' being just under some chunk of opened descriptors.
In that case we end up with observably wrong behaviour - e.g. spawn
a child with CLONE_FILES, get all descriptors in range 0..127 open,
then close_range(64, ~0U, CLOSE_RANGE_UNSHARE) and watch dup(0) ending
up with descriptor #128, despite #64 being observably not open.
The minimally invasive fix would be to deal with that in dup_fd().
If this proves to add measurable overhead, we can go that way, but
let's try to fix copy_fd_bitmaps() first.
* new helper: bitmap_copy_and_expand(to, from, bits_to_copy, size).
* make copy_fd_bitmaps() take the bitmap size in words, rather than
bits; it's 'count' argument is always a multiple of BITS_PER_LONG,
so we are not losing any information, and that way we can use the
same helper for all three bitmaps - compiler will see that count
is a multiple of BITS_PER_LONG for the large ones, so it'll generate
plain memcpy()+memset().
Reproducer added to tools/testing/selftests/core/close_range_test.c
Cc: stable@vger.kernel.org
Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/file.c | 28 ++++++++++++----------------
include/linux/bitmap.h | 12 ++++++++++++
2 files changed, 24 insertions(+), 16 deletions(-)
--- a/fs/file.c
+++ b/fs/file.c
@@ -41,27 +41,23 @@ static void free_fdtable_rcu(struct rcu_
#define BITBIT_NR(nr) BITS_TO_LONGS(BITS_TO_LONGS(nr))
#define BITBIT_SIZE(nr) (BITBIT_NR(nr) * sizeof(long))
+#define fdt_words(fdt) ((fdt)->max_fds / BITS_PER_LONG) // words in ->open_fds
/*
* Copy 'count' fd bits from the old table to the new table and clear the extra
* space if any. This does not copy the file pointers. Called with the files
* spinlock held for write.
*/
-static void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
- unsigned int count)
+static inline void copy_fd_bitmaps(struct fdtable *nfdt, struct fdtable *ofdt,
+ unsigned int copy_words)
{
- unsigned int cpy, set;
+ unsigned int nwords = fdt_words(nfdt);
- cpy = count / BITS_PER_BYTE;
- set = (nfdt->max_fds - count) / BITS_PER_BYTE;
- memcpy(nfdt->open_fds, ofdt->open_fds, cpy);
- memset((char *)nfdt->open_fds + cpy, 0, set);
- memcpy(nfdt->close_on_exec, ofdt->close_on_exec, cpy);
- memset((char *)nfdt->close_on_exec + cpy, 0, set);
-
- cpy = BITBIT_SIZE(count);
- set = BITBIT_SIZE(nfdt->max_fds) - cpy;
- memcpy(nfdt->full_fds_bits, ofdt->full_fds_bits, cpy);
- memset((char *)nfdt->full_fds_bits + cpy, 0, set);
+ bitmap_copy_and_extend(nfdt->open_fds, ofdt->open_fds,
+ copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG);
+ bitmap_copy_and_extend(nfdt->close_on_exec, ofdt->close_on_exec,
+ copy_words * BITS_PER_LONG, nwords * BITS_PER_LONG);
+ bitmap_copy_and_extend(nfdt->full_fds_bits, ofdt->full_fds_bits,
+ copy_words, nwords);
}
/*
@@ -79,7 +75,7 @@ static void copy_fdtable(struct fdtable
memcpy(nfdt->fd, ofdt->fd, cpy);
memset((char *)nfdt->fd + cpy, 0, set);
- copy_fd_bitmaps(nfdt, ofdt, ofdt->max_fds);
+ copy_fd_bitmaps(nfdt, ofdt, fdt_words(ofdt));
}
static struct fdtable * alloc_fdtable(unsigned int nr)
@@ -330,7 +326,7 @@ struct files_struct *dup_fd(struct files
open_files = count_open_files(old_fdt);
}
- copy_fd_bitmaps(new_fdt, old_fdt, open_files);
+ copy_fd_bitmaps(new_fdt, old_fdt, open_files / BITS_PER_LONG);
old_fds = old_fdt->fd;
new_fds = new_fdt->fd;
--- a/include/linux/bitmap.h
+++ b/include/linux/bitmap.h
@@ -256,6 +256,18 @@ static inline void bitmap_copy_clear_tai
dst[nbits / BITS_PER_LONG] &= BITMAP_LAST_WORD_MASK(nbits);
}
+static inline void bitmap_copy_and_extend(unsigned long *to,
+ const unsigned long *from,
+ unsigned int count, unsigned int size)
+{
+ unsigned int copy = BITS_TO_LONGS(count);
+
+ memcpy(to, from, copy * sizeof(long));
+ if (count % BITS_PER_LONG)
+ to[copy - 1] &= BITMAP_LAST_WORD_MASK(count);
+ memset(to + copy, 0, bitmap_size(size) - copy * sizeof(long));
+}
+
/*
* On 32-bit systems bitmaps are represented as u32 arrays internally, and
* therefore conversion is not needed when copying data from/to arrays of u32.
next prev parent reply other threads:[~2024-09-01 16:20 UTC|newest]
Thread overview: 108+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-01 16:15 [PATCH 4.19 00/98] 4.19.321-rc1 review Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 01/98] fuse: Initialize beyond-EOF page contents before setting uptodate Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 02/98] ALSA: usb-audio: Support Yamaha P-125 quirk entry Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 03/98] xhci: Fix Panther point NULL pointer deref at full-speed re-enumeration Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 04/98] arm64: ACPI: NUMA: initialize all values of acpi_early_node_map to NUMA_NO_NODE Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 05/98] dm resume: dont return EINVAL when signalled Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 06/98] dm persistent data: fix memory allocation failure Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 07/98] bitmap: introduce generic optimized bitmap_size() Greg Kroah-Hartman
2024-09-01 16:15 ` Greg Kroah-Hartman [this message]
2024-09-01 16:15 ` [PATCH 4.19 09/98] selinux: fix potential counting error in avc_add_xperms_decision() Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 10/98] drm/amdgpu: Actually check flags for all context ops Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 11/98] memcg_write_event_control(): fix a user-triggerable oops Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 12/98] s390/cio: rename bitmap_size() -> idset_bitmap_size() Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 13/98] btrfs: rename bitmap_set_bits() -> btrfs_bitmap_set_bits() Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 14/98] net/mlx5e: Correctly report errors for ethtool rx flows Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 15/98] atm: idt77252: prevent use after free in dequeue_rx() Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 16/98] net: dsa: vsc73xx: pass value in phy_write operation Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 17/98] ssb: Fix division by zero issue in ssb_calc_clock_rate Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 18/98] wifi: cw1200: Avoid processing an invalid TIM IE Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 19/98] i2c: riic: avoid potential division by zero Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 20/98] staging: ks7010: disable bh on tx_dev_lock Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 21/98] binfmt_misc: cleanup on filesystem umount Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 22/98] scsi: spi: Fix sshdr use Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 23/98] gfs2: setattr_chown: Add missing initialization Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 24/98] wifi: iwlwifi: abort scan when rfkill on but device enabled Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 25/98] powerpc/xics: Check return value of kasprintf in icp_native_map_one_cpu Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 26/98] ext4: do not trim the group with corrupted block bitmap Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 27/98] quota: Remove BUG_ON from dqget() Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 28/98] media: pci: cx23885: check cx23885_vdev_init() return Greg Kroah-Hartman
2024-09-01 16:15 ` [PATCH 4.19 29/98] fs: binfmt_elf_efpic: dont use missing interpreters properties Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 30/98] scsi: lpfc: Initialize status local variable in lpfc_sli4_repost_sgl_list() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 31/98] net/sun3_82586: Avoid reading past buffer in debug output Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 32/98] md: clean up invalid BUG_ON in md_ioctl Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 33/98] parisc: Use irq_enter_rcu() to fix warning at kernel/context_tracking.c:367 Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 34/98] powerpc/boot: Handle allocation failure in simple_realloc() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 35/98] powerpc/boot: Only free if realloc() succeeds Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 36/98] btrfs: change BUG_ON to assertion when checking for delayed_node root Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 37/98] btrfs: handle invalid root reference found in may_destroy_subvol() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 38/98] btrfs: send: handle unexpected data in header buffer in begin_cmd() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 39/98] btrfs: delete pointless BUG_ON check on quota root in btrfs_qgroup_account_extent() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 40/98] f2fs: fix to do sanity check in update_sit_entry Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 41/98] usb: gadget: fsl: Increase size of name buffer for endpoints Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 42/98] Bluetooth: bnep: Fix out-of-bound access Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 43/98] NFS: avoid infinite loop in pnfs_update_layout Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 44/98] openrisc: Call setup_memory() earlier in the init sequence Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 45/98] s390/iucv: fix receive buffer virtual vs physical address confusion Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 46/98] usb: dwc3: core: Skip setting event buffers for host only controllers Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 47/98] fbdev: offb: replace of_node_put with __free(device_node) Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 48/98] irqchip/gic-v3-its: Remove BUG_ON in its_vpe_irq_domain_alloc Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 49/98] ext4: set the type of max_zeroout to unsigned int to avoid overflow Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 50/98] nvmet-rdma: fix possible bad dereference when freeing rsps Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 51/98] hrtimer: Prevent queuing of hrtimer without a function callback Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 52/98] gtp: pull network headers in gtp_dev_xmit() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 53/98] block: use "unsigned long" for blk_validate_block_size() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 54/98] Bluetooth: Make use of __check_timeout on hci_sched_le Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 55/98] Bluetooth: hci_core: Fix not handling link timeouts propertly Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 56/98] Bluetooth: hci_core: Fix LE quote calculation Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 57/98] kcm: Serialise kcm_sendmsg() for the same socket Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 58/98] netfilter: nft_counter: Synchronize nft_counter_reset() against reader Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 59/98] ipv6: prevent UAF in ip6_send_skb() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 60/98] net: xilinx: axienet: Always disable promiscuous mode Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 61/98] drm/msm: use drm_debug_enabled() to check for debug categories Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 62/98] drm/msm/dpu: dont play tricks with debug macros Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 63/98] mmc: mmc_test: Fix NULL dereference on allocation failure Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 64/98] Bluetooth: MGMT: Add error handling to pair_device() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 65/98] HID: wacom: Defer calculation of resolution until resolution_code is known Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 66/98] cxgb4: add forgotten u64 ivlan cast before shift Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 67/98] mmc: dw_mmc: allow biu and ciu clocks to defer Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 68/98] ALSA: timer: Relax start tick time check for slave timer elements Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 69/98] Bluetooth: hci_ldisc: check HCI_UART_PROTO_READY flag in HCIUARTGETPROTO Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 70/98] Input: MT - limit max slots Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 71/98] tools: move alignment-related macros to new <linux/align.h> Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 72/98] drm/amdgpu: Using uninitialized value *size when calling amdgpu_vce_cs_reloc Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 73/98] pinctrl: single: fix potential NULL dereference in pcs_get_function() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 74/98] wifi: mwifiex: duplicate static structs used in driver instances Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 75/98] dm suspend: return -ERESTARTSYS instead of -EINTR Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 76/98] scsi: mpt3sas: Avoid IOMMU page faults on REPORT ZONES Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 77/98] filelock: Correct the filelock owner in fcntl_setlk/fcntl_setlk64 Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 78/98] media: uvcvideo: Fix integer overflow calculating timestamp Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 79/98] ata: libata-core: Fix null pointer dereference on error Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 80/98] cgroup/cpuset: Prevent UAF in proc_cpuset_show() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 81/98] memcg: enable accounting of ipc resources Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 82/98] fbcon: Prevent that screen size is smaller than font size Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 83/98] fbmem: Check virtual screen sizes in fb_set_var() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 84/98] net:rds: Fix possible deadlock in rds_message_put Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 85/98] ida: Fix crash in ida_free when the bitmap is empty Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 86/98] net: prevent mss overflow in skb_segment() Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 87/98] soundwire: stream: fix programming slave ports for non-continous port maps Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 88/98] gtp: fix a potential NULL pointer dereference Greg Kroah-Hartman
2024-09-01 16:16 ` [PATCH 4.19 89/98] net: busy-poll: use ktime_get_ns() instead of local_clock() Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 90/98] cdc-acm: Add DISABLE_ECHO quirk for GE HealthCare UI Controller Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 91/98] USB: serial: option: add MeiG Smart SRM825L Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 92/98] usb: dwc3: omap: add missing depopulate in probe error path Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 93/98] usb: dwc3: core: Prevent USB core invalid event buffer address access Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 94/98] usb: dwc3: st: fix probed platform device ref count on probe error path Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 95/98] usb: core: sysfs: Unmerge @usb3_hardware_lpm_attr_group in remove_power_attributes() Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 96/98] scsi: aacraid: Fix double-free on probe failure Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 97/98] ipc: remove memcg accounting for sops objects in do_semtimedop() Greg Kroah-Hartman
2024-09-01 16:17 ` [PATCH 4.19 98/98] drm/fb-helper: set x/yres_virtual in drm_fb_helper_check_var Greg Kroah-Hartman
2024-09-02 7:10 ` [PATCH 4.19 00/98] 4.19.321-rc1 review Pavel Machek
2024-09-02 8:46 ` Naresh Kamboju
2024-09-04 9:30 ` Greg Kroah-Hartman
2024-09-02 9:00 ` Naresh Kamboju
2024-09-04 9:38 ` Greg Kroah-Hartman
2024-09-04 9:46 ` Greg Kroah-Hartman
2024-09-02 9:14 ` Harshit Mogalapalli
2024-09-04 9:51 ` Greg Kroah-Hartman
2024-09-03 8:42 ` Jon Hunter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240901160803.999210410@linuxfoundation.org \
--to=gregkh@linuxfoundation.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--cc=viro@zeniv.linux.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox