Bug #1701

mkdir / returns EPERM instead of EEXIST (related to pkg_add)

Added by c.turner about 4 years ago. Updated over 3 years ago.

Status:ClosedStart date:
Priority:NormalDue date:
Assignee:c.turner% Done:

0%

Category:-
Target version:-

Description

Hello all,

sent this to bugs@ instead of kernel@ so it gets tracked..

revamping my dev setup - which includes a number of tools which
interface with pkg_add -

long story short - anyone know where to find why in
the code 'mkdir /' fails with 'EPERM' ?

Having trouble finding this, specifically..

(yes, I tried with syscall - this is how I found the bug)

It seems like this behavior is incorrect w/r/t posix -
or at least undefined .. I'd think it should return EEXIST ..

http://www.opengroup.org/onlinepubs/000095399/functions/mkdir.html

The pkgsrc connection is that packages generated with install prefix
of '/' (e.g. for packaged config files) fail as pkg_add tries to 'mkdir
/' .. and fails for this case as it is unexpected.

I've been using packages that do this since 1.8 or so - with a hiatus
from 2.0-2.4 era - in the meantime joerg? changed the pkgsrc tools to
internally use their own mkdir implementation, but this doesn't appear
to be related, as the regular mkdir utility fails with the same error,
and the previous pkg_add implementation had similar behaviour ..

so my theory is it happened somewhere in the VFS reworking to support
hammer.. but not sure when/where.

Yes, I know it's silly to 'mkdir /' - so perhaps this should be fixed in
pkgsrc instead.. but in any case, if this isn't up to spec, it should
be fixed here also..

unfortunately dont have any other BSD based systems around at the moment
to cross check - linux reports 'EEXIST' ..

Once I know where to fix it, I have no problem working up a patch..
and if my leaf account is still functional after my journey into
the abyss I will get up to speed with git and make the commit..

just need a bit of pointers (HA!) in the right direction I suppose..

Thanks,

- Chris

nlookup-mkdir.patch Magnifier (952 Bytes) c.turner, 03/29/2010 02:42 AM

History

#1 Updated by c.turner about 4 years ago

Forgot to mention I am still using FFS root if that makes any difference...

Thanks,

- Chris

#2 Updated by alexh about 4 years ago

I can't take care of this this week, so I'll just give you the pointers:
The following lines in kern/vfs_nlookup.c are probably causing your issue. this
is called from many points, including from kern_mkdir to check if a directory
already exists. If nlookup returns EPERM, kern_mkdir just returns that.

471 /*
472 * Fast-track termination. There is no parent directory of
473 * the root in the same mount from the point of view of
474 * the caller so return EPERM if NLC_REFDVP is specified.
475 * e.g. 'rmdir /' is not allowed.
476 */
477 if (*ptr == 0) {
478 if (nd->nl_flags & NLC_REFDVP)
479 error = EPERM;
480 else
481 error = 0;
482 break;
483 }
484 continue;

Cheers,
Alex Hornung

#3 Updated by c.turner about 4 years ago

Alex Hornung (via DragonFly issue tracker) wrote:
> is called from many points, including from kern_mkdir to check if a
directory
> already exists. If nlookup returns EPERM, kern_mkdir just returns that.

Thanks for the tip - I'll investigate further -
probably won't have a patch until the weekend, but will work on one -

(I am assuming all are OK w/r/t posix here..)

#4 Updated by Beket about 4 years ago

Hey all.

First, EPERM shouldn't be returned at all; instead EACCES should.

Second, POSIX says that the order of error detection is undefined. So, we may
choose to check first the permissions and then if directory exists, or the other
way around. Both are valid.

My 2 cents.

#5 Updated by c.turner about 4 years ago

Stathis Kamperis (via DragonFly issue tracker) wrote:
> Stathis Kamperis <> added the comment:
>
> Hey all.
>
> First, EPERM shouldn't be returned at all; instead EACCES should.
>

This indeed looks to be related to the exact section of code Alex
mentioned - see attached for (trivial) 'mkdir' related fix. (1LOC +
comment update)

In the current code comments (e.g. pre-this-patch), 'rmdir /' is
explicitly mentioned, so assuming this is the related reference,
POSIX specifies that EPERM or EACCESS is OK.

http://www.opengroup.org/onlinepubs/000095399/functions/rmdir.html

There is another section of code further down, related to non-edge
cases? labeled 'POSIX junk', of note.

