Bug 205703
Summary: | [xfstests generic/461]: BUG: KASAN: use-after-free in iomap_finish_ioend+0x58c/0x5c0 | ||
---|---|---|---|
Product: | File System | Reporter: | Zorro Lang (zlang) |
Component: | XFS | Assignee: | FileSystem/XFS Default Virtual Assignee (filesystem_xfs) |
Status: | NEW --- | ||
Severity: | normal | CC: | djwong |
Priority: | P1 | ||
Hardware: | All | ||
OS: | Linux | ||
Kernel Version: | linux 5.4+ with xfs-5.5-merge-15 and iomap-5.5-merge-11 | Subsystem: | |
Regression: | No | Bisected commit-id: |
Description
Zorro Lang
2019-11-29 11:47:21 UTC
Could you please post the source line translations of the iomap functions? I don't have your kernel build. (In reply to Darrick J. Wong from comment #1) > Could you please post the source line translations of the iomap functions? > I don't have your kernel build. I tryed to use the faddr2line tool, then it point to a printk_ratelimited() function. I'm sure I didn't change the kernel source code, the current kernel is installed from it. Is that something wrong? # ./scripts/faddr2line vmlinux iomap_finish_ioend+0x58c iomap_finish_ioend+0x58c/0x5c0: iomap_finish_ioend at /mnt/tests/kernel/distribution/upstream-kernel/install/kernel/fs/iomap/buffered-io.c:1153 # ./scripts/faddr2line vmlinux iomap_finish_ioend+0x168 iomap_finish_ioend+0x168/0x5c0: iomap_finish_ioend at /mnt/tests/kernel/distribution/upstream-kernel/install/kernel/fs/iomap/buffered-io.c:1133 1124 static void 1125 iomap_finish_ioend(struct iomap_ioend *ioend, int error) 1126 { 1127 struct inode *inode = ioend->io_inode; 1128 struct bio *bio = &ioend->io_inline_bio; 1129 struct bio *last = ioend->io_bio, *next; 1130 u64 start = bio->bi_iter.bi_sector; 1131 bool quiet = bio_flagged(bio, BIO_QUIET); 1132 1133 for (bio = &ioend->io_inline_bio; bio; bio = next) { 1134 struct bio_vec *bv; 1135 struct bvec_iter_all iter_all; 1136 1137 /* 1138 * For the last bio, bi_private points to the ioend, so we 1139 * need to explicitly end the iteration here. 1140 */ 1141 if (bio == last) 1142 next = NULL; 1143 else 1144 next = bio->bi_private; 1145 1146 /* walk each page on bio, ending page IO on them */ 1147 bio_for_each_segment_all(bv, bio, iter_all) 1148 iomap_finish_page_writeback(inode, bv->bv_page, error); 1149 bio_put(bio); 1150 } 1151 1152 if (unlikely(error && !quiet)) { 1153 printk_ratelimited(KERN_ERR 1154 "%s: writeback error on inode %lu, offset %lld, sector %llu", 1155 inode->i_sb->s_id, inode->i_ino, ioend->io_offset, 1156 start); 1157 } 1158 } (In reply to Zorro Lang from comment #2) > (In reply to Darrick J. Wong from comment #1) > > Could you please post the source line translations of the iomap functions? > > I don't have your kernel build. > > I tryed to use the faddr2line tool, then it point to a printk_ratelimited() > function. I'm sure I didn't change the kernel source code, the current > kernel is installed from it. Is that something wrong? > > # ./scripts/faddr2line vmlinux iomap_finish_ioend+0x58c > iomap_finish_ioend+0x58c/0x5c0: > iomap_finish_ioend at > /mnt/tests/kernel/distribution/upstream-kernel/install/kernel/fs/iomap/ > buffered-io.c:1153 > > # ./scripts/faddr2line vmlinux iomap_finish_ioend+0x168 > iomap_finish_ioend+0x168/0x5c0: > iomap_finish_ioend at > /mnt/tests/kernel/distribution/upstream-kernel/install/kernel/fs/iomap/ > buffered-io.c:1133 > > 1124 static void > 1125 iomap_finish_ioend(struct iomap_ioend *ioend, int error) > 1126 { > 1127 struct inode *inode = ioend->io_inode; > 1128 struct bio *bio = &ioend->io_inline_bio; > 1129 struct bio *last = ioend->io_bio, *next; > 1130 u64 start = bio->bi_iter.bi_sector; > 1131 bool quiet = bio_flagged(bio, BIO_QUIET); > 1132 > 1133 for (bio = &ioend->io_inline_bio; bio; bio = next) { > 1134 struct bio_vec *bv; > 1135 struct bvec_iter_all iter_all; > 1136 > 1137 /* > 1138 * For the last bio, bi_private points to the ioend, > so we > 1139 * need to explicitly end the iteration here. > 1140 */ > 1141 if (bio == last) > 1142 next = NULL; > 1143 else > 1144 next = bio->bi_private; > 1145 > 1146 /* walk each page on bio, ending page IO on them */ > 1147 bio_for_each_segment_all(bv, bio, iter_all) > 1148 iomap_finish_page_writeback(inode, > bv->bv_page, error); > 1149 bio_put(bio); > 1150 } > 1151 > 1152 if (unlikely(error && !quiet)) { > 1153 printk_ratelimited(KERN_ERR > 1154 "%s: writeback error on inode %lu, offset %lld, sector %llu", > 1155 inode->i_sb->s_id, inode->i_ino, > ioend->io_offset, The bio_put(bio) might already free the bio. The ioend->io_offset is invalid. I'll test by saving the offset in a local var at first. If it's the issue, I'll try to send a patch. > 1156 start); > 1157 } > 1158 } |