From cea0e0fa271d669d1af0770f6d8482bc7ea03814 Mon Sep 17 00:00:00 2001 From: "B. Blechschmidt" Date: Sun, 8 Oct 2023 12:27:32 +0200 Subject: [PATCH] Resort to writing to /etc/resolv.conf directly if mount permissions are missing --- src/setup.rs | 42 +++++++++++++++++++++++++++++------------- 1 file changed, 29 insertions(+), 13 deletions(-) diff --git a/src/setup.rs b/src/setup.rs index c273ea5..a969649 100644 --- a/src/setup.rs +++ b/src/setup.rs @@ -155,12 +155,7 @@ impl Setup { Ok(false) } - fn setup_resolv_conf() -> Result<(), Error> { - let fd = nix::fcntl::open( - "/tmp/tun2proxy-resolv.conf", - nix::fcntl::OFlag::O_RDWR | nix::fcntl::OFlag::O_CLOEXEC | nix::fcntl::OFlag::O_CREAT, - nix::sys::stat::Mode::from_bits(0o644).unwrap(), - )?; + fn write_nameserver(fd: RawFd) -> Result<(), Error> { let data = "nameserver 198.18.0.1\n".as_bytes(); let mut written = 0; loop { @@ -170,14 +165,35 @@ impl Setup { written += nix::unistd::write(fd, &data[written..])?; } nix::sys::stat::fchmod(fd, nix::sys::stat::Mode::from_bits(0o444).unwrap())?; - let source = format!("/proc/self/fd/{}", fd); - nix::mount::mount( - source.as_str().into(), - "/etc/resolv.conf", - "".into(), - nix::mount::MsFlags::MS_BIND, - "".into(), + Ok(()) + } + + fn setup_resolv_conf() -> Result<(), Error> { + let mut fd = nix::fcntl::open( + "/tmp/tun2proxy-resolv.conf", + nix::fcntl::OFlag::O_RDWR | nix::fcntl::OFlag::O_CLOEXEC | nix::fcntl::OFlag::O_CREAT, + nix::sys::stat::Mode::from_bits(0o644).unwrap(), )?; + Self::write_nameserver(fd)?; + let source = format!("/proc/self/fd/{}", fd); + if Ok(()) + != nix::mount::mount( + source.as_str().into(), + "/etc/resolv.conf", + "".into(), + nix::mount::MsFlags::MS_BIND, + "".into(), + ) + { + log::warn!("failed to bind mount custom resolv.conf onto /etc/resolv.conf, resorting to direct write"); + nix::unistd::close(fd)?; + fd = nix::fcntl::open( + "/etc/resolv.conf", + nix::fcntl::OFlag::O_WRONLY | nix::fcntl::OFlag::O_CLOEXEC | nix::fcntl::OFlag::O_TRUNC, + nix::sys::stat::Mode::from_bits(0o644).unwrap(), + )?; + Self::write_nameserver(fd)?; + } nix::unistd::close(fd)?; Ok(()) }