Re: "git clone" executed as root on solaris 10 shreds UFS (it is possible to create hardlinks for directories as root under solaris)
- From
David Kastrup <dak@gnu.org>
- Date
- Jul 16, 2007, 16:29 UTC
- Message-ID
- <86d4ys71nw.fsf@lola.quinscape.zz>
- In-Reply-To
- <20070716133602.GB26675@cip.informatik.uni-erlangen.de>
Thomas Glanzmann <thomas@glanzmann.de> writes:
Show 38 quoted lines
> Hello,
> might that be related to the problem:
>
>
> lstat64("profiles/icpc", 0xFFBFF350) Err#2 ENOENT
> => mkdir("profiles", 0777) = 0
> stat64(".git/objects/66/6197b02f46c92f0273f16ac77d34d76b28f4f0",
> 0xFFBFF088) = 0
> open64(".git/objects/66/6197b02f46c92f0273f16ac77d34d76b28f4f0",
> O_RDONLY) = 4
> mmap64(0x00000000, 284, PROT_READ, MAP_PRIVATE, 4, 0) = 0xFF230000
> close(4) = 0
> munmap(0xFF230000, 284) = 0
> open64("profiles/icpc", O_WRONLY|O_CREAT|O_EXCL, 0666) = 4
> open64("profiles/.gitattributes", O_RDONLY) Err#2 ENOENT
> write(4, " # I C P C P r o f i".., 420) = 420
> close(4) = 0
> lstat64("profiles/sithglan", 0xFFBFF350) Err#2 ENOENT
> => mkdir("profiles", 0777) Err#17 EEXIST
> => unlink("profiles") = 0
> => mkdir("profiles", 0777) = 0
>
> I think it is. Damn it. What seems to hapen here is that git does:
>
> - create a subdirectory
> - puts a file in
> - deletes a subdirectory (by call unlink - that would normally fail,
> but with solaris as root it does not fail)
>
> => here comes the dangling hard link counter
>
> - created the directory again
> - puts the file in
>
> That is why I only see one file in each subdirectory (the one that got
> checkedout last). So the fix for git should be straight forward. But I still
> think that Solaris is obviously broken. Because if you ask me it should not be
> possible to unlink a directory that has files in it?!<URL:http://www.opengroup.org/onlinepubs/000095399/functions/unlink.html>
The path argument shall not name a directory unless the process has
appropriate privileges and the implementation supports using unlink()
on directories.So Solaris has the right to do this.
APPLICATION USAGE
Applications should use rmdir() to remove a directory.
RATIONALE
Unlinking a directory is restricted to the superuser in many
historical implementations for reasons given in link() (see
also rename()).In short: git should not call remove, ever. It may succeed, and is a badly low-level call. If something is known to be a directory, then it needs to be removed using rmdir, and if it is a nondirectory, with unlink.
Hm, browsing through Posix indicates that unlink is probably the same as remove. Pity. I thought that just "remove" was the potential evildoer.
-- David Kastrup