Обновить

Комментарии 6

ЗакрепленныеЗакреплённые комментарии

Очередной диалог с ChatGPT на эту тему:

— ты тут не указал важную деталь про ✌️* ✌️в версии от Солар, как я понимаю

Да. Я упустил принципиальную деталь: в оригинальной crypt_blowfish Solar Designer тоже использовал строковые маркеры ошибки вместо NULL, но специально предусмотрел защиту от их совпадения с входным значением.

Механизм был таким:

return setting[0] == '*' && setting[1] == '0'

    ? "*1" : "*0";

То есть при ошибке возвращается 0, но если входное значение начинается с 0, возвращается *1.

Гарантируется несовпадение результата ошибки с исходным setting. Это не просто выбор редкого символа, а сохранение конкретного свойства безопасности.

И вот здесь различие существенное:

  • Solar: возвращает маркер ошибки, гарантированно отличный от входного значения.

  • musl: возвращает *, полагаясь на то, что конкретный путь исполнения не позволит этому значению совпасть с проверяемым хешем.

  • Rich: в переписке 2016 года предпочитает NULL, поскольку тот позволяет вызывающему коду однозначно распознать ошибку.

Получается, musl не просто выбрала другой символ. Она потеряла инвариант, который Solar уже обеспечил в исходной реализации.

И это напрямую относится к твоему предыдущему рассуждению о неправильном переиспользовании смысла: Solar предусмотрел, что маркер отказа нельзя превращать в положительный результат сравнением. В musl эта гарантия стала зависеть от контекста вызова — и впоследствии не выдержала его изменения.

придётся и это внести в статью, видимо 🤷‍♂️

И никто не хочет брать на себя ответственность…

OpenSSH:

We consider the root cause of this bug to be outside sshd, but it is exploitable via sshd and can be avoided there.

musl (Rich Felker):

It is my position that this is not a bug in musl just an erroneous use by the caller. But the mechanism by which this happened is something we have been wanting to change for a while now, and it very likely will be changed in the upcoming release cycle.

Хотя, по-хорошему, musl откровенно поломали POSIX-совместимость:

Upon successful completion, crypt() shall return a pointer to the hashed password; the first two bytes of the returned value shall be those of the salt argument. Otherwise, it shall return a null pointer and set errno to indicate the error. (IEEE Std 1003.1™-2024 Edition)

(режим подозревателя программ)

А не спланированное ли это было? Мог ли разработчик musl, который реализовал (или протолкнул) такую идею, действовать в своих злостных интересах? Или интересах третьей стороны? Ну, может, ему сделали предложение, от которого нельзя отказаться, суровые дядьки в погонах.

Ведь так было с xz, когда кто-то долго и терпеливо "готовил почву" для внесения проблемных изменений, и до последнего никто не догадался, а нашли опять же применительно к ssh (совпадение? Не думаю)

Вообще, по стандарту, программа должна возвращать код ошибки, а другие программы этот код проверять. Тут явно какую-то дичь сотворили.

I never trusted these muslims!

glibc / libxcrypt:

Upon error, [...] crypt writes an invalid hash to its static storage area. This string will be shorter than 13 characters, will begin with a ‘*’, and will not compare equal to setting.

Очередной диалог с ChatGPT на эту тему:

— ты тут не указал важную деталь про ✌️* ✌️в версии от Солар, как я понимаю

Да. Я упустил принципиальную деталь: в оригинальной crypt_blowfish Solar Designer тоже использовал строковые маркеры ошибки вместо NULL, но специально предусмотрел защиту от их совпадения с входным значением.

Механизм был таким:

return setting[0] == '*' && setting[1] == '0'

    ? "*1" : "*0";

То есть при ошибке возвращается 0, но если входное значение начинается с 0, возвращается *1.

Гарантируется несовпадение результата ошибки с исходным setting. Это не просто выбор редкого символа, а сохранение конкретного свойства безопасности.

И вот здесь различие существенное:

  • Solar: возвращает маркер ошибки, гарантированно отличный от входного значения.

  • musl: возвращает *, полагаясь на то, что конкретный путь исполнения не позволит этому значению совпасть с проверяемым хешем.

  • Rich: в переписке 2016 года предпочитает NULL, поскольку тот позволяет вызывающему коду однозначно распознать ошибку.

Получается, musl не просто выбрала другой символ. Она потеряла инвариант, который Solar уже обеспечил в исходной реализации.

И это напрямую относится к твоему предыдущему рассуждению о неправильном переиспользовании смысла: Solar предусмотрел, что маркер отказа нельзя превращать в положительный результат сравнением. В musl эта гарантия стала зависеть от контекста вызова — и впоследствии не выдержала его изменения.

придётся и это внести в статью, видимо 🤷‍♂️

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации