Говно еще в том, что strncpy принятно использовать без проверки на ошибки. Было переполнение или нет - коду пофиг, он молотит дальше.
Когда-то были дыры из-за того, что например PHP видит строку "evil\0innocent" и она проходит проверку, а нативный код видит "evil\0". Даже если отдельно порешать проблему с '\0', расширив буфер, проблема с неоднозначностью строк из-за обрезки остается. Я даже подозреваю, что если хорошенько поиграться со шрифтами с UTF-8, можно из двух неудачно обрезанных последовательностей собрать UTF-8-франкенштейна с новыми символами.
Че-то прошли мимо того факта, что strncpy работает с байтами, а не с UTF-8 и поэтому может разрезать символ посредине. Хотя да, по сравнению с отсутствием нуля это мелочи. Ужасная функция :)
Ну и правда, не совсем понятно, как будет выглядеть рынок, когда все пилят одно и то же и у всех одинаковая подписка на ChatGPT. Думаю, это решится естественным образом - будут очень дорогие и очень дешевые нейросети. Богатые будут богатеть, а бедные беднеть.
Мой персональный адочек с целочисленными преобразованиями:
off64_t lseek64(int fd, off64_t offset, int whence); lseek64(fd, -sizeof(envelope)-0x10, SEEK_END);
Работает на 64-битных системах и не работает на 32-битных. Понимаете, почему?
Я конечно же рукожоп и сам виноват. Но мое мнение - неявные преобразования между знаковыми и беззнаковыми надо запретить или хотя-бы ограничить. Человек должен явно все прописать и понимать, что он делает.
Нода - это ядро. Та сущность, которая исполняет один тред. Нумеруем все сервера, в каждом сервере нумеруем все процессоры, там нумеруем все ядра, получаем уникальный node_id. Все это нужно, чтобы избежать синхронизации при доступе к counter(node_id).
В целом, то на то и выходит, правда 256 бит перебор, UUID 128 бит, наверное вы его имели ввиду.
Надо было просто написать "Y = AES(secret_key, X) - отображение из 16 байт в 16 байт", но я решил выебнуться.
Кстати, я тут подумал, что в AES смысла особого нет.
Если честно да. И проблемы с ротацией ключей тоже есть. Более того, 128-битный UUID это слишком дофига. А рандом в UUID нехорошо для индексации в БД.
Короче, разумным выглядит использовать внутри системы 64-битный аналог UUID без рандома, типа Snowflake ID, а наружу уже выдавать что-то типа n || AES(secret_key[n], UUID)
В том-то и дело, что вы не понимаете и считаете меня несколько туповатым, либо попросту меряете по себе. Я больше ничего не буду писать, ибо уже и так написал половину комметариев. Было бы ради чего. Идеи описываются вполне тривиальные.
Конструкция node_id || timestamp || counter(node_id) || random - это аналог Snowflake ID. Вычисления ведутся на каждой ноде (моя нода - это ядро процессора) независимо и без необходимости синхронизации. counter(node_id) - это свой отдельный счетчик у каждой ноды.
На этот Snowflake ID навернули AES, чтобы скрыть внутреннюю структуру. Это отдельная идея. Это можно и не делать.
secret_key - один для всех и навсегда зафиксирован. Y = AES(secret_key, X) - это AES в режиме ECB, который отображает 256-битовую строку X в 256-битовую строку Y биективно (то есть, one-to-one) и не отличим вычислительно от случайно выбранного отображения.
Где вы увидели косяки с secret_key? secret_key задаем мы. Как вам вообще в голову пришло, что я допускаю различные secret_key? Тогда Y = AES(secret_key, X) не будет работать как биективное отображение и будут коллизии.
В целом мне уже больше нравится раздавать из выделенного микросервиса диапазоны UUID, как в Ticket Server с Pre-Generated Blocks. Это сильно проще в плане корректности, меньше нюансов, нет дрочева с timestamp.
Как минимум две идеи из индустрии я сегодня "изобрел" - аналог Snowflake ID и Ticket Server с Pre-Generated Blocks. То есть это нихера не тупые идеи, а вполне рабочие.
Окей, UUIDv7 тоже работает с вероятность 99.9...9%, а не 100%. Мне очень не нравится использовать вероятностный алгоритм там, где можно сделать детерминистический.
Второй абзац не совсем понял. Да, у меня все детерминистическое. Рандом там лишь для красоты и надежности, а не для защиты от повторов. Уникальность достигается за счет: 1) Уникальных и фиксированных node_id. 2) Достаточно точного timestamp. 3) Перезапуск ноды с обнулением counter(node_id) происходит с задержкой, за которую успеет измениться timestamp. 4) Переполнение counter(node_id) тоже учитывается.
Ключ AES навсегда фиксирован и одинаков для всех. Он для обфускации, чтобы UUID выглядел как рандом и не выдавал инфу.
В целом, что-то сложно напридумывал. Можно сделать тупо микросервис, который раздает нодам достаточно большие диапазоны UUID, чтобы не было слишком частых запросов, но достаточно маленькие, чтобы не потратить все UUID в обозримом будущем. Ну и AES для обфускации.
Просто вы в самом начале грозились уволить всех, кто причастен к микросервису по генерации UUID.
А потом предложили типа свои хорошие решения, которые так или иначе тоже являются микросервисом по генерации UUID.
Более того, сильно подозреваю, что сделать надежно (не тупо random) с нодами без априорных знаний не получится без того самого микросервиса в том или ином виде. Навскидку, в решениях, которые я вижу, он нужен: 1) Либо для раздачи точного времени. 2) Либо для раздачи уникальных node_id. 3) Либо для раздачи непересекающихся диапазонов UUID. Доказать строго не могу, но чуечка подсказывает.
Это хорошо, если у вас БД проверяет на уникальность UUID и сразу же выдает ошибку. И при этом можно без проблем сделать новый UUID и поворить попытку. Это надежная система, которая работает всегда.
Или если ваша БД генерирует UUID при вставке - тоже замечательно.
В обоих вышеописанных случаях ваша БД по сути и есть тот самый микросервис для генерации UUID. Просто называется иначе.
А вот что, если нет? Где-то есть системы, где любая централизованная БД станет бутылочным горлышком и поэтому уникальные UUID надо генерирововать полностью независимо и без какой-либо синхронизации. А что, если ошибка из-за коллизии UUID вылезет уже потом, когда уже поздно что-то менять?
Все же потенциальное отсутствие '\0' - явно задокументированная особенность и с ней умеют работать через конструкцию вида strncpy(buf, ..., sizeof(buf)-1).
Как здесь например:
https://github.com/torvalds/linux/commit/340ff3216799a947fe0b07bed8f0409ffc716be9#diff-81db6161fb0345ecabeac4f346089871ab4d62d9e8ee1fdb04c73757b8e8bbb8L133
А вот фигня с UTF-8 - более тонкая, неочевидная, и непредсказуемая.
Говно еще в том, что strncpy принятно использовать без проверки на ошибки.
Было переполнение или нет - коду пофиг, он молотит дальше.
Когда-то были дыры из-за того, что например PHP видит строку "evil\0innocent" и она проходит проверку, а нативный код видит "evil\0".
Даже если отдельно порешать проблему с '\0', расширив буфер, проблема с неоднозначностью строк из-за обрезки остается.
Я даже подозреваю, что если хорошенько поиграться
со шрифтамис UTF-8, можно из двух неудачно обрезанных последовательностей собрать UTF-8-франкенштейна с новыми символами.Короче, strncpy - непредсказуемое говно.
Ну ок.
А если буфер src закончился посреди символа?
Каким образом эта функция учтет UTF-8?
https://github.com/torvalds/linux/commit/079a028d6327e68cfa5d38b36123637b321c19a7#diff-caf1d936b395dcac087bd2b6d8585de0e06695cfe00c899d9299dc9cfec2a118L91
Че-то прошли мимо того факта, что strncpy работает с байтами, а не с UTF-8 и поэтому может разрезать символ посредине. Хотя да, по сравнению с отсутствием нуля это мелочи. Ужасная функция :)
А ви таки боретесь?
Честно говоря, первый раз слышу о таком нарративе.
Они могут публиковаться хоть до усрачки.
Капитализм и технический прогресс идут своим путем.
И совсем не факт, что там в конце туннеля всеобщее благо.
Как я вижу, Mythos - это какая-то более продвинутая архитектура, а не просто тупо безопасник.
Ну как раз вполне понятный ход с их стороны.
Не понимаю шквал критики и злорадства по поводу ИИ.
Это совершенно удивительная технология.
У меня в реверс-инжиниринге ИИ - это как помощник с огромным кругозором.
Подсказывает всякие заковыристые штуки, о которых я никогда не слышал.
В математике уже тоже начинаются серьезные подвижки.
То что оно еще не умеет в полный цикл разработки - ну так блядь радуйтесь, что дали пожить нормально.
Ну и правда, не совсем понятно, как будет выглядеть рынок, когда все пилят одно и то же и у всех одинаковая подписка на ChatGPT.
Думаю, это решится естественным образом - будут очень дорогие и очень дешевые нейросети.
Богатые будут богатеть, а бедные беднеть.
А че, статические анализаторы не умеют такое обнаруживать?
memcpy в буфер без должной проверки размера?
int32_t rpchdr[128 / sizeof(int32_t)];int32_t *buf;...buf = rpchdr;...if (oa->oa_length) {memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);Мой персональный адочек с целочисленными преобразованиями:
off64_t lseek64(intfd, off64_toffset, intwhence);lseek64(fd, -sizeof(envelope)-0x10, SEEK_END);Работает на 64-битных системах и не работает на 32-битных.
Понимаете, почему?
Я конечно же рукожоп и сам виноват.
Но мое мнение - неявные преобразования между знаковыми и беззнаковыми надо запретить или хотя-бы ограничить. Человек должен явно все прописать и понимать, что он делает.
Нода - это ядро. Та сущность, которая исполняет один тред. Нумеруем все сервера, в каждом сервере нумеруем все процессоры, там нумеруем все ядра, получаем уникальный node_id. Все это нужно, чтобы избежать синхронизации при доступе к counter(node_id).
Надо было просто написать "Y = AES(secret_key, X) - отображение из 16 байт в 16 байт", но я решил выебнуться.
Если честно да. И проблемы с ротацией ключей тоже есть. Более того, 128-битный UUID это слишком дофига. А рандом в UUID нехорошо для индексации в БД.
Короче, разумным выглядит использовать внутри системы 64-битный аналог UUID без рандома, типа Snowflake ID, а наружу уже выдавать что-то типа
n || AES(secret_key[n], UUID)
Хеш конечно же нельзя, это необратимая функция.
В том-то и дело, что вы не понимаете и считаете меня несколько туповатым, либо попросту меряете по себе. Я больше ничего не буду писать, ибо уже и так написал половину комметариев. Было бы ради чего. Идеи описываются вполне тривиальные.
Конструкция node_id || timestamp || counter(node_id) || random - это аналог Snowflake ID.
Вычисления ведутся на каждой ноде (моя нода - это ядро процессора) независимо и без необходимости синхронизации.
counter(node_id) - это свой отдельный счетчик у каждой ноды.
На этот Snowflake ID навернули AES, чтобы скрыть внутреннюю структуру.
Это отдельная идея. Это можно и не делать.
secret_key - один для всех и навсегда зафиксирован.
Y = AES(secret_key, X) - это AES в режиме ECB, который отображает 256-битовую строку X в 256-битовую строку Y биективно (то есть, one-to-one) и не отличим вычислительно от случайно выбранного отображения.
Где вы увидели косяки с secret_key? secret_key задаем мы.
Как вам вообще в голову пришло, что я допускаю различные secret_key?
Тогда Y = AES(secret_key, X) не будет работать как биективное отображение и будут коллизии.
В целом мне уже больше нравится раздавать из выделенного микросервиса диапазоны UUID, как в Ticket Server с Pre-Generated Blocks. Это сильно проще в плане корректности, меньше нюансов, нет дрочева с timestamp.
Нет, мы походу нашли самого ограниченного кодера в треде.
Расширяйте сознание и не хамите незнакомым людям в интернете.
https://dilipkumar.medium.com/design-a-system-to-generate-a-unique-id-1517dc624975
https://en.wikipedia.org/wiki/Snowflake_ID
Как минимум две идеи из индустрии я сегодня "изобрел" - аналог Snowflake ID и Ticket Server с Pre-Generated Blocks. То есть это нихера не тупые идеи, а вполне рабочие.
Окей, UUIDv7 тоже работает с вероятность 99.9...9%, а не 100%.
Мне очень не нравится использовать вероятностный алгоритм там, где можно сделать детерминистический.
Второй абзац не совсем понял.
Да, у меня все детерминистическое. Рандом там лишь для красоты и надежности, а не для защиты от повторов.
Уникальность достигается за счет:
1) Уникальных и фиксированных node_id.
2) Достаточно точного timestamp.
3) Перезапуск ноды с обнулением counter(node_id) происходит с задержкой, за которую успеет измениться timestamp.
4) Переполнение counter(node_id) тоже учитывается.
Ключ AES навсегда фиксирован и одинаков для всех.
Он для обфускации, чтобы UUID выглядел как рандом и не выдавал инфу.
В целом, что-то сложно напридумывал.
Можно сделать тупо микросервис, который раздает нодам достаточно большие диапазоны UUID, чтобы не было слишком частых запросов, но достаточно маленькие, чтобы не потратить все UUID в обозримом будущем. Ну и AES для обфускации.
Да блин, нормально я читаю.
Просто вы в самом начале грозились уволить всех, кто причастен к микросервису по генерации UUID.
А потом предложили типа свои хорошие решения, которые так или иначе тоже являются микросервисом по генерации UUID.
Более того, сильно подозреваю, что сделать надежно (не тупо random) с нодами без априорных знаний не получится без того самого микросервиса в том или ином виде.
Навскидку, в решениях, которые я вижу, он нужен:
1) Либо для раздачи точного времени.
2) Либо для раздачи уникальных node_id.
3) Либо для раздачи непересекающихся диапазонов UUID.
Доказать строго не могу, но чуечка подсказывает.
Ой, опять тот самый микросервис?
Это хорошо, если у вас БД проверяет на уникальность UUID и сразу же выдает ошибку.
И при этом можно без проблем сделать новый UUID и поворить попытку.
Это надежная система, которая работает всегда.
Или если ваша БД генерирует UUID при вставке - тоже замечательно.
В обоих вышеописанных случаях ваша БД по сути и есть тот самый микросервис для генерации UUID. Просто называется иначе.
А вот что, если нет?
Где-то есть системы, где любая централизованная БД станет бутылочным горлышком и поэтому уникальные UUID надо генерирововать полностью независимо и без какой-либо синхронизации.
А что, если ошибка из-за коллизии UUID вылезет уже потом, когда уже поздно что-то менять?