Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 06 Nov 2009 18:52:40 +0100 (CET)
From:      Alexander Best <alexbestms@math.uni-muenster.de>
To:        Alexander Best <alexbestms@math.uni-muenster.de>, <gary.jennejohn@freenet.de>, Alexander Best <alexbestms@math.uni-muenster.de>
Cc:        freebsd-hackers@FreeBSD.org, Alex Dupre <ale@FreeBSD.org>
Subject:   Re: rmdir(2) and mkdir(2) both return EISDIR for argument "/"
Message-ID:  <permail-200911061752401e86ffa8000045c7-a_best01@message-id.uni-muenster.de>
In-Reply-To: <permail-200911061742271e86ffa800003d54-a_best01@message-id.uni-muenster.de>

next in thread | previous in thread | raw e-mail | index | archive | help
Alexander Best schrieb am 2009-11-06:
> Gary Jennejohn schrieb am 2009-11-06:
> > On Fri, 06 Nov 2009 17:43:06 +0100 (CET)
> > Alexander Best <alexbestms@math.uni-muenster.de> wrote:

> > > Gary Jennejohn schrieb am 2009-11-06:
> > > > On Fri, 06 Nov 2009 16:32:22 +0100 (CET)
> > > > Alexander Best <alexbestms@math.uni-muenster.de> wrote:

> > > > > Alex Dupre schrieb am 2009-11-06:
> > > > > > Alexander Best ha scritto:
> > > > > > > i dug up this old pr
> > > > > > > http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/59739

> > > > > > I think the EISDIR error is coming from kern/vfs_lookup.c,
> > > > > > lookup()
> > > > > > function with cn_nameptr = "":


> > > > > >         /*
> > > > > >          * Check for degenerate name (e.g. / or "")
> > > > > >          * which is a way of talking about a directory,
> > > > > >          * e.g. like "/." or ".".
> > > > > >          */
> > > > > >         if (cnp->cn_nameptr[0] == '\0') {
> > > > > >                 ...
> > > > > >                 if (cnp->cn_nameiop != LOOKUP) {
> > > > > >                         error = EISDIR;
> > > > > >                         goto bad;
> > > > > >                 }
> > > > > >                 ...

> > > > > thanks a lot for finding the problem in the src. what do you
> > > > > think
> > > > > of the
> > > > > patch attached to this message? after applying it the example
> > > > > code
> > > > > i posted in
> > > > > my previous message returns the following output (instead of
> > > > > EISDIR):

> > > > > rmdir errno: 16 (which is EBUSY)
> > > > > mkdir errno: 17 (which is EEXIST)

> > > > > i don't know if these really are the correct return values,
> > > > > but
> > > > > it's what the
> > > > > originator of the PR requested.


> > > > What if cn_nameiop is != LOOKUP but also neither DELETE nor
> > > > CREATE,
> > > > assuming that case is possible?  I'd leave the original
> > > > if-clause
> > > > at
> > > > the end to catch that.

> > > > ---
> > > > Gary Jennejohn

> > > how about this patch?

> > > 1. i've added "if (cnp->cn_nameiop != LOOKUP)" although i don't
> > >    think it's
> > > necessary since the first blocks should cover all the possible
> > > cases.
> > > 2. i've used rename() to test the case (cnp->cn_nameiop !=
> > >    RENAME).
> > >    is this
> > > correct or does rename() use a combo of DELETE and CREATE?
> > > problem
> > > is that the
> > > rename(2) manual doesn't seem to cover the case that arg 1 is a
> > > mountpoint.
> > > right now EBUSY gets returned if cnp->cn_nameiop != RENAME.
> > > however
> > > BUSY needs
> > > to be added to all manuals which use cnp->cn_nameiop != RENAME
> > > (shouldn't be
> > > too many). or are there any other suggestions what rename()
> > > should
> > > return if
> > > arg 1 is a mountpoint?


> > Hmm. In rename(2) there's

> > [EINVAL]           The from argument is a parent directory of to,
> > or
> > an
> >                    attempt is made to rename `.' or `..'.

> > and a few lines below your patch this case is handled for ISDOTDOT
> > for both RENAME and DELETE.  I don't see off hand where renaming or
> > deleting "." is handled.

> > According to the comment above your patch the case of "/." or "."
> > is
> > being checked, which would seem to correspond to the above part of
> > rename(2), i.e. perhaps EINVAL should be returned for RENAME and
> > DELETE.

> > ---
> > Gary Jennejohn


> that would be an option. however in the case of rmdir(2) EINVAL and
> EBUYS
> would both fit. depends whether be forbid deletion of / because it is
> a
> mountpoint or because / is actually /. and paths ending with . are
> forbidden
> as arg in rmdir(2).

> i guess we have to take a look at the POSIX specs before we can
> decide how to
> handle this.

> also i've discovered that permission checks for / seem to be handled
> differently than any other dir. on my machine /usr is a mountpoint.
> doing
> rmdir /usr returns EACCES as regular user and EBUSY as superuser.
> doing rmdir
> / as regular user however doesn't seem to check permission but
>   returns EBUSY
> right away. but that's not a problem i guess. this is probably
> happening
> because the kern/vfs_lookup.c code is being executed before anything
> else
> (including permission checks).

> i'll have a look what POSIX has to say about the return values. but i
> agree
> with you. returning EINVAL seems logical.

> alex.

ok. here it goes. POSIX says:

rmdir()
[http://www.opengroup.org/onlinepubs/9699919799/functions/rmdir.html#tag_16_618]:
If the directory is the root directory or the current working directory of any
process, it is unspecified whether the function succeeds, or whether it shall
fail and set errno to [EBUSY].

mkdir()
[http://www.opengroup.org/onlinepubs/9699919799/functions/mkdir.html#tag_16_372]:
nothing regarding /.

rename()
[http://www.opengroup.org/onlinepubs/9699919799/functions/rename.html#tag_16_614]:
If either pathname argument refers to a path whose final component is either
dot or dot-dot, rename() shall fail.

so at least rmdir() should return EBUSY. also POSIX defines EBUSY for return()
which isn't documented in our return(2) manual.

alex



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?permail-200911061752401e86ffa8000045c7-a_best01>