Message ID | 20180206190938.172792-1-jinqian@android.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On Tue, Feb 06, 2018 at 11:09:37AM -0800, Jin Qian wrote: > From: Jin Qian <jinqian@google.com> > > partial backport from 21fc61c73c3903c4c312d0802da01ec2b323d174 upstream > to v4.4 to prevent virt_to_page on highmem. > > ext4_encrypted_follow_link uses kmap() for cpage > caddr = kmap(cpage); > > _ext4_fname_disk_to_usr calls virt_to_page on the kmapped address. > _ext4_fname_disk_to_usr() > ext4_fname_decrypt() > sg_init_one() > sg_init_one(&src_sg, iname->name, iname->len); > sg_set_page(sg, virt_to_page(buf), buflen, offset_in_page(buf)); > > Cc: stable@vger.kernel.org > Signed-off-by: Al Viro <viro@zeniv.linux.org.uk> > Signed-off-by: Jin Qian <jinqian@google.com> > Signed-off-by: Jin Qian <jinqian@android.com> Ted, any objection to this patch? thanks, greg k-h
On Tue, Feb 06, 2018 at 12:39:53PM -0800, Greg KH wrote: > On Tue, Feb 06, 2018 at 11:09:37AM -0800, Jin Qian wrote: > > From: Jin Qian <jinqian@google.com> > > > > partial backport from 21fc61c73c3903c4c312d0802da01ec2b323d174 upstream > > to v4.4 to prevent virt_to_page on highmem. > > Ted, any objection to this patch? No objections with my ext4 hat on. It should be noted though that this is a partial backport because it only fixes ext4, while Al's original upstream fix addressed a much larger set of file systems. In the Android kernel the f2fs fix had been backported separately. But for the upstream kernel, it *might* be the case that we should try backporting the original commit so that in case there is some other general purpose distribution decides (a) to base their system on 4.4, and (b) support a 32-bit kernel, they get the more general bug fixes which applies for btrfs, isofs, ocfs2, nfs, etc. I haevn't been paying attention to what LTS kernels general purpose distro's are using, so I don't know how important this would be. And if there are companies like Cloudflare which are using upstream LTS kernel, it seems unlikely they would want to use a 32-bit kernel, so.... shrug. Greg, I'll let you decide if you want to backport the full commit or not. (We had a similar discussion on the AOSP kernel, and came to the conclusion that we only needed to make the patch support ext4. No one was going to test the other file systems besides ext4 and f2fs, anyway. But the calculus might be different might be different for the general upstream LTS kernel.) - Ted
On Tue, Feb 06, 2018 at 06:11:49PM -0500, Theodore Ts'o wrote: > On Tue, Feb 06, 2018 at 12:39:53PM -0800, Greg KH wrote: > > On Tue, Feb 06, 2018 at 11:09:37AM -0800, Jin Qian wrote: > > > From: Jin Qian <jinqian@google.com> > > > > > > partial backport from 21fc61c73c3903c4c312d0802da01ec2b323d174 upstream > > > to v4.4 to prevent virt_to_page on highmem. > > > > Ted, any objection to this patch? > > No objections with my ext4 hat on. > > It should be noted though that this is a partial backport because it > only fixes ext4, while Al's original upstream fix addressed a much > larger set of file systems. In the Android kernel the f2fs fix had > been backported separately. But for the upstream kernel, it *might* > be the case that we should try backporting the original commit so that > in case there is some other general purpose distribution decides (a) > to base their system on 4.4, and (b) support a 32-bit kernel, they get > the more general bug fixes which applies for btrfs, isofs, ocfs2, nfs, > etc. > > I haevn't been paying attention to what LTS kernels general purpose > distro's are using, so I don't know how important this would be. And > if there are companies like Cloudflare which are using upstream LTS > kernel, it seems unlikely they would want to use a 32-bit kernel, > so.... shrug. Greg, I'll let you decide if you want to backport the > full commit or not. > > (We had a similar discussion on the AOSP kernel, and came to the > conclusion that we only needed to make the patch support ext4. No one > was going to test the other file systems besides ext4 and f2fs, > anyway. But the calculus might be different might be different for > the general upstream LTS kernel.) > Well, the main point of backporting this change is to fix symlink decryption on 32-bit systems. So, it would be needed on both ext4 and f2fs. Jin, it might be a good idea to fix f2fs in this patch at well, since unlike the AOSP kernels, the LTS kernels do not have the latest f2fs backported to them. I don't think backporting this change for other filesystems is particularly important, since if I understand correctly, the reasons that Al made the change originally were: - to allow following symlinks in RCU mode, but that's not implemented in old kernels - to prevent a process from using up all kmaps and deadlocking the system, which I'm not sure is a real problem (someone would need to try to put together a reproducer), but if so it would probably just be a local device of service. Also if we actually backported the full commit there are follow-on fixes such as e8ecde25f5e that would be needed as well but might be missed. Thanks, - Eric
On Tue, Feb 06, 2018 at 03:38:09PM -0800, Eric Biggers wrote: > I don't think backporting this change for other filesystems is particularly > important, since if I understand correctly, the reasons that Al made the change > originally were: > > - to allow following symlinks in RCU mode, but that's not implemented in old > kernels Yup. > - to prevent a process from using up all kmaps and deadlocking the system, which > I'm not sure is a real problem (someone would need to try to put together a > reproducer), but if so it would probably just be a local device of service. .. and *that's* only a problem on 32-bit systems. And aside from Android, it's unclear to me how much we need to support 32-bit systems on upstream LTS kernels. I suppose there might be Rasperry PI's which are 32-bits and which might want to use btrfs. Personally I'm not sure we should care all that much, but others who care more about LTS kernels and 32-bit systems might have a different opinion. > Also if we actually backported the full commit there are follow-on fixes such as > e8ecde25f5e that would be needed as well but might be missed. Good point. - Ted
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c index 4df1cb19a243..f0cabc8c96cb 100644 --- a/fs/ext4/inode.c +++ b/fs/ext4/inode.c @@ -4417,6 +4417,7 @@ struct inode *ext4_iget(struct super_block *sb, unsigned long ino) inode->i_op = &ext4_symlink_inode_operations; ext4_set_aops(inode); } + inode_nohighmem(inode); } else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) { inode->i_op = &ext4_special_inode_operations; diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c index 4c36dca486cc..32960b3ecd4f 100644 --- a/fs/ext4/namei.c +++ b/fs/ext4/namei.c @@ -3151,6 +3151,7 @@ static int ext4_symlink(struct inode *dir, if ((disk_link.len > EXT4_N_BLOCKS * 4)) { if (!encryption_required) inode->i_op = &ext4_symlink_inode_operations; + inode_nohighmem(inode); ext4_set_aops(inode); /* * We cannot call page_symlink() with transaction started diff --git a/fs/ext4/symlink.c b/fs/ext4/symlink.c index e8e7af62ac95..287c3980fa0b 100644 --- a/fs/ext4/symlink.c +++ b/fs/ext4/symlink.c @@ -45,7 +45,7 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook cpage = read_mapping_page(inode->i_mapping, 0, NULL); if (IS_ERR(cpage)) return ERR_CAST(cpage); - caddr = kmap(cpage); + caddr = page_address(cpage); caddr[size] = 0; } @@ -75,16 +75,12 @@ static const char *ext4_encrypted_follow_link(struct dentry *dentry, void **cook /* Null-terminate the name */ if (res <= plen) paddr[res] = '\0'; - if (cpage) { - kunmap(cpage); + if (cpage) page_cache_release(cpage); - } return *cookie = paddr; errout: - if (cpage) { - kunmap(cpage); + if (cpage) page_cache_release(cpage); - } kfree(paddr); return ERR_PTR(res); } diff --git a/fs/inode.c b/fs/inode.c index b0edef500590..b95615f3fc50 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -2028,3 +2028,9 @@ void inode_set_flags(struct inode *inode, unsigned int flags, new_flags) != old_flags)); } EXPORT_SYMBOL(inode_set_flags); + +void inode_nohighmem(struct inode *inode) +{ + mapping_set_gfp_mask(inode->i_mapping, GFP_USER); +} +EXPORT_SYMBOL(inode_nohighmem); diff --git a/include/linux/fs.h b/include/linux/fs.h index c8decb7075d6..f746a59fcc88 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -3066,5 +3066,6 @@ static inline bool dir_relax(struct inode *inode) } extern bool path_noexec(const struct path *path); +extern void inode_nohighmem(struct inode *inode); #endif /* _LINUX_FS_H */