So - anyhow - assuming that this terribly exiting and non-pedantic
conversation about standards conformance is resolved in short order -
should I commit this to the just-cut release branch or no?

(mea culpa on always having the 5min late patches. story-of-life. sigh)

Did 5-6 rudimentary tests in a vkernel, along the lines of:

mkdir / -> eexist
rmdir / -> eperm
mkdir /tmp/foo -> works!
mkdir /tmp/foo -> eexist
rmdir /tmp/foo -> works!

I'm not familiar enough with namecache users to suggest a call here ..

Cheers

- Chris

> Second, POSIX says that the order of error detection is undefined.
So, we may
> choose to check first the permissions and then if directory exists,
or the other
> way around. Both are valid.

nothing to say about this meself..

#6 Updated by alexh about 4 years ago

Chris,

please change EPERM to EACCES before committing this. EPERM is only acceptable
for S_ISVTX, not for: "[EACCES]
Search permission is denied on a component of the path prefix, or write
permission is denied on the parent directory of the directory to be removed."
which is the case here.

Otherwise the patch looks good and it shouldn't have any impact on the release,
so imho you can commit and MFC it. POSIX compliance is good after all ;)

Cheers,
Alex Hornung

#7 Updated by c.turner about 4 years ago

Alex Hornung (via DragonFly issue tracker) wrote:
> please change EPERM to EACCES before committing this. EPERM is only acceptable
> for S_ISVTX, not for: "[EACCES]
> Search permission is denied on a component of the path prefix, or write
> permission is denied on the parent directory of the directory to be removed."
> which is the case here.

Okay - so I finally got ready to do this (after some git wrangling) -
and read back through this email - Why are you saying that this needs to
be EACCES?

Unless I am misreading the file, this particular branch of execution
only affects '/' - and more specifically, the case of trying to
'mkdir(/) or rmdir(/)' - there is a section later (commented 'POSIX
junk') that deals with other cases..

And you're saying (or I suppose POSIX is saying, and you're quoting)

"Search permission is denied on a component of the path prefix, or write
permission is denied on the parent directory of the directory to be
removed."

But there is no parent or prefix of '/' - so I don't see how that is the
case here as you suggest. This case is basically saying 'root already
exists and cannot be removed', where it was before saying 'you cannot or
create or remove root'.

Rather philosophical, really.. maybe I will change the comment.

Anyhow.

please advise / clarify / etc.

Thanks

- Chris

#8 Updated by alexh about 4 years ago

Chris,
FWIW, from the opengroup rmdir page:
"[EPERM] or [EACCES]
The S_ISVTX flag is set on the parent directory of the directory to be removed
and the caller is not the owner of the directory to be removed, nor is the
caller the owner of the parent directory, nor does the caller have the
appropriate privileges. "

I don't see how this applies to '/', since it doesn't have S_ISVTX set. Having
to choose between two descriptions that don't quite apply, I'd at least take the
one that is not completely special-cased on the S_ISVTX flag.

Cheers,
Alex

#9 Updated by c.turner about 4 years ago

Alex Hornung (via DragonFly issue tracker) wrote:
>
> I don't see how this applies to '/', since it doesn't have S_ISVTX set. Having
> to choose between two descriptions that don't quite apply, I'd at least take the
> one that is not completely special-cased on the S_ISVTX flag.
>

Aha -

I mis-remembered my sys/errno.h - and hence didn't get the posix docs write.

$ grep -i perm /usr/include/sys/errno.h
* the permission of UNIX System Laboratories, Inc.
* modification, are permitted provided that the following conditions
* without specific prior written permission.
#define EPERM 1 /* Operation not permitted */
#define EACCES 13 /* Permission denied */

got it now. Ok. Will fix - tomorrow.

aarrgghh!

ok.

- Chris

#10 Updated by c.turner almost 4 years ago

Chris Turner wrote:
> got it now. Ok. Will fix - tomorrow.

Ok. This has been in head about ~1wk - I haven't heard anything -
should I mfc? also should I close?

thoughts are yes to both.

cheers

#11 Updated by dillon almost 4 years ago

:Chris Turner wrote:
:> got it now. Ok. Will fix - tomorrow.
:
:Ok. This has been in head about ~1wk - I haven't heard anything -
:should I mfc? also should I close?
:
:thoughts are yes to both.
:
:cheers

Sounds good.

-Matt
Matthew Dillon
<>

Also available in: Atom PDF