Commit 3b4efa14 authored by Mika Kuoppala's avatar Mika Kuoppala

drm/i915: Fix cmd parser desc matching with masks

Our variety of defined gpu commands have the actual
command id field and possibly length and flags applied.

We did start to apply the mask during initialization of
the cmd descriptors but forgot to also apply it on comparisons.

Fix comparisons in order to properly deny access with
associated commands.

v2: fix lri with correct mask (Chris)

References: 926abff2 ("drm/i915/cmdparser: Ignore Length operands during command matching")
Reported-by: default avatarNicolai Stange <nstange@suse.de>
Cc: stable@vger.kernel.org # v5.4+
Cc: Miroslav Benes <mbenes@suse.cz>
Cc: Takashi Iwai <tiwai@suse.de>
Cc: Tyler Hicks <tyhicks@canonical.com>
Cc: Jon Bloomfield <jon.bloomfield@intel.com>
Cc: Chris Wilson <chris.p.wilson@intel.com>
Signed-off-by: default avatarMika Kuoppala <mika.kuoppala@linux.intel.com>
Reviewed-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
Link: https://patchwork.freedesktop.org/patch/msgid/20200817195926.12671-1-mika.kuoppala@linux.intel.com
parent d24f1341
...@@ -1204,6 +1204,12 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj, ...@@ -1204,6 +1204,12 @@ static u32 *copy_batch(struct drm_i915_gem_object *dst_obj,
return dst; return dst;
} }
static inline bool cmd_desc_is(const struct drm_i915_cmd_descriptor * const desc,
const u32 cmd)
{
return desc->cmd.value == (cmd & desc->cmd.mask);
}
static bool check_cmd(const struct intel_engine_cs *engine, static bool check_cmd(const struct intel_engine_cs *engine,
const struct drm_i915_cmd_descriptor *desc, const struct drm_i915_cmd_descriptor *desc,
const u32 *cmd, u32 length) const u32 *cmd, u32 length)
...@@ -1242,19 +1248,19 @@ static bool check_cmd(const struct intel_engine_cs *engine, ...@@ -1242,19 +1248,19 @@ static bool check_cmd(const struct intel_engine_cs *engine,
* allowed mask/value pair given in the whitelist entry. * allowed mask/value pair given in the whitelist entry.
*/ */
if (reg->mask) { if (reg->mask) {
if (desc->cmd.value == MI_LOAD_REGISTER_MEM) { if (cmd_desc_is(desc, MI_LOAD_REGISTER_MEM)) {
DRM_DEBUG("CMD: Rejected LRM to masked register 0x%08X\n", DRM_DEBUG("CMD: Rejected LRM to masked register 0x%08X\n",
reg_addr); reg_addr);
return false; return false;
} }
if (desc->cmd.value == MI_LOAD_REGISTER_REG) { if (cmd_desc_is(desc, MI_LOAD_REGISTER_REG)) {
DRM_DEBUG("CMD: Rejected LRR to masked register 0x%08X\n", DRM_DEBUG("CMD: Rejected LRR to masked register 0x%08X\n",
reg_addr); reg_addr);
return false; return false;
} }
if (desc->cmd.value == MI_LOAD_REGISTER_IMM(1) && if (cmd_desc_is(desc, MI_LOAD_REGISTER_IMM(1)) &&
(offset + 2 > length || (offset + 2 > length ||
(cmd[offset + 1] & reg->mask) != reg->value)) { (cmd[offset + 1] & reg->mask) != reg->value)) {
DRM_DEBUG("CMD: Rejected LRI to masked register 0x%08X\n", DRM_DEBUG("CMD: Rejected LRI to masked register 0x%08X\n",
...@@ -1478,7 +1484,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine, ...@@ -1478,7 +1484,7 @@ int intel_engine_cmd_parser(struct intel_engine_cs *engine,
break; break;
} }
if (desc->cmd.value == MI_BATCH_BUFFER_START) { if (cmd_desc_is(desc, MI_BATCH_BUFFER_START)) {
ret = check_bbstart(cmd, offset, length, batch_length, ret = check_bbstart(cmd, offset, length, batch_length,
batch_addr, shadow_addr, batch_addr, shadow_addr,
jump_whitelist); jump_whitelist);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment