drm/komeda: Fix bit check to import to value of proper type

Another issue found by KASAN. The bit finding is buried inside the
dp_for_each_set_bit() macro (that passes on to for_each_set_bit() that
calls the bit stuff. These bit functions want an unsigned long pointer
as input and just dumbly casting leads to out-of-bounds accesses.
This fixes that.

Signed-off-by: Carsten Haitzler <carsten.haitzler@arm.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: James Qian Wang <james.qian.wang@arm.com>
Signed-off-by: Liviu Dudau <liviu.dudau@arm.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20210204131102.68658-1-carsten.haitzler@foss.arm.com
This commit is contained in:
Carsten Haitzler 2021-02-04 13:11:02 +00:00 committed by Liviu Dudau
parent 6f6ab53359
commit a1c3be8904
3 changed files with 22 additions and 16 deletions

View File

@ -13,9 +13,6 @@
#define has_bit(nr, mask) (BIT(nr) & (mask)) #define has_bit(nr, mask) (BIT(nr) & (mask))
#define has_bits(bits, mask) (((bits) & (mask)) == (bits)) #define has_bits(bits, mask) (((bits) & (mask)) == (bits))
#define dp_for_each_set_bit(bit, mask) \
for_each_set_bit((bit), ((unsigned long *)&(mask)), sizeof(mask) * 8)
#define dp_wait_cond(__cond, __tries, __min_range, __max_range) \ #define dp_wait_cond(__cond, __tries, __min_range, __max_range) \
({ \ ({ \
int num_tries = __tries; \ int num_tries = __tries; \

View File

@ -46,8 +46,9 @@ void komeda_pipeline_destroy(struct komeda_dev *mdev,
{ {
struct komeda_component *c; struct komeda_component *c;
int i; int i;
unsigned long avail_comps = pipe->avail_comps;
dp_for_each_set_bit(i, pipe->avail_comps) { for_each_set_bit(i, &avail_comps, 32) {
c = komeda_pipeline_get_component(pipe, i); c = komeda_pipeline_get_component(pipe, i);
komeda_component_destroy(mdev, c); komeda_component_destroy(mdev, c);
} }
@ -247,6 +248,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
{ {
struct komeda_component *c; struct komeda_component *c;
int id; int id;
unsigned long avail_comps = pipe->avail_comps;
DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n", DRM_INFO("Pipeline-%d: n_layers: %d, n_scalers: %d, output: %s.\n",
pipe->id, pipe->n_layers, pipe->n_scalers, pipe->id, pipe->n_layers, pipe->n_scalers,
@ -258,7 +260,7 @@ static void komeda_pipeline_dump(struct komeda_pipeline *pipe)
pipe->of_output_links[1] ? pipe->of_output_links[1] ?
pipe->of_output_links[1]->full_name : "none"); pipe->of_output_links[1]->full_name : "none");
dp_for_each_set_bit(id, pipe->avail_comps) { for_each_set_bit(id, &avail_comps, 32) {
c = komeda_pipeline_get_component(pipe, id); c = komeda_pipeline_get_component(pipe, id);
komeda_component_dump(c); komeda_component_dump(c);
@ -270,8 +272,9 @@ static void komeda_component_verify_inputs(struct komeda_component *c)
struct komeda_pipeline *pipe = c->pipeline; struct komeda_pipeline *pipe = c->pipeline;
struct komeda_component *input; struct komeda_component *input;
int id; int id;
unsigned long supported_inputs = c->supported_inputs;
dp_for_each_set_bit(id, c->supported_inputs) { for_each_set_bit(id, &supported_inputs, 32) {
input = komeda_pipeline_get_component(pipe, id); input = komeda_pipeline_get_component(pipe, id);
if (!input) { if (!input) {
c->supported_inputs &= ~(BIT(id)); c->supported_inputs &= ~(BIT(id));
@ -302,8 +305,9 @@ static void komeda_pipeline_assemble(struct komeda_pipeline *pipe)
struct komeda_component *c; struct komeda_component *c;
struct komeda_layer *layer; struct komeda_layer *layer;
int i, id; int i, id;
unsigned long avail_comps = pipe->avail_comps;
dp_for_each_set_bit(id, pipe->avail_comps) { for_each_set_bit(id, &avail_comps, 32) {
c = komeda_pipeline_get_component(pipe, id); c = komeda_pipeline_get_component(pipe, id);
komeda_component_verify_inputs(c); komeda_component_verify_inputs(c);
} }
@ -355,13 +359,15 @@ void komeda_pipeline_dump_register(struct komeda_pipeline *pipe,
{ {
struct komeda_component *c; struct komeda_component *c;
u32 id; u32 id;
unsigned long avail_comps;
seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id); seq_printf(sf, "\n======== Pipeline-%d ==========\n", pipe->id);
if (pipe->funcs && pipe->funcs->dump_register) if (pipe->funcs && pipe->funcs->dump_register)
pipe->funcs->dump_register(pipe, sf); pipe->funcs->dump_register(pipe, sf);
dp_for_each_set_bit(id, pipe->avail_comps) { avail_comps = pipe->avail_comps;
for_each_set_bit(id, &avail_comps, 32) {
c = komeda_pipeline_get_component(pipe, id); c = komeda_pipeline_get_component(pipe, id);
seq_printf(sf, "\n------%s------\n", c->name); seq_printf(sf, "\n------%s------\n", c->name);

View File

@ -1231,14 +1231,15 @@ komeda_pipeline_unbound_components(struct komeda_pipeline *pipe,
struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state); struct komeda_pipeline_state *old = priv_to_pipe_st(pipe->obj.state);
struct komeda_component_state *c_st; struct komeda_component_state *c_st;
struct komeda_component *c; struct komeda_component *c;
u32 disabling_comps, id; u32 id;
unsigned long disabling_comps;
WARN_ON(!old); WARN_ON(!old);
disabling_comps = (~new->active_comps) & old->active_comps; disabling_comps = (~new->active_comps) & old->active_comps;
/* unbound all disabling component */ /* unbound all disabling component */
dp_for_each_set_bit(id, disabling_comps) { for_each_set_bit(id, &disabling_comps, 32) {
c = komeda_pipeline_get_component(pipe, id); c = komeda_pipeline_get_component(pipe, id);
c_st = komeda_component_get_state_and_set_user(c, c_st = komeda_component_get_state_and_set_user(c,
drm_st, NULL, new->crtc); drm_st, NULL, new->crtc);
@ -1286,7 +1287,8 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,
struct komeda_pipeline_state *old; struct komeda_pipeline_state *old;
struct komeda_component *c; struct komeda_component *c;
struct komeda_component_state *c_st; struct komeda_component_state *c_st;
u32 id, disabling_comps = 0; u32 id;
unsigned long disabling_comps;
old = komeda_pipeline_get_old_state(pipe, old_state); old = komeda_pipeline_get_old_state(pipe, old_state);
@ -1296,10 +1298,10 @@ bool komeda_pipeline_disable(struct komeda_pipeline *pipe,
disabling_comps = old->active_comps & disabling_comps = old->active_comps &
pipe->standalone_disabled_comps; pipe->standalone_disabled_comps;
DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%x.\n", DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, disabling_comps: 0x%lx.\n",
pipe->id, old->active_comps, disabling_comps); pipe->id, old->active_comps, disabling_comps);
dp_for_each_set_bit(id, disabling_comps) { for_each_set_bit(id, &disabling_comps, 32) {
c = komeda_pipeline_get_component(pipe, id); c = komeda_pipeline_get_component(pipe, id);
c_st = priv_to_comp_st(c->obj.state); c_st = priv_to_comp_st(c->obj.state);
@ -1330,16 +1332,17 @@ void komeda_pipeline_update(struct komeda_pipeline *pipe,
struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state); struct komeda_pipeline_state *new = priv_to_pipe_st(pipe->obj.state);
struct komeda_pipeline_state *old; struct komeda_pipeline_state *old;
struct komeda_component *c; struct komeda_component *c;
u32 id, changed_comps = 0; u32 id;
unsigned long changed_comps;
old = komeda_pipeline_get_old_state(pipe, old_state); old = komeda_pipeline_get_old_state(pipe, old_state);
changed_comps = new->active_comps | old->active_comps; changed_comps = new->active_comps | old->active_comps;
DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%x.\n", DRM_DEBUG_ATOMIC("PIPE%d: active_comps: 0x%x, changed: 0x%lx.\n",
pipe->id, new->active_comps, changed_comps); pipe->id, new->active_comps, changed_comps);
dp_for_each_set_bit(id, changed_comps) { for_each_set_bit(id, &changed_comps, 32) {
c = komeda_pipeline_get_component(pipe, id); c = komeda_pipeline_get_component(pipe, id);
if (new->active_comps & BIT(c->id)) if (new->active_comps & BIT(c->id))