From: Xiyu Yang xiyuyang19@fudan.edu.cn
hulk inclusion category: bugfix bugzilla: 186971, https://gitee.com/openeuler/kernel/issues/I5C8IW CVE: NA
--------------------------------
refcount_t type and corresponding API can protect refcounters from accidental underflow and overflow and further use-after-free situations.
Signed-off-by: Xiyu Yang xiyuyang19@fudan.edu.cn Signed-off-by: Xin Tan tanxin.ctf@gmail.com Reviewed-by: Jan Kara jack@suse.cz Link: https://lore.kernel.org/r/1626674355-55795-1-git-send-email-xiyuyang19@fudan... Signed-off-by: Theodore Ts'o tytso@mit.edu Signed-off-by: Li Nan linan122@huawei.com Reviewed-by: Zhang Yi yi.zhang@huawei.com Signed-off-by: Yongqiang Liu liuyongqiang13@huawei.com --- fs/ext4/ext4.h | 3 ++- fs/ext4/page-io.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/fs/ext4/ext4.h b/fs/ext4/ext4.h index 16e2b719d47c..6efc710b07bf 100644 --- a/fs/ext4/ext4.h +++ b/fs/ext4/ext4.h @@ -17,6 +17,7 @@ #ifndef _EXT4_H #define _EXT4_H
+#include <linux/refcount.h> #include <linux/types.h> #include <linux/blkdev.h> #include <linux/magic.h> @@ -231,7 +232,7 @@ typedef struct ext4_io_end { struct bio *bio; /* Linked list of completed * bios covering the extent */ unsigned int flag; /* unwritten or not */ - atomic_t count; /* reference counter */ + refcount_t count; /* reference counter */ loff_t offset; /* offset in the file */ ssize_t size; /* size of the extent */ } ext4_io_end_t; diff --git a/fs/ext4/page-io.c b/fs/ext4/page-io.c index 3de933354a08..decae80aeb98 100644 --- a/fs/ext4/page-io.c +++ b/fs/ext4/page-io.c @@ -256,14 +256,14 @@ ext4_io_end_t *ext4_init_io_end(struct inode *inode, gfp_t flags) if (io) { io->inode = inode; INIT_LIST_HEAD(&io->list); - atomic_set(&io->count, 1); + refcount_set(&io->count, 1); } return io; }
void ext4_put_io_end_defer(ext4_io_end_t *io_end) { - if (atomic_dec_and_test(&io_end->count)) { + if (refcount_dec_and_test(&io_end->count)) { if (!(io_end->flag & EXT4_IO_END_UNWRITTEN) || !io_end->size) { ext4_release_io_end(io_end); return; @@ -276,7 +276,7 @@ int ext4_put_io_end(ext4_io_end_t *io_end) { int err = 0;
- if (atomic_dec_and_test(&io_end->count)) { + if (refcount_dec_and_test(&io_end->count)) { if (io_end->flag & EXT4_IO_END_UNWRITTEN) { err = ext4_convert_unwritten_extents(io_end->handle, io_end->inode, io_end->offset, @@ -291,7 +291,7 @@ int ext4_put_io_end(ext4_io_end_t *io_end)
ext4_io_end_t *ext4_get_io_end(ext4_io_end_t *io_end) { - atomic_inc(&io_end->count); + refcount_inc(&io_end->count); return io_end; }