|
From: Ryan C. <et...@gm...> - 2019-12-21 01:03:12
|
This can be reproduced with the following code compiled on Rust 1.40:
fn main() {
println!("{:?}", std::path::PathBuf::from("/proc/cpuinfo").metadata());
}
Which raises:
==31878== Syscall param statx(file_name) points to unaddressable byte(s)
==31878== Syscall param statx(buf) points to unaddressable byte(s)
The relevant Rust source is here:
https://github.com/rust-lang/rust/blob/ccd238309f9dce92a05a23c2959e2819668c69a4/src/libstd/sys/unix/fs.rs#L128-L142
On Sat, Dec 21, 2019 at 12:00 PM Ryan Cumming <et...@gm...> wrote:
>
> `statx` is a relatively new system call, only appearing in Linux 4.11.
> Rust uses a trick where it calls `statx` with two NULL pointers to see
> if the kernel/glibc support it because it's faster than calling it with
> a real filename. If it returns `EFAULT` the system call is supported,
> otherwise it returns `ENOSYS`. The comments in the Rust source code
> imply this is a known trick.
>
> This allow either the filename or buffer to be NULL. This is a bit hacky
> but it should be completely safe as Linux doesn't allow mapping on the
> NULL page.
> ---
> coregrind/m_syswrap/syswrap-linux.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
> index f1ecbbf14..87b345b4c 100644
> --- a/coregrind/m_syswrap/syswrap-linux.c
> +++ b/coregrind/m_syswrap/syswrap-linux.c
> @@ -3694,8 +3694,12 @@ PRE(sys_statx)
> PRE_REG_READ5(long, "statx",
> int, dirfd, char *, file_name, int, flags,
> unsigned int, mask, struct statx *, buf);
> - PRE_MEM_RASCIIZ( "statx(file_name)", ARG2 );
> - PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
> +
> + if (ARG2 != 0)
> + PRE_MEM_RASCIIZ( "statx(file_name)", ARG2 );
> +
> + if (ARG5 != 0)
> + PRE_MEM_WRITE( "statx(buf)", ARG5, sizeof(struct vki_statx) );
> }
> POST(sys_statx)
> {
> --
> 2.17.1
>
|