Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

lightnvm: pblk: fix race on sysfs line state

pblk exposes a sysfs interface that represents its internal state. Part
of this state is the map bitmap for the current open line, which should
be protected by the line lock to avoid a race when freeing the line
metadata. Currently, it is not.

This patch makes sure that the line state is consistent and NULL
bitmap pointers are not dereferenced.

Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <mb@lightnvm.io>
Signed-off-by: Jens Axboe <axboe@kernel.dk>

authored by

Javier González and committed by
Jens Axboe
44cdbdc6 02a1520d

+10 -3
+3 -2
drivers/lightnvm/pblk-core.c
··· 1611 1611 struct pblk_line *cur, *new = NULL; 1612 1612 unsigned int left_seblks; 1613 1613 1614 - cur = l_mg->data_line; 1615 1614 new = l_mg->data_next; 1616 1615 if (!new) 1617 1616 goto out; 1618 - l_mg->data_line = new; 1619 1617 1620 1618 spin_lock(&l_mg->free_lock); 1619 + cur = l_mg->data_line; 1620 + l_mg->data_line = new; 1621 + 1621 1622 pblk_line_setup_metadata(new, l_mg, &pblk->lm); 1622 1623 spin_unlock(&l_mg->free_lock); 1623 1624
+7 -1
drivers/lightnvm/pblk-sysfs.c
··· 263 263 sec_in_line = l_mg->data_line->sec_in_line; 264 264 meta_weight = bitmap_weight(&l_mg->meta_bitmap, 265 265 PBLK_DATA_LINES); 266 - map_weight = bitmap_weight(l_mg->data_line->map_bitmap, 266 + 267 + spin_lock(&l_mg->data_line->lock); 268 + if (l_mg->data_line->map_bitmap) 269 + map_weight = bitmap_weight(l_mg->data_line->map_bitmap, 267 270 lm->sec_per_line); 271 + else 272 + map_weight = 0; 273 + spin_unlock(&l_mg->data_line->lock); 268 274 } 269 275 spin_unlock(&l_mg->free_lock); 270 276