Otherwise, fsck.f2fs will access invalid memory address as below:
- fsck_verify
- dump_node
- dump_file
- dump_inode_blk
- dump_xattr
- read_all_xattrs
- get_node_info
access &(F2FS_FSCK(sbi)->entries[nid])
Signed-off-by: Chao Yu <[email protected]>
---
fsck/dump.c | 2 ++
fsck/fsck.c | 8 ++++++++
fsck/fsck.h | 3 +++
fsck/mount.c | 8 +++++---
fsck/xattr.c | 20 ++++++++++++++++++--
5 files changed, 36 insertions(+), 5 deletions(-)
diff --git a/fsck/dump.c b/fsck/dump.c
index 144c10e..001b7cb 100644
--- a/fsck/dump.c
+++ b/fsck/dump.c
@@ -309,6 +309,8 @@ static void dump_xattr(struct f2fs_sb_info *sbi, struct
f2fs_node *node_blk)
int ret;
xattr = read_all_xattrs(sbi, node_blk);
+ if (!xattr)
+ return;
list_for_each_xattr(ent, xattr) {
char *name = strndup(ent->e_name, ent->e_name_len);
diff --git a/fsck/fsck.c b/fsck/fsck.c
index a08a8cb..0389146 100644
--- a/fsck/fsck.c
+++ b/fsck/fsck.c
@@ -487,6 +487,14 @@ static int sanity_check_nid(struct f2fs_sb_info *sbi, u32
nid,
return 0;
}
+int fsck_sanity_check_nid(struct f2fs_sb_info *sbi, u32 nid,
+ struct f2fs_node *node_blk,
+ enum FILE_TYPE ftype, enum NODE_TYPE ntype,
+ struct node_info *ni)
+{
+ return sanity_check_nid(sbi, nid, node_blk, ftype, ntype, ni);
+}
+
static int fsck_chk_xattr_blk(struct f2fs_sb_info *sbi, u32 ino,
u32 x_nid, u32 *blk_cnt)
{
diff --git a/fsck/fsck.h b/fsck/fsck.h
index c4432e8..2de6f62 100644
--- a/fsck/fsck.h
+++ b/fsck/fsck.h
@@ -144,6 +144,9 @@ static inline bool need_fsync_data_record(struct
f2fs_sb_info *sbi)
extern int fsck_chk_orphan_node(struct f2fs_sb_info *);
extern int fsck_chk_quota_node(struct f2fs_sb_info *);
extern int fsck_chk_quota_files(struct f2fs_sb_info *);
+extern int fsck_sanity_check_nid(struct f2fs_sb_info *, u32,
+ struct f2fs_node *, enum FILE_TYPE, enum NODE_TYPE,
+ struct node_info *);
extern int fsck_chk_node_blk(struct f2fs_sb_info *, struct f2fs_inode *, u32,
enum FILE_TYPE, enum NODE_TYPE, u32 *,
struct child_info *);
diff --git a/fsck/mount.c b/fsck/mount.c
index 4d16659..0aab071 100644
--- a/fsck/mount.c
+++ b/fsck/mount.c
@@ -257,10 +257,12 @@ void print_inode_info(struct f2fs_sb_info *sbi,
DISP_u32(inode, i_nid[4]); /* double indirect */
xattr_addr = read_all_xattrs(sbi, node);
- list_for_each_xattr(ent, xattr_addr) {
- print_xattr_entry(ent);
+ if (xattr_addr) {
+ list_for_each_xattr(ent, xattr_addr) {
+ print_xattr_entry(ent);
+ }
+ free(xattr_addr);
}
- free(xattr_addr);
printf("\n");
}
diff --git a/fsck/xattr.c b/fsck/xattr.c
index d5350e3..e9dcb52 100644
--- a/fsck/xattr.c
+++ b/fsck/xattr.c
@@ -22,6 +22,22 @@ void *read_all_xattrs(struct f2fs_sb_info *sbi, struct
f2fs_node *inode)
struct f2fs_xattr_header *header;
void *txattr_addr;
u64 inline_size = inline_xattr_size(&inode->i);
+ nid_t xnid = le32_to_cpu(inode->i.i_xattr_nid);
+
+ if (xnid) {
+ struct f2fs_node *node_blk = NULL;
+ struct node_info ni;
+ int ret;
+
+ node_blk = (struct f2fs_node *)calloc(BLOCK_SZ, 1);
+ ASSERT(node_blk != NULL);
+
+ ret = fsck_sanity_check_nid(sbi, xnid, node_blk,
+ F2FS_FT_XATTR, TYPE_XATTR, &ni);
+ free(node_blk);
+ if (ret)
+ return NULL;
+ }
txattr_addr = calloc(inline_size + BLOCK_SZ, 1);
ASSERT(txattr_addr);
@@ -30,11 +46,11 @@ void *read_all_xattrs(struct f2fs_sb_info *sbi, struct
f2fs_node *inode)
memcpy(txattr_addr, inline_xattr_addr(&inode->i), inline_size);
/* Read from xattr node block. */
- if (inode->i.i_xattr_nid) {
+ if (xnid) {
struct node_info ni;
int ret;
- get_node_info(sbi, le32_to_cpu(inode->i.i_xattr_nid), &ni);
+ get_node_info(sbi, xnid, &ni);
ret = dev_read_block(txattr_addr + inline_size, ni.blk_addr);
ASSERT(ret >= 0);
}
--
2.18.0.rc1
_______________________________________________
Linux-f2fs-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/linux-f2fs-devel