Линус Торвальдс в переписке в списке рассылки (1, 2, 3, 4) по поводу обсуждения возможности смягчения неожиданных арифметических переполнений/недополнений/зацикливания в исходном коде C ядра Linux посоветовал Кису Куку из Google быть решением, а не проблемой в рамках работы с мейнтейнерами ядра Linux, а также перестать плодить неразумные жалобы на код компилятора.
Кук вместе с другими экспертами Google работает над выяснением того, как лучше справляться с неожиданными ошибками арифметического переполнения в исходном коде C ядра Linux. Он надеется увидеть систематический способ, позволяющий ядру Linux справляться с такими арифметическими проблемами переполнения/недополнения/зацикливания. Среди первоначальных идей — лучше использовать санитайзеры на основе компилятора или возможности языка C для перегрузки операторов без искажения имён. В последнем его предложении в качестве потенциального решения перегрузки операторов C был озвучен способ произвольной обработки переполнений внутри помощников (C operator overloading could allow for arbitrary handling of overflows within the helpers).
Первоначально Кис думал о смягчении последствий с помощью санитайзеров (sanitizer-based mitigations), и завершил свою ветку в списке рассылки такими словами: «Я стремлюсь к общему согласию относительно подхода № 1, описанного выше. Любое решение, которое действительно принесёт значительную пользу, потребует довольно обширных изменений в типах Linux, так что это универсальная болевая точка. Но я преодолел задачу сделать Linux безопасным уже давно, и я надеюсь, что смогу убедить людей, что нам действительно нужно что-то изменить. Статус-кво недостаточно хорош, и мы можем добиться большего. Мне просто нужно найти общее решение, которое мы сможем согласовать и реально применить в ближайшие годы».
Линус Торвальдс поспешил поделиться своими мыслями по поводу этого предложения Киса.
Я все ещё совершенно не убеждён. Дело в том, что циклический возврат (wrap around) не только чётко определён, он *общепринятый* и *ОЖИДАЕМЫЙ*. Пример: static inline u32 __hash_32_generic(u32 val) { return val * GOLDEN_RATIO_32; } И, черт возьми, я абсолютно НЕ ДУМАЮ, что нам следует аннотировать это как своего рода «специальное умножение» (special multiply).
Я понятия не имею, сколько их существует. Но я на 100% убеждён, что заставлять разработчиков это аннотировать и ухудшать исходный код — абсолютно неправильный подход.
По сути, беззнаковая арифметика четко определяется как циклическая, и на это есть веская причина (Basically, unsigned arithmetic is well-defined as wrapping around, and it is so for a good reason).
Поэтому у меня будет ЖЁСТКОЕ ТРЕБОВАНИЕ: любые жалобы на компилятор должны быть действительно разумными. Им нужно обнаружить, когда разработчики делают подобные вещи намеренно, и им нужно SHUT THE ^&% UP о том, что происходит циклическое завершение.
Любой инструмент, который настолько глуп, что жалуется на цикличность, описанную выше, является СЛОМАННЫМ ИНСТРУМЕНТОМ, КОТОРЫЙ НУЖНО ИГНОРИРОВАТЬ. Действительно. Это не подлежит обсуждению.
Это похоже в целом на
unsigned int a, b;
if (a+b < a) ..
своего рода шаблон: инструмент, который жалуется на циклический возврат, описанный выше, абсолютно сломан и его нужно игнорировать.Поэтому я считаю, что вам нужно ограничить количество жалоб, связанных с циклическими возвратами, и серьёзно подумать о том, как их ограничить. Если вы скажете: «Обход неправильный», как какой-то общий, я буду игнорировать вас, и я скажу разработчикам игнорировать вас и отказываться от любых идиотских патчей, которые являются результатом таких идиотских правил.
Другими словами, самое первое и фундаментальное, на что вам следует обратить внимание, — это убедиться, что инструменты не жалуются на разумное поведение.
Пока вы этого не сделаете и не отнесётесь к этому серьёзно, эта дискуссия никогда не приведёт ни к чему продуктивному.
В рамках продолжения дискуссии Торвальдс продолжил свои рассуждения по поводу текущей ситуации с запросами Кука.
Любое бессмысленное «это может быть циклическими возвратами» непростительно.
Нужно быть умнее. И да, это означает именно учёт того, как на самом деле используется результат возможного циклического возврата.
Если он используется в качестве размера или индекса массива, это может стать проблемой. Но если он используется для маскирования, а затем его маскированная версия используется для индекса, это явно НЕ проблема.
IOW, это точно так же, как «a+b <a». Да, «a+b» может быть циклическим возвратом, но если его использовать для последующего сравнения с одним из слагаемых, то очевидно, что такой циклический возврат подойдёт.
Инструмент, который не смотрит на то, как используется результат, и просто слепо говорит «ошибка циклического возврата», — это инструмент, который, я считаю, определённо вреден.
И нет, мой ответ АБСОЛЮТНО НЕ нужно увеличивать когнитивную нагрузку на мейнтейнеров ядра путём добавления ещё большего количества случайных вспомогательных типов и/или функций.
Мы уже ожидаем многого от разработчиков ядра. Нам не следует увеличивать это бремя из-за вашего любимого проекта.
Другими словами: я возлагаю на ВАС ответственность за то, чтобы ваш пет-проект был уровня Yogi Bear среди остальных пет-проектов — умнее среднего медведя.
Пока вы подходите к этому с позиции «возлагать ответственность на других», ВЫ являетесь проблемой. Будьте решением, а не проблемой.
Примечательно, что Торвальдс продолжает переписку по этой ситуации. Он предложил Куку более подробного подойти к изучения этого вопроса и искать потенциальное решение путём целенаправленных действий и небольших шагов, а не использовать какой-то драконовский «обходной путь». В настоящее время продолжается дискуссия по поводу изменения кода C ядра Linux между Куком, мейнтейнерами и Торвальдсом.
Subject: Re: [RFC] Mitigating unexpected arithmetic overflow
12 января 2024 года Линус Торвальдс обозвал %^!@$% новый код Intel Xe для DRM (Direct Rendering Manager) в Linux 6.8. Он сам исправил его огрехи и призвал сторонних разработчиков и мейнтейнеров проекта тестировать, тестировать и ещё раз тестировать свои патчи.
В апреле в рамках подготовки патчей для Linux 6.9-rc4 Линус Торвальдс решил бороться с парсерами конфигурационных файлов Kconfig, которые не могут правильно обрабатывать табуляции. Торвальдс написал патч, чтобы намеренно добавить несколько собственных табов в Kconfig, чтобы отбросить любые внешние или сторонние парсеры, которые не могут их правильно обработать. Торвальдс намеренно добавил эти скрытые табы в общий файл Kconfig для обработки размеров страниц ядра. Таким образом, это обязательно приведёт к серьёзным и заметным ошибкам для любых парсеров, не имеющих правильную обработку табов.
В декабре 2023 года Торвальдс рассказал об усталости сопровождающих ядра проекта. По его мнению, сопровождающие ядра Linux должны уметь смотреть на код других людей и обладать возможностью ответить на вопрос: «Это хороший или плохой подход?».
В октябре 2022 года Торвальдс отчитал ментейнеров проекта версии ядра Linux за постоянный срыв дедлайнов и расслабленность в работе. В своём обращении к разработчикам Торвальдс также обратился к тем, кто сдаёт ему проделанную работу после заявленного срока. «Привычку откладывать всё до последнего нужно было оставить в школе. Это совершенно не подходит для разработки ядра Linux», — написал Торвальдс.