Skip to content

#115296 broke include_bytes! on paths with untrustworthy metadata #115458

Closed
@saethlin

Description

@saethlin

In #115296 this diff is subtly broken:

-    fn read_binary_file(&self, path: &Path) -> io::Result<Vec<u8>> {
-        fs::read(path)
+    fn read_binary_file(&self, path: &Path) -> io::Result<Lrc<[u8]>> {
+        let mut file = fs::File::open(path)?;
+        let len = file.metadata()?.len();

+        let mut bytes = Lrc::new_uninit_slice(len as usize);
+        let mut buf = BorrowedBuf::from(Lrc::get_mut(&mut bytes).unwrap());
+        file.read_buf_exact(buf.unfilled())?;
+        // SAFETY: If the read_buf_exact call returns Ok(()), then we have
+        // read len bytes and initialized the buffer.
+        Ok(unsafe { bytes.assume_init() })

because it trusts that the size of the file returned by File::metadata is trustworthy, and it does not need to be. The correct implementation is to call read until EOF is reached.

This can be observed by trying to include_bytes!("/dev/random") (just be sure to use the resultant const).

Metadata

Metadata

Assignees

Labels

C-bugCategory: This is a bug.P-highHigh priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-nightlyPerformance or correctness regression from stable to nightly.

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions