| From 63d2f95d63396059200c391ca87161897b99e74a Mon Sep 17 00:00:00 2001 |
| From: Torsten Hilbrich <torsten.hilbrich@secunet.com> |
| Date: Fri, 24 Jun 2016 14:50:18 -0700 |
| Subject: fs/nilfs2: fix potential underflow in call to crc32_le |
| |
| From: Torsten Hilbrich <torsten.hilbrich@secunet.com> |
| |
| commit 63d2f95d63396059200c391ca87161897b99e74a upstream. |
| |
| The value `bytes' comes from the filesystem which is about to be |
| mounted. We cannot trust that the value is always in the range we |
| expect it to be. |
| |
| Check its value before using it to calculate the length for the crc32_le |
| call. It value must be larger (or equal) sumoff + 4. |
| |
| This fixes a kernel bug when accidentially mounting an image file which |
| had the nilfs2 magic value 0x3434 at the right offset 0x406 by chance. |
| The bytes 0x01 0x00 were stored at 0x408 and were interpreted as a |
| s_bytes value of 1. This caused an underflow when substracting sumoff + |
| 4 (20) in the call to crc32_le. |
| |
| BUG: unable to handle kernel paging request at ffff88021e600000 |
| IP: crc32_le+0x36/0x100 |
| ... |
| Call Trace: |
| nilfs_valid_sb.part.5+0x52/0x60 [nilfs2] |
| nilfs_load_super_block+0x142/0x300 [nilfs2] |
| init_nilfs+0x60/0x390 [nilfs2] |
| nilfs_mount+0x302/0x520 [nilfs2] |
| mount_fs+0x38/0x160 |
| vfs_kern_mount+0x67/0x110 |
| do_mount+0x269/0xe00 |
| SyS_mount+0x9f/0x100 |
| entry_SYSCALL_64_fastpath+0x16/0x71 |
| |
| Link: http://lkml.kernel.org/r/1466778587-5184-2-git-send-email-konishi.ryusuke@lab.ntt.co.jp |
| Signed-off-by: Torsten Hilbrich <torsten.hilbrich@secunet.com> |
| Tested-by: Torsten Hilbrich <torsten.hilbrich@secunet.com> |
| Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> |
| Signed-off-by: Andrew Morton <akpm@linux-foundation.org> |
| Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| fs/nilfs2/the_nilfs.c | 2 +- |
| 1 file changed, 1 insertion(+), 1 deletion(-) |
| |
| --- a/fs/nilfs2/the_nilfs.c |
| +++ b/fs/nilfs2/the_nilfs.c |
| @@ -431,7 +431,7 @@ static int nilfs_valid_sb(struct nilfs_s |
| if (!sbp || le16_to_cpu(sbp->s_magic) != NILFS_SUPER_MAGIC) |
| return 0; |
| bytes = le16_to_cpu(sbp->s_bytes); |
| - if (bytes > BLOCK_SIZE) |
| + if (bytes < sumoff + 4 || bytes > BLOCK_SIZE) |
| return 0; |
| crc = crc32_le(le32_to_cpu(sbp->s_crc_seed), (unsigned char *)sbp, |
| sumoff); |