snapshot_merge_next_chunks() calls s->store->type->prepare_merge() without
checking it. The transient store ("N") implements neither prepare_merge nor
commit_merge, and snapshot_ctr() validates those callbacks only on the handover
path (__validate_exception_handover()), so a directly constructed snapshot-merge
calls a NULL prepare_merge on resume:

  snapshot_merge_resume -> snapshot_merge_next_chunks -> prepare_merge(...)

commit_merge() is NULL for the same reason. Userspace only issues documented
device-mapper ioctls (CAP_SYS_ADMIN); this is a misconfiguration the kernel must
reject rather than oops on.

Reject the combination in snapshot_ctr() at table-load time (-EINVAL), the same
check the handover path already performs; this also covers the commit_merge()
call site, which a guard local to the prepare_merge call would miss.

Tested on Linux v6.6.157 KASAN: unpatched, the dmsetup reproducer oopses in
snapshot_merge_next_chunks(); with this patch, the table load fails with -EINVAL
and no oops. Also present on v6.6.145; still present on the linux-dm tree
(555f3d7be91a) and on torvalds/linux master (62f4c998b297) as of 2026-09-22.

Signed-off-by: Ma Xinmeng <[email protected]>
---
 drivers/md/dm-snap.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/drivers/md/dm-snap.c b/drivers/md/dm-snap.c
index dcf34c6b0..f42935361 100644
--- a/drivers/md/dm-snap.c
+++ b/drivers/md/dm-snap.c
@@ -1320,6 +1320,20 @@ static int snapshot_ctr(struct dm_target *ti, unsigned 
int argc, char **argv)
                goto bad_store;
        }
 
+       /*
+        * snapshot-merge requires the optional prepare_merge/commit_merge
+        * callbacks; the transient exception store does not implement them.
+        * The handover path checks this in __validate_exception_handover(),
+        * but a directly constructed snapshot-merge never goes through it.
+        */
+       if (dm_target_is_snapshot_merge(ti) &&
+           (!s->store->type->prepare_merge ||
+            !s->store->type->commit_merge)) {
+               ti->error = "Snapshot exception store does not support 
snapshot-merge.";
+               r = -EINVAL;
+               goto bad_hash_tables;
+       }
+
        argv += args_used;
        argc -= args_used;
 
-- 
2.49.0.windows.1


Reply via email to