Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs

Pull symlink fixes from Al Viro:
"The ceph fix is already in mainline, Daniel's bpf fix is in bpf tree
(1da6c4d9140c "bpf: fix use after free in bpf_evict_inode"), the rest
is in here"

* 'fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/viro/vfs:
debugfs: fix use-after-free on symlink traversal
ubifs: fix use-after-free on symlink traversal
jffs2: fix use-after-free on symlink traversal

+14 -13
+9 -4
fs/debugfs/inode.c
··· 163 163 return 0; 164 164 } 165 165 166 - static void debugfs_evict_inode(struct inode *inode) 166 + static void debugfs_i_callback(struct rcu_head *head) 167 167 { 168 - truncate_inode_pages_final(&inode->i_data); 169 - clear_inode(inode); 168 + struct inode *inode = container_of(head, struct inode, i_rcu); 170 169 if (S_ISLNK(inode->i_mode)) 171 170 kfree(inode->i_link); 171 + free_inode_nonrcu(inode); 172 + } 173 + 174 + static void debugfs_destroy_inode(struct inode *inode) 175 + { 176 + call_rcu(&inode->i_rcu, debugfs_i_callback); 172 177 } 173 178 174 179 static const struct super_operations debugfs_super_operations = { 175 180 .statfs = simple_statfs, 176 181 .remount_fs = debugfs_remount, 177 182 .show_options = debugfs_show_options, 178 - .evict_inode = debugfs_evict_inode, 183 + .destroy_inode = debugfs_destroy_inode, 179 184 }; 180 185 181 186 static void debugfs_release_dentry(struct dentry *dentry)
-5
fs/jffs2/readinode.c
··· 1414 1414 1415 1415 jffs2_kill_fragtree(&f->fragtree, deleted?c:NULL); 1416 1416 1417 - if (f->target) { 1418 - kfree(f->target); 1419 - f->target = NULL; 1420 - } 1421 - 1422 1417 fds = f->dents; 1423 1418 while(fds) { 1424 1419 fd = fds;
+4 -1
fs/jffs2/super.c
··· 47 47 static void jffs2_i_callback(struct rcu_head *head) 48 48 { 49 49 struct inode *inode = container_of(head, struct inode, i_rcu); 50 - kmem_cache_free(jffs2_inode_cachep, JFFS2_INODE_INFO(inode)); 50 + struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 51 + 52 + kfree(f->target); 53 + kmem_cache_free(jffs2_inode_cachep, f); 51 54 } 52 55 53 56 static void jffs2_destroy_inode(struct inode *inode)
+1 -3
fs/ubifs/super.c
··· 276 276 { 277 277 struct inode *inode = container_of(head, struct inode, i_rcu); 278 278 struct ubifs_inode *ui = ubifs_inode(inode); 279 + kfree(ui->data); 279 280 kmem_cache_free(ubifs_inode_slab, ui); 280 281 } 281 282 282 283 static void ubifs_destroy_inode(struct inode *inode) 283 284 { 284 - struct ubifs_inode *ui = ubifs_inode(inode); 285 - 286 - kfree(ui->data); 287 285 call_rcu(&inode->i_rcu, ubifs_i_callback); 288 286 } 289 287