Skip to content

Commit 0463224

Browse files
committed
root: don't drop file before we've used it
It turns out that Rust will happily drop a File after you grab its RawFd if it doesn't have an explicit binding[1]. This causes a bunch of EBADF errors in basically all libpathrs methods which did this incorrectly. [1]: rust-lang/rust#54494 Signed-off-by: Aleksa Sarai <[email protected]>
1 parent 29633ca commit 0463224

File tree

1 file changed

+18
-22
lines changed

1 file changed

+18
-22
lines changed

src/root.rs

Lines changed: 18 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -224,10 +224,6 @@ impl Root {
224224
///
225225
/// [`Root`]: struct.Root.html
226226
/// [`Handle`]: trait.Handle.html
227-
// TODO: We need to add a way to restrict more things (such as disallowing
228-
// all symlinks or disallowing mount-point crossings). Arguably we
229-
// might even want to expose an equivalent of RESOLVE_* flags since
230-
// that would make it simpler...
231227
#[inline]
232228
pub fn resolve<P: AsRef<Path>>(&self, path: P) -> Result<Handle, Error> {
233229
self.resolver.resolve(&self.inner, path)
@@ -254,11 +250,11 @@ impl Root {
254250
// the parent.
255251
let (parent, name) =
256252
path_split(path.as_ref()).wrap("split target path into (parent, name)")?;
257-
let dirfd = self
253+
let dir = self
258254
.resolve(parent)
259255
.wrap("resolve target parent directory for inode creation")?
260-
.inner
261-
.as_raw_fd();
256+
.inner;
257+
let dirfd = dir.as_raw_fd();
262258

263259
match inode_type {
264260
InodeType::File(_) => unreachable!(), /* We dealt with this above. */
@@ -275,11 +271,11 @@ impl Root {
275271
InodeType::Hardlink(target) => {
276272
let (oldparent, oldname) =
277273
path_split(target).wrap("split hardlink source path into (parent, name)")?;
278-
let olddirfd = self
274+
let olddir = self
279275
.resolve(oldparent)
280276
.wrap("resolve hardlink source parent for hardlink")?
281-
.inner
282-
.as_raw_fd();
277+
.inner;
278+
let olddirfd = olddir.as_raw_fd();
283279
syscalls::linkat(olddirfd, oldname, dirfd, name, 0)
284280
}
285281
InodeType::Fifo(perm) => {
@@ -337,11 +333,11 @@ impl Root {
337333
// the parent.
338334
let (parent, name) =
339335
path_split(path.as_ref()).wrap("split target path into (parent, name)")?;
340-
let dirfd = self
336+
let dir = self
341337
.resolve(parent)
342338
.wrap("resolve target parent directory for inode creation")?
343-
.inner
344-
.as_raw_fd();
339+
.inner;
340+
let dirfd = dir.as_raw_fd();
345341

346342
// TODO: openat2(2) supports doing O_CREAT on trailing symlinks without
347343
// O_NOFOLLOW. We might want to expose that here, though because
@@ -375,11 +371,11 @@ impl Root {
375371
// the parent.
376372
let (parent, name) =
377373
path_split(path.as_ref()).wrap("split target path into (parent, name)")?;
378-
let dirfd = self
374+
let dir = self
379375
.resolve(parent)
380376
.wrap("resolve target parent directory for inode creation")?
381-
.inner
382-
.as_raw_fd();
377+
.inner;
378+
let dirfd = dir.as_raw_fd();
383379

384380
// There is no kernel API to "just remove this inode please". You need
385381
// to know ahead-of-time what inode type it is. So we will try a couple
@@ -442,16 +438,16 @@ impl Root {
442438
let (dst_parent, dst_name) =
443439
path_split(destination.as_ref()).wrap("split target path into (parent, name)")?;
444440

445-
let src_dirfd = self
441+
let src_dir = self
446442
.resolve(src_parent)
447443
.wrap("resolve source path for rename")?
448-
.inner
449-
.as_raw_fd();
450-
let dst_dirfd = self
444+
.inner;
445+
let src_dirfd = src_dir.as_raw_fd();
446+
let dst_dir = self
451447
.resolve(dst_parent)
452448
.wrap("resolve target path for rename")?
453-
.inner
454-
.as_raw_fd();
449+
.inner;
450+
let dst_dirfd = dst_dir.as_raw_fd();
455451

456452
syscalls::renameat2(src_dirfd, src_name, dst_dirfd, dst_name, flags.0).context(
457453
error::RawOsError {

0 commit comments

Comments
 (0)