diff mbox series

[SRU,B,1/2] f2fs: fix wrong total_sections check and fsmeta check

Message ID 24bc3852cd72fa870f0caa3f4916a105a4f976f5.1633025011.git.luke.nowakowskikrijger@canonical.com
State New
Headers show
Series CVE-2019-19449 | expand

Commit Message

Luke Nowakowski-Krijger Sept. 30, 2021, 6:28 p.m. UTC
From: Wang Xiaojun <wangxiaojun11@huawei.com>

Meta area is not included in section_count computation.
So the minimum number of total_sections is 1 meanwhile it cannot be
greater than segment_count_main.

The minimum number of meta segments is 8 (SB + 2 (CP + SIT + NAT) + SSA).

Signed-off-by: Wang Xiaojun <wangxiaojun11@huawei.com>
Reviewed-by: Chao Yu <yuchao0@huawei.com>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
(cherry-picked from f99ba9add67ce63eca3fe68a3d5e9996cd2c33b5)
CVE-2019-19449
Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
---
 fs/f2fs/segment.h | 1 +
 fs/f2fs/super.c   | 8 ++++----
 2 files changed, 5 insertions(+), 4 deletions(-)

Comments

Thadeu Lima de Souza Cascardo Sept. 30, 2021, 7:06 p.m. UTC | #1
On Thu, Sep 30, 2021 at 11:28:46AM -0700, Luke Nowakowski-Krijger wrote:
> From: Wang Xiaojun <wangxiaojun11@huawei.com>
> 
> Meta area is not included in section_count computation.
> So the minimum number of total_sections is 1 meanwhile it cannot be
> greater than segment_count_main.
> 
> The minimum number of meta segments is 8 (SB + 2 (CP + SIT + NAT) + SSA).
> 
> Signed-off-by: Wang Xiaojun <wangxiaojun11@huawei.com>
> Reviewed-by: Chao Yu <yuchao0@huawei.com>
> Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> (cherry-picked from f99ba9add67ce63eca3fe68a3d5e9996cd2c33b5)
> CVE-2019-19449

Hey, Luke.

Didn't this commit require a conflict fix due to f2fs_msg vs f2fs_info/f2fs_err
as well? It looks like it didn't, as I just tested it.

Again, thanks for the work.

Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>

> Signed-off-by: Luke Nowakowski-Krijger <luke.nowakowskikrijger@canonical.com>
> ---
>  fs/f2fs/segment.h | 1 +
>  fs/f2fs/super.c   | 8 ++++----
>  2 files changed, 5 insertions(+), 4 deletions(-)
> 
> diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> index 135e14f9bfbd..dbc9549ef0a4 100644
> --- a/fs/f2fs/segment.h
> +++ b/fs/f2fs/segment.h
> @@ -19,6 +19,7 @@
>  #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS	4096	/* 8GB in maximum */
>  
>  #define F2FS_MIN_SEGMENTS	9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
> +#define F2FS_MIN_META_SEGMENTS	8 /* SB + 2 (CP + SIT + NAT) + SSA */
>  
>  /* L: Logical segment # in volume, R: Relative segment # in main area */
>  #define GET_L2R_SEGNO(free_i, segno)	((segno) - (free_i)->start_segno)
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index d51f78df2c57..9eba35db374c 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -1970,7 +1970,7 @@ static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
>  static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
>  				struct buffer_head *bh)
>  {
> -	block_t segment_count, segs_per_sec, secs_per_zone;
> +	block_t segment_count, segs_per_sec, secs_per_zone, segment_count_main;
>  	block_t total_sections, blocks_per_seg;
>  	struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
>  					(bh->b_data + F2FS_SUPER_OFFSET);
> @@ -2029,6 +2029,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
>  	}
>  
>  	segment_count = le32_to_cpu(raw_super->segment_count);
> +	segment_count_main = le32_to_cpu(raw_super->segment_count_main);
>  	segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
>  	secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
>  	total_sections = le32_to_cpu(raw_super->section_count);
> @@ -2044,8 +2045,7 @@ static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
>  		return -EFSCORRUPTED;
>  	}
>  
> -	if (total_sections > segment_count ||
> -			total_sections < F2FS_MIN_SEGMENTS ||
> +	if (total_sections > segment_count_main || total_sections < 1 ||
>  			segs_per_sec > segment_count || !segs_per_sec) {
>  		f2fs_msg(sb, KERN_INFO,
>  			"Invalid segment/section count (%u, %u x %u)",
> @@ -2139,7 +2139,7 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
>  	ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
>  	reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
>  
> -	if (unlikely(fsmeta < F2FS_MIN_SEGMENTS ||
> +	if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS ||
>  			ovp_segments == 0 || reserved_segments == 0)) {
>  		f2fs_msg(sbi->sb, KERN_ERR,
>  			"Wrong layout: check mkfs.f2fs version");
> -- 
> 2.30.2
> 
> 
> -- 
> kernel-team mailing list
> kernel-team@lists.ubuntu.com
> https://lists.ubuntu.com/mailman/listinfo/kernel-team
Luke Nowakowski-Krijger Sept. 30, 2021, 8:10 p.m. UTC | #2
Hey Thadeu,

It looks like the git cherry-pick happened to auto merge it in the correct
way and I did not question it :)

Thanks for the review,

- Luke

On Thu, Sep 30, 2021 at 12:06 PM Thadeu Lima de Souza Cascardo <
cascardo@canonical.com> wrote:

> On Thu, Sep 30, 2021 at 11:28:46AM -0700, Luke Nowakowski-Krijger wrote:
> > From: Wang Xiaojun <wangxiaojun11@huawei.com>
> >
> > Meta area is not included in section_count computation.
> > So the minimum number of total_sections is 1 meanwhile it cannot be
> > greater than segment_count_main.
> >
> > The minimum number of meta segments is 8 (SB + 2 (CP + SIT + NAT) + SSA).
> >
> > Signed-off-by: Wang Xiaojun <wangxiaojun11@huawei.com>
> > Reviewed-by: Chao Yu <yuchao0@huawei.com>
> > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
> > (cherry-picked from f99ba9add67ce63eca3fe68a3d5e9996cd2c33b5)
> > CVE-2019-19449
>
> Hey, Luke.
>
> Didn't this commit require a conflict fix due to f2fs_msg vs
> f2fs_info/f2fs_err
> as well? It looks like it didn't, as I just tested it.
>
> Again, thanks for the work.
>
> Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com>
>
> > Signed-off-by: Luke Nowakowski-Krijger <
> luke.nowakowskikrijger@canonical.com>
> > ---
> >  fs/f2fs/segment.h | 1 +
> >  fs/f2fs/super.c   | 8 ++++----
> >  2 files changed, 5 insertions(+), 4 deletions(-)
> >
> > diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
> > index 135e14f9bfbd..dbc9549ef0a4 100644
> > --- a/fs/f2fs/segment.h
> > +++ b/fs/f2fs/segment.h
> > @@ -19,6 +19,7 @@
> >  #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS     4096    /* 8GB in maximum
> */
> >
> >  #define F2FS_MIN_SEGMENTS    9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN
> */
> > +#define F2FS_MIN_META_SEGMENTS       8 /* SB + 2 (CP + SIT + NAT) + SSA
> */
> >
> >  /* L: Logical segment # in volume, R: Relative segment # in main area */
> >  #define GET_L2R_SEGNO(free_i, segno) ((segno) - (free_i)->start_segno)
> > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> > index d51f78df2c57..9eba35db374c 100644
> > --- a/fs/f2fs/super.c
> > +++ b/fs/f2fs/super.c
> > @@ -1970,7 +1970,7 @@ static inline bool
> sanity_check_area_boundary(struct f2fs_sb_info *sbi,
> >  static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
> >                               struct buffer_head *bh)
> >  {
> > -     block_t segment_count, segs_per_sec, secs_per_zone;
> > +     block_t segment_count, segs_per_sec, secs_per_zone,
> segment_count_main;
> >       block_t total_sections, blocks_per_seg;
> >       struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
> >                                       (bh->b_data + F2FS_SUPER_OFFSET);
> > @@ -2029,6 +2029,7 @@ static int sanity_check_raw_super(struct
> f2fs_sb_info *sbi,
> >       }
> >
> >       segment_count = le32_to_cpu(raw_super->segment_count);
> > +     segment_count_main = le32_to_cpu(raw_super->segment_count_main);
> >       segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
> >       secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
> >       total_sections = le32_to_cpu(raw_super->section_count);
> > @@ -2044,8 +2045,7 @@ static int sanity_check_raw_super(struct
> f2fs_sb_info *sbi,
> >               return -EFSCORRUPTED;
> >       }
> >
> > -     if (total_sections > segment_count ||
> > -                     total_sections < F2FS_MIN_SEGMENTS ||
> > +     if (total_sections > segment_count_main || total_sections < 1 ||
> >                       segs_per_sec > segment_count || !segs_per_sec) {
> >               f2fs_msg(sb, KERN_INFO,
> >                       "Invalid segment/section count (%u, %u x %u)",
> > @@ -2139,7 +2139,7 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
> >       ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
> >       reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
> >
> > -     if (unlikely(fsmeta < F2FS_MIN_SEGMENTS ||
> > +     if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS ||
> >                       ovp_segments == 0 || reserved_segments == 0)) {
> >               f2fs_msg(sbi->sb, KERN_ERR,
> >                       "Wrong layout: check mkfs.f2fs version");
> > --
> > 2.30.2
> >
> >
> > --
> > kernel-team mailing list
> > kernel-team@lists.ubuntu.com
> > https://lists.ubuntu.com/mailman/listinfo/kernel-team
>
Stefan Bader Oct. 1, 2021, 8:40 a.m. UTC | #3
On 30.09.21 22:10, Luke Nowakowski-Krijger wrote:
> Hey Thadeu,
> 
> It looks like the git cherry-pick happened to auto merge it in the correct way 
> and I did not question it :)

Personally I prefer to use git format-patch and am for that reason (maybe other 
reasons as well). I rather like to fail but then know where subtle differences 
are than having git cleverly papering over the issues. This is not a reason to 
object, just wanted to point it out.

-Stefan

> 
> Thanks for the review,
> 
> - Luke
> 
> On Thu, Sep 30, 2021 at 12:06 PM Thadeu Lima de Souza Cascardo 
> <cascardo@canonical.com <mailto:cascardo@canonical.com>> wrote:
> 
>     On Thu, Sep 30, 2021 at 11:28:46AM -0700, Luke Nowakowski-Krijger wrote:
>      > From: Wang Xiaojun <wangxiaojun11@huawei.com
>     <mailto:wangxiaojun11@huawei.com>>
>      >
>      > Meta area is not included in section_count computation.
>      > So the minimum number of total_sections is 1 meanwhile it cannot be
>      > greater than segment_count_main.
>      >
>      > The minimum number of meta segments is 8 (SB + 2 (CP + SIT + NAT) + SSA).
>      >
>      > Signed-off-by: Wang Xiaojun <wangxiaojun11@huawei.com
>     <mailto:wangxiaojun11@huawei.com>>
>      > Reviewed-by: Chao Yu <yuchao0@huawei.com <mailto:yuchao0@huawei.com>>
>      > Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org <mailto:jaegeuk@kernel.org>>
>      > (cherry-picked from f99ba9add67ce63eca3fe68a3d5e9996cd2c33b5)
>      > CVE-2019-19449
> 
>     Hey, Luke.
> 
>     Didn't this commit require a conflict fix due to f2fs_msg vs f2fs_info/f2fs_err
>     as well? It looks like it didn't, as I just tested it.
> 
>     Again, thanks for the work.
> 
>     Acked-by: Thadeu Lima de Souza Cascardo <cascardo@canonical.com
>     <mailto:cascardo@canonical.com>>
> 
>      > Signed-off-by: Luke Nowakowski-Krijger
>     <luke.nowakowskikrijger@canonical.com
>     <mailto:luke.nowakowskikrijger@canonical.com>>
>      > ---
>      >  fs/f2fs/segment.h | 1 +
>      >  fs/f2fs/super.c   | 8 ++++----
>      >  2 files changed, 5 insertions(+), 4 deletions(-)
>      >
>      > diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
>      > index 135e14f9bfbd..dbc9549ef0a4 100644
>      > --- a/fs/f2fs/segment.h
>      > +++ b/fs/f2fs/segment.h
>      > @@ -19,6 +19,7 @@
>      >  #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS     4096    /* 8GB in maximum */
>      >
>      >  #define F2FS_MIN_SEGMENTS    9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
>      > +#define F2FS_MIN_META_SEGMENTS       8 /* SB + 2 (CP + SIT + NAT) + SSA */
>      >
>      >  /* L: Logical segment # in volume, R: Relative segment # in main area */
>      >  #define GET_L2R_SEGNO(free_i, segno) ((segno) - (free_i)->start_segno)
>      > diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
>      > index d51f78df2c57..9eba35db374c 100644
>      > --- a/fs/f2fs/super.c
>      > +++ b/fs/f2fs/super.c
>      > @@ -1970,7 +1970,7 @@ static inline bool
>     sanity_check_area_boundary(struct f2fs_sb_info *sbi,
>      >  static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
>      >                               struct buffer_head *bh)
>      >  {
>      > -     block_t segment_count, segs_per_sec, secs_per_zone;
>      > +     block_t segment_count, segs_per_sec, secs_per_zone, segment_count_main;
>      >       block_t total_sections, blocks_per_seg;
>      >       struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
>      >                                       (bh->b_data + F2FS_SUPER_OFFSET);
>      > @@ -2029,6 +2029,7 @@ static int sanity_check_raw_super(struct
>     f2fs_sb_info *sbi,
>      >       }
>      >
>      >       segment_count = le32_to_cpu(raw_super->segment_count);
>      > +     segment_count_main = le32_to_cpu(raw_super->segment_count_main);
>      >       segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
>      >       secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
>      >       total_sections = le32_to_cpu(raw_super->section_count);
>      > @@ -2044,8 +2045,7 @@ static int sanity_check_raw_super(struct
>     f2fs_sb_info *sbi,
>      >               return -EFSCORRUPTED;
>      >       }
>      >
>      > -     if (total_sections > segment_count ||
>      > -                     total_sections < F2FS_MIN_SEGMENTS ||
>      > +     if (total_sections > segment_count_main || total_sections < 1 ||
>      >                       segs_per_sec > segment_count || !segs_per_sec) {
>      >               f2fs_msg(sb, KERN_INFO,
>      >                       "Invalid segment/section count (%u, %u x %u)",
>      > @@ -2139,7 +2139,7 @@ int sanity_check_ckpt(struct f2fs_sb_info *sbi)
>      >       ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
>      >       reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
>      >
>      > -     if (unlikely(fsmeta < F2FS_MIN_SEGMENTS ||
>      > +     if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS ||
>      >                       ovp_segments == 0 || reserved_segments == 0)) {
>      >               f2fs_msg(sbi->sb, KERN_ERR,
>      >                       "Wrong layout: check mkfs.f2fs version");
>      > --
>      > 2.30.2
>      >
>      >
>      > --
>      > kernel-team mailing list
>      > kernel-team@lists.ubuntu.com <mailto:kernel-team@lists.ubuntu.com>
>      > https://lists.ubuntu.com/mailman/listinfo/kernel-team
>     <https://lists.ubuntu.com/mailman/listinfo/kernel-team>
> 
>
diff mbox series

Patch

diff --git a/fs/f2fs/segment.h b/fs/f2fs/segment.h
index 135e14f9bfbd..dbc9549ef0a4 100644
--- a/fs/f2fs/segment.h
+++ b/fs/f2fs/segment.h
@@ -19,6 +19,7 @@ 
 #define DEF_MAX_RECLAIM_PREFREE_SEGMENTS	4096	/* 8GB in maximum */
 
 #define F2FS_MIN_SEGMENTS	9 /* SB + 2 (CP + SIT + NAT) + SSA + MAIN */
+#define F2FS_MIN_META_SEGMENTS	8 /* SB + 2 (CP + SIT + NAT) + SSA */
 
 /* L: Logical segment # in volume, R: Relative segment # in main area */
 #define GET_L2R_SEGNO(free_i, segno)	((segno) - (free_i)->start_segno)
diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index d51f78df2c57..9eba35db374c 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -1970,7 +1970,7 @@  static inline bool sanity_check_area_boundary(struct f2fs_sb_info *sbi,
 static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
 				struct buffer_head *bh)
 {
-	block_t segment_count, segs_per_sec, secs_per_zone;
+	block_t segment_count, segs_per_sec, secs_per_zone, segment_count_main;
 	block_t total_sections, blocks_per_seg;
 	struct f2fs_super_block *raw_super = (struct f2fs_super_block *)
 					(bh->b_data + F2FS_SUPER_OFFSET);
@@ -2029,6 +2029,7 @@  static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
 	}
 
 	segment_count = le32_to_cpu(raw_super->segment_count);
+	segment_count_main = le32_to_cpu(raw_super->segment_count_main);
 	segs_per_sec = le32_to_cpu(raw_super->segs_per_sec);
 	secs_per_zone = le32_to_cpu(raw_super->secs_per_zone);
 	total_sections = le32_to_cpu(raw_super->section_count);
@@ -2044,8 +2045,7 @@  static int sanity_check_raw_super(struct f2fs_sb_info *sbi,
 		return -EFSCORRUPTED;
 	}
 
-	if (total_sections > segment_count ||
-			total_sections < F2FS_MIN_SEGMENTS ||
+	if (total_sections > segment_count_main || total_sections < 1 ||
 			segs_per_sec > segment_count || !segs_per_sec) {
 		f2fs_msg(sb, KERN_INFO,
 			"Invalid segment/section count (%u, %u x %u)",
@@ -2139,7 +2139,7 @@  int sanity_check_ckpt(struct f2fs_sb_info *sbi)
 	ovp_segments = le32_to_cpu(ckpt->overprov_segment_count);
 	reserved_segments = le32_to_cpu(ckpt->rsvd_segment_count);
 
-	if (unlikely(fsmeta < F2FS_MIN_SEGMENTS ||
+	if (unlikely(fsmeta < F2FS_MIN_META_SEGMENTS ||
 			ovp_segments == 0 || reserved_segments == 0)) {
 		f2fs_msg(sbi->sb, KERN_ERR,
 			"Wrong layout: check mkfs.f2fs version");