Skip to content

Commit

Permalink
mtd: maps: pcmciamtd: fix possible sleep-in-atomic-context bugs in pc…
Browse files Browse the repository at this point in the history
…mciamtd_set_vpp()

The driver may sleep while holding a spinlock.
The function call path (from bottom to top) in Linux 4.19 is:

drivers/pcmcia/pcmcia_resource.c, 312:
	mutex_lock in pcmcia_fixup_vpp
drivers/mtd/maps/pcmciamtd.c, 309:
	pcmcia_fixup_vpp in pcmciamtd_set_vpp
drivers/mtd/maps/pcmciamtd.c, 306:
	_raw_spin_lock_irqsave in pcmciamtd_set_vpp

drivers/pcmcia/pcmcia_resource.c, 312:
	mutex_lock in pcmcia_fixup_vpp
drivers/mtd/maps/pcmciamtd.c, 312:
	pcmcia_fixup_vpp in pcmciamtd_set_vpp
drivers/mtd/maps/pcmciamtd.c, 306:
	_raw_spin_lock_irqsave in pcmciamtd_set_vp

mutex_lock() may sleep at runtime.

To fix these bugs, the spinlock is replaced with a mutex.

These bugs are found by a static analysis tool STCheck written by
myself.

Signed-off-by: Jia-Ju Bai <[email protected]>
Reviewed-by: Dominik Brodowski <[email protected]>
Signed-off-by: Miquel Raynal <[email protected]>
  • Loading branch information
XidianGeneral authored and miquelraynal committed Jan 27, 2020
1 parent e42617b commit 2a0b390
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions drivers/mtd/maps/pcmciamtd.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,24 +294,23 @@ static void pcmcia_copy_to(struct map_info *map, unsigned long to, const void *f
}


static DEFINE_SPINLOCK(pcmcia_vpp_lock);
static DEFINE_MUTEX(pcmcia_vpp_lock);
static int pcmcia_vpp_refcnt;
static void pcmciamtd_set_vpp(struct map_info *map, int on)
{
struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
struct pcmcia_device *link = dev->p_dev;
unsigned long flags;

pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
spin_lock_irqsave(&pcmcia_vpp_lock, flags);
mutex_lock(&pcmcia_vpp_lock);
if (on) {
if (++pcmcia_vpp_refcnt == 1) /* first nested 'on' */
pcmcia_fixup_vpp(link, dev->vpp);
} else {
if (--pcmcia_vpp_refcnt == 0) /* last nested 'off' */
pcmcia_fixup_vpp(link, 0);
}
spin_unlock_irqrestore(&pcmcia_vpp_lock, flags);
mutex_unlock(&pcmcia_vpp_lock);
}


Expand Down

0 comments on commit 2a0b390

Please sign in to comment.