* [heads-up] mknod() broken on nfs4
@ 2011-06-21 23:59 Al Viro
2011-06-22 0:23 ` Al Viro
0 siblings, 1 reply; 6+ messages in thread
From: Al Viro @ 2011-06-21 23:59 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-fsdevel
Try mknod(path, 0777, 0); with path leading into nfs4. It
leads to call of nfs_open_create(), with nd->intent.open.file being
uninitialized. Note that LOOKUP_CREATE is set and so's LOOKUP_EXCL,
but LOOKUP_OPEN isn't. So nfs_atomic_lookup() falls through to
nfs_lookup(), which sees that we are doing exclusive create and just
does d_instantiate(dentry, NULL) and do nothing else. And then
we hit ->create()...
Results are ugly - random errors (often -EINVAL or -ENOENT)
and possibility of memory corruption if we manage to generate a request
that won't fail on server.
The really interesting question is what should we pass in
NFS_PROTO(dir)->create() in open_flags. I suspect that you are
checking the wrong flag there (LOOKUP_CREATE instead of LOOKUP_OPEN),
but I'm not sure what *should* be passed when LOOKUP_OPEN is not
there...
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [heads-up] mknod() broken on nfs4
2011-06-21 23:59 [heads-up] mknod() broken on nfs4 Al Viro
@ 2011-06-22 0:23 ` Al Viro
[not found] ` <20110622002359.GC11521-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: Al Viro @ 2011-06-22 0:23 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-fsdevel, linux-nfs
On Wed, Jun 22, 2011 at 12:59:00AM +0100, Al Viro wrote:
> Try mknod(path, 0777, 0); with path leading into nfs4. It
> leads to call of nfs_open_create(), with nd->intent.open.file being
> uninitialized. Note that LOOKUP_CREATE is set and so's LOOKUP_EXCL,
> but LOOKUP_OPEN isn't. So nfs_atomic_lookup() falls through to
> nfs_lookup(), which sees that we are doing exclusive create and just
> does d_instantiate(dentry, NULL) and do nothing else. And then
> we hit ->create()...
>
> Results are ugly - random errors (often -EINVAL or -ENOENT)
> and possibility of memory corruption if we manage to generate a request
> that won't fail on server.
>
> The really interesting question is what should we pass in
> NFS_PROTO(dir)->create() in open_flags. I suspect that you are
> checking the wrong flag there (LOOKUP_CREATE instead of LOOKUP_OPEN),
> but I'm not sure what *should* be passed when LOOKUP_OPEN is not
> there...
Argh... Alas, it's not that simple. Even though the code in nfs_open_create()
and nfs4_proc_create() seems to imply that passing NULL as ctx is OK and
expected, in reality that blows up since we end up with NULL cred passed
to nfs4_do_open(), which oopses on attempt to do get_rpccred(NULL) from
nfs4_get_state_owner().
Folks, how is that code supposed to work? lookup_instantiate_filp() should
*not* be called by vfs_create() triggered by mknod(). And I don't see any
codepath in nfs_open_create() that would not step into that. ctx == NULL
is the only thing that would skip it and it definitely isn't survivable
by nfs4_proc_create(). Moreover, we need the rpc_cred to come from somewhere
and nfs4_proc_create() needs to get it from us.
BTW, AFAICS fuse will oops in such situation as well...
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [heads-up] mknod() broken on nfs4
[not found] ` <20110622002359.GC11521-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
@ 2011-06-22 23:00 ` Trond Myklebust
[not found] ` <1308783620.25875.30.camel-SyLVLa/KEI9HwK5hSS5vWB2eb7JE58TQ@public.gmane.org>
0 siblings, 1 reply; 6+ messages in thread
From: Trond Myklebust @ 2011-06-22 23:00 UTC (permalink / raw)
To: Al Viro
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA
On Wed, 2011-06-22 at 01:23 +0100, Al Viro wrote:
> On Wed, Jun 22, 2011 at 12:59:00AM +0100, Al Viro wrote:
> > Try mknod(path, 0777, 0); with path leading into nfs4. It
> > leads to call of nfs_open_create(), with nd->intent.open.file being
> > uninitialized. Note that LOOKUP_CREATE is set and so's LOOKUP_EXCL,
> > but LOOKUP_OPEN isn't. So nfs_atomic_lookup() falls through to
> > nfs_lookup(), which sees that we are doing exclusive create and just
> > does d_instantiate(dentry, NULL) and do nothing else. And then
> > we hit ->create()...
> >
> > Results are ugly - random errors (often -EINVAL or -ENOENT)
> > and possibility of memory corruption if we manage to generate a request
> > that won't fail on server.
> >
> > The really interesting question is what should we pass in
> > NFS_PROTO(dir)->create() in open_flags. I suspect that you are
> > checking the wrong flag there (LOOKUP_CREATE instead of LOOKUP_OPEN),
> > but I'm not sure what *should* be passed when LOOKUP_OPEN is not
> > there...
>
> Argh... Alas, it's not that simple. Even though the code in nfs_open_create()
> and nfs4_proc_create() seems to imply that passing NULL as ctx is OK and
> expected, in reality that blows up since we end up with NULL cred passed
> to nfs4_do_open(), which oopses on attempt to do get_rpccred(NULL) from
> nfs4_get_state_owner().
>
> Folks, how is that code supposed to work? lookup_instantiate_filp() should
> *not* be called by vfs_create() triggered by mknod(). And I don't see any
> codepath in nfs_open_create() that would not step into that. ctx == NULL
> is the only thing that would skip it and it definitely isn't survivable
> by nfs4_proc_create(). Moreover, we need the rpc_cred to come from somewhere
> and nfs4_proc_create() needs to get it from us.
I agree that we should error out gracefully instead of blowing up, but I
fail to see why we want to support mknod for a regular file: it's not a
posix interface, nor is it substantially different from open(O_CREAT|
O_EXCL|O_NOFOLLOW). What is it's purpose?
> BTW, AFAICS fuse will oops in such situation as well...
--
Trond Myklebust
Linux NFS client maintainer
NetApp
Trond.Myklebust-HgOvQuBEEgTQT0dZR+AlfA@public.gmane.org
www.netapp.com
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [heads-up] mknod() broken on nfs4
[not found] ` <1308783620.25875.30.camel-SyLVLa/KEI9HwK5hSS5vWB2eb7JE58TQ@public.gmane.org>
@ 2011-06-22 23:19 ` Al Viro
2011-06-23 2:48 ` Al Viro
2011-06-23 5:37 ` Al Viro
0 siblings, 2 replies; 6+ messages in thread
From: Al Viro @ 2011-06-22 23:19 UTC (permalink / raw)
To: Trond Myklebust
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-nfs-u79uwXL29TY76Z2rM5mHXA
On Wed, Jun 22, 2011 at 07:00:20PM -0400, Trond Myklebust wrote:
> > Folks, how is that code supposed to work? lookup_instantiate_filp() should
> > *not* be called by vfs_create() triggered by mknod(). And I don't see any
> > codepath in nfs_open_create() that would not step into that. ctx == NULL
> > is the only thing that would skip it and it definitely isn't survivable
> > by nfs4_proc_create(). Moreover, we need the rpc_cred to come from somewhere
> > and nfs4_proc_create() needs to get it from us.
>
> I agree that we should error out gracefully instead of blowing up, but I
> fail to see why we want to support mknod for a regular file: it's not a
> posix interface, nor is it substantially different from open(O_CREAT|
> O_EXCL|O_NOFOLLOW). What is it's purpose?
It always worked that way, all the way back to Unix v6 (and I'm fairly sure
to earlier than that; don't have v5 kernel source, unfortunately). Worked
that way in Linux since 0.02/0.03/0.10, when Linus first added mknod(2)
(presumably 0.01 had been tested with /dev populated by Minix ;-)
As for POSIX, what it says is
The only portable use of mknod() is to create a FIFO-special file.
If mode is not S_IFIFO or dev is not 0, the behaviour of mknod() is
unspecified.
and we support it for all non-directories. Always had...
Note that the right thing to do is to issue CLOSE and _not_ call
lookup_instantiate_filp() if we are called from sys_mknodat(). We don't
want to leak stateid...
--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [heads-up] mknod() broken on nfs4
2011-06-22 23:19 ` Al Viro
@ 2011-06-23 2:48 ` Al Viro
2011-06-23 5:37 ` Al Viro
1 sibling, 0 replies; 6+ messages in thread
From: Al Viro @ 2011-06-23 2:48 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-fsdevel, linux-nfs
On Thu, Jun 23, 2011 at 12:19:46AM +0100, Al Viro wrote:
> It always worked that way, all the way back to Unix v6 (and I'm fairly sure
> to earlier than that; don't have v5 kernel source, unfortunately). Worked
> that way in Linux since 0.02/0.03/0.10, when Linus first added mknod(2)
> (presumably 0.01 had been tested with /dev populated by Minix ;-)
After looking around on the net: in v3 kernel, ken/sys2.c:
mknod()
{
int *ip;
extern uchar;
if(suser()) {
ip = namei(&uchar, 1);
if(ip != NULL) {
u.u_error = EEXIST;
goto out;
}
}
if(u.u_error)
return;
ip = maknode(u.u_arg[1]);
ip->i_addr[0] = u.u_arg[2];
out:
iput(ip);
}
IOW, mknod(path, 0777, 0) will, indeed, create a regular file. Root-only,
back then.
; ls -l ken/sys2.c
-rw-r--r-- 1 al al 3060 Aug 30 1973 ken/sys2.c
v3 manpages don't mention mknod(2) at all; it *is* wired in syscall table
(syscall 14). Section 2 manpages give syscall numbers; what they have for
#14 is makdir (not mentioned by that name in the kernel, described as
creating an empty directory with given pathname and mode sans . and ..
links - i.e. exactly what mknod(2) did all the way to v7 when given
S_IFDIR | something).
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [heads-up] mknod() broken on nfs4
2011-06-22 23:19 ` Al Viro
2011-06-23 2:48 ` Al Viro
@ 2011-06-23 5:37 ` Al Viro
1 sibling, 0 replies; 6+ messages in thread
From: Al Viro @ 2011-06-23 5:37 UTC (permalink / raw)
To: Trond Myklebust; +Cc: linux-fsdevel, linux-nfs
On Thu, Jun 23, 2011 at 12:19:46AM +0100, Al Viro wrote:
> It always worked that way, all the way back to Unix v6 (and I'm fairly sure
> to earlier than that; don't have v5 kernel source, unfortunately). Worked
> that way in Linux since 0.02/0.03/0.10, when Linus first added mknod(2)
> (presumably 0.01 had been tested with /dev populated by Minix ;-)
>
> As for POSIX, what it says is
> The only portable use of mknod() is to create a FIFO-special file.
> If mode is not S_IFIFO or dev is not 0, the behaviour of mknod() is
> unspecified.
> and we support it for all non-directories. Always had...
>
> Note that the right thing to do is to issue CLOSE and _not_ call
> lookup_instantiate_filp() if we are called from sys_mknodat(). We don't
> want to leak stateid...
OK... See #untested in vfs-2.6.git; the last 5 commits there. The actual
fixes are in the last one; to get rid of the dependency on the previous
we'd just need to pass open_flags as additional argument to
nameidata_to_nfs_open_context() (like untested@{1}, but without removal
of nameidata argument - that part depends on earlier commits and is, IMO,
a good idea anyway).
It seems to work here. Testing and comments would be welcome...
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2011-06-23 5:37 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-06-21 23:59 [heads-up] mknod() broken on nfs4 Al Viro
2011-06-22 0:23 ` Al Viro
[not found] ` <20110622002359.GC11521-3bDd1+5oDREiFSDQTTA3OLVCufUGDwFn@public.gmane.org>
2011-06-22 23:00 ` Trond Myklebust
[not found] ` <1308783620.25875.30.camel-SyLVLa/KEI9HwK5hSS5vWB2eb7JE58TQ@public.gmane.org>
2011-06-22 23:19 ` Al Viro
2011-06-23 2:48 ` Al Viro
2011-06-23 5:37 ` Al Viro
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).