<div>> В чём заключается ошибка?</div><div> </div><div>В функцию gfs2_log_flush может прийти нулевой указатель</div><div>sdp->sd_jdesc, после чего будет цепочка вызовов:</div><div>gfs2_log_shutdown(sdp) -> log_pull_tail(sdp) -></div><div>dist = log_distance(sdp, new_tail, sdp->sd_log_tail), а в log_distance</div><div>уже происходит его разыменование. Согласен, из патча это неясно, перепишу.</div><div> </div><div><div>> То есть после патча по неизвестной (пока) причине будет пропускаться<br />> код, который вроде как и готов обрабатывать нулевой указатель<br /><br />Тот код был добавлен как раз в целях избежания разыменования</div><div>в конкретном месте, прикладываю ссылку на коммит:</div><div><div><a href="https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/gfs2/log.c?id=35264909e9d1973ab9aaa2a1b07cda70f12bb828" rel="noopener noreferrer" target="_blank">https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/fs/gfs2/log.c?id=35264909e9d1973ab9aaa2a1b07cda70f12bb828</a><br />Там нет полноценной обработки указателя, как я понял,</div><div>только обработка частной траектории выполнения.</div><div> </div><div>В данном коммите нет тега Fixes, я последовал примеру и не стал</div><div>его добавлять.</div><div><br />Действительно, я думал над тем, чтобы убрать обработку</div><div>указателя в том месте, но старался следовать инструкции с</div><div><div><a href="https://portal.linuxtesting.ru/How-to-send-patches-to-kernel.html" rel="noopener noreferrer" target="_blank">https://portal.linuxtesting.ru/How-to-send-patches-to-kernel.html</a>,<br />в которой говорится, что само исправление и рефакторинг</div><div>следует разносить по разным патчам, а удаление этой</div><div>проверки подпадает под рефакторинг, потому и не стал</div><div>смешивать всё в один патч.</div><div> </div><div>Мне показалось логичнее сделать ассерт в начале,</div><div>чтобы в следующей строчке сразу было попадание на проверку</div><div>withdrawn.</div></div></div></div><blockquote><p>On Mon, 06. Apr 15:00, Николай Кузнецов wrote:</p><blockquote>    > Без контекста не очень ясно, на какой ветке ядра встретили срабатывание<br />    > стат. анализатора и готовили исправление?<br /> <br />    Под контекстом имеются в виду теги Fixes или Cc? Если нет, то как его указать?</blockquote><p><br />Теги Fixes в фикс-патчи ставить надо, но это другое. Контекст мне уже<br />пояснили, я просто не заметил сначала знакомые CS MSU в почтовом адресе.<br /> </p><blockquote> <br />    Версия ядра 6.1.164.</blockquote><p><br />ОК, для определённости тогда будем рассматривать ситуацию на этой версии.<br /> </p><blockquote>    > Бывает полезно осматривать<br />    > состояние исследуемого кода в самом свежем апстрим-репозитории ядра [1].<br />    > Каков статус проблемы там?<br /> <br />    Смотрел исправляемый файл в апстрим репозитории, там никаких действий по<br />    предотвращению разыменования нулевого указателя не увидел, сделал вывод,<br />    что ошибка всё ещё присутствует.</blockquote><p><br />В чём заключается ошибка? Из описания текущего патча её честно говоря<br />не понять.. Что и где должно разыменоваться и упасть?<br /> </p><blockquote>    > gfs2_assert_withdraw() предотвращает выполнение текущей функции?<br />    > Насколько понимаю, нет. Т.е. от потенциального дальнейшего креша не<br />    > спасёт<br /> <br />    Как я понял, после ассерта и в итоге withdraw будет выставлен<br />    флаг SDF_WITHDRAWN ([1]<a href="https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/util.c#L339" rel="noopener noreferrer">https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/util.c#L339</a>)<br />    и тогда, сразу после ассерта, на проверке в<br />    строчке [2]<a href="https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/log.c#L1051" rel="noopener noreferrer">https://elixir.bootlin.com/linux/v6.1.164/source/fs/gfs2/log.c#L1051</a><br />    будет goto out, что позволит избежать проблемы.</blockquote><p><br />После патча функция gfs2_log_flush() будет выглядеть так:<br /><br />void gfs2_log_flush(struct gfs2_sbd *sdp, struct gfs2_glock *gl, u32 flags)<br />{<!-- --><br />        ...<br />        gfs2_assert_withdraw(sdp, sdp->sd_jdesc != NULL); // допустим sdp->sd_jdesc правда NULL<br /><br />repeat:<br />        /*<br />         * Do this check while holding the log_flush_lock to prevent new<br />         * buffers from being added to the ail via gfs2_pin()<br />         */<br />        if (gfs2_withdrawn(sdp) || !test_bit(SDF_JOURNAL_LIVE, &sdp->sd_flags))<br />                goto out; <<<<<============ тогда здесь идём в метку out<br /><br />        ...<br />        if (sdp->sd_jdesc) <<<<<========= а здесь вроде готовы обработать указатель<br />                gfs2_log_submit_bio(&sdp->sd_jdesc->jd_log_bio, REQ_OP_WRITE);<br /><br />out:<br />        ...<br />}<br /><br />Это всё на версии 6.1.164.<br /><br />То есть после патча по неизвестной (пока) причине будет пропускаться<br />код, который вроде как и готов обрабатывать нулевой указатель..</p></blockquote>