aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlyssa Rosenzweig <[email protected]>2019-08-19 15:14:48 -0700
committerAlyssa Rosenzweig <[email protected]>2019-08-21 08:40:53 -0700
commit4391c65f105fc1efcd7ead9f12c552dc21dce4bf (patch)
treef6b783b860da9ced2583554c60726cc4ae01abf8
parent9dfbc8dc03d2339c7deac0c1c44fe1968b402d4a (diff)
pan/decode: Add static bounds checking utility
Many structures in the command stream have a GPU address and size determined statically. We should check that the pointers we are passed are valid and the buffers they point to are big enough for the given size. If they're not, an MMU fault would be raised. Signed-off-by: Alyssa Rosenzweig <[email protected]>
-rw-r--r--src/panfrost/pandecode/decode.c38
1 files changed, 38 insertions, 0 deletions
diff --git a/src/panfrost/pandecode/decode.c b/src/panfrost/pandecode/decode.c
index c9df2cecc61..47ecc744ea9 100644
--- a/src/panfrost/pandecode/decode.c
+++ b/src/panfrost/pandecode/decode.c
@@ -115,6 +115,44 @@ pandecode_log_cont(const char *format, ...)
va_end(ap);
}
+/* To check for memory safety issues, validates that the given pointer in GPU
+ * memory is valid, containing at least sz bytes. The goal is to eliminate
+ * GPU-side memory bugs (NULL pointer dereferences, buffer overflows, or buffer
+ * overruns) by statically validating pointers.
+ */
+
+static void
+pandecode_validate_buffer(mali_ptr addr, size_t sz)
+{
+ if (!addr) {
+ pandecode_msg("XXX: null pointer deref");
+ return;
+ }
+
+ /* Find a BO */
+
+ struct pandecode_mapped_memory *bo =
+ pandecode_find_mapped_gpu_mem_containing(addr);
+
+ if (!bo) {
+ pandecode_msg("XXX: invalid memory dereference\n");
+ return;
+ }
+
+ /* Bounds check */
+
+ unsigned offset = addr - bo->gpu_va;
+ unsigned total = offset + sz;
+
+ if (total > bo->length) {
+ pandecode_msg("XXX: buffer overrun."
+ "Chunk of size %d at offset %d in buffer of size %d. "
+ "Overrun by %d bytes.",
+ sz, offset, bo->length, total - bo->length);
+ return;
+ }
+}
+
struct pandecode_flag_info {
u64 flag;
const char *name;