On 14 June 2018 at 17:15, Tigran Aivazian <aivazian.tigran@xxxxxxxxx> wrote: > On 14 June 2018 at 16:13, Tigran Aivazian <aivazian.tigran@xxxxxxxxx> wrote: >> On 14 June 2018 at 14:28, Tetsuo Handa >> <penguin-kernel@xxxxxxxxxxxxxxxxxxx> wrote: >>> What is possible largest value for imap_len ? >>> >>> info->si_lasti = (le32_to_cpu(bfs_sb->s_start) - BFS_BSIZE) / sizeof(struct bfs_inode) + BFS_ROOT_INO - 1; >>> imap_len = (info->si_lasti / 8) + 1; >>> info->si_imap = kzalloc(imap_len, GFP_KERNEL); >>> >>> Since sizeof(struct bfs_inode) is 64 and bfs_sb->s_start is unsigned 32bits integer >>> (where constraints is BFS_BSIZE <= bfs_sb->s_start <= bfs_sb->s_end), theoretically >>> it is possible to assign bfs_sb->s_start > 2GB (apart from whether such value makes >>> sense). Then, isn't it possible that imap_len > 4M and still hit KMALLOC_MAX_SIZE limit? >> >> You are correct, but the proper fix should be to restrict imap_len to >> whatever the maximum value allowed by BFS filesystem layout and reject >> anything beyond it. I will try to remember what it was from the notes >> I made when I wrote BFS back in 1999. Please wait (possibly a few >> days) and I will let you know what those values are. > > Actually, a more accurate sanity check for the value of s_start should > be (patch against 4.16.3): > > --- fs/bfs/inode.c.0 2018-06-14 16:50:52.136792126 +0100 > +++ fs/bfs/inode.c 2018-06-14 16:51:49.344792119 +0100 > @@ -350,7 +350,8 @@ > > s->s_magic = BFS_MAGIC; > > - if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end)) { > + if (le32_to_cpu(bfs_sb->s_start) > le32_to_cpu(bfs_sb->s_end) || > + le32_to_cpu(bfs_sb->s_start) < sizeof(struct bfs_super_block) > + sizeof(struct bfs_dirent)) { > printf("Superblock is corrupted\n"); > goto out1; > } > > However, that doesn't address the issue of the _upper_ limit of > s_start, i.e. it can still get (on an invalid image pretending to be > BFS) arbitrarily large and cause the allocation to fail as you > described. I will dig a bit more (in my memories :) and try to come up > with the check which doesn't reject a valid BFS image and at the same > time restricts s_start (or imap_len which ultimately depends on it) > sufficiently to prevent wild kernel memory allocation requests. > > Btw, I included in the WikiPedia article "Boot File System" a > reference to the original "BFS kernel support" webpage from those > ancient days: http://ftp.linux.org.uk/pub/linux/iBCS/bfs/ Ah, it turned out easier than I thought! The maximum number of inodes of a BFS filesystem is 512, so an inode map cannot be longer than 65 bytes. Well, we can be generous and restrict imap_len to 128 and be done with it :) Namely, if the calculated imap_len turns out to be greater than 128, then something is definitely wrong and the filesystem image should be rejected as corrupted.