[bug report] dm flakey: clone pages on write bio before corrupting them

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hello Mikulas Patocka,

The patch 90ed93c305a0: "dm flakey: clone pages on write bio before
corrupting them" from May 1, 2023, leads to the following Smatch
static checker warning:

	drivers/md/dm.c:1157 clone_endio()
	warn: passing freed memory 'ti'

drivers/md/dm.c
    1105 static void clone_endio(struct bio *bio)
    1106 {
    1107         blk_status_t error = bio->bi_status;
    1108         struct dm_target_io *tio = clone_to_tio(bio);
    1109         struct dm_target *ti = tio->ti;
    1110         dm_endio_fn endio = ti->type->end_io;
    1111         struct dm_io *io = tio->io;
    1112         struct mapped_device *md = io->md;
    1113 
    1114         if (unlikely(error == BLK_STS_TARGET)) {
    1115                 if (bio_op(bio) == REQ_OP_DISCARD &&
    1116                     !bdev_max_discard_sectors(bio->bi_bdev))
    1117                         disable_discard(md);
    1118                 else if (bio_op(bio) == REQ_OP_WRITE_ZEROES &&
    1119                          !bdev_write_zeroes_sectors(bio->bi_bdev))
    1120                         disable_write_zeroes(md);
    1121         }
    1122 
    1123         if (static_branch_unlikely(&zoned_enabled) &&
    1124             unlikely(bdev_is_zoned(bio->bi_bdev)))
    1125                 dm_zone_endio(io, bio);
    1126 
    1127         if (endio) {
    1128                 int r = endio(ti, bio, &error);

clone_endio() from drivers/md/dm-flakey.c frees "ti".  (Yes, I get
that "flakey" in the filename means it is supposed to crash but
presumably not in this way).

    1129 
    1130                 switch (r) {
    1131                 case DM_ENDIO_REQUEUE:
    1132                         if (static_branch_unlikely(&zoned_enabled)) {
    1133                                 /*
    1134                                  * Requeuing writes to a sequential zone of a zoned
    1135                                  * target will break the sequential write pattern:
    1136                                  * fail such IO.
    1137                                  */
    1138                                 if (WARN_ON_ONCE(dm_is_zone_write(md, bio)))
    1139                                         error = BLK_STS_IOERR;
    1140                                 else
    1141                                         error = BLK_STS_DM_REQUEUE;
    1142                         } else
    1143                                 error = BLK_STS_DM_REQUEUE;
    1144                         fallthrough;
    1145                 case DM_ENDIO_DONE:
    1146                         break;
    1147                 case DM_ENDIO_INCOMPLETE:
    1148                         /* The target will handle the io */
    1149                         return;
    1150                 default:
    1151                         DMCRIT("unimplemented target endio return value: %d", r);
    1152                         BUG();
    1153                 }
    1154         }
    1155 
    1156         if (static_branch_unlikely(&swap_bios_enabled) &&
--> 1157             unlikely(swap_bios_limit(ti, bio)))

Use after free.

    1158                 up(&md->swap_bios_semaphore);
    1159 
    1160         free_tio(bio);
    1161         dm_io_dec_pending(io, error);
    1162 }

regards,
dan carpenter

--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://listman.redhat.com/mailman/listinfo/dm-devel




[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux