I think we don't care about the compiler splitting the store, as long as it isn't interleaved with a system call. Our hook only ever runs as a direct result of an intercepted system call.<div><br></div><div>We have some (limited) control over when we output system calls, as we know that basic assignments won't generate system calls behind the scenes. But of course, something like "delete[]" could very legitimately result in system calls. So, our assignment to the pointer has to be completed prior to "delete[]".</div>

<div><br></div><div>Otherwise, we could end up dereferencing the old pointer from our hook, even though "delete[]" already released the memory.</div><div><br></div><div>Similarly, we have to make sure that "memcpy()" has completed prior to us switching the pointer.</div>

<div><br></div><div>N.B.: this is all single threaded code and due to the nature of how the sandbox works, we know it will never be changed to be multi-threaded code. So, as far as the CPU is concerned, this is perfectly deterministic code. We don't need to worry about CPU barriers or about effects of the memory model. Neither do we have to worry about any asynchronous events. All we care about are compiler barriers.</div>

<div><br><br>Markus<br><br><div class="gmail_quote">On Fri, Jan 18, 2013 at 3:02 AM, Dmitri Gribenko <span dir="ltr"><<a href="mailto:gribozavr@gmail.com" target="_blank">gribozavr@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">

<div class="HOEnZb"><div class="h5">On Fri, Jan 18, 2013 at 3:53 AM, Markus Gutschke (顧孟勤)<br>
<<a href="mailto:markus@google.com">markus@google.com</a>> wrote:<br>
> I am writing sandboxing code for Google Chrome that has the potential to<br>
> trigger execution of a hook function on any arbitrary system call that the<br>
> program makes. Inside of the hook function, it performs a read-only<br>
> operation on a global data structure that describes some of the sandboxing<br>
> policies. This works fine once sandbox initialization has completed, but it<br>
> requires special care when initially setting up this data structure as we<br>
> never want to present invalid data (e.g. use after free) to the hook<br>
> function. And as system calls are somewhat out of the scope of the C++<br>
> language specification, we have to assume that they can happen at (almost)<br>
> any time.<br>
><br>
> A very simplified version of our code looks like this:<br>
><br>
> #include <string.h><br>
><br>
> // We have some low-level code that can trigger on any system call and that<br>
> // performs a read-only access to "data". It is guaranteed to only ever<br>
> access<br>
> // indices between [0..n_data) and it doesn't need to look at "n_data". So,<br>
> it<br>
> // is OK if a) "data" points to either new or old memory locations as long<br>
> as<br>
> // they contain valid data, and b) the value of "n_data" does not need to be<br>
> // consistent.<br>
> // We are not concerned about multi-threaded code. Our code is guaranteed to<br>
> be<br>
> // single-threaded at this time.<br>
> // We are also not concerned about asynchronous signals. Our code will only<br>
> ever<br>
> // execute synchronously as a direct result of a system call.<br>
> static char *data;<br>
> static size_t n_data;<br>
><br>
> void AddToData(char ch) {<br>
>   // Copy data from "data" to "new_data". Don't use realloc() as it could be<br>
>   // making system calls at unexpected times.<br>
>   // Then switch pointers without making any interleaving system calls.<br>
>   char *old_data = data;<br>
>   char *new_data = new char[n_data + 1];<br>
>   memcpy(new_data, data, n_data);<br>
><br>
>   // Do we need a barrier here to make sure memcpy() has completed before<br>
>   // we switch the pointer in "data"?<br>
>   data = new_data;<br>
<br>
</div></div>I think you need an atomic store here, or the compiler could e.g.,<br>
split an 8-byte store into two 4-byte stores.<br>
<span class="HOEnZb"><font color="#888888"><br>
Dmitri<br>
<br>
--<br>
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if<br>
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <<a href="mailto:gribozavr@gmail.com">gribozavr@gmail.com</a>>*/<br>
</font></span></blockquote></div><br></div>