[lvc-project] [PATCH] gfs2: Fix NULL pointer dereference in gfs2_log_flush
Fedor Pchelkin
pchelkin at ispras.ru
Sun Apr 12 21:30:19 MSK 2026
On Sat, 11. Apr 15:20, Николай Кузнецов wrote:
> Здравствуйте! Отправляю исправленную версию
> рассуждений по предупреждению анализатора.
>
> Предупреждение было ошибочным, далее привожу
> обоснование.
> Согласно коммиту
> [1]https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/gfs2/log.c?id=35264909e9d1973ab9aaa2a1b07cda70f12bb828,
> нулевой указатель sdp->sd_jdesc приходит
> в gfs2_log_flush в ситуации гонки между
> размонтированием файловой системы и
> асинхронной обработки glock в workqueue.
Хм, всё же уверены, что этот коммит валиден? Для этого стоит изучить,
действительно ли возможно состояние гонки, которое он правит: где
зануляется указатель sdp->sd_jdesc и как происходит жизненный цикл
работы &gl->gl_work.
>
> Однако при размонтировании журнал
> обнуляется уже после переведения фс
> в режим readonly и сброса всех изменений
> на диск, а задача из очереди вызывает
> gfs2_log_flush (по цепочке glock_work_func ->
> run_queue -> do_xmote -> inode_go_sync ->
> gfs2_log_flush) без флага
> GFS2_LOG_HEAD_FLUSH_NORMAL, а значит,
> до gfs2_log_shutdown (стр. 1139 log.c)
> исполнение функции просто не дойдёт.
Здесь возможно опечатка. gfs2_log_shutdown() вызывается вроде как раз
когда во флагах _не_ выставлен GFS2_LOG_HEAD_FLUSH_NORMAL.
>
> Проблемы с вызовами log_write_header (строки
> 1111 и 1113) тоже нет, поскольку перед обнулением
> журнала вызывается gfs2_log_flush с флагом
> GFS2_LOG_HEAD_FLUSH_SHUTDOWN и
> из-за вызовов log_pull_tail и gfs2_log_update_head
> при размонтировании не будут выполнены
> условия в строках 1110 и 1112.
Как понимаю, речь идёт об условиях
if (sdp->sd_log_head != sdp->sd_log_flush_head) {
log_write_header(sdp, flags);
} else if (sdp->sd_log_tail != sdp->sd_log_flush_tail && !sdp->sd_log_idle) {
log_write_header(sdp, flags);
}
и почему они не будут выполнены при shutdown? Не ясна связь с
log_pull_tail() и gfs2_log_update_head().
Разыменовывание возможно ещё по метке out_end в функции log_distance():
https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/log.c#L1143
Пока предлагаю подробнее изучить коммит 35264909e9d1 ("gfs2: Fix NULL
pointer dereference in gfs2_log_flush"). Согласны ли с проблемой,
которую он правит?
More information about the lvc-project
mailing list