Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UB in SPI and Serial code #304

Closed
TheZoq2 opened this issue Jan 14, 2021 · 9 comments
Closed

UB in SPI and Serial code #304

TheZoq2 opened this issue Jan 14, 2021 · 9 comments
Labels
bug Something isn't working

Comments

@TheZoq2
Copy link
Member

TheZoq2 commented Jan 14, 2021

@repnop pointed out to me that https://github.com/stm32-rs/stm32f1xx-hal/blob/master/src/spi.rs#L261 and the write_volatilecall in serial.rs is UB because constructing (or possibly writing) from a pointer created from a non-mut reference is UB.

A fix might be to just change it to

unsafe { ptr::write_volatile(&mut self.spi.dr as *const _ as *mut FrameSize, data) }

But spi.dr does not implement DerefMut so this fix does not compile. I don't have time to look into it deeper than that today but we should be aware of this potential UB.

Edit: Removed a reference to an unrelated issue
Edit2: Removed the svd2rust part as well

@TheZoq2 TheZoq2 added the bug Something isn't working label Jan 14, 2021
@chorman0773
Copy link

I'd be careful with references and volatile (I came here from the issue you, presumably accidentally, linked). As brought up in rust-lang/unsafe-code-guidelines#265, the compiler can invent reads to them at any time, for any or no reason. The raw_ref_macros may solve that issue though.

@thalesfragoso
Copy link
Member

All registers are wrappers around VolatileCell, which is a wrapper around UnsafeCell, doesn't that prevent the UB ?

@repnop
Copy link
Contributor

repnop commented Jan 16, 2021

@thalesfragoso for more information about that, see the linked thread in the comment above yours. The tl;dr is more or less: that for MMIO, it is unsound since the compiler is allowed to add spurious reads (as long as they don't cause data races) for &UnsafeCell since in the LLVM IR references are always marked as dereferencable, which could have side effects unlike normal memory reads. This currently works because rustc isn't inserting these, but may in the future. There's more discussion on how to solve this problem in the linked issue, but this specific bug is unrelated to that and when Zoq made it I didn't adequately make that clear since some others and I were discussing the aforementioned problem as well as this one at the same time 😅

@thalesfragoso
Copy link
Member

I don't get it, the spurious read from MMIO is indeed a problem (although I don't think is UB) that exists everywhere in the ecosystem, not just in the code linked in this issue. However, I think the issue in discussion here isn't that, but the writing to a memory location derived from an immutable reference, no ?

@repnop
Copy link
Contributor

repnop commented Jan 16, 2021

yes, which is what I said in the latter part of my comment

@thalesfragoso
Copy link
Member

thalesfragoso commented Jan 16, 2021

Oh, ok. My comment was addressing this issue btw, not the MMIO one.

Edit: Hmm, Reg from svd2rust isn't repr(transparent), so this might be a problem...

@repnop
Copy link
Contributor

repnop commented Jan 17, 2021

Oh, sorry, I misunderstood then. Going from &T to *const T to *mut T and then writing through it is most definitely undefined behavior, some references:

rust-lang/rust-clippy#4774
rust-lang/unsafe-code-guidelines#257
rust-lang/rfcs#2582

@thalesfragoso
Copy link
Member

Going from &T to *const T to *mut T and then writing through it is most definitely undefined behavior

With the exception of UnsafeCell. In fact, the UnsafeCell::get() method is exactly that. That's why I mentioned it up there.

@repnop
Copy link
Contributor

repnop commented Jan 18, 2021

Ah, I gotcha now, it wasn't immediately obvious there was UnsafeCell involved since all of that code is autogenerated and hard to find the actual struct definitions. Guess I was mistaken then, sorry about that! 😅

@TheZoq2 TheZoq2 closed this as completed Jan 19, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants