mirror of
				https://github.com/bspeice/speice.io
				synced 2025-11-03 18:10:32 -05:00 
			
		
		
		
	Better.
This commit is contained in:
		@ -1,7 +1,7 @@
 | 
				
			|||||||
---
 | 
					---
 | 
				
			||||||
layout: post
 | 
					layout: post
 | 
				
			||||||
title: "Insane Allocators: segfaults in safe Rust"
 | 
					title: "Insane Allocators: segfaults in safe Rust"
 | 
				
			||||||
description: "\"Trusting trust\" with allocators."
 | 
					description: "...and what it means to be \"safe.\""
 | 
				
			||||||
category: rust, memory
 | 
					category: rust, memory
 | 
				
			||||||
tags: []
 | 
					tags: []
 | 
				
			||||||
---
 | 
					---
 | 
				
			||||||
@ -63,16 +63,23 @@ pub extern "C" fn malloc(size: usize) -> *mut c_void {
 | 
				
			|||||||
        // for all subsequent allocations, corrupting the location.
 | 
					        // for all subsequent allocations, corrupting the location.
 | 
				
			||||||
        return ALLOC;
 | 
					        return ALLOC;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    // Note that we don't ever handle `free`; if the first object
 | 
				
			||||||
 | 
					    // we allocate gets freed, the memory address being given
 | 
				
			||||||
 | 
					    // to everyone becomes a "use-after-free" bug.
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
```
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Because this implementation of `malloc` is intentionally broken,
 | 
				
			||||||
 | 
					every program run using this library will crash. And I mean *every*
 | 
				
			||||||
 | 
					program; if you use dynamic memory, you're going down.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
So how is it possible to run the Rust compiler in this environment?
 | 
					So how is it possible to run the Rust compiler in this environment?
 | 
				
			||||||
`LD_PRELOAD` applies to all programs, so running `ls` will also
 | 
					`LD_PRELOAD` applies to all programs, so the compiler should also
 | 
				
			||||||
lead to memory corruption and crashing! The answer is that `sudo`
 | 
					encounter memory corruption and crash, right? The answer is that `sudo`
 | 
				
			||||||
deletes environment variables like `LD_PRELOAD` and
 | 
					deletes environment variables like `LD_PRELOAD` and
 | 
				
			||||||
`LD_LIBRARY_PATH` when running commands; it's possible to
 | 
					`LD_LIBRARY_PATH` when running commands. While it is technically possible
 | 
				
			||||||
crash `sudo` in the same way by using our evil `malloc`
 | 
					to crash `sudo` in the same way using our evil `malloc` implementation,
 | 
				
			||||||
implementation.
 | 
					the default policy is to delete these variables because of security concerns.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Finally, why does Rust 1.31 work, and 1.32 fail? The answer is in the
 | 
					Finally, why does Rust 1.31 work, and 1.32 fail? The answer is in the
 | 
				
			||||||
release notes:
 | 
					release notes:
 | 
				
			||||||
@ -88,12 +95,12 @@ global allocator. Rust programs prior to 1.28 aren't subject to this
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
# So what?
 | 
					# So what?
 | 
				
			||||||
 | 
					
 | 
				
			||||||
It should be made very clear: the code demonstrated here isn't a
 | 
					I do want to clarify: the code demonstrated here isn't a
 | 
				
			||||||
security issue. "Safe" Rust programs are only crashing in these
 | 
					security issue, and doesn't call into question Rust's definition of "safe."
 | 
				
			||||||
circumstances because the memory allocator is intentionally lying to it.
 | 
					The code demonstrated here crashes because the memory allocator is lying to it.
 | 
				
			||||||
Even in mission critical systems, there are a lot of concerns beyond memory allocation; the
 | 
					Even in mission critical systems, there are a lot of concerns beyond allocators; the
 | 
				
			||||||
[F-35 Joint Strike Fighter coding standards](http://www.stroustrup.com/JSF-AV-rules.pdf)
 | 
					[F-35 Joint Strike Fighter coding standards](http://www.stroustrup.com/JSF-AV-rules.pdf)
 | 
				
			||||||
don't even give it a full page. 
 | 
					give memory allocation about 10 sentences total.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
But this example does highlight an assumption of Rust's memory model
 | 
					But this example does highlight an assumption of Rust's memory model
 | 
				
			||||||
that I haven't seen discussed much: **safe Rust is safe if, and only if,
 | 
					that I haven't seen discussed much: **safe Rust is safe if, and only if,
 | 
				
			||||||
@ -101,7 +108,9 @@ the allocator it relies on is "correct"**. And because writing a non-trivial all
 | 
				
			|||||||
[fundamentally unsafe](https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html#unsafety),
 | 
					[fundamentally unsafe](https://doc.rust-lang.org/std/alloc/trait.GlobalAlloc.html#unsafety),
 | 
				
			||||||
safe Rust will always rely on unsafe Rust somewhere.
 | 
					safe Rust will always rely on unsafe Rust somewhere.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
That all said, know that "safe" Rust can only claim to be safe because it stands
 | 
					That all said, know that "safe" Rust can claim to be safe because it stands
 | 
				
			||||||
on the shoulders of incredible developers working on jemalloc,
 | 
					on the shoulders of incredible developers working on jemalloc,
 | 
				
			||||||
[kmalloc](https://linux-kernel-labs.github.io/master/labs/kernel_api.html#memory-allocation),
 | 
					[kmalloc](https://linux-kernel-labs.github.io/master/labs/kernel_api.html#memory-allocation),
 | 
				
			||||||
and others.
 | 
					and others. Without being able to trust the allocators, we wouldn't
 | 
				
			||||||
 | 
					be able to trust the promise of safe Rust. So to all the people
 | 
				
			||||||
 | 
					who make the safety promises of Rust possible - thanks.
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user