KASAN: use-after-free Read in task_is_descendant

Oleg Nesterov oleg at redhat.com
Mon Oct 22 09:54:39 UTC 2018


On 10/21, Tetsuo Handa wrote:
>
> On 2018/10/21 16:10, syzbot wrote:
> > BUG: KASAN: use-after-free in __read_once_size include/linux/compiler.h:188 [inline]
> > BUG: KASAN: use-after-free in task_is_descendant.part.2+0x610/0x670 security/yama/yama_lsm.c:295
> > Read of size 8 at addr ffff8801c4666b20 by task syz-executor3/12722
> >
> > CPU: 1 PID: 12722 Comm: syz-executor3 Not tainted 4.19.0-rc8+ #70
> > Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
> > Call Trace:
> >  __dump_stack lib/dump_stack.c:77 [inline]
> >  dump_stack+0x1c4/0x2b4 lib/dump_stack.c:113
> >  print_address_description.cold.8+0x9/0x1ff mm/kasan/report.c:256
> >  kasan_report_error mm/kasan/report.c:354 [inline]
> >  kasan_report.cold.9+0x242/0x309 mm/kasan/report.c:412
> >  __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433
> >  __read_once_size include/linux/compiler.h:188 [inline]
> >  task_is_descendant.part.2+0x610/0x670 security/yama/yama_lsm.c:295
>
> Do we need to hold
>
>   write_lock_irq(&tasklist_lock);
>
> rather than
>
>   rcu_read_lock();
>
> when accessing
>
>   "struct task_struct"->real_parent

Well, if "task" is stable (can't exit), then I think

	rcu_dereference(task->real_parent)

is fine, we know that ->real_parent did not pass exit_notif() yet.

However, task_is_descendant() looks unnecessarily complicated, it could be

	static int task_is_descendant(struct task_struct *parent,
				      struct task_struct *child)
	{
		int rc = 0;
		struct task_struct *walker;

		if (!parent || !child)
			return 0;

		rcu_read_lock();
		for (walker = child; walker->pid; walker = rcu_dereference(walker->real_parent))
			if (same_thread_group(parent, walker)) {
				rc = 1;
				break;
			}
		rcu_read_unlock();

		return rc;
	}

And again, I do not know how/if yama ensures that child is rcu-protected, perhaps
task_is_descendant() needs to check pid_alive(child) right after rcu_read_lock() ?

Oleg.




More information about the Linux-security-module-archive mailing list