Post a Comment
Red paint, girlscout, etc?
More seriously, the GPU is *again* the weak link. That is cause for concern for the security of modern browsers: is it manageable when they have so much code touching so many hard/soft wares?
Actually C and C++ are the weakest links, not the GPU, as the exploits take advantage of the pointer tricks so dear to C and C++ developers.
If ComputeMaxResults() was done in a more sane language, this exploit wouldn't have been possible, without doing some Assembly code rewriting.
Did you actually read the functions? It is a calculation logic error. There is no language alive to prevent logic errors. The logic error results in an invalid buffer access for a GPU related task. No "sane" language has yet been extended to use GPUs that do no rely on creating buffers directly at some point in its execution.
You do understand that were a managed language required to access the GPU, it would also need to do manual memory management undercovers, don't you?
Yes I've read the functions, ComputeMaxResults() and ComputeSize(),
are the standard way to manipulate blocks of memory/arrays in C and related to the way arrays decay into pointers.
Safe programming languages != GC != Managed.
Ada, Modula-2, Delphi, Turbo Pascal are safe programming languages with manual memory management, compiling nicely to native code as well, just as an example.
Really.
static uint32 ComputeMaxResults(size_t size_of_buffer) { return (size_of_buffer - sizeof(uint32)) / sizeof(T); }
So, say, Delphi, would prevent someone from making a mistake doing a subtraction and then a division, knowing what the calculation would be used for, would it?
size_of_buffer is an integer.
So is sizeof(uint32).
So is sizeof(T).
Are you seriously telling me there are programming languages out there that would actually tell the programmer "hey, did you know size_of_buffer you passed in was smaller than the size of uint32, and I checked every usage of ComputeMaxResults and I've noticed these unsafe uses?"
Yes, because if you really cared to read everything, you will see that the outcome of such functions is used for buffer manipulation tricks.
The next thing Pinkie needed was a target that met two criteria: it had to be positioned within range of his overwrite, and the first eight bytes needed to be something worth changing. For this, he used the GPU buckets, which are another IPC primitive exposed from the GPU process to the Native Client process. The buckets are implemented as a tree structure, with the first eight bytes containing pointers to other nodes in the tree. By overwriting the first eight bytes of a bucket, Pinkie was able to point it to a fake tree structure he created in one of his transfer buffers. Using that fake tree, Pinkie could read and write arbitrary addresses in the GPU process. Combined with some predictable addresses in Windows, this allowed him to build a ROP chain and execute arbitrary code inside the GPU process.
A safer language would have a runtime error when such situations get detected.
The logic error as you called is only required, because they need to calculate specific values for pointer math. Without pointer math no need for logic errors that turn into buffer exploits.
Really.
static uint32 ComputeMaxResults(size_t size_of_buffer) { return (size_of_buffer - sizeof(uint32)) / sizeof(T); }
So, say, Delphi, would prevent someone from making a mistake doing a subtraction and then a division, knowing what the calculation would be used for, would it?
I don't know about Delphi specifically, but for most of the languages that are considered "safe" in this respect, you're not allowed to pass around raw blocks of memory without any type safety/control. As a consequence, the language's runtime always knows and tracks the size of any currently allocated arrays. Given this knowledge, the runtime effectively converts any instance of array[x] to something analogous to:
if (x < 0 || x >= arraySize)
raise_runtime_error();
else
return array[x];
Obviously this incurs some overhead compared to the raw C version, but it does indeed prevent these kinds of problems. So yes, it really is possible to handle in a safe/high level language, if the logic error in question is confined to the level of the language. However, if the logic error is actually in the instructions passed to the GPU itself, and the latter is able to access arbitrary areas of memory, then that's a different story.
Edited 2012-05-23 17:54 UTC
**ALL** languages talk to the hardware the same way!
Memory pointers are a hardware feature. They just happen to be 'exposed' in c/++. I can use assembly to fool any programming written in any language that I am friendly and of the same breed and interject myself using hardware features.
Security like you are speaking would require a massive hardware change where memory is addressed in locked relative-memory segments. That is every process can create restricted areas of memory which can only be accessed by a compile-time validated code-path - something a few steps beyond nX-bits.
Even then, you would only need to find a way to inject yourself into that code-path by altering the binary... but that would be easier to catch and prevent. You would then need to rely on OS/hardware bugs... but you would still be able to get 'in' in some manner...nothing is safe beyond not permitting execution at all...
Which language was used simply doesn't mean squat. A program written in Delphi still debases itself to the same approximate code which was written in c. I'm still using movl %eax, %ecx, call, jmp, etc...
--The loon
Edited 2012-05-23 17:02 UTC
You say there is no known language where this calculation would return the right result? Obviously you don't know Python or Ruby. These language have variable length integers which means that you never have a integer overflow/underflow.
Yes, the result is then a negative number. But given the definition of the function and the parameters the result is "correct". And in Ruby/Python you don't have any buffers through which you can access arbitrary memory anyway.
I've programmed in Python. I love Python. How would you suggest Python be able to directly instruct the GPU? I'll give you a hint: you write the extension in C.
This is the cause of my earlier lament. People like you treat it as though languages like Python and Ruby magically spawn out of nowhere without having anything to do with C.
But given the PURPOSE of the function, the "correct" answer is wrong. And you'll end up with the same problem of incorrectly addressing the buffers contents.
So it is a LOGIC error. The formula is WRONG. Languages cannot fix wrong formulae, which is the heart of the problem with the function.
Unless you write an extension in C, which you pretty much have to do if you want it to talk to the GPU.
This is why one of the earlier commenters was right. This is about the GPU. Not the language.
And it's only a start: when I read about Firefox's developpers working on WebGL, I immediately thought: this feature has a lot of potential security issues..
Maybe not the same guys, but they obviously got the inspiration from the same place (see http://arstechnica.com/business/2012/03/googles-chrome-browser-on-f... ). Which is all right, because Pinkie Pie is awesome.




