Re: [PATCH 1/2] exfat: add dir-entry set checksum validation
Thnak you for your reply. -void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) +static int exfat_calc_dir_chksum_with_entry_set(struct +exfat_entry_set_cache *es, u16 *chksum) { - int chksum_type = CS_DIR_ENTRY, i; - unsigned short chksum = 0; struct exfat_dentry *ep; + int i; - for (i = 0; i < es->num_entries; i++) { - ep = exfat_get_validated_dentry(es, i, TYPE_ALL); - chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum, -chksum_type); - chksum_type = CS_DEFAULT; + ep = container_of(es->de_file, struct exfat_dentry, dentry.file); + *chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, 0, CS_DIR_ENTRY); + for (i = 0; i < es->de_file->num_ext; i++) { + ep = exfat_get_validated_dentry(es, 1 + i, TYPE_SECONDARY); + if (!ep) + return -EIO; + *chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, *chksum, CS_DEFAULT); } + return 0; We can return checksum after removing u16 *chksum argument. I want to do that too! How should I return the error? Right now, I found that the type of chksum is not 'u16'. I'll fix in v2. +} + +void exfat_update_dir_chksum_with_entry_set(struct +exfat_entry_set_cache *es) { + u16 chksum; + + exfat_calc_dir_chksum_with_entry_set(es, ); es->de_file->checksum = cpu_to_le16(chksum); es->modified = true; } @@ -775,6 +784,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, struct exfat_entry_set_cache *es; struct exfat_dentry *ep; struct buffer_head *bh; + u16 chksum; if (p_dir->dir == DIR_DELETED) { exfat_err(sb, "access to deleted dentry"); @@ -839,10 +849,10 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, goto free_es; es->de_stream = >dentry.stream; - for (i = 2; i < es->num_entries; i++) { - if (!exfat_get_validated_dentry(es, i, TYPE_SECONDARY)) - goto free_es; - } + if (max_entries == ES_ALL_ENTRIES && + ((exfat_calc_dir_chksum_with_entry_set(es, ) || + chksum != le16_to_cpu(es->de_file->checksum Please add error print log if checksum mismatch error happen. OK. I'll add in v2. BR --- Tetsuhiro Kohada
RE: [PATCH 1/2] exfat: add dir-entry set checksum validation
> Add checksum validation for dir-entry set when getting it. > exfat_calc_dir_chksum_with_entry_set() also validates entry-type. > > ** This patch depends on: > '[PATCH v3] exfat: integrates dir-entry getting and validation' > > Signed-off-by: Tetsuhiro Kohada > --- > fs/exfat/dir.c | 34 ++ > 1 file changed, 22 insertions(+), 12 deletions(-) > > diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index c9715c7a55a1..2e79ac464f5f > 100644 > --- a/fs/exfat/dir.c > +++ b/fs/exfat/dir.c > @@ -563,18 +563,27 @@ int exfat_remove_entries(struct inode *inode, struct > exfat_chain *p_dir, > return 0; > } > > -void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) > +static int exfat_calc_dir_chksum_with_entry_set(struct > +exfat_entry_set_cache *es, u16 *chksum) > { > - int chksum_type = CS_DIR_ENTRY, i; > - unsigned short chksum = 0; > struct exfat_dentry *ep; > + int i; > > - for (i = 0; i < es->num_entries; i++) { > - ep = exfat_get_validated_dentry(es, i, TYPE_ALL); > - chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum, > - chksum_type); > - chksum_type = CS_DEFAULT; > + ep = container_of(es->de_file, struct exfat_dentry, dentry.file); > + *chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, 0, CS_DIR_ENTRY); > + for (i = 0; i < es->de_file->num_ext; i++) { > + ep = exfat_get_validated_dentry(es, 1 + i, TYPE_SECONDARY); > + if (!ep) > + return -EIO; > + *chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, *chksum, > CS_DEFAULT); > } > + return 0; We can return checksum after removing u16 *chksum argument. > +} > + > +void exfat_update_dir_chksum_with_entry_set(struct > +exfat_entry_set_cache *es) { > + u16 chksum; > + > + exfat_calc_dir_chksum_with_entry_set(es, ); > es->de_file->checksum = cpu_to_le16(chksum); > es->modified = true; > } > @@ -775,6 +784,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct > super_block *sb, > struct exfat_entry_set_cache *es; > struct exfat_dentry *ep; > struct buffer_head *bh; > + u16 chksum; > > if (p_dir->dir == DIR_DELETED) { > exfat_err(sb, "access to deleted dentry"); @@ -839,10 +849,10 > @@ struct > exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, > goto free_es; > es->de_stream = >dentry.stream; > > - for (i = 2; i < es->num_entries; i++) { > - if (!exfat_get_validated_dentry(es, i, TYPE_SECONDARY)) > - goto free_es; > - } > + if (max_entries == ES_ALL_ENTRIES && > + ((exfat_calc_dir_chksum_with_entry_set(es, ) || > + chksum != le16_to_cpu(es->de_file->checksum Please add error print log if checksum mismatch error happen. > + goto free_es; > > return es; > > -- > 2.25.1
[PATCH 1/2] exfat: add dir-entry set checksum validation
Add checksum validation for dir-entry set when getting it. exfat_calc_dir_chksum_with_entry_set() also validates entry-type. ** This patch depends on: '[PATCH v3] exfat: integrates dir-entry getting and validation' Signed-off-by: Tetsuhiro Kohada --- fs/exfat/dir.c | 34 ++ 1 file changed, 22 insertions(+), 12 deletions(-) diff --git a/fs/exfat/dir.c b/fs/exfat/dir.c index c9715c7a55a1..2e79ac464f5f 100644 --- a/fs/exfat/dir.c +++ b/fs/exfat/dir.c @@ -563,18 +563,27 @@ int exfat_remove_entries(struct inode *inode, struct exfat_chain *p_dir, return 0; } -void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) +static int exfat_calc_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es, u16 *chksum) { - int chksum_type = CS_DIR_ENTRY, i; - unsigned short chksum = 0; struct exfat_dentry *ep; + int i; - for (i = 0; i < es->num_entries; i++) { - ep = exfat_get_validated_dentry(es, i, TYPE_ALL); - chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, chksum, -chksum_type); - chksum_type = CS_DEFAULT; + ep = container_of(es->de_file, struct exfat_dentry, dentry.file); + *chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, 0, CS_DIR_ENTRY); + for (i = 0; i < es->de_file->num_ext; i++) { + ep = exfat_get_validated_dentry(es, 1 + i, TYPE_SECONDARY); + if (!ep) + return -EIO; + *chksum = exfat_calc_chksum16(ep, DENTRY_SIZE, *chksum, CS_DEFAULT); } + return 0; +} + +void exfat_update_dir_chksum_with_entry_set(struct exfat_entry_set_cache *es) +{ + u16 chksum; + + exfat_calc_dir_chksum_with_entry_set(es, ); es->de_file->checksum = cpu_to_le16(chksum); es->modified = true; } @@ -775,6 +784,7 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, struct exfat_entry_set_cache *es; struct exfat_dentry *ep; struct buffer_head *bh; + u16 chksum; if (p_dir->dir == DIR_DELETED) { exfat_err(sb, "access to deleted dentry"); @@ -839,10 +849,10 @@ struct exfat_entry_set_cache *exfat_get_dentry_set(struct super_block *sb, goto free_es; es->de_stream = >dentry.stream; - for (i = 2; i < es->num_entries; i++) { - if (!exfat_get_validated_dentry(es, i, TYPE_SECONDARY)) - goto free_es; - } + if (max_entries == ES_ALL_ENTRIES && + ((exfat_calc_dir_chksum_with_entry_set(es, ) || + chksum != le16_to_cpu(es->de_file->checksum + goto free_es; return es; -- 2.25.1