[cfe-dev] Which optimization barriers do I need here?

Dmitri Gribenko gribozavr at gmail.com
Fri Jan 18 03:02:49 PST 2013


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

I think you need an atomic store here, or the compiler could e.g.,
split an 8-byte store into two 4-byte stores.

Dmitri

-- 
main(i,j){for(i=2;;i++){for(j=2;j<i;j++){if(!(i%j)){j=0;break;}}if
(j){printf("%d\n",i);}}} /*Dmitri Gribenko <gribozavr at gmail.com>*/




More information about the cfe-dev mailing list