[Trusty SRU][PATCH 0/1] Fix for CVE-2017-0750

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

[Trusty SRU][PATCH 0/1] Fix for CVE-2017-0750

Kleber Souza
Only Trusty needs the fix, the other supported series are either not
affected or have been already fixed.

The backport was needed only to adjust for context.

Chao Yu (1):
  f2fs: do more integrity verification for superblock

 fs/f2fs/super.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

[Trusty SRU][PATCH 1/1] f2fs: do more integrity verification for superblock

Kleber Souza
From: Chao Yu <[hidden email]>

CVE-2017-0750

Do more sanity check for superblock during ->mount.

Signed-off-by: Chao Yu <[hidden email]>
Signed-off-by: Jaegeuk Kim <[hidden email]>
(backported from commit 9a59b62fd88196844cee5fff851bee2cfd7afb6e upstream)
Signed-off-by: Kleber Sacilotto de Souza <[hidden email]>
---
 fs/f2fs/super.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 97 insertions(+)

diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
index ec70a2176c57..8c017100b7f7 100644
--- a/fs/f2fs/super.c
+++ b/fs/f2fs/super.c
@@ -677,6 +677,79 @@ static loff_t max_file_size(unsigned bits)
  return result;
 }
 
+static inline bool sanity_check_area_boundary(struct super_block *sb,
+ struct f2fs_super_block *raw_super)
+{
+ u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
+ u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr);
+ u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr);
+ u32 nat_blkaddr = le32_to_cpu(raw_super->nat_blkaddr);
+ u32 ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
+ u32 main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
+ u32 segment_count_ckpt = le32_to_cpu(raw_super->segment_count_ckpt);
+ u32 segment_count_sit = le32_to_cpu(raw_super->segment_count_sit);
+ u32 segment_count_nat = le32_to_cpu(raw_super->segment_count_nat);
+ u32 segment_count_ssa = le32_to_cpu(raw_super->segment_count_ssa);
+ u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main);
+ u32 segment_count = le32_to_cpu(raw_super->segment_count);
+ u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
+
+ if (segment0_blkaddr != cp_blkaddr) {
+ f2fs_msg(sb, KERN_INFO,
+ "Mismatch start address, segment0(%u) cp_blkaddr(%u)",
+ segment0_blkaddr, cp_blkaddr);
+ return true;
+ }
+
+ if (cp_blkaddr + (segment_count_ckpt << log_blocks_per_seg) !=
+ sit_blkaddr) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong CP boundary, start(%u) end(%u) blocks(%u)",
+ cp_blkaddr, sit_blkaddr,
+ segment_count_ckpt << log_blocks_per_seg);
+ return true;
+ }
+
+ if (sit_blkaddr + (segment_count_sit << log_blocks_per_seg) !=
+ nat_blkaddr) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong SIT boundary, start(%u) end(%u) blocks(%u)",
+ sit_blkaddr, nat_blkaddr,
+ segment_count_sit << log_blocks_per_seg);
+ return true;
+ }
+
+ if (nat_blkaddr + (segment_count_nat << log_blocks_per_seg) !=
+ ssa_blkaddr) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong NAT boundary, start(%u) end(%u) blocks(%u)",
+ nat_blkaddr, ssa_blkaddr,
+ segment_count_nat << log_blocks_per_seg);
+ return true;
+ }
+
+ if (ssa_blkaddr + (segment_count_ssa << log_blocks_per_seg) !=
+ main_blkaddr) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong SSA boundary, start(%u) end(%u) blocks(%u)",
+ ssa_blkaddr, main_blkaddr,
+ segment_count_ssa << log_blocks_per_seg);
+ return true;
+ }
+
+ if (main_blkaddr + (segment_count_main << log_blocks_per_seg) !=
+ segment0_blkaddr + (segment_count << log_blocks_per_seg)) {
+ f2fs_msg(sb, KERN_INFO,
+ "Wrong MAIN_AREA boundary, start(%u) end(%u) blocks(%u)",
+ main_blkaddr,
+ segment0_blkaddr + (segment_count << log_blocks_per_seg),
+ segment_count_main << log_blocks_per_seg);
+ return true;
+ }
+
+ return false;
+}
+
 static int sanity_check_raw_super(struct super_block *sb,
  struct f2fs_super_block *raw_super)
 {
@@ -706,6 +779,14 @@ static int sanity_check_raw_super(struct super_block *sb,
  return 1;
  }
 
+ /* check log blocks per segment */
+ if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) {
+ f2fs_msg(sb, KERN_INFO,
+ "Invalid log blocks per segment (%u)\n",
+ le32_to_cpu(raw_super->log_blocks_per_seg));
+ return 1;
+ }
+
  if (le32_to_cpu(raw_super->log_sectorsize) !=
  F2FS_LOG_SECTOR_SIZE) {
  f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize");
@@ -724,6 +805,22 @@ static int sanity_check_raw_super(struct super_block *sb,
  return 1;
  }
 
+ /* check reserved ino info */
+ if (le32_to_cpu(raw_super->node_ino) != 1 ||
+ le32_to_cpu(raw_super->meta_ino) != 2 ||
+ le32_to_cpu(raw_super->root_ino) != 3) {
+ f2fs_msg(sb, KERN_INFO,
+ "Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)",
+ le32_to_cpu(raw_super->node_ino),
+ le32_to_cpu(raw_super->meta_ino),
+ le32_to_cpu(raw_super->root_ino));
+ return 1;
+ }
+
+ /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
+ if (sanity_check_area_boundary(sb, raw_super))
+ return 1;
+
  return 0;
 }
 
