На iOS браузеры за пределами ЕС обязаны работать на WebKit, а прокси-браузеры вроде Tor-клиентов настраивают прокси через
Всё это происходит вне обычного цикла загрузки страницы, поэтому утечки задевают и iCloud Private Relay; VPN не затронуты, они тянут трафик на уровне системы. Началось с одного бага от пользователя, у которого DNS утекал только на некоторых сайтах: без тега prefetch запроса просто не было. Авторы делают собственный браузер Psylo: в 1.3.1 prefetch блокируется, а WebTransport и WebAuthn выключены по умолчанию и включаются отдельной настройкой на сайт. PoC лежит на leaks.psylo.app.
@prog_stuff
WKWebsiteDataStore.proxyConfigurations: весь трафик страницы должен уходить через прокси. Исследователи Mysk нашли три функции WebKit, которые эту настройку обходят и ходят в сеть напрямую с устройства.<link rel="dns-prefetch"> резолвит имя через системный DNS, а не через прокси: сайт вставляет уникальное имя на посетителя и смотрит, с какого резолвера прилетает запрос. WebAuthn Related Origin Requests заставляет системный сервис учётных данных скачать файл проверки напрямую, раскрывая реальный IP. WebTransport поднимает прямое HTTP/3-соединение мимо прокси. Функции появились в iOS 26.0, 18.0 и 26.4 соответственно.Всё это происходит вне обычного цикла загрузки страницы, поэтому утечки задевают и iCloud Private Relay; VPN не затронуты, они тянут трафик на уровне системы. Началось с одного бага от пользователя, у которого DNS утекал только на некоторых сайтах: без тега prefetch запроса просто не было. Авторы делают собственный браузер Psylo: в 1.3.1 prefetch блокируется, а WebTransport и WebAuthn выключены по умолчанию и включаются отдельной настройкой на сайт. PoC лежит на leaks.psylo.app.
@prog_stuff
В BGP есть поле ORIGIN: оно говорит, как маршрут попал в протокол, и по стандарту менять его не должен никто, кроме того, кто маршрут объявил. Cloudflare проверили, как это соблюдается, и обнаружили, что примерно у 70 процентов наблюдаемых путей значение отличается от исходного.
Мотив денежный. При выборе лучшего пути маршрутизатор смотрит на ORIGIN рано, ещё до сравнения других признаков, и предпочитает меньшее значение. Переписав поле в самое приоритетное, транзитный провайдер повышает шанс, что трафик — и оплата за него — пойдёт через него.
Эксперимент простой: объявить шесть блоков адресов с разными значениями и посмотреть, что дойдёт до публичных коллекторов. Переписывают немногие, 64 системы из 606 разобранных, но это в основном крупные игроки: шесть из шестнадцати сетей верхнего уровня.
Вывод авторов радикальный: осмысленной роли у этого поля в современном интернете не осталось.
@prog_stuff
Мотив денежный. При выборе лучшего пути маршрутизатор смотрит на ORIGIN рано, ещё до сравнения других признаков, и предпочитает меньшее значение. Переписав поле в самое приоритетное, транзитный провайдер повышает шанс, что трафик — и оплата за него — пойдёт через него.
Эксперимент простой: объявить шесть блоков адресов с разными значениями и посмотреть, что дойдёт до публичных коллекторов. Переписывают немногие, 64 системы из 606 разобранных, но это в основном крупные игроки: шесть из шестнадцати сетей верхнего уровня.
Вывод авторов радикальный: осмысленной роли у этого поля в современном интернете не осталось.
@prog_stuff
После одной перенастройки контроллера памяти
Автор показывает на AMD Family 16h, что финальное преобразование адреса живёт уже за пределами всего, что защищает операционная система. Он проходит цепочку целиком: MMU, EPT и NPT, IOMMU, кэши, когерентная шина, контроллер памяти и только потом чередование по каналам, рангам и банкам. Один переключатель в конфигурации bank-swizzle схлопывает разные адреса в одну физическую координату.
Само преобразование не документировано, поэтому автор восстанавливает его как линейное отображение над GF(2) и решает систему линейной алгеброй и Z3. Дальше в README идут доступ к областям PSP, SMM и SMRAM, к C6 save area и микрокоду.
Оговорка у автора честная: почти всё проверено на Family 16h, для 17h и новее нужные регистры уже не документированы, а сама документация AMD неполна — порядок XOR-преобразований и стадии MMIO зависят от модели. Переносимость на другие поколения он не обещает.
@prog_stuff
&x != &x: два разных адреса начинают указывать в одну ячейку DRAM, притом что таблицы страниц, TLB и физические адреса, которые видит ядро, никто не трогал.Автор показывает на AMD Family 16h, что финальное преобразование адреса живёт уже за пределами всего, что защищает операционная система. Он проходит цепочку целиком: MMU, EPT и NPT, IOMMU, кэши, когерентная шина, контроллер памяти и только потом чередование по каналам, рангам и банкам. Один переключатель в конфигурации bank-swizzle схлопывает разные адреса в одну физическую координату.
Само преобразование не документировано, поэтому автор восстанавливает его как линейное отображение над GF(2) и решает систему линейной алгеброй и Z3. Дальше в README идут доступ к областям PSP, SMM и SMRAM, к C6 save area и микрокоду.
Оговорка у автора честная: почти всё проверено на Family 16h, для 17h и новее нужные регистры уже не документированы, а сама документация AMD неполна — порядок XOR-преобразований и стадии MMIO зависят от модели. Переносимость на другие поколения он не обещает.
@prog_stuff
👍2
Микаэль Лагерквист собирал корпус из 434 201 судоку для экспериментов с программированием в ограничениях, потом захотел в них поиграть — и сделал игровые версии девяти типов головоломок, где все задачи сгенерированы решателем.
Общий приём один: начать с готового решения или картинки, а потом добавлять, двигать и удалять подсказки, пока решение не станет единственным. Для судоку это выглядит так: сгенерировать полную таблицу, убирать подсказки и каждый раз проверять уникальность.
Сложность судоку определяется не числом подсказок, а самым слабым набором правил распространения ограничений, которого хватает решателю без перебора вариантов. У других головоломок свои измерения, и метки сравнимы только внутри одного типа.
Японские кроссворды описаны регулярным выражением вида
И приятная деталь: браузер решателя не запускает вовсе, ему отдают заранее сгенерированные головоломки вместе с решениями.
@prog_stuff
Общий приём один: начать с готового решения или картинки, а потом добавлять, двигать и удалять подсказки, пока решение не станет единственным. Для судоку это выглядит так: сгенерировать полную таблицу, убирать подсказки и каждый раз проверять уникальность.
Сложность судоку определяется не числом подсказок, а самым слабым набором правил распространения ограничений, которого хватает решателю без перебора вариантов. У других головоломок свои измерения, и метки сравнимы только внутри одного типа.
Японские кроссворды описаны регулярным выражением вида
Empty* Filled{3} Empty+ Filled{2} Empty*, которое среда сама превращает в конечный автомат. Замкнутая линия в Loopy выражается через готовое ограничение на подциклы, путь в Zip — через ограничение на гамильтонов цикл.И приятная деталь: браузер решателя не запускает вовсе, ему отдают заранее сгенерированные головоломки вместе с решениями.
@prog_stuff
Час, который стоит потратить: доклад Рича Хики «Simple Made Easy» со Strange Loop 2011.
Весь доклад держится на разведении двух слов, которые в русском тоже слиплись. Простое — это то, что не переплетено с другими вещами, свойство самой конструкции. Лёгкое — это то, что близко и знакомо лично вам, свойство вашего опыта. Выбирая лёгкое, команда набирает сложность, которую потом невозможно распутать.
Хики вводит слово complecting — сплетать вместе то, что могло бы жить раздельно. Изменяемая переменная сплетает значение и время. Наследование сплетает тип и реализацию. Объект сплетает данные и поведение. Всё это удобно писать и тяжело менять через полгода.
Отдельный удар по привычным успокоительным: тесты, рефакторинг и система типов повышают безопасность, но не делают дизайн проще. Они ловят ошибки, а не распутывают связи.
Практическое, что можно унести на завтра: при проектировании развести вопросы «что», «кто», «как», «когда», «где» и «почему» и следить, чтобы в одном месте не отвечали сразу на несколько.
@prog_stuff
Весь доклад держится на разведении двух слов, которые в русском тоже слиплись. Простое — это то, что не переплетено с другими вещами, свойство самой конструкции. Лёгкое — это то, что близко и знакомо лично вам, свойство вашего опыта. Выбирая лёгкое, команда набирает сложность, которую потом невозможно распутать.
Хики вводит слово complecting — сплетать вместе то, что могло бы жить раздельно. Изменяемая переменная сплетает значение и время. Наследование сплетает тип и реализацию. Объект сплетает данные и поведение. Всё это удобно писать и тяжело менять через полгода.
Отдельный удар по привычным успокоительным: тесты, рефакторинг и система типов повышают безопасность, но не делают дизайн проще. Они ловят ошибки, а не распутывают связи.
Практическое, что можно унести на завтра: при проектировании развести вопросы «что», «кто», «как», «когда», «где» и «почему» и следить, чтобы в одном месте не отвечали сразу на несколько.
@prog_stuff
👍1
Идея, которую в девяностых довели до рабочего состояния, а потом почти все забыли: файловая система, которая одновременно является базой данных.
Даниэль Козенца разбирает Be File System — ту, что досталась Haiku от BeOS. У файла там есть не только имя и содержимое, но и типизированные именованные атрибуты: у аудиофайла исполнитель и альбом, у письма отправитель и статус. По выбранным атрибутам строятся индексы, к тому можно писать предикаты, а живые запросы шлют приложению сообщение, когда подходящий файл появился, исчез или изменился. Почтовый клиент, который просто показывает результат запроса к файловой системе, — это оттуда.
Автор при этом честно очерчивает границы. Индекс принадлежит конкретному тому: наличие его на загрузочном диске ничего не говорит про соседний. Результат запроса не вечен — файл могут переименовать или удалить. Соединений таблиц, ссылочной целостности и транзакций над несколькими записями тут нет.
И главная ловушка: при переименовании атрибуты следуют за файлом, а вот при копировании наружу как повезёт — архиваторы и средства переноса ведут себя по-разному, и на файловой системе без поддержки атрибутов они просто теряются. Байты остались, смысл потерялся.
@prog_stuff
Даниэль Козенца разбирает Be File System — ту, что досталась Haiku от BeOS. У файла там есть не только имя и содержимое, но и типизированные именованные атрибуты: у аудиофайла исполнитель и альбом, у письма отправитель и статус. По выбранным атрибутам строятся индексы, к тому можно писать предикаты, а живые запросы шлют приложению сообщение, когда подходящий файл появился, исчез или изменился. Почтовый клиент, который просто показывает результат запроса к файловой системе, — это оттуда.
Автор при этом честно очерчивает границы. Индекс принадлежит конкретному тому: наличие его на загрузочном диске ничего не говорит про соседний. Результат запроса не вечен — файл могут переименовать или удалить. Соединений таблиц, ссылочной целостности и транзакций над несколькими записями тут нет.
И главная ловушка: при переименовании атрибуты следуют за файлом, а вот при копировании наружу как повезёт — архиваторы и средства переноса ведут себя по-разному, и на файловой системе без поддержки атрибутов они просто теряются. Байты остались, смысл потерялся.
@prog_stuff
👍1
Телефон переставал играть музыку в Bluetooth-наушниках, как только на компьютере открывалась вкладка AliExpress. Закрыть вкладку — звук возвращается, замьютить вкладку или всю систему — не помогает.
Автор блога laserphile обернул конструктор
Граф в обоих одинаковый: пилообразный осциллятор,
Звук здесь одна из мерок отпечатка. Рядом снимаются canvas и
@prog_stuff
Автор блога laserphile обернул конструктор
AudioContext и нашёл два скрытых аудиоконтекста в состоянии running, подключённых к destination, — при том что ни <audio>, ни <video>, ни вызовов play() на странице нет. Создают их collina.js и fireyejs.js из каталога AWSC, антифрод-обвязки Alibaba.Граф в обоих одинаковый: пилообразный осциллятор,
AnalyserNode, ScriptProcessorNode, GainNode с нулевым усилением, выход в destination. Слышно ничего, но подключение к destination заставляет браузер обсчитывать граф по-настоящему, и аудиопуть остаётся занятым.Звук здесь одна из мерок отпечатка. Рядом снимаются canvas и
toDataURL(), данные WebGL, размеры экрана, hardwareConcurrency, поведение WebRTC, события мыши и скролла, показания акселерометра.@prog_stuff
👍1💯1
Статический анализатор выдал 147 643 предупреждения о работе с неинициализированной памятью в ядре Linux. Подтвердились и были исправлены 52.
Эта цифра — отправная точка работы группы из Калифорнийского университета в Риверсайде, представленной на OSDI в июле. Проблема известна всем, кто пробовал внедрить анализатор в большой проект: покрытие огромное, а доля настоящих находок такая, что список никто не разбирает.
Идея авторов: проверять каждое предупреждение отдельно, исполняя подозрительный участок кода по-настоящему. Для этого произвольный набор функций на C и C++ собирается в самостоятельный исполняемый файл без правки исходников, а дальше по нему идёт символьное исполнение. Запускать всё ядро или готовить окружение не нужно.
По цифрам: для Linux 6.16.0 удалось собрать 88,9 процента участков, для Android LTS 5.10.240 — 96,2 процента. Разбор одного предупреждения занимал в среднем 0,32 секунды против 5,14 у сравниваемого подхода, а до вердикта доводилось 95,46 процента случаев против 41,29.
@prog_stuff
Эта цифра — отправная точка работы группы из Калифорнийского университета в Риверсайде, представленной на OSDI в июле. Проблема известна всем, кто пробовал внедрить анализатор в большой проект: покрытие огромное, а доля настоящих находок такая, что список никто не разбирает.
Идея авторов: проверять каждое предупреждение отдельно, исполняя подозрительный участок кода по-настоящему. Для этого произвольный набор функций на C и C++ собирается в самостоятельный исполняемый файл без правки исходников, а дальше по нему идёт символьное исполнение. Запускать всё ядро или готовить окружение не нужно.
По цифрам: для Linux 6.16.0 удалось собрать 88,9 процента участков, для Android LTS 5.10.240 — 96,2 процента. Разбор одного предупреждения занимал в среднем 0,32 секунды против 5,14 у сравниваемого подхода, а до вердикта доводилось 95,46 процента случаев против 41,29.
@prog_stuff
Список, который стоит открывать каждый раз, когда садитесь писать что-то с датами: «Заблуждения программистов о времени» Ноа Сассмана. Тридцать четыре утверждения, каждое из которых кажется очевидно верным и каждое неверно. Во второй части их ещё семьдесят девять.
Выборочно: в сутках не всегда 24 часа. Часовой пояс машины не совпадает с поясом пользователя. Часовые пояса меняются политическим решением, а переходы на летнее время не постоянны. Часы клиента и сервера не совпадают. Минута на часах не всегда равна минуте реального времени. Временные метки не обязаны быть уникальными. Время события, время записи в журнал и время получения сообщения — три разных момента.
Любимый пример оттуда: виртуальная машина, приостановленная на два часа, после запуска продолжила считать, что всё ещё час дня.
Вторая часть добирается до високосных секунд, разницы между настенными и монотонными часами и до того, почему
@prog_stuff
Выборочно: в сутках не всегда 24 часа. Часовой пояс машины не совпадает с поясом пользователя. Часовые пояса меняются политическим решением, а переходы на летнее время не постоянны. Часы клиента и сервера не совпадают. Минута на часах не всегда равна минуте реального времени. Временные метки не обязаны быть уникальными. Время события, время записи в журнал и время получения сообщения — три разных момента.
Любимый пример оттуда: виртуальная машина, приостановленная на два часа, после запуска продолжила считать, что всё ещё час дня.
Вторая часть добирается до високосных секунд, разницы между настенными и монотонными часами и до того, почему
sleep(1000) не значит «ровно секунда».@prog_stuff
👍1
Профилировщик показывает, что горячая функция ждёт память. Дальше начинается гадание: какое именно поле какой структуры не влезает в кэш.
Группа из Университета штата Северная Каролина и Google сделала профилировщик, который отвечает на этот вопрос прямо: каждое обращение к памяти связывается с конкретным типом и полем внутри него. Работает поверх штатного
Проверяли на ядре Linux 6.17, memcached, Redis, Git, FFmpeg и Binutils. Покрытие типов для обычной сборки Ubuntu — 92,7 процента, циклов ядра — больше 90. У FFmpeg покрытие циклов всего 40 процентов, потому что там много рукописного векторного кода без отладочной информации.
Пример находки: в нагрузке MySQL на 256 серверах структура
@prog_stuff
Группа из Университета штата Северная Каролина и Google сделала профилировщик, который отвечает на этот вопрос прямо: каждое обращение к памяти связывается с конкретным типом и полем внутри него. Работает поверх штатного
perf и отладочной информации, накладных расходов во время работы программы не добавляет, потому что разбор идёт офлайн.Проверяли на ядре Linux 6.17, memcached, Redis, Git, FFmpeg и Binutils. Покрытие типов для обычной сборки Ubuntu — 92,7 процента, циклов ядра — больше 90. У FFmpeg покрытие циклов всего 40 процентов, потому что там много рукописного векторного кода без отладочной информации.
Пример находки: в нагрузке MySQL на 256 серверах структура
cfs_rq из планировщика занимала 7,58 процента циклов ядра и давала 49,02 процента промахов последнего уровня кэша. Перестановка полей внутри структуры этот вклад заметно снизила.@prog_stuff
20 августа на crates.io вышла версия 0.3.10 крейта
Настоящий крейт называется
Отдельный ход: с того же аккаунта отозвали версии с 0.3.5 по 0.3.9. Cargo на отозванную версию предлагает обновиться, и единственной неотозванной оставалась 0.3.10.
Rust Security Response Team сообщила, что 0.3.10 была доступна 86 минут: опубликована в 07:15 UTC, удалена в 08:41. Отозванные версии вернули, аккаунт заблокировали. Задеты ещё
@prog_stuff
arrayref. Исходники макросов в ней прежние, в манифесте одно изменение — добавлена зависимость proc-macro1 версии 1.0.107.Настоящий крейт называется
proc-macro2, а proc-macro1 — типосквот с подделанным полем authors под именем Дэвида Толная; его src/ копирует proc-macro2, поэтому сборка продолжала работать. Вредонос лежит в сборочном скрипте: адрес сервера собирается из base64-фрагментов, бинарник качается по TLS без проверки сертификата и запускается отдельно от сборки. Срабатывает во время компиляции — достаточно просто собрать проект.Отдельный ход: с того же аккаунта отозвали версии с 0.3.5 по 0.3.9. Cargo на отозванную версию предлагает обновиться, и единственной неотозванной оставалась 0.3.10.
Rust Security Response Team сообщила, что 0.3.10 была доступна 86 минут: опубликована в 07:15 UTC, удалена в 08:41. Отозванные версии вернули, аккаунт заблокировали. Задеты ещё
internment 0.8.7 и append-only-vec 0.1.9.@prog_stuff
Обычная модель угроз для защиты от шифровальщиков предполагает, что операционная система на нашей стороне. Группа из Мичиганского университета взяла модель пожёстче: атакующий контролирует ядро, файловую систему, драйверы, гипервизор и даже привилегированного администратора.
Защита вынесена ниже всего этого — на уровень блочного устройства. Физический блок нельзя перезаписать до истечения заданного интервала, состояние блоков ведётся в журнале, который можно только дополнять, а каждая операция проверяется перед записью. То есть шифровальщик может записать свои данные, но не может стереть старые.
Прототип собран как блочный драйвер для ext4 на Raspberry Pi с обычными диском и твердотельным накопителем. Ядро проверяющей части занимает около 400 строк кода, а свойства «обход невозможен» и «восстановление корректно» доказаны формально в Dafny.
Проверили на 18 семействах программ-вымогателей: файловую систему удалось восстановить в каждом случае. Накладные расходы — 0,4 процента по времени и 0,5 процента по пропускной способности накопителя, счётчики занимают около 2 мегабайт на терабайт данных.
@prog_stuff
Защита вынесена ниже всего этого — на уровень блочного устройства. Физический блок нельзя перезаписать до истечения заданного интервала, состояние блоков ведётся в журнале, который можно только дополнять, а каждая операция проверяется перед записью. То есть шифровальщик может записать свои данные, но не может стереть старые.
Прототип собран как блочный драйвер для ext4 на Raspberry Pi с обычными диском и твердотельным накопителем. Ядро проверяющей части занимает около 400 строк кода, а свойства «обход невозможен» и «восстановление корректно» доказаны формально в Dafny.
Проверили на 18 семействах программ-вымогателей: файловую систему удалось восстановить в каждом случае. Накладные расходы — 0,4 процента по времени и 0,5 процента по пропускной способности накопителя, счётчики занимают около 2 мегабайт на терабайт данных.
@prog_stuff
Если хочется разобраться в криптографии руками, а не по формулам, есть Cryptopals — восемь наборов заданий, где вы последовательно ломаете реальные конструкции.
Устроено так: предварительных знаний криптографии не требуется, нужен только уверенный навык программирования, а язык любой. Каждое задание решается кодом, а не угадыванием.
Первый набор — разминка: hex, Base64, XOR одним байтом, XOR повторяющимся ключом, обнаружение режима ECB. Второй уже интереснее: дополнение по PKCS#7, режим CBC, оракул выбора режима, переворот битов в CBC. Дальше — потоковые шифры, генераторы случайных чисел и повторное использование одноразового значения. Затем атака посредника на обмен ключами Диффи-Хеллмана, подмена параметров группы. Ближе к концу — восстановление сообщений RSA, слабые одноразовые значения в подписях, оракулы дополнения.
Почему это не устарело за тринадцать лет: ECB, оракул дополнения, повторно использованный nonce и плохая случайность — это классы ошибок, а не конкретные библиотеки. Оговорка авторов тоже важна: набор учит ломать, но не является руководством по выбору криптографии для продакшена.
@prog_stuff
Устроено так: предварительных знаний криптографии не требуется, нужен только уверенный навык программирования, а язык любой. Каждое задание решается кодом, а не угадыванием.
Первый набор — разминка: hex, Base64, XOR одним байтом, XOR повторяющимся ключом, обнаружение режима ECB. Второй уже интереснее: дополнение по PKCS#7, режим CBC, оракул выбора режима, переворот битов в CBC. Дальше — потоковые шифры, генераторы случайных чисел и повторное использование одноразового значения. Затем атака посредника на обмен ключами Диффи-Хеллмана, подмена параметров группы. Ближе к концу — восстановление сообщений RSA, слабые одноразовые значения в подписях, оракулы дополнения.
Почему это не устарело за тринадцать лет: ECB, оракул дополнения, повторно использованный nonce и плохая случайность — это классы ошибок, а не конкретные библиотеки. Оговорка авторов тоже важна: набор учит ломать, но не является руководством по выбору криптографии для продакшена.
@prog_stuff
👍1
Как тестировать сервис, у которого 96 операций в API, больше 500 триллионов объектов и свыше 200 миллионов запросов в секунду? Инженеры Amazon описали свой подход на примере S3: рядом с настоящим сервисом живёт исполняемая эталонная модель, которая хранит состояние и сверяет с ним каждый ответ.
Сценарии к модели не пишутся руками и не берутся случайно. Поведение раскладывается на признаки: например, для чтения объекта учитываются 21 параметр запроса, 36 параметров ответа и само содержимое. В одном из экспериментов из 37 признаков получилось 135 категорий поведения и 1025 качественно различных сценариев, которые и генерируются целенаправленно.
Сравнение с обычным тестированием на свойствах показательно: там 28 457 запросов дали 9040 уникальных сценариев, остальные 19 417 оказались повторами. У направленной генерации трёхчасовая кампания выполняет около 432 000 запросов.
В трёх запусках в конвейере сборки модель поймала 171, 92 и 109 расхождений поведения — среди них десятки настоящих проблем, которые иначе уехали бы дальше.
@prog_stuff
Сценарии к модели не пишутся руками и не берутся случайно. Поведение раскладывается на признаки: например, для чтения объекта учитываются 21 параметр запроса, 36 параметров ответа и само содержимое. В одном из экспериментов из 37 признаков получилось 135 категорий поведения и 1025 качественно различных сценариев, которые и генерируются целенаправленно.
Сравнение с обычным тестированием на свойствах показательно: там 28 457 запросов дали 9040 уникальных сценариев, остальные 19 417 оказались повторами. У направленной генерации трёхчасовая кампания выполняет около 432 000 запросов.
В трёх запусках в конвейере сборки модель поймала 171, 92 и 109 расхождений поведения — среди них десятки настоящих проблем, которые иначе уехали бы дальше.
@prog_stuff
Самый быстрый известный алгоритм печати double безымянный: он живёт в файле
Классический Schubfach на каждое число делает два-три 192-битных умножения. Здесь ядро работает на целых фиксированной ширины и обходится одним умножением на заранее вычисленную степень десяти. Дальше рассматриваются четыре кандидата на округление и выбирается кратчайшее корректное представление с округлением к чётному. Отдельно разобран пограничный случай, где алгоритм выбирает между
Автор использует тот же алгоритм в своей библиотеке Żmij. К тексту приложен интерактивный визуализатор на формате E4M3 из 256 кодировок, на котором видно, как работает каждый шаг.
@prog_stuff
yy_double.c внутри JSON-библиотеки yyjson, написан её автором ibireme и почти нигде не описан. Виктор Зверович, автор {fmt}, разобрал, как он устроен и за счёт чего входит в число самых быстрых.Классический Schubfach на каждое число делает два-три 192-битных умножения. Здесь ядро работает на целых фиксированной ширины и обходится одним умножением на заранее вычисленную степень десяти. Дальше рассматриваются четыре кандидата на округление и выбирается кратчайшее корректное представление с округлением к чётному. Отдельно разобран пограничный случай, где алгоритм выбирает между
2e2 и более длинным 19e1, и на первый взгляд это похоже на баг.Автор использует тот же алгоритм в своей библиотеке Żmij. К тексту приложен интерактивный визуализатор на формате E4M3 из 256 кодировок, на котором видно, как работает каждый шаг.
@prog_stuff
В LLVM 23 время компиляции сократилось на 6,75 процента, а на sqlite3 — на 10,53. Никакого одного крупного изменения за этим нет: Александр Энгельке собрал по частям, откуда взялись эти проценты.
Хеш-таблицы перевели с квадратичного пробирования на линейное и избавились от ключей-надгробий:
Отдельная линия — GlobalISel на AArch64
@prog_stuff
Хеш-таблицы перевели с квадратичного пробирования на линейное и избавились от ключей-надгробий:
DenseMap дал −1,27 процента, SmallPtrSet −0,24, StringMap −0,10. Хеш-функцию сменили с CityHash на xxh3. В SmallVector путь роста вынесли из тела push_back, чтобы разрешить хвостовой вызов, — ещё −0,50.Отдельная линия — GlobalISel на AArch64
-O0: отставание от FastISel упало с 12,71 до 9,39 процента. Автор оговаривает, что любимую свою правку тут потом откатили.@prog_stuff
Одна строка
В коде видна попытка переопределить
Отдельная часть текста про ревью: автор сравнивает обычный коммит на 15 строк и 235 символов описания с подозрительным изменением на 1534 строки и 5 символов в сообщении. Это независимый разбор, а не официальный отчёт Coldcard, о чём в тексте сказано прямо.
@prog_stuff
#define MICROPY_HW_ENABLE_RNG (0) отключила аппаратный генератор случайных чисел на STM32, и прошивка аппаратного кошелька молча перешла на слабый программный Yasmarang. Гостевой разбор на btc++ по мотивам истории с Coldcard показывает, как это осталось незамеченным.В коде видна попытка переопределить
pyb_rng_get под собственный источник энтропии, рядом комментарий «у нас своя версия этого кода». Но make_new_wallet() вызывал random.bytes(32), а тот шёл другим путём, через rng_get(), и в итоге брал числа из генератора, который годится для игр, а не для ключей. Код исполнялся без ошибок и честно возвращал 32 байта.Отдельная часть текста про ревью: автор сравнивает обычный коммит на 15 строк и 235 символов описания с подозрительным изменением на 1534 строки и 5 символов в сообщении. Это независимый разбор, а не официальный отчёт Coldcard, о чём в тексте сказано прямо.
@prog_stuff
Как понять, что программисту пора в отпуск:
— на столе бардак;
— шорты не доставались с позапрошлого лета;
— чудится тифлинг;
— на вопрос «когда отдыхаешь?» отвечает «после релиза»;
— релиз был в феврале.
Сам он с места не сдвинется. Помогите Типичному Программисту собраться и улететь в отпуск в новой мини-игре!
— на столе бардак;
— шорты не доставались с позапрошлого лета;
— чудится тифлинг;
— на вопрос «когда отдыхаешь?» отвечает «после релиза»;
— релиз был в феврале.
Сам он с места не сдвинется. Помогите Типичному Программисту собраться и улететь в отпуск в новой мини-игре!
😁4
ELF — это база данных, которая отказывается в этом признаться:
Фарид Закария довёл мысль до конца. Его прототип SELF — исполняемый файл, который целиком является базой SQLite:
Отсюда
Цена: около 5 миллисекунд на старте и страницы, которые копируются из b-дерева вместо отображения в память.
@prog_stuff
.strtab делает интернирование строк, .gnu.hash работает индексом, таблица заголовков секций — это таблица таблиц, а st_name — внешний ключ, разложенный руками.Фарид Закария довёл мысль до конца. Его прототип SELF — исполняемый файл, который целиком является базой SQLite:
file hello показывает «SQLite 3.x database», ./hello печатает Hello, world!, а sqlite3 hello 'SELECT soname FROM ldd' отвечает libc.so.6. Запуск идёт через binfmt_misc и отдельный интерпретатор.Отсюда
strip — это DELETE и VACUUM, patchelf — UPDATE, а LD_PRELOAD — строка в таблице, которую можно включить и откатить транзакцией.Цена: около 5 миллисекунд на старте и страницы, которые копируются из b-дерева вместо отображения в память.
@prog_stuff
На скриншоте ролик, к которому YouTube показывает пометку «снято камерой». Внутри — рендер из Big Buck Bunny.
Дэвид Бьюкенен разобрал, почему C2PA на Android так подделывается. Приложения-камеры опираются на Key Attestation и Play Integrity, а рут, полученный через эксплойт, обе проверки не тревожит: загрузчик остаётся заблокированным, ключи AVB — вендорскими, и серверы Google спокойно выдают устройству ключи подписи. Сам ключ из StrongBox не вытащить, но попросить Titan M2 подписать произвольные данные рут может.
Проверял автор на Pixel 8a и 9a, рут брал одноклик-эксплойтом CVE-2026-43499, который на полностью обновлённых Pixel всё ещё работает. Приложение Pixel Camera при этом имеет Assurance Level 2 — высший из определённых сейчас уровней программы соответствия C2PA.
Google закрыла отчёт как «Won't fix (infeasible)», выплатила 7500 долларов, а плашка у ролика после публикации исчезла — автор считает, что её сняли руками.
@prog_stuff
Дэвид Бьюкенен разобрал, почему C2PA на Android так подделывается. Приложения-камеры опираются на Key Attestation и Play Integrity, а рут, полученный через эксплойт, обе проверки не тревожит: загрузчик остаётся заблокированным, ключи AVB — вендорскими, и серверы Google спокойно выдают устройству ключи подписи. Сам ключ из StrongBox не вытащить, но попросить Titan M2 подписать произвольные данные рут может.
Проверял автор на Pixel 8a и 9a, рут брал одноклик-эксплойтом CVE-2026-43499, который на полностью обновлённых Pixel всё ещё работает. Приложение Pixel Camera при этом имеет Assurance Level 2 — высший из определённых сейчас уровней программы соответствия C2PA.
Google закрыла отчёт как «Won't fix (infeasible)», выплатила 7500 долларов, а плашка у ролика после публикации исчезла — автор считает, что её сняли руками.
@prog_stuff