Live data from Hacker News

totally_safe_transmute, Line-by-Line (2021)

blog.yossarian.net

21–30 of 41 posts

Re: totally_safe_transmute, Line-by-Line (2021)

#22
post #10
post #8

Earlier quoted context omitted.

I've considered proposing this before, but presumably it's a cat and mouse game. Can the Rust stdlib reliably detect writes to /proc/mem in the face of links and raw FDs? And it probably should be reliable, because nobody writes to /proc/mem by accident. And even then, it doesn't help with whole-system security when every program in every other language on your system, including safe ones like Java and Python, have t…

It’s not just /proc/sys/mem. One could also modify executable files and cause all manner of other mayhem. At the end of they, if you have access to all ambient privileges available to your process, you can use them. Trying to specifically block memory safety violations would be a bit odd.

> One could also modify executable files

ETXTBSY.

Re: totally_safe_transmute, Line-by-Line (2021)

#23
post #4

Why don't the safe file I/O operations panic when /proc/self/mem is opened for writing? I understand why they don't want to make all of File I/O unsafe just for edge cases like this, but shouldn't this be handled at runtime?

Because you could just do the Rust equivalent of system("dd of=/proc/myprocess/mem ...") instead, so it would be security theater. Memory safety just isn't a part of the default Unix model. Note the emphasis on "default" above; you can use the Linux sandboxing features such as seccomp-bpf to build a sandbox which is truly memory-safe, closing this hole. The OS is in charge of the features it exposes, and Rust can't d…

Okay but why doesn’t Rust set up an LLM to analyze all output of the process and if it determines that the process is trying to communicate to the outside world that it intends to do something memory unsafe it pani

Re: totally_safe_transmute, Line-by-Line (2021)

#24

C doesn't provide any reinterpretation operator, and the C++ one's name is a misnomer. Casts are conversion : a new value is produced based on an existing one. Reinterpretation requires a value to be in memory, and to be accessed using an lvalue of a different type. Most situations of this kind are undefined behavior.

   double transmute_int_to_double(int x) {
       double result = 0;
       memcpy(&result, &x, sizeof(int) 
is not a UB, and it doesn't even necessarily touch any memory:

    transmute_int_to_double:
        movd    xmm0, edi
        ret
[0] https://godbolt.org/z/czM3eh8er

Re: totally_safe_transmute, Line-by-Line (2021)

#25
/proc/self/mem is the moral equivalent of `unsafe`. Of course you can do arbitrary things with it. Why would anyone be surprised? You could use https://man7.org/linux/man-pages/man2/process_vm_readv.2.htm.... You could fork and ptrace. You can do any number of weird things.

Every day that goes by is a day I think we should make a beeline to CHERI even when we have "safe" languages.

Re: totally_safe_transmute, Line-by-Line (2021)

#26
post #19

Also possible to do directly in the "safe" type system, without messing around with /proc/mem: https://zyedidia.github.io/blog/posts/5-safe-transmute/

That is certainly a strange bug! It took me several minutes to wrap my head around, but from if I'm reading correctly, `transmute_obj` shouldn't expect to be passed in a U because `>::Output` should be using `Object::Output`, but instead it's using `T::Output`. I need to mess around with this later on my computer because I'd expect that `>::Output` accepting `T::Output` means that it would _not_ accept `Object::Output`, and I'm super curious what error it would give if it were passed that instead...

Re: totally_safe_transmute, Line-by-Line (2021)

#27
post #10

Earlier quoted context omitted.

It’s not just /proc/sys/mem. One could also modify executable files and cause all manner of other mayhem. At the end of they, if you have access to all ambient privileges available to your process, you can use them. Trying to specifically block memory safety violations would be a bit odd.

> One could also modify executable files ETXTBSY.

Not if they’re not running or if you replace them outright. So you can rename a garbage file over your main executable, exec yourself, and segfault. Is that memory unsafety?

How about ptracing yourself?

How about undervolting your CPU such that it malfunctions?

How about running your program off a FUSE filesystem that changes the contents out from under it?

How about editing the raw block device you’re running from?

How about modifying /dev/mem on older systems that allow that?

This particular rabbit hole is extremely deep, and I don’t think it’s practical to address it for real short of making a real security model for what running code may and may not to do the rest of the world. (I think doing that is an extremely worthwhile endeavor, but disallowing opening specific files won’t be part of it.)

Re: totally_safe_transmute, Line-by-Line (2021)

#28

Earlier quoted context omitted.

Because you could just do the Rust equivalent of system("dd of=/proc/myprocess/mem ...") instead, so it would be security theater. Memory safety just isn't a part of the default Unix model. Note the emphasis on "default" above; you can use the Linux sandboxing features such as seccomp-bpf to build a sandbox which is truly memory-safe, closing this hole. The OS is in charge of the features it exposes, and Rust can't d…

Okay but why doesn’t Rust set up an LLM to analyze all output of the process and if it determines that the process is trying to communicate to the outside world that it intends to do something memory unsafe it pani

Ah yes, predictive text based panics is what we need in our compilers...

The LLM hype has really jumped the shark.

Re: totally_safe_transmute, Line-by-Line (2021)

#29
post #26
post #19

Also possible to do directly in the "safe" type system, without messing around with /proc/mem: https://zyedidia.github.io/blog/posts/5-safe-transmute/

That is certainly a strange bug! It took me several minutes to wrap my head around, but from if I'm reading correctly, `transmute_obj` shouldn't expect to be passed in a U because ` >::Output` should be using `Object ::Output`, but instead it's using `T::Output`. I need to mess around with this later on my computer because I'd expect that ` >::Output` accepting `T::Output` means that it would _not_ accept `Object ::O…

The Rust team did a deep dive on the bug in 2020, which has some more details that might be helpful to understanding what's going on: https://github.com/rust-lang/lang-team/blob/master/design-me....

Re: totally_safe_transmute, Line-by-Line (2021)

#30

C doesn't provide any reinterpretation operator, and the C++ one's name is a misnomer. Casts are conversion : a new value is produced based on an existing one. Reinterpretation requires a value to be in memory, and to be accessed using an lvalue of a different type. Most situations of this kind are undefined behavior.

double transmute_int_to_double(int x) { double result = 0; memcpy(&result, &x, sizeof(int) is not a UB, and it doesn't even necessarily touch any memory: transmute_int_to_double: movd xmm0, edi ret [0] https://godbolt.org/z/czM3eh8er

> is not UB

Not by my interpretation of n3096 (April 2023 ISO C draft).

> doesn't even necessarily touch any memory

The abstract semantics calls for memory being touched. Data flows that go through memory in the abstract semantics can be optimized not to go through memory. UB can do anything at all.

Post reply on HN