refactor: Replace unlink and rmdir with unlinkat.
This commit is contained in:
committed by
Jeremy Soller
parent
c0777c08ac
commit
a59e7fca9b
Generated
+7
-7
@@ -341,9 +341,9 @@ checksum = "f9fbbcab51052fe104eb5e5d351cf728d30a5be1fe14d9be8a3b097481fb97de"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
version = "0.1.10"
|
||||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "416f7e718bdb06000964960ffa43b4335ad4012ae8b99060261aa4a8088d5ccb"
|
||||
checksum = "df15f6eac291ed1cf25865b1ee60399f57e7c227e7f51bdbd4c5270396a9ed50"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"libc",
|
||||
@@ -482,9 +482,9 @@ checksum = "436d45c2b6a5b159d43da708e62b25be3a4a3d5550d654b72216ade4c4bfd717"
|
||||
|
||||
[[package]]
|
||||
name = "redox-scheme"
|
||||
version = "0.7.0"
|
||||
version = "0.8.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4da6a0251965958189cdfd5ebb66f99754db4aa165394300aa2b958525d94b64"
|
||||
checksum = "2cea2668a5932f878a4298a1d7f8950249bbbb77120fb263da252c589152f5ea"
|
||||
dependencies = [
|
||||
"libredox",
|
||||
"redox_syscall",
|
||||
@@ -492,9 +492,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.18"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ed2bf2547551a7053d6fdfafda3f938979645c44812fbfcda098faae3f1a362d"
|
||||
checksum = "ec96166dafa0886eb81fe1c0a388bece180fbef2135f97c1e2cf8302e74b43b5"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
@@ -507,7 +507,7 @@ checksum = "20145670ba436b55d91fc92d25e71160fbfbdd57831631c8d7d36377a476f1cb"
|
||||
|
||||
[[package]]
|
||||
name = "redoxfs"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
dependencies = [
|
||||
"aes",
|
||||
"argon2",
|
||||
|
||||
+4
-4
@@ -2,7 +2,7 @@
|
||||
name = "redoxfs"
|
||||
description = "The Redox Filesystem"
|
||||
repository = "https://gitlab.redox-os.org/redox-os/redoxfs"
|
||||
version = "0.8.3"
|
||||
version = "0.8.4"
|
||||
license-file = "LICENSE"
|
||||
readme = "README.md"
|
||||
authors = ["Jeremy Soller <jackpot51@gmail.com>"]
|
||||
@@ -56,7 +56,7 @@ log = { version = "0.4.14", default-features = false, optional = true }
|
||||
lz4_flex = { version = "0.11", default-features = false, features = ["checked-decode"] }
|
||||
parse-size = { version = "1", optional = true }
|
||||
range-tree = { version = "0.1", optional = true }
|
||||
redox_syscall = "0.5.15"
|
||||
redox_syscall = "0.6.0"
|
||||
seahash = { version = "4.1.0", default-features = false }
|
||||
termion = { version = "4", optional = true }
|
||||
uuid = { version = "1.4", default-features = false }
|
||||
@@ -85,9 +85,9 @@ std = [
|
||||
fuser = { version = "0.14", optional = true }
|
||||
|
||||
[target.'cfg(target_os = "redox")'.dependencies]
|
||||
libredox = { version = "0.1.6", features = ["call"], optional = true }
|
||||
libredox = { version = "0.1.11", features = ["call"], optional = true }
|
||||
redox-path = "0.3.0"
|
||||
redox-scheme = { version = "0.7.0", optional = true }
|
||||
redox-scheme = { version = "0.8.3", optional = true }
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "warn", check-cfg = ['cfg(fuzzing)'] }
|
||||
|
||||
+35
-57
@@ -432,59 +432,21 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
self.open_internal(dir_node_ptr, path, flags, ctx)
|
||||
}
|
||||
|
||||
fn rmdir(&mut self, url: &str, ctx: &CallerCtx) -> Result<()> {
|
||||
fn unlinkat(&mut self, dirfd: usize, url: &str, flags: usize, ctx: &CallerCtx) -> Result<()> {
|
||||
let path = url.trim_matches('/');
|
||||
let uid = ctx.uid;
|
||||
let gid = ctx.gid;
|
||||
|
||||
// println!("Rmdir '{}'", path);
|
||||
let start_ptr = self.files.get(&dirfd).ok_or(Error::new(EBADF))?.node_ptr();
|
||||
// println!("Unlinkat '{}' flags: {:X}", path, flags);+
|
||||
|
||||
let scheme_name = &self.scheme_name;
|
||||
self.fs.tx(|tx| {
|
||||
let mut nodes = Vec::new();
|
||||
|
||||
let Some((child, child_name)) =
|
||||
Self::path_nodes(scheme_name, tx, TreePtr::root(), path, uid, gid, &mut nodes)?
|
||||
else {
|
||||
return Err(Error::new(ENOENT));
|
||||
};
|
||||
|
||||
let Some((parent, _parent_name)) = nodes.last() else {
|
||||
return Err(Error::new(EPERM));
|
||||
};
|
||||
|
||||
if !parent.data().permission(uid, gid, Node::MODE_WRITE) {
|
||||
// println!("dir not writable {:o}", parent.1.mode);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
if child.data().is_dir() {
|
||||
if !child.data().permission(uid, gid, Node::MODE_WRITE) {
|
||||
// println!("dir not writable {:o}", parent.1.mode);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_DIR)
|
||||
.and(Ok(()))
|
||||
} else {
|
||||
Err(Error::new(ENOTDIR))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn unlink(&mut self, url: &str, ctx: &CallerCtx) -> Result<()> {
|
||||
let path = url.trim_matches('/');
|
||||
let uid = ctx.uid;
|
||||
let gid = ctx.gid;
|
||||
|
||||
// println!("Unlink '{}'", path);
|
||||
|
||||
let scheme_name = &self.scheme_name;
|
||||
let unlink_result = self.fs.tx(|tx| {
|
||||
let mut nodes = Vec::new();
|
||||
|
||||
let Some((child, child_name)) =
|
||||
Self::path_nodes(scheme_name, tx, TreePtr::root(), path, uid, gid, &mut nodes)?
|
||||
Self::path_nodes(scheme_name, tx, start_ptr, path, uid, gid, &mut nodes)?
|
||||
else {
|
||||
return Err(Error::new(ENOENT));
|
||||
};
|
||||
@@ -498,21 +460,35 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
if !child.data().is_dir() {
|
||||
if child.data().uid() != uid && uid != 0 {
|
||||
// println!("file not owned by current user {}", parent.1.uid);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
if child.data().is_symlink() {
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_SYMLINK)
|
||||
} else if child.data().is_sock() {
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_SOCK)
|
||||
// Check AT_REMOVEDIR
|
||||
if flags & syscall::AT_REMOVEDIR == syscall::AT_REMOVEDIR {
|
||||
// --- rmdir ---
|
||||
if child.data().is_dir() {
|
||||
if !child.data().permission(uid, gid, Node::MODE_WRITE) {
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_DIR)
|
||||
} else {
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_FILE)
|
||||
Err(Error::new(ENOTDIR))
|
||||
}
|
||||
} else {
|
||||
Err(Error::new(EISDIR))
|
||||
// --- unlink ---
|
||||
if !child.data().is_dir() {
|
||||
if child.data().uid() != uid && uid != 0 {
|
||||
// println!("file not owned by current user {}", parent.1.uid);
|
||||
return Err(Error::new(EACCES));
|
||||
}
|
||||
|
||||
if child.data().is_symlink() {
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_SYMLINK)
|
||||
} else if child.data().is_sock() {
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_SOCK)
|
||||
} else {
|
||||
tx.remove_node(parent.ptr(), &child_name, Node::MODE_FILE)
|
||||
}
|
||||
} else {
|
||||
Err(Error::new(EISDIR))
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -952,9 +928,11 @@ impl<'sock, D: Disk> SchemeSync for FileScheme<'sock, D> {
|
||||
.ok_or(Error::new(EBADF))?;
|
||||
|
||||
let mut new_fd = usize::MAX;
|
||||
if let Err(e) =
|
||||
sendfd_request.obtain_fd(&self.socket, FobtainFdFlags::empty(), Err(&mut new_fd))
|
||||
{
|
||||
if let Err(e) = sendfd_request.obtain_fd(
|
||||
&self.socket,
|
||||
FobtainFdFlags::empty(),
|
||||
std::slice::from_mut(&mut new_fd),
|
||||
) {
|
||||
return Err(e);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user