[Intel-gfx] Error in inner loop in validate_cmds_sorted / out of bounds issue
Chris Wilson
chris at chris-wilson.co.uk
Mon Jul 27 01:59:45 PDT 2015
On Sat, Jul 25, 2015 at 06:56:20PM -0700, Hanno Böck wrote:
> Hi,
>
> I was trying to track down an out of bounds read issue in the intel drm
> driver that got reported by kasan.
>
> It happens in the function validate_cmds_sorted (i915_cmd_parser.c),
> where there are two nested loops, this is the relevant code part:
> for (i = 0; i < cmd_table_count; i++) {
> const struct drm_i915_cmd_table *table = &cmd_tables[i];
> u32 previous = 0;
> int j;
>
> for (j = 0; j < table->count; j++) {
> const struct drm_i915_cmd_descriptor *desc =
> &table->table[i];
>
>
> Now that &table->table[i] should probably really be &table->table[j],
> because that's the counter variable of the inner loop. Otherwise it
> doesn't make any sense (the inner loop would just repeat doing the same
> thing multiple times).
> However if I try to change [i] to [j] here my system doesn't boot any
> more, I just get a black screen. So I assume this bug is somehow hiding
> another more severe bug.
The tables aren't sorted, that is worth fixing.
This should get you booting with minimal fuss if you care to track down
the error.
diff --git a/drivers/gpu/drm/i915/i915_cmd_parser.c b/drivers/gpu/drm/i915/i915_cmd_parser.c
index 430571b..688e814 100644
--- a/drivers/gpu/drm/i915/i915_cmd_parser.c
+++ b/drivers/gpu/drm/i915/i915_cmd_parser.c
@@ -672,6 +672,13 @@ static void fini_hash_table(struct intel_engine_cs *ring)
}
}
+#define DRM_ERROR_ON(cond, fmt, ...) ({ \
+ bool __cond = !!(cond); \
+ if (unlikely(__cond)) \
+ drm_err("assertion failed, %s: " fmt, #cond, ##__VA_ARGS__); \
+ unlikely(__cond); \
+})
+
/**
* i915_cmd_parser_init_ring() - set cmd parser related fields for a ringbuffer
* @ring: the ringbuffer to initialize
@@ -751,11 +758,16 @@ int i915_cmd_parser_init_ring(struct intel_engine_cs *ring)
default:
DRM_ERROR("CMD: cmd_parser_init with unknown ring: %d\n",
ring->id);
- BUG();
+ return -ENODEV;
}
- BUG_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count));
- BUG_ON(!validate_regs_sorted(ring));
+ if (DRM_ERROR_ON(!validate_cmds_sorted(ring, cmd_tables, cmd_table_count),
+ "command parser table is not sorted - required for bisetion searching\n"))
+ return -ENODEV;
+
+ if (DRM_ERROR_ON(!validate_regs_sorted(ring),
+ "register lists are not sorted - required for bisection searching\n"))
+ return -ENODEV;
WARN_ON(!hash_empty(ring->cmd_hash));
--
Chris Wilson, Intel Open Source Technology Centre
More information about the Intel-gfx
mailing list