Subject: Re: eliminating veriexec #ifdefs in vfs_vnops.c
To: YAMAMOTO Takashi <yamt@mwd.biglobe.ne.jp>
From: Elad Efrat <elad@NetBSD.org>
List: tech-kern
Date: 12/30/2006 00:24:55
YAMAMOTO Takashi wrote:
>> YAMAMOTO Takashi wrote:
>>>>> - it seems quite racy.  i don't know if it's a problem for veriexec, tho.
>>>>>   first and second namei() can see different
>>>>>   pathnames (if userland pathname buffer is modified) and/or
>>>>>   vnode (if any components in the pathname is renamed).
>>>> that's what I was worried about: we do two consequtive namei() calls.
>>>>
>>>> do you think there's a way we could have a single namei() in vn_open()
>>>> to avoid it? or maybe we can copy the pathname to the kernel in
>>>> vn_open(), and then in consequent namei() calls just use that. because
>>>> veriexec doesn't care about permissions but relies on internal tables
>>>> it shouldn't matter, I *think*.
>>> for the pathname problem, i suggested a solution in PR/35278.
>>>
>>> YAMAMOTO Takashi
>> can you be more specific?
> 
> i meant this one.
> 
>> i'd suggest something like this.
>>
>> sys_xxx()
>> {
>> 	pathname_t *pn;
>>
>> 	error = pathname_get(user_pointer, &pn); /* allocate buffer and copyinst
>> 	NDINIT(.., pn, ..);
>>
>> 	pathname_put(pn);
>> }
> 
> YAMAMOTO Takashi

yeah something like that is already in tree. we can just do the
above as:

	pathname_t pn;

	error = pathname_get(ndp->ni_dirp, ndp->ni_segflg, &pn);
	NDINIT(.., UIO_SYSSPACE, pathanme_path(pn), ...);

(I already said I am not going to change namei().)

if this is okay, then we solve one problem. but can't user a race and
replace the path after validation? say:

	1. userland: open(/bin/ls)
	2. kernel: copies in path, '/bin/ls', veriexec check, passes
	3. userland: mv /tmp/evil /bin/ls
	4. kernel: second namei(), proceeds to open the file

classic toctou. ideas?

-e.