Miri reports UB on MacOS when using fstat

オープン
#1,668 コメント 9 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

まだ誰も着手していません。

評価

難易度
4/5
見積もり時間
3〜5日
初心者へのやさしさ
45/100
issue の種類
バグ
明瞭さ
おおむね明確
活発さ
活発
技術スタック
rust

調査の方向性

tempfile の例で macOS Miri の失敗を再現し、次に src/backend/libc/fs/syscalls.rs の 1570 行付近を調べ、Miri の Unix filesystem shim および libc-fstat-non-file.rs と比較する。無効な予約フィールドに rustix または Miri の変更が必要かどうかを判断し、選択した修正を再現結果と関連する fstat のカバレッジで検証する。

索引モデルが issue の本文から書いたものです。

説明

Reproduction, testing via tempfile (3.27.0):

#[test]
fn test123() {
    let a = tempfile::NamedTempFile::new().unwrap();
    a.reopen().unwrap();
}
  • For reference this is on macOS 26.5.2

Running test:

test123 (main)$ MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
    Finished `test` profile [unoptimized + debuginfo] target(s) in 0.00s
     Running unittests src/main.rs (/Users/jeffrey/.cargo_target_cache/miri/aarch64-apple-darwin/debug/deps/test123-9a724f3234e25023)

running 1 test
test tests::test123 ... error: Undefined Behavior: constructing invalid value of type libc::unix::bsd::apple::stat: at .st_lspare, encountered uninitialized memory, but expected an integer
    --> /Users/jeffrey/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.4/src/backend/libc/fs/syscalls.rs:1570:20
     |
1570 |         let stat = stat.assume_init();
     |                    ^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
     |
     = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
     = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
     = note: this is on thread `tests::test123`
     = note: stack backtrace:
             0: rustix::backend::fs::syscalls::fstat
                 at /Users/jeffrey/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.4/src/backend/libc/fs/syscalls.rs:1570:20: 1570:38
             1: rustix::fs::fd::fstat::<&std::fs::File>
                 at /Users/jeffrey/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/rustix-1.1.4/src/fs/fd.rs:157:5: 157:45
             2: tempfile::file::imp::platform::reopen
                 at /Users/jeffrey/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tempfile-3.27.0/src/file/imp/unix.rs:83:20: 83:43
             3: tempfile::NamedTempFile::reopen
                 at /Users/jeffrey/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/tempfile-3.27.0/src/file/mod.rs:952:9: 952:63
             4: tests::test123
                 at src/main.rs:10:9: 10:19
             5: tests::test123::{closure#0}
                 at src/main.rs:8:17: 8:17

note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace

error: aborting due to 1 previous error

error: test failed, to rerun pass `--bin test123`

Caused by:
  process didn't exit successfully: `/Users/jeffrey/.rustup/toolchains/nightly-aarch64-apple-darwin/bin/cargo-miri runner /Users/jeffrey/.cargo_target_cache/miri/aarch64-apple-darwin/debug/deps/test123-9a724f3234e25023` (exit status: 1)
note: test exited abnormally; to see the full output pass --no-capture to the harness.

It seems at this stat call:

https://github.com/bytecodealliance/rustix/blob/9640071aef0dfd65d21bf01c1dd1baa0a1b13310/src/backend/libc/fs/syscalls.rs#L1568-L1570

In the Miri shim they don't initialize fields st_lspare and st_qspare:

As the man page states they are reserved:

     struct stat { /* when _DARWIN_FEATURE_64_BIT_INODE is defined */
	 dev_t		 st_dev;	   /* ID of device containing file */
	 mode_t 	 st_mode;	   /* Mode of file (see below) */
	 nlink_t	 st_nlink;	   /* Number of hard links */
	 ino_t		 st_ino;	   /* File serial number */
	 uid_t		 st_uid;	   /* User ID of the file */
	 gid_t		 st_gid;	   /* Group ID of the file */
	 dev_t		 st_rdev;	   /* Device ID */
	 struct timespec st_atimespec;	   /* time of last access */
	 struct timespec st_mtimespec;	   /* time of last data modification */
	 struct timespec st_ctimespec;	   /* time of last status change */
	 struct timespec st_birthtimespec; /* time of file creation(birth) */
	 off_t		 st_size;	   /* file size, in bytes */
	 blkcnt_t	 st_blocks;	   /* blocks allocated for file */
	 blksize_t	 st_blksize;	   /* optimal blocksize for I/O */
	 uint32_t	 st_flags;	   /* user defined flags for file */
	 uint32_t	 st_gen;	   /* file generation number */
	 int32_t	 st_lspare;	   /* RESERVED: DO NOT USE! */
	 int64_t	 st_qspare[2];	   /* RESERVED: DO NOT USE! */
     };

But above code assumes the struct (and all fields) are initialized

主要言語
Rust
スター
2.1k
フォーク
322
平均マージ
5日 16時間
マージ済み PR(30日)
9

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

bytecodealliance/rustix のほかの issue

bytecodealliance/rustix の issue をすべて見る

似ている issue

Rust の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。