caif: Bugfix list_del_rcu race in cfmuxl_ctrlcmd.
Always use cfmuxl_remove_uplayer when removing a up-layer. cfmuxl_ctrlcmd() can be called independently and in parallel with cfmuxl_remove_uplayer(). The race between them could cause list_del_rcu to be called on a node which has been already taken out from the list. That lead to a (rare) crash on accessing poisoned node->prev inside list_del_rcu. This fix ensures that deletion are done holding the same lock. Reported-by: Dmitry Tarnyagin <dmitry.tarnyagin@stericsson.com> Signed-off-by: Sjur Brændeland <sjur.brandeland@stericsson.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
c31c151b1c
commit
b01377a420
1 changed files with 2 additions and 8 deletions
|
@ -248,7 +248,6 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
|
||||||
{
|
{
|
||||||
struct cfmuxl *muxl = container_obj(layr);
|
struct cfmuxl *muxl = container_obj(layr);
|
||||||
struct cflayer *layer;
|
struct cflayer *layer;
|
||||||
int idx;
|
|
||||||
|
|
||||||
rcu_read_lock();
|
rcu_read_lock();
|
||||||
list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
|
list_for_each_entry_rcu(layer, &muxl->srvl_list, node) {
|
||||||
|
@ -257,14 +256,9 @@ static void cfmuxl_ctrlcmd(struct cflayer *layr, enum caif_ctrlcmd ctrl,
|
||||||
|
|
||||||
if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
|
if ((ctrl == _CAIF_CTRLCMD_PHYIF_DOWN_IND ||
|
||||||
ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
|
ctrl == CAIF_CTRLCMD_REMOTE_SHUTDOWN_IND) &&
|
||||||
layer->id != 0) {
|
layer->id != 0)
|
||||||
|
cfmuxl_remove_uplayer(layr, layer->id);
|
||||||
|
|
||||||
idx = layer->id % UP_CACHE_SIZE;
|
|
||||||
spin_lock_bh(&muxl->receive_lock);
|
|
||||||
RCU_INIT_POINTER(muxl->up_cache[idx], NULL);
|
|
||||||
list_del_rcu(&layer->node);
|
|
||||||
spin_unlock_bh(&muxl->receive_lock);
|
|
||||||
}
|
|
||||||
/* NOTE: ctrlcmd is not allowed to block */
|
/* NOTE: ctrlcmd is not allowed to block */
|
||||||
layer->ctrlcmd(layer, ctrl, phyid);
|
layer->ctrlcmd(layer, ctrl, phyid);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue