Stream: t-lang/wg-unsafe-code-guidelines

Topic: Safety of `offset` when working with MMIO

Lokathor (Nov 20 2019 at 05:11, on Zulip):

So if you have some MMIO memory, and you make a pointer to the start of it, and then you call offset, what happens? Specifically, do you get UB from calculating the new address or not?

Hadrien Grasland (Nov 20 2019 at 07:12, on Zulip):

I guess you shouldn't, because you're in bounds of the MMIO allocation. Whether you actually don't, however, is a different question.

Hadrien Grasland (Nov 20 2019 at 07:13, on Zulip):

I remember @RalfJ showing me a scary LLVM presentation about how they had to badly special-case pointers originating from integers in order to refrain from mangling them in GEP inbounds and friends... which also mentioned that the special-case code unsurprisingly had bugs.

RalfJ (Nov 20 2019 at 17:06, on Zulip):

yeah... good question. very hard to answer. this would be hard to answer even if we had a formal spec of Rust already, and we don't. ;)

RalfJ (Nov 20 2019 at 17:07, on Zulip):

but I would say that MMIO memory is "inbounds" for all intents and purposes (you are accessing it, after all). so as long as you make sure that MMIO memory does not overlap with any memory the R-AM knows about, and that you follow offset's "inbounds" rules using the bound of the MMIO region, you should be good.

RalfJ (Nov 20 2019 at 17:07, on Zulip):

by "knows about" I specifically mean "Rust allocations" -- stack and heap and statics

rkruppe (Nov 20 2019 at 17:43, on Zulip):

That is also how I feel things should be. Though in practice I am concerned that some parts of LLVM may be tempted to infer from "a GEPi is executed" that "the base pointer is dereferenceable" which for MMIO of course isn't so great

rkruppe (Nov 20 2019 at 17:45, on Zulip):

Oh wait, nevermind, GEPi only returns poison if the inbounds condition is violated, so that would be unsound anyway.

gnzlbg (Nov 21 2019 at 09:53, on Zulip):

How are you obtaining the pointer to MMIO ?

gnzlbg (Nov 21 2019 at 09:54, on Zulip):

I expect that API to give you a “fresh” allocation.

gnzlbg (Nov 21 2019 at 09:54, on Zulip):

For example, mmap gives you a noalias pointer to new virtual memory - independently of whether it is IPC shared or not. From LLVM POV thatsa fresh allocation.

gnzlbg (Nov 21 2019 at 09:55, on Zulip):

You can use the Alloc size hints to tell LLVM about the size of the allocation at run time

gnzlbg (Nov 21 2019 at 09:56, on Zulip):

(notice that noalias in return position is different than in argument position)

Lokathor (Nov 23 2019 at 14:23, on Zulip):

The pointer is just a usize cast to the right type.

gnzlbg (Nov 25 2019 at 12:29, on Zulip):

That's fine then.

gnzlbg (Nov 25 2019 at 12:30, on Zulip):

We assume that you will do pointer arithmetic in bounds of the allocation.

gnzlbg (Nov 25 2019 at 12:30, on Zulip):

If the assumption is incorrect, your code might get misoptimized, but if the assumption is correct, everything works out - if your code gets misoptimized, Rust or LLVM have a bug.

gnzlbg (Nov 25 2019 at 12:32, on Zulip):


gnzlbg (Nov 25 2019 at 12:35, on Zulip):

Or in other words, you only get UB for doing pointer arithmetic that's out-of-bound of the actual allocation.

RalfJ (Nov 25 2019 at 13:10, on Zulip):

well you also have to account for the aliasing rules, but since it looks like everything here is raw ptrs those shouldn't come into play

Last update: May 27 2020 at 23:05UTC