* fs: use-after-free in link_path_walk @ 2016-01-22 22:33 Dmitry Vyukov 2016-01-22 23:08 ` Al Viro 0 siblings, 1 reply; 3+ messages in thread From: Dmitry Vyukov @ 2016-01-22 22:33 UTC (permalink / raw) To: Alexander Viro, linux-fsdevel@vger.kernel.org, LKML, Hugh Dickins, linux-mm@kvack.org Cc: syzkaller, Kostya Serebryany, Alexander Potapenko, Sasha Levin, Eric Dumazet Hello, The following program triggers a use-after-free in link_path_walk: https://gist.githubusercontent.com/dvyukov/fc0da4b914d607ba8129/raw/b761243c44106d74f2173745132c82d179cbdc58/gistfile1.txt ================================================================== BUG: KASAN: use-after-free in link_path_walk+0xe13/0x1030 at addr ffff88005f29d6e2 Read of size 1 by task syz-executor/29494 ============================================================================= BUG kmalloc-16 (Not tainted): kasan: bad access detected ----------------------------------------------------------------------------- INFO: Allocated in shmem_symlink+0x18c/0x600 age=2 cpu=2 pid=29504 [< none >] __kmalloc_track_caller+0x28e/0x320 mm/slub.c:4068 [< none >] kmemdup+0x24/0x50 mm/util.c:113 [< none >] shmem_symlink+0x18c/0x600 mm/shmem.c:2548 [< none >] vfs_symlink+0x218/0x3a0 fs/namei.c:3997 [< inline >] SYSC_symlinkat fs/namei.c:4024 [< none >] SyS_symlinkat+0x1ab/0x230 fs/namei.c:4004 [< none >] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 INFO: Freed in shmem_evict_inode+0xa6/0x420 age=12 cpu=2 pid=29504 [< none >] kfree+0x2b7/0x2e0 mm/slub.c:3664 [< none >] shmem_evict_inode+0xa6/0x420 mm/shmem.c:705 [< none >] evict+0x22c/0x500 fs/inode.c:542 [< inline >] iput_final fs/inode.c:1477 [< none >] iput+0x45f/0x860 fs/inode.c:1504 [< none >] do_unlinkat+0x3c0/0x830 fs/namei.c:3939 [< inline >] SYSC_unlink fs/namei.c:3980 [< none >] SyS_unlink+0x1a/0x20 fs/namei.c:3978 [< none >] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 INFO: Slab 0xffffea00017ca700 objects=16 used=12 fp=0xffff88005f29d6e0 flags=0x5fffc0000004080 INFO: Object 0xffff88005f29d6e0 @offset=5856 fp=0xffff88005f29d310 CPU: 3 PID: 29494 Comm: syz-executor Tainted: G B 4.4.0+ #276 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS Bochs 01/01/2011 00000000ffffffff ffff88000056fa08 ffffffff82999e2d ffff88003e807900 ffff88005f29d6e0 ffff88005f29c000 ffff88000056fa38 ffffffff81757354 ffff88003e807900 ffffea00017ca700 ffff88005f29d6e0 ffff88005f29d6e2 Call Trace: [<ffffffff8176092e>] __asan_report_load1_noabort+0x3e/0x40 mm/kasan/report.c:292 [<ffffffff817deb33>] link_path_walk+0xe13/0x1030 fs/namei.c:1913 [<ffffffff817df049>] path_lookupat+0x1a9/0x450 fs/namei.c:2120 [<ffffffff817e6aad>] filename_lookup+0x18d/0x370 fs/namei.c:2155 [<ffffffff817e6dd0>] user_path_at_empty+0x40/0x50 fs/namei.c:2393 [< inline >] user_path_at include/linux/namei.h:52 [<ffffffff8185ab29>] do_utimes+0x209/0x280 fs/utimes.c:169 [< inline >] SYSC_utimensat fs/utimes.c:200 [<ffffffff8185ada3>] SyS_utimensat+0xd3/0x130 fs/utimes.c:185 [<ffffffff86336c36>] entry_SYSCALL_64_fastpath+0x16/0x7a arch/x86/entry/entry_64.S:185 ================================================================== On commit 30f05309bde49295e02e45c7e615f73aa4e0ccc2 (Jan 20). -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: fs: use-after-free in link_path_walk 2016-01-22 22:33 fs: use-after-free in link_path_walk Dmitry Vyukov @ 2016-01-22 23:08 ` Al Viro 2016-02-05 13:33 ` Dmitry Vyukov 0 siblings, 1 reply; 3+ messages in thread From: Al Viro @ 2016-01-22 23:08 UTC (permalink / raw) To: Dmitry Vyukov Cc: linux-fsdevel@vger.kernel.org, LKML, Hugh Dickins, linux-mm@kvack.org, syzkaller, Kostya Serebryany, Alexander Potapenko, Sasha Levin, Eric Dumazet On Fri, Jan 22, 2016 at 11:33:09PM +0100, Dmitry Vyukov wrote: > Hello, > > The following program triggers a use-after-free in link_path_walk: > https://gist.githubusercontent.com/dvyukov/fc0da4b914d607ba8129/raw/b761243c44106d74f2173745132c82d179cbdc58/gistfile1.txt Hmm... Actually, I wonder if that had been triggerable since May. What happens is that unlike struct inode itself, shmem info->symlink is freed immediately, without an RCU delay. Easy to fix, fortunately... Could you check if the patch below fixes that for you? diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h index a43f41c..4d4780c 100644 --- a/include/linux/shmem_fs.h +++ b/include/linux/shmem_fs.h @@ -15,10 +15,7 @@ struct shmem_inode_info { unsigned int seals; /* shmem seals */ unsigned long flags; unsigned long alloced; /* data pages alloced to file */ - union { - unsigned long swapped; /* subtotal assigned to swap */ - char *symlink; /* unswappable short symlink */ - }; + unsigned long swapped; /* subtotal assigned to swap */ struct shared_policy policy; /* NUMA memory alloc policy */ struct list_head swaplist; /* chain of maybes on swap */ struct simple_xattrs xattrs; /* list of xattrs */ diff --git a/mm/shmem.c b/mm/shmem.c index 38c5e72..440e2a7 100644 --- a/mm/shmem.c +++ b/mm/shmem.c @@ -701,8 +701,7 @@ static void shmem_evict_inode(struct inode *inode) list_del_init(&info->swaplist); mutex_unlock(&shmem_swaplist_mutex); } - } else - kfree(info->symlink); + } simple_xattrs_free(&info->xattrs); WARN_ON(inode->i_blocks); @@ -2549,13 +2548,12 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s info = SHMEM_I(inode); inode->i_size = len-1; if (len <= SHORT_SYMLINK_LEN) { - info->symlink = kmemdup(symname, len, GFP_KERNEL); - if (!info->symlink) { + inode->i_link = kmemdup(symname, len, GFP_KERNEL); + if (!inode->i_link) { iput(inode); return -ENOMEM; } inode->i_op = &shmem_short_symlink_operations; - inode->i_link = info->symlink; } else { inode_nohighmem(inode); error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); @@ -3132,6 +3130,7 @@ static struct inode *shmem_alloc_inode(struct super_block *sb) static void shmem_destroy_callback(struct rcu_head *head) { struct inode *inode = container_of(head, struct inode, i_rcu); + kfree(inode->i_link); kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); } -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: fs: use-after-free in link_path_walk 2016-01-22 23:08 ` Al Viro @ 2016-02-05 13:33 ` Dmitry Vyukov 0 siblings, 0 replies; 3+ messages in thread From: Dmitry Vyukov @ 2016-02-05 13:33 UTC (permalink / raw) To: Al Viro Cc: linux-fsdevel@vger.kernel.org, LKML, Hugh Dickins, linux-mm@kvack.org, syzkaller, Kostya Serebryany, Alexander Potapenko, Sasha Levin, Eric Dumazet On Sat, Jan 23, 2016 at 12:08 AM, Al Viro <viro@zeniv.linux.org.uk> wrote: > On Fri, Jan 22, 2016 at 11:33:09PM +0100, Dmitry Vyukov wrote: >> Hello, >> >> The following program triggers a use-after-free in link_path_walk: >> https://gist.githubusercontent.com/dvyukov/fc0da4b914d607ba8129/raw/b761243c44106d74f2173745132c82d179cbdc58/gistfile1.txt > > Hmm... Actually, I wonder if that had been triggerable since May. What > happens is that unlike struct inode itself, shmem info->symlink is > freed immediately, without an RCU delay. Easy to fix, fortunately... > > Could you check if the patch below fixes that for you? Yes, it fixes the crash for me. Thanks > diff --git a/include/linux/shmem_fs.h b/include/linux/shmem_fs.h > index a43f41c..4d4780c 100644 > --- a/include/linux/shmem_fs.h > +++ b/include/linux/shmem_fs.h > @@ -15,10 +15,7 @@ struct shmem_inode_info { > unsigned int seals; /* shmem seals */ > unsigned long flags; > unsigned long alloced; /* data pages alloced to file */ > - union { > - unsigned long swapped; /* subtotal assigned to swap */ > - char *symlink; /* unswappable short symlink */ > - }; > + unsigned long swapped; /* subtotal assigned to swap */ > struct shared_policy policy; /* NUMA memory alloc policy */ > struct list_head swaplist; /* chain of maybes on swap */ > struct simple_xattrs xattrs; /* list of xattrs */ > diff --git a/mm/shmem.c b/mm/shmem.c > index 38c5e72..440e2a7 100644 > --- a/mm/shmem.c > +++ b/mm/shmem.c > @@ -701,8 +701,7 @@ static void shmem_evict_inode(struct inode *inode) > list_del_init(&info->swaplist); > mutex_unlock(&shmem_swaplist_mutex); > } > - } else > - kfree(info->symlink); > + } > > simple_xattrs_free(&info->xattrs); > WARN_ON(inode->i_blocks); > @@ -2549,13 +2548,12 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s > info = SHMEM_I(inode); > inode->i_size = len-1; > if (len <= SHORT_SYMLINK_LEN) { > - info->symlink = kmemdup(symname, len, GFP_KERNEL); > - if (!info->symlink) { > + inode->i_link = kmemdup(symname, len, GFP_KERNEL); > + if (!inode->i_link) { > iput(inode); > return -ENOMEM; > } > inode->i_op = &shmem_short_symlink_operations; > - inode->i_link = info->symlink; > } else { > inode_nohighmem(inode); > error = shmem_getpage(inode, 0, &page, SGP_WRITE, NULL); > @@ -3132,6 +3130,7 @@ static struct inode *shmem_alloc_inode(struct super_block *sb) > static void shmem_destroy_callback(struct rcu_head *head) > { > struct inode *inode = container_of(head, struct inode, i_rcu); > + kfree(inode->i_link); > kmem_cache_free(shmem_inode_cachep, SHMEM_I(inode)); > } > -- To unsubscribe, send a message with 'unsubscribe linux-mm' in the body to majordomo@kvack.org. For more info on Linux MM, see: http://www.linux-mm.org/ . Don't email: <a href=mailto:"dont@kvack.org"> email@kvack.org </a> ^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2016-02-05 13:33 UTC | newest] Thread overview: 3+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2016-01-22 22:33 fs: use-after-free in link_path_walk Dmitry Vyukov 2016-01-22 23:08 ` Al Viro 2016-02-05 13:33 ` Dmitry Vyukov
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).