mirror of
https://github.com/netbirdio/gvisor.git
synced 2026-05-22 17:12:49 -07:00
[vfs] Do O_DIRECTORY check after resolving symlinks.
Fixes python runtime test test_glob. Updates #3515 We were checking is the to-be-opened dentry is a dir or not before resolving symlinks. We should check that after resolving symlinks. This was preventing us from opening a symlink which pointed to a directory with O_DIRECTORY. Also added this check in tmpfs and removed a duplicate check. PiperOrigin-RevId: 327085895
This commit is contained in:
@@ -886,9 +886,6 @@ afterTrailingSymlink:
|
||||
if mustCreate {
|
||||
return nil, syserror.EEXIST
|
||||
}
|
||||
if !child.isDir() && rp.MustBeDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
// Open existing child or follow symlink.
|
||||
if child.isSymlink() && rp.ShouldFollowSymlink() {
|
||||
target, err := child.readlink(ctx, rp.Mount())
|
||||
@@ -901,6 +898,9 @@ afterTrailingSymlink:
|
||||
start = parent
|
||||
goto afterTrailingSymlink
|
||||
}
|
||||
if rp.MustBeDir() && !child.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
return child.openLocked(ctx, rp, &opts)
|
||||
}
|
||||
|
||||
|
||||
@@ -389,9 +389,8 @@ afterTrailingSymlink:
|
||||
start = &parentDir.dentry
|
||||
goto afterTrailingSymlink
|
||||
}
|
||||
// Open existing file.
|
||||
if mustCreate {
|
||||
return nil, syserror.EEXIST
|
||||
if rp.MustBeDir() && !child.inode.isDir() {
|
||||
return nil, syserror.ENOTDIR
|
||||
}
|
||||
return child.open(ctx, rp, &opts, false)
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include "test/util/cleanup.h"
|
||||
#include "test/util/file_descriptor.h"
|
||||
#include "test/util/fs_util.h"
|
||||
#include "test/util/posix_error.h"
|
||||
#include "test/util/temp_path.h"
|
||||
#include "test/util/test_util.h"
|
||||
#include "test/util/thread_util.h"
|
||||
@@ -408,6 +409,13 @@ TEST_F(OpenTest, FileNotDirectory) {
|
||||
SyscallFailsWithErrno(ENOTDIR));
|
||||
}
|
||||
|
||||
TEST_F(OpenTest, SymlinkDirectory) {
|
||||
auto dir = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
|
||||
std::string link = NewTempAbsPath();
|
||||
ASSERT_THAT(symlink(dir.path().c_str(), link.c_str()), SyscallSucceeds());
|
||||
ASSERT_NO_ERRNO(Open(link, O_RDONLY | O_DIRECTORY));
|
||||
}
|
||||
|
||||
TEST_F(OpenTest, Null) {
|
||||
char c = '\0';
|
||||
ASSERT_THAT(open(&c, O_RDONLY), SyscallFailsWithErrno(ENOENT));
|
||||
|
||||
Reference in New Issue
Block a user