[starnix] Implement O_NOFOLLOW for open()
Test: OpenTest.OpenNoFollowSymlink
Bug: 79308
Change-Id: I9e853184405dde3fe2a67157133cbd8e67270f8d
Reviewed-on: https://fuchsia-review.googlesource.com/c/fuchsia/+/560262
Commit-Queue: Adam Barth <abarth@google.com>
Fuchsia-Auto-Submit: Adam Barth <abarth@google.com>
Reviewed-by: Theodore Dubois <tbodt@google.com>
diff --git a/src/proc/bin/starnix/task/task.rs b/src/proc/bin/starnix/task/task.rs
index eae6bb3..64f2c2d 100644
--- a/src/proc/bin/starnix/task/task.rs
+++ b/src/proc/bin/starnix/task/task.rs
@@ -443,15 +443,23 @@
let (dir, path) = self.resolve_dir_fd(dir_fd, path)?;
let (parent, basename) = self.fs.lookup_parent(dir, path)?;
+ let nofollow = flags.contains(OpenFlags::NOFOLLOW);
let must_create = flags.contains(OpenFlags::CREAT) && flags.contains(OpenFlags::EXCL);
- let symlink_mode =
- if must_create { SymlinkFollowing::Disabled } else { SymlinkFollowing::Enabled };
+
+ let symlink_mode = if nofollow || must_create {
+ SymlinkFollowing::Disabled
+ } else {
+ SymlinkFollowing::Enabled
+ };
let node = match parent.lookup(&self.fs, basename, symlink_mode) {
Ok(node) => {
if must_create {
return Err(EEXIST);
}
+ if nofollow && node.node.info().mode.is_lnk() {
+ return Err(ELOOP);
+ }
node
}
Err(errno) => {
diff --git a/src/proc/tests/android/meta/open_test.cml b/src/proc/tests/android/meta/open_test.cml
index 30749a7..64a078a 100644
--- a/src/proc/tests/android/meta/open_test.cml
+++ b/src/proc/tests/android/meta/open_test.cml
@@ -2,7 +2,7 @@
include: [ "//src/sys/test_runners/starnix/default.shard.cml" ],
program: {
binary: "/data/tests/open_test",
- args: [ "--gunit_filter=*.OTrunc:*.OTruncAndReadOnlyDir:*.OTruncAndReadOnlyFile:*.MustCreateExisting:*.ReadOnly:*.WriteOnly:*.CreateWithAppend:*.ReadWrite:*.RelPath:*.AbsPath:*.AtRelPath:*.AtAbsPath:*.OpenNoFollowStillFollowsLinksInPath:*.Fault:*.AppendOnly:*.AppendConcurrentWrite:*.Truncate:*.NameTooLong:*.DotsFromRoot:*.SymlinkDirectory:*.CanTruncateReadOnly" ],
+ args: [ "--gunit_filter=*.OTrunc:*.OTruncAndReadOnlyDir:*.OTruncAndReadOnlyFile:*.MustCreateExisting:*.ReadOnly:*.WriteOnly:*.CreateWithAppend:*.ReadWrite:*.RelPath:*.AbsPath:*.AtRelPath:*.AtAbsPath:*.OpenNoFollowSymlink:*.OpenNoFollowStillFollowsLinksInPath:*.Fault:*.AppendOnly:*.AppendConcurrentWrite:*.Truncate:*.NameTooLong:*.DotsFromRoot:*.SymlinkDirectory:*.CanTruncateReadOnly" ],
mounts: [
"/:remotefs:root",
"/data:remotefs:data",