--
2.14.1


--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team
Reply | Threaded
Open this post in threaded view
|

ACK: [Trusty SRU][PATCH 1/1] f2fs: do more integrity verification for superblock

Colin King
On 28/11/17 09:09, Kleber Sacilotto de Souza wrote:

> From: Chao Yu <[hidden email]>
>
> CVE-2017-0750
>
> Do more sanity check for superblock during ->mount.
>
> Signed-off-by: Chao Yu <[hidden email]>
> Signed-off-by: Jaegeuk Kim <[hidden email]>
> (backported from commit 9a59b62fd88196844cee5fff851bee2cfd7afb6e upstream)
> Signed-off-by: Kleber Sacilotto de Souza <[hidden email]>
> ---
>  fs/f2fs/super.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 97 insertions(+)
>
> diff --git a/fs/f2fs/super.c b/fs/f2fs/super.c
> index ec70a2176c57..8c017100b7f7 100644
> --- a/fs/f2fs/super.c
> +++ b/fs/f2fs/super.c
> @@ -677,6 +677,79 @@ static loff_t max_file_size(unsigned bits)
>   return result;
>  }
>  
> +static inline bool sanity_check_area_boundary(struct super_block *sb,
> + struct f2fs_super_block *raw_super)
> +{
> + u32 segment0_blkaddr = le32_to_cpu(raw_super->segment0_blkaddr);
> + u32 cp_blkaddr = le32_to_cpu(raw_super->cp_blkaddr);
> + u32 sit_blkaddr = le32_to_cpu(raw_super->sit_blkaddr);
> + u32 nat_blkaddr = le32_to_cpu(raw_super->nat_blkaddr);
> + u32 ssa_blkaddr = le32_to_cpu(raw_super->ssa_blkaddr);
> + u32 main_blkaddr = le32_to_cpu(raw_super->main_blkaddr);
> + u32 segment_count_ckpt = le32_to_cpu(raw_super->segment_count_ckpt);
> + u32 segment_count_sit = le32_to_cpu(raw_super->segment_count_sit);
> + u32 segment_count_nat = le32_to_cpu(raw_super->segment_count_nat);
> + u32 segment_count_ssa = le32_to_cpu(raw_super->segment_count_ssa);
> + u32 segment_count_main = le32_to_cpu(raw_super->segment_count_main);
> + u32 segment_count = le32_to_cpu(raw_super->segment_count);
> + u32 log_blocks_per_seg = le32_to_cpu(raw_super->log_blocks_per_seg);
> +
> + if (segment0_blkaddr != cp_blkaddr) {
> + f2fs_msg(sb, KERN_INFO,
> + "Mismatch start address, segment0(%u) cp_blkaddr(%u)",
> + segment0_blkaddr, cp_blkaddr);
> + return true;
> + }
> +
> + if (cp_blkaddr + (segment_count_ckpt << log_blocks_per_seg) !=
> + sit_blkaddr) {
> + f2fs_msg(sb, KERN_INFO,
> + "Wrong CP boundary, start(%u) end(%u) blocks(%u)",
> + cp_blkaddr, sit_blkaddr,
> + segment_count_ckpt << log_blocks_per_seg);
> + return true;
> + }
> +
> + if (sit_blkaddr + (segment_count_sit << log_blocks_per_seg) !=
> + nat_blkaddr) {
> + f2fs_msg(sb, KERN_INFO,
> + "Wrong SIT boundary, start(%u) end(%u) blocks(%u)",
> + sit_blkaddr, nat_blkaddr,
> + segment_count_sit << log_blocks_per_seg);
> + return true;
> + }
> +
> + if (nat_blkaddr + (segment_count_nat << log_blocks_per_seg) !=
> + ssa_blkaddr) {
> + f2fs_msg(sb, KERN_INFO,
> + "Wrong NAT boundary, start(%u) end(%u) blocks(%u)",
> + nat_blkaddr, ssa_blkaddr,
> + segment_count_nat << log_blocks_per_seg);
> + return true;
> + }
> +
> + if (ssa_blkaddr + (segment_count_ssa << log_blocks_per_seg) !=
> + main_blkaddr) {
> + f2fs_msg(sb, KERN_INFO,
> + "Wrong SSA boundary, start(%u) end(%u) blocks(%u)",
> + ssa_blkaddr, main_blkaddr,
> + segment_count_ssa << log_blocks_per_seg);
> + return true;
> + }
> +
> + if (main_blkaddr + (segment_count_main << log_blocks_per_seg) !=
> + segment0_blkaddr + (segment_count << log_blocks_per_seg)) {
> + f2fs_msg(sb, KERN_INFO,
> + "Wrong MAIN_AREA boundary, start(%u) end(%u) blocks(%u)",
> + main_blkaddr,
> + segment0_blkaddr + (segment_count << log_blocks_per_seg),
> + segment_count_main << log_blocks_per_seg);
> + return true;
> + }
> +
> + return false;
> +}
> +
>  static int sanity_check_raw_super(struct super_block *sb,
>   struct f2fs_super_block *raw_super)
>  {
> @@ -706,6 +779,14 @@ static int sanity_check_raw_super(struct super_block *sb,
>   return 1;
>   }
>  
> + /* check log blocks per segment */
> + if (le32_to_cpu(raw_super->log_blocks_per_seg) != 9) {
> + f2fs_msg(sb, KERN_INFO,
> + "Invalid log blocks per segment (%u)\n",
> + le32_to_cpu(raw_super->log_blocks_per_seg));
> + return 1;
> + }
> +
>   if (le32_to_cpu(raw_super->log_sectorsize) !=
>   F2FS_LOG_SECTOR_SIZE) {
>   f2fs_msg(sb, KERN_INFO, "Invalid log sectorsize");
> @@ -724,6 +805,22 @@ static int sanity_check_raw_super(struct super_block *sb,
>   return 1;
>   }
>  
> + /* check reserved ino info */
> + if (le32_to_cpu(raw_super->node_ino) != 1 ||
> + le32_to_cpu(raw_super->meta_ino) != 2 ||
> + le32_to_cpu(raw_super->root_ino) != 3) {
> + f2fs_msg(sb, KERN_INFO,
> + "Invalid Fs Meta Ino: node(%u) meta(%u) root(%u)",
> + le32_to_cpu(raw_super->node_ino),
> + le32_to_cpu(raw_super->meta_ino),
> + le32_to_cpu(raw_super->root_ino));
> + return 1;
> + }
> +
> + /* check CP/SIT/NAT/SSA/MAIN_AREA area boundary */
> + if (sanity_check_area_boundary(sb, raw_super))
> + return 1;
> +
>   return 0;
>  }
>  
>
Looks OK to me.

Acked-by: Colin Ian King <[hidden email]>

--
kernel-team mailing list
[hidden email]
https://lists.ubuntu.com/mailman/listinfo/kernel-team