From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.remote-ip=100.103.45.18 ARC-Seal: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; cv=none; t=1793675975; b=AD0vFZPvlit6Q+rCsalBqUOh918gNw+G36tHcT2iNh5J/tZQTuujsaArvW4yrOOipQK7 5AUjRo1SjCTS7m6CyNDOWgxP/6l96eoaTNjRnlO964NG9geWY6DC+zp5KFxtIriaAm3S0 3CuzBjfQmV4VgW+8C2ckR3xCv+ucpHM9NuvrdvVM6dq1cXaPd4cFqqJl4hZRr8bzyTQ1o SVJhHIISLCNsCrB/YBRsEXOSi2knG6id1Ygb4L9kXTMlUFa653WXY0RHRx1DIogu+VRHP XseQoRFndBD+JzZsMYZ7Kor8mc3y6ajeteEO0LW6lh06JhhrDLONeW/JXM8vpZ0E19A== ARC-Message-Signature: i=1; d=subspace.kernel.org; s=arc20261015; a=rsa-sha256; c=relaxed/relaxed; t=1793675975; h=Received:DKIM-Signature:Date:To:From:Subject:Message-Id; bh=ZBc6vW+MC16lgEAg684k9mt22s9+kyKXBv0BnVsALQY=; b=qVGg11XXZeUb8xycU6JdhDeQPOHjACllxr+SK3yBUhEaBslr8jS0MwRe4fV6RXqsOm78 eznjH2n7y+qxRq1mBCkHHws44OH9wSidpTtidSALgMlYKQcP0SFwofa1FazH2yvurLQlf NBcMhhMQ4BuQneHLq/CHQHtEDlHUYWjbpmwwYxi2de2ShW+c12eUBBcSx3Bs7n6dy29to xYFP/AO/FkWVS+63flvAAGKxDBX0mdK8NLmFvbso3GYEt7os10T6McrKfwIxblrklYqzz H8pdkfJ0YGcTeoDHnHtj/2IxlcmQiTuu8UzbvH6BTosGTLRwRNZQs1JE6IlktWDv/bg== ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=ezc61Fl5; arc=none smtp.remote-ip=100.103.45.18 Received: from smtp.kernel.org (quasi.space.kernel.org [100.103.45.18]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 629F8606A335; Tue, 3 Nov 2026 03:19:35 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key, unprotected) header.d=linux-foundation.org header.i=@linux-foundation.org header.a=rsa-sha256 header.s=korg header.b=ezc61Fl5 Received: by smtp.kernel.org (Postfix) with ESMTPSA id E02F91F000C1; Tue, 3 Nov 2026 03:19:34 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linux-foundation.org; s=korg; t=1793675975; bh=ZBc6vW+MC16lgEAg684k9mt22s9+kyKXBv0BnVsALQY=; h=Date:To:From:Subject; b=ezc61Fl5dyUL+6tGnLGmDaRy2613ZKlhXmAMNhvJZM9XyfbfJAV6o2i+AOAG3DbCn VhtL2nJO2xLiL+Uie22YWNRf8F30qVg7BKpBxBthwL4cZxDn7K5lnaHaJ4wUpyouDf ogwg4LwScFul33OrH4lCWXE2V3AQXqfP+LNL8buw= Date: Mon, 02 Nov 2026 19:19:34 -0800 To: mm-commits@vger.kernel.org,zzzccc427@gmail.com, syzbot+5d4e96acd0febccb5e87@syzkaller.appspotmail.com,stable@vger.kernel.org, mark@fasheh.com,kartikey406@gmail.com,joseph.qi@linux.alibaba.com, jlbec@evilplan.org,heming.zhao@suse.com,eklavyasingh2106@gmail.com, akpm@linux-foundation.org From: Andrew Morton Subject: [merged mm-nonmm-hotfixes-stable] ocfs2-heartbeat-serialize-concurrent-writes-to-a-regions-dev-attribute.patch removed from -mm tree Message-Id: <20261103031934.E02F91F000C1@smtp.kernel.org> X-Mailing-List: stable@vger.kernel.org List-Id: List-Post: List-Help: List-Subscribe: List-Unsubscribe: List-Owner: Precedence: list The quilt patch titled Subject: ocfs2/heartbeat: serialize concurrent writes to a region's dev attribute has been removed from the -mm tree. Its filename was ocfs2-heartbeat-serialize-concurrent-writes-to-a-regions-dev-attribute.patch This patch was dropped because it was merged into the mm-nonmm-hotfixes-stable branch of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm ------------------------------------------------------ From: Eklavya Singh Subject: ocfs2/heartbeat: serialize concurrent writes to a region's dev attribute Date: Wed, 21 Oct 2026 02:53:39 +0530 o2hb_region_dev_store() checks reg->hr_bdev_file to see if the region is already started, but nothing stops two writers from doing that at the same time. configfs only serializes writes through the same open file, so two processes that each open the dev attribute can both get past the check: A: hr_bdev_file is NULL, opens file A, sets hr_bdev_file = A B: hr_bdev_file is NULL, opens file B, sets hr_bdev_file = B A: start fails, fput(hr_bdev_file) drops B, sets it to NULL B: start fails, fput(NULL) Both calls also use the same hr_slots, hr_slot_data and hr_tmp_block, so the error paths can free the slot data twice. syzbot hit the fput(NULL) with an unbound loop device, where every start fails with -EIO. With four threads doing the same thing on a KASAN kernel I get both crashes within a second: BUG: KASAN: double-free in o2hb_unmap_slot_data+0x14d/0x2f0 BUG: kernel NULL pointer dereference, address: 0000000000000158 Add a mutex to the region and hold it in dev_store(), in the block_bytes, start_block and blocks stores, and in dev_show(), since they all look at hr_bdev_file. dev_store() cleans up with goto, so it takes the mutex in a small wrapper rather than with guard(). The mutex is dropped while dev_store() waits for the heartbeat to become steady, which takes seconds, so a read of dev doesn't stall behind a start. hr_bdev_file is already set at that point, so other writers still get -EINVAL, and the cleanup after the wait retakes the mutex. With the patch the same test ran for 10 minutes with lockdep on and nothing was reported. So did a second one, with a working loop device, that interrupts starts during the wait while other threads read and write the attributes. Link: https://lore.kernel.org/20261020212339.46591-1-eklavyasingh2106@gmail.com Fixes: a7f6a5fb4bde ("[PATCH] OCFS2: The Second Oracle Cluster Filesystem") Signed-off-by: Eklavya Singh Signed-off-by: Andrew Morton Reported-by: Closes: https://syzkaller.appspot.com/bug?extid=5d4e96acd0febccb5e87 Reviewed-by: Joseph Qi Cc: Mark Fasheh Cc: Joel Becker Cc: Heming Zhao Cc: Deepanshu Kartikey Cc: Cen Zhang Cc: --- fs/ocfs2/cluster/heartbeat.c | 40 ++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 6 deletions(-) --- a/fs/ocfs2/cluster/heartbeat.c~ocfs2-heartbeat-serialize-concurrent-writes-to-a-regions-dev-attribute +++ a/fs/ocfs2/cluster/heartbeat.c @@ -269,6 +269,8 @@ struct o2hb_region { struct list_head hr_handler_list; /* Serializes timeout arming against failed-start and teardown. */ struct mutex hr_arming_mutex; + /* Serializes the dev, block_bytes, start_block and blocks attributes. */ + struct mutex hr_dev_mutex; bool hr_stopping; /* last hb status, 0 for success, other value for error. */ @@ -1681,6 +1683,7 @@ static ssize_t o2hb_region_block_bytes_s unsigned long block_bytes; unsigned int block_bits; + guard(mutex)(®->hr_dev_mutex); if (reg->hr_bdev_file) return -EINVAL; @@ -1710,6 +1713,7 @@ static ssize_t o2hb_region_start_block_s char *p = (char *)page; ssize_t ret; + guard(mutex)(®->hr_dev_mutex); if (reg->hr_bdev_file) return -EINVAL; @@ -1736,6 +1740,7 @@ static ssize_t o2hb_region_blocks_store( char *p = (char *)page; int ret; + guard(mutex)(®->hr_dev_mutex); if (reg->hr_bdev_file) return -EINVAL; @@ -1753,10 +1758,12 @@ static ssize_t o2hb_region_blocks_store( static ssize_t o2hb_region_dev_show(struct config_item *item, char *page) { + struct o2hb_region *reg = to_o2hb_region(item); unsigned int ret = 0; - if (to_o2hb_region(item)->hr_bdev_file) - ret = sprintf(page, "%pg\n", reg_bdev(to_o2hb_region(item))); + guard(mutex)(®->hr_dev_mutex); + if (reg->hr_bdev_file) + ret = sprintf(page, "%pg\n", reg_bdev(reg)); return ret; } @@ -1872,11 +1879,9 @@ out: * this is acting as commit; we set up all of hr_bdev_file and hr_task or * nothing */ -static ssize_t o2hb_region_dev_store(struct config_item *item, - const char *page, - size_t count) +static ssize_t __o2hb_region_dev_store(struct o2hb_region *reg, + const char *page, size_t count) { - struct o2hb_region *reg = to_o2hb_region(item); struct task_struct *hb_task; long fd; int sectsize; @@ -1884,6 +1889,8 @@ static ssize_t o2hb_region_dev_store(str ssize_t ret = -EINVAL; int live_threshold; + lockdep_assert_held(®->hr_dev_mutex); + if (reg->hr_bdev_file) return -EINVAL; @@ -1987,9 +1994,15 @@ static ssize_t o2hb_region_dev_store(str wake_up_process(hb_task); + /* + * Don't hold hr_dev_mutex across the wait, which can take seconds. + * hr_bdev_file is already set, so other writers still get -EINVAL. + */ + mutex_unlock(®->hr_dev_mutex); ret = wait_event_interruptible(o2hb_steady_queue, atomic_read(®->hr_steady_iterations) == 0 || reg->hr_node_deleted); + mutex_lock(®->hr_dev_mutex); if (ret) { atomic_set(®->hr_steady_iterations, 0); reg->hr_aborted_start = 1; @@ -2041,6 +2054,20 @@ out: return ret; } +static ssize_t o2hb_region_dev_store(struct config_item *item, + const char *page, + size_t count) +{ + struct o2hb_region *reg = to_o2hb_region(item); + ssize_t ret; + + mutex_lock(®->hr_dev_mutex); + ret = __o2hb_region_dev_store(reg, page, count); + mutex_unlock(®->hr_dev_mutex); + + return ret; +} + static ssize_t o2hb_region_pid_show(struct config_item *item, char *page) { struct o2hb_region *reg = to_o2hb_region(item); @@ -2143,6 +2170,7 @@ static struct config_item *o2hb_heartbea INIT_LIST_HEAD(®->hr_all_item); mutex_init(®->hr_arming_mutex); + mutex_init(®->hr_dev_mutex); reg->hr_stopping = true; INIT_DELAYED_WORK(®->hr_write_timeout_work, o2hb_write_timeout); INIT_DELAYED_WORK(®->hr_nego_timeout_work, o2hb_nego_timeout); _ Patches currently in -mm which might be from eklavyasingh2106@gmail.com are