Я тут интереса ради (давно хотел на чем-нибудь попробовать) проверил libaal и reiser4progs статическим анализатором PVS (используя бесплатную лицензию для свободных проектов) и получил несколько подозрительных мест. Может потом проверю код reiser4 в самом ядре (на сайте Habrahabr в блоге PVS они как-то проверяли ядро).
В libaal ничего криминального, предупреждения в types.h о повторном typedef (некоторые типы в C11 добавили, va_list в стандарте есть) и две возможные ошибки, где используется битовый сдвиг на 32-битном значении и преобразуется в 64-битное.
С reiser4progs немного поинтереснее. В файлах plugin/key/key_short/key_short_repair.c и plugin/key/key_large/key_large_repair.c присуствуют подобные выражения:
key_short_set_locality(key, oid & !KEY_SHORT_BAND_MASK)
KEY_SHORT_BAND_MASK это enum 0xf000000000000000ull и при булевой операции отрицания ! получается ноль. Может в этих местах имелся в виду битовый оператор инвертирования ~?
В plugin/hash/tea_hash/tea_hash.c есть несколько условий которые всегда ложны (в while условие len >= 16, соотвественно следующая проверка len >= 16 ложна и так дальше по лесенке). Хотя учитывая что в теле этих if'ов подобный код:
*(int *)0 = 0;
То я даже не уверен что это.
В plugin/sdext/sdext_plug/sdext_plug.c проверка stat на nullptr идет после разыменования stat (да и перед этим он тоже разыменовывается), т.к. по стандарту выражение в if вычисляется слева направо, а !stat находится в самом конце.
В plugin/item/cde40/cde40_repair.c проверка pol == 3 где-то в дебрях макросов, клубок размотать не получилось.
В plugin/object/sym40/sym40.c в 76-й строке скорее всего ошибка:
if ((res = sym40_read(sym, path, size) < 0))
Т.е. он res присваивает выражение sym40_read()<0.
В libreiser4/flow.c следующая проверка не работает, т.к. обе переменные безнаковые:
if (end - off > 0) {
Возможно имелось в виду end > off.
А так-же:
if (insert > 0) {
Всегда истенен, т.к. в цикле for используется то-же условие, а в теле цикла значение insert не изменяется.
В librepair/node.c возможно так-же ошибка что и в sym40.c:
if ((ret = objcall(&key, check_struct) < 0))
Так-же есть опечатка, где переменной level два раза присваивается одно и то-же значение.
В librepair/filter.c RE_EMPTY, RE_DKEYS и RE_PTR это enum константы, а по стандарту enum гарантирует только int, т.е. если компилятору вбредет в голову брать их 32-битными, то будет выход за пределы. Т.е. в данном случае в выражениях они могут стать 0-ми.
В librepair/semantic.c есть два цикла while() где в самом конце стоит break. Т.е. это либо ошибка, либо это if().
В librepair/repair.c проверяется:
if (mode == RM_BUILD) {
и в этом-же if'е проверяется еще раз.
Далее по коду есть такая проверка:
if (repair->fatal) {
и там либо goto error, либо goto update. Чуть дальше:
if (repair->mode != RM_BUILD || repair->fatal)
и repair->fatal всегда ложь, т.к. в ином случае сработал бы goto.
В libmisc/profile.c есть странное место:
if (c + 1 == '\0') {
c это указатель на char. Т.е. скорее всего имелось в виду *(c+1) == '\0'.
/ ------------------- /
В общем подозрительные места есть, а ошибки это или "хаки" не всегда понятно. Хотя есть места где явно видны ошибки / опечатки.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Вообще, после того, как были написаны эти прогсы, автор сразу уволился, и с тех пор в этот код никто не заглядывал (я только пару раз фиксил fsck по просьбам). Так что весь этот урожай ошибок не удивителен. Спасибо, очень полезные логи! Проверить reiser4 в ядре - черезвычайно важно.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
key_short_set_locality(key, oid & !KEY_SHORT_BAND_MASK)
Ну, тут полная ерунда написана. Нужно обнулить старшие 4 бита у oid. Т.е. да - подразумевалось "~". Не срабатывает из-за условия if (oid & KEY_SHORT_BAND_MASK). Не думаю, что у кого-то номера инодов перевалили за 60 бит :) Вобщем, надо будет посидеть, причесать всё это на досуге..
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Анализ для ядра.
Вроде ошибок связанных именно с кодом R4 не так уж и много.
Правда настройки анализатора стандартные, может там еще чего включить можно.
Некая работа над ошибками имеет место быть. Могу я вас попросить проверить ещё ветку format41, что у меня на гитхабе https://github.com/edward6/reiser4/tree/format41
(это совсем не к спеху). Спасибо!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Эдик. Я наблюдаю за проектом Reiser4 очень много лет. Это была ФС по умолчанию в старом RTK GNU/Linux. Это была ФС "искаропки" в S.C.R. GNU/Linux. Это по-прежнему ФС по умолчанию в ныне разрабатываемой RTK GNU/Linux. Не отчаивайся, ты молодец и ты не один. :-)
С искренним уважением, Ne01eX. Координатор и текущий майтейнер Russian Technology Kit GNU/Linux. :-)
Last edit: Aleksandr Sayfulin 2018-06-13
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Я тут интереса ради (давно хотел на чем-нибудь попробовать) проверил libaal и reiser4progs статическим анализатором PVS (используя бесплатную лицензию для свободных проектов) и получил несколько подозрительных мест. Может потом проверю код reiser4 в самом ядре (на сайте Habrahabr в блоге PVS они как-то проверяли ядро).
В libaal ничего криминального, предупреждения в types.h о повторном typedef (некоторые типы в C11 добавили, va_list в стандарте есть) и две возможные ошибки, где используется битовый сдвиг на 32-битном значении и преобразуется в 64-битное.
С reiser4progs немного поинтереснее. В файлах plugin/key/key_short/key_short_repair.c и plugin/key/key_large/key_large_repair.c присуствуют подобные выражения:
KEY_SHORT_BAND_MASK это enum 0xf000000000000000ull и при булевой операции отрицания ! получается ноль. Может в этих местах имелся в виду битовый оператор инвертирования ~?
В plugin/hash/tea_hash/tea_hash.c есть несколько условий которые всегда ложны (в while условие len >= 16, соотвественно следующая проверка len >= 16 ложна и так дальше по лесенке). Хотя учитывая что в теле этих if'ов подобный код:
То я даже не уверен что это.
В plugin/sdext/sdext_plug/sdext_plug.c проверка stat на nullptr идет после разыменования stat (да и перед этим он тоже разыменовывается), т.к. по стандарту выражение в if вычисляется слева направо, а !stat находится в самом конце.
В plugin/item/cde40/cde40_repair.c проверка pol == 3 где-то в дебрях макросов, клубок размотать не получилось.
В plugin/object/sym40/sym40.c в 76-й строке скорее всего ошибка:
Т.е. он res присваивает выражение sym40_read()<0.
В libreiser4/flow.c следующая проверка не работает, т.к. обе переменные безнаковые:
Возможно имелось в виду end > off.
А так-же:
Всегда истенен, т.к. в цикле for используется то-же условие, а в теле цикла значение insert не изменяется.
В librepair/node.c возможно так-же ошибка что и в sym40.c:
Так-же есть опечатка, где переменной level два раза присваивается одно и то-же значение.
В librepair/filter.c RE_EMPTY, RE_DKEYS и RE_PTR это enum константы, а по стандарту enum гарантирует только int, т.е. если компилятору вбредет в голову брать их 32-битными, то будет выход за пределы. Т.е. в данном случае в выражениях они могут стать 0-ми.
В librepair/semantic.c есть два цикла while() где в самом конце стоит break. Т.е. это либо ошибка, либо это if().
В librepair/repair.c проверяется:
и в этом-же if'е проверяется еще раз.
Далее по коду есть такая проверка:
и там либо goto error, либо goto update. Чуть дальше:
и repair->fatal всегда ложь, т.к. в ином случае сработал бы goto.
В libmisc/profile.c есть странное место:
c это указатель на char. Т.е. скорее всего имелось в виду *(c+1) == '\0'.
/ ------------------- /
В общем подозрительные места есть, а ошибки это или "хаки" не всегда понятно. Хотя есть места где явно видны ошибки / опечатки.
Сами логи.
Вообще, после того, как были написаны эти прогсы, автор сразу уволился, и с тех пор в этот код никто не заглядывал (я только пару раз фиксил fsck по просьбам). Так что весь этот урожай ошибок не удивителен. Спасибо, очень полезные логи! Проверить reiser4 в ядре - черезвычайно важно.
Ну, тут полная ерунда написана. Нужно обнулить старшие 4 бита у oid. Т.е. да - подразумевалось "~". Не срабатывает из-за условия if (oid & KEY_SHORT_BAND_MASK). Не думаю, что у кого-то номера инодов перевалили за 60 бит :) Вобщем, надо будет посидеть, причесать всё это на досуге..
Анализ для ядра.
Вроде ошибок связанных именно с кодом R4 не так уж и много.
Правда настройки анализатора стандартные, может там еще чего включить можно.
Некая работа над ошибками имеет место быть. Могу я вас попросить проверить ещё ветку format41, что у меня на гитхабе https://github.com/edward6/reiser4/tree/format41
(это совсем не к спеху). Спасибо!
А эту ветку можно добавить в R4 просто скопировав?
Я тут немного проанализировал некоторые сообщения анализатора в коде ядра: https://habrahabr.ru/post/345894/
Может вам поможет в дальнейшем.
Last edit: BratSinot 2017-12-30
Да, думаю, можно и просто скопировать. Это, что называется, version 5. Я его время от времени синхронизирую с мастер-веткой...
Ну вот лог выше он с этой ветки. По крайней мере файл format41.c там точно есть =)
Эдик. Я наблюдаю за проектом Reiser4 очень много лет. Это была ФС по умолчанию в старом RTK GNU/Linux. Это была ФС "искаропки" в S.C.R. GNU/Linux. Это по-прежнему ФС по умолчанию в ныне разрабатываемой RTK GNU/Linux. Не отчаивайся, ты молодец и ты не один. :-)
С искренним уважением, Ne01eX. Координатор и текущий майтейнер Russian Technology Kit GNU/Linux. :-)
Last edit: Aleksandr Sayfulin 2018-06-13
Спасибо! В этом году нам 25 лет. Обещаю Reiser5. Будет интересно!