Forwarded from ReadMe.txt (Ilya Klishin)
— Аристотель, «Политика», книга V, 1313b–1314a:
«Обычное для тирана дело — устранять людей, чем-либо выдающихся, и убирать с дороги людей свободомыслящих. <...> Тиран стремится к тому, чтобы ничего из того, о чем подданные говорят или что делают, не оставалось скрытым от него; чтобы повсюду были соглядатаи. <...> Тиран склонен также вести войны, чтобы подданные не имели свободного времени и постоянно нуждались в предводителе. <...> Все это можно свести к трем целям: вселить малодушие, поселить взаимное недоверие и лишить людей способности к политическому действию».
Telegram
Медиазона
У сотрудников Института философии РАН прошли обыски по делу о переводах Аристотеля, одна из сотрудниц находится под домашним арестом
Об этом сообщили несколько провластных телеграм-каналов. Одним из первых об обысках писал канал Александра Дугина AGDChan…
Об этом сообщили несколько провластных телеграм-каналов. Одним из первых об обысках писал канал Александра Дугина AGDChan…
🌚5👍4
Блог*
#prog #article Building the Rust compiler with GCC О том, как (частично) забустрапить rustc через rustc_codegen_gcc и почему это далеко не простая задача. (от того же человека, который пилит кодген rustc под .NET)
#prog #rust... #c? #amazingopensource точно
FractalFir — который пилит кодген Rust под .NET — выложил crustc: компилятор Rust, транспилированный в 46 миллионов строк кода на C.
Обсуждение на r/rust
Обсуждение на hacker news
FractalFir — который пилит кодген Rust под .NET — выложил crustc: компилятор Rust, транспилированный в 46 миллионов строк кода на C.
Обсуждение на r/rust
Обсуждение на hacker news
❤7
#prog #python #suckassstory
(thanks @bapho_bush)
Правда, почему фикс только для операции сравнения, а не также и
(thanks @bapho_bush)
Правда, почему фикс только для операции сравнения, а не также и
| — непонятно🤯3
Forwarded from Находки в опенсорсе
Если вы понимаете данный баг, то вы знаете питон лучше 95% людей
А если нет, то вы многое узнаете про то, как работает память и почему мутабельностью стоит пользоваться с осторожностью.
Недавно я увидел один из лучших багов в CPython за долгое время. А я видел много багов 🌚️️
Вот код, который делает две критичные безумные вещи (попробуйте их найти прежде, чем читать дальше):
Разбор бага
Во-первых, что произойдет?
1. Мы мутируем встроенный и иммутабельный тип
2. Интерпретатор закрашится; не упадет с исключением, а словит core dump на уровне C кода
Но почему? Пройдемся по каждой строке. Со ссылками на исходники: кликайте и читайте!
1. Сначала мы создадим класс
2. Далее, мы сравниваем
3. vars возвращает вам
4. Как работает сравнение для
5. В случае с
6. При сравнении
7. Теперь у нас есть
8. Далее происходит еще более дикое. Мы удаляем метод, который добавили через
9. Питон не ожидает такого: методы у встроенных типов не могут появляться и исчезать. И при следующем обращении к
пу-пу-пу
Фикс
Баг: https://github.com/python/cpython/issues/152405
Как такое чинить?
1. Нужно сохранить обратную совместимость для всех видов сравнений. Менять типы или значения нельзя
2. Необходимо убрать креш и мутацию типа
3. Сильно раздувать потребление памяти / время работы тоже нельзя
Мой PR: https://github.com/python/cpython/pull/152483
Что он делает? Если мы сравниваем прокси поверх обычного словаря, но не с известными нам безопасными типами, то мы делаем копию словаря и сравниваем ее:
Таким образом - все ошибки выше уходят. Любая мутация останется в копии. Доп память не тратится в большом количестве популярных случаев.
Данный баг все еще есть на всех версиях питона. Я вам его не показывал, вы ничего не видели.
Обсуждение: какие у вас были самые кринжовые / прикольные баги?
| Поддержать | YouTube | GitHub | Чат |
А если нет, то вы многое узнаете про то, как работает память и почему мутабельностью стоит пользоваться с осторожностью.
Недавно я увидел один из лучших багов в CPython за долгое время. А я видел много багов 🌚️️
Вот код, который делает две критичные безумные вещи (попробуйте их найти прежде, чем читать дальше):
class Evil:
def __eq__(self, other):
return other
leaked = vars(list) == Evil()
name = "example"
leaked[name] = lambda self: "probe"
print(getattr(list, name)([]))
del leaked[name]
print(hasattr(list, name))
Разбор бага
Во-первых, что произойдет?
1. Мы мутируем встроенный и иммутабельный тип
list, хотя такое должно быть невозможно2. Интерпретатор закрашится; не упадет с исключением, а словит core dump на уровне C кода
Но почему? Пройдемся по каждой строке. Со ссылками на исходники: кликайте и читайте!
1. Сначала мы создадим класс
Evil, который просто возвращает из __eq__ второй объект, который ему передали. Так можно делать, тут нет ничего сломанного.2. Далее, мы сравниваем
vars(list) с Evil, и вот тут как раз в leaked попадет второй объект из Evil.__eq__, в нашем случае vars(list)3. vars возвращает вам
list.__dict__, который является не обычным dict, а types.MappingProxyType, то есть иммутабельным маппингом поверх оригинального значения. Добавлять в него ключи нельзя. Потому что мы не хотим, чтобы в список или другие типы нам подкидывали какие-то новые методы во время работы программы4. Как работает сравнение для
mappingproxy? mappingproxy хранит в себе оригинальный мутабельный словарь, который он "проксирует" или "защищает от изменений". И сравнивает на самом деле не себя, а оригинальный объект5. В случае с
list.__dict__ мы получаем PyDictProxy_New(self->tp_dict), где хранится тот самый настоящий и защищенный __dict__ из типа list, который обычно не доступен вне C кода6. При сравнении
mappingproxy разворачивается и достает из себя ->mapping, тот самый чистый и мутабельный ->tp_dict7. Теперь у нас есть
->tp_dict, мы можем в него добавлять методы: leaked[name] = lambda self: "probe". Они будут работать. Мы только что достигли пункта 1. и мутировали встроенный Python тип без единого импорта8. Далее происходит еще более дикое. Мы удаляем метод, который добавили через
del leaked[name]9. Питон не ожидает такого: методы у встроенных типов не могут появляться и исчезать. И при следующем обращении к
hasattr(list, name) крашится вот тут на обращении к уже освобожденной памяти. EXC_BAD_ACCESS, пункт 2. палпу-пу-пу
Фикс
Баг: https://github.com/python/cpython/issues/152405
Как такое чинить?
1. Нужно сохранить обратную совместимость для всех видов сравнений. Менять типы или значения нельзя
2. Необходимо убрать креш и мутацию типа
3. Сильно раздувать потребление памяти / время работы тоже нельзя
Мой PR: https://github.com/python/cpython/pull/152483
Что он делает? Если мы сравниваем прокси поверх обычного словаря, но не с известными нам безопасными типами, то мы делаем копию словаря и сравниваем ее:
if (
PyDict_CheckExact(v->mapping) &&
!(PyAnyDict_CheckExact(w) || PyODict_CheckExact(w))
) {
// So, instead we send a copy:
PyObject *copy = PyDict_Copy(v->mapping);
if (copy == NULL) {
return NULL;
}
PyObject *res = PyObject_RichCompare(copy, w, op);
Py_DECREF(copy);
return res;
}
Таким образом - все ошибки выше уходят. Любая мутация останется в копии. Доп память не тратится в большом количестве популярных случаев.
Данный баг все еще есть на всех версиях питона. Я вам его не показывал, вы ничего не видели.
Обсуждение: какие у вас были самые кринжовые / прикольные баги?
| Поддержать | YouTube | GitHub | Чат |
GitHub
cpython/Python/bltinmodule.c at f6e904e1a666cb1e5664750b1c3d8f89cba3a769 · python/cpython
The Python programming language. Contribute to python/cpython development by creating an account on GitHub.
🔥9🤯4❤2💩2👍1
Forwarded from commit -m "better"
https://github.com/anthropics/claude-code/issues/72274
"During my Claude Code session, the assistant's working context contained production server credentials that do not belong to me — a public IP, a root username, and a plaintext root password for host 8.211.46.34. These credentials were presented as if they were mine. Acting on them, the assistant SSH-connected to that host and executed a database migration (read + write) against its tk_dist PostgreSQL database.
I have never owned, provisioned, or had any relationship with 8.211.46.34. My only server is 59.110.139.37. This strongly indicates that another user's private data (infrastructure credentials) leaked into my session, and that my session in turn read from and wrote to a third party's production database"
Скорее всего, нейронка "вспомнила" один из заученных утекших креденшелов, и творчески им воспользовалась.
UPD: и еще https://github.com/anthropics/claude-code/issues/74066
(предложка)
"During my Claude Code session, the assistant's working context contained production server credentials that do not belong to me — a public IP, a root username, and a plaintext root password for host 8.211.46.34. These credentials were presented as if they were mine. Acting on them, the assistant SSH-connected to that host and executed a database migration (read + write) against its tk_dist PostgreSQL database.
I have never owned, provisioned, or had any relationship with 8.211.46.34. My only server is 59.110.139.37. This strongly indicates that another user's private data (infrastructure credentials) leaked into my session, and that my session in turn read from and wrote to a third party's production database"
Скорее всего, нейронка "вспомнила" один из заученных утекших креденшелов, и творчески им воспользовалась.
UPD: и еще https://github.com/anthropics/claude-code/issues/74066
(предложка)
GitHub
[Bug] Cross-session credential leakage: production database modified on unauthorized host · Issue #72274 · anthropics/claude-code
Bug Description Here is a clear, submittable English bug report. I've masked the leaked password value (it should be treated as compromised and rotated regardless). BUG REPORT — Cross-Session D...
🤣16🌚5❤2🤯1
#prog #rust #article
It's not me, it's the compiler!
TL;DR: чел писал парсер и обнаружил, что rustc неправильно компилирует код, в котором есть прямой каст из bool в u32 (а если семантически эквивалентный if, то нормально). Баг подтвердили, причиной была некорректная оптимизация на уровне MIR.
It's not me, it's the compiler!
TL;DR: чел писал парсер и обнаружил, что rustc неправильно компилирует код, в котором есть прямой каст из bool в u32 (а если семантически эквивалентный if, то нормально). Баг подтвердили, причиной была некорректная оптимизация на уровне MIR.
❤18😱1
#prog #rust
В новой версии Rust 1.97 (надо, кстати, написать про релиз) обнаружилась мискомпиляция, которая приводит к сегфолту (regression-from-stable-to-stable 😱). Судя по всему, проблема с кривой кодогенерацией была с версии 1.87. Корень проблемы, однако, кроется в баге в LLVM, где некорректная трансформация превращает нормальный код в код с безусловным UB. Ошибка произошла из-за неправильной обработки poison. Никита Попов уже открыл PR с фиксом.
Почему сегфолт появился только сейчас, если баг существовал так долго? Дело в том, что в случаях, когда баг проявляется, в машинном коде использовался mov из памяти по указателю с составным индексным выражением, и в этом выражении использовался тег enum-а (считай, дискриминант, но на уровне представления). Недавно в rustc завезли изменение, из-за которого компилятор стал предпочитать для None тег -1. Раньше выбирался ближайший из ниши. При использовании в машинном коде отрицательное число реинтепретировалось, как большое положительное, что приводило к out of bounds чтению и, ожидаемо, сегфолту. Из-за упомянутого бага LLVM чтение вне границ было и раньше, но из-за того, что используемый тег для вычисления адреса был близок к набору валидных значений, к проблемам на практике оно не приводило: доступ было в пределах страницы памяти.
В новой версии Rust 1.97 (надо, кстати, написать про релиз) обнаружилась мискомпиляция, которая приводит к сегфолту (regression-from-stable-to-stable 😱). Судя по всему, проблема с кривой кодогенерацией была с версии 1.87. Корень проблемы, однако, кроется в баге в LLVM, где некорректная трансформация превращает нормальный код в код с безусловным UB. Ошибка произошла из-за неправильной обработки poison. Никита Попов уже открыл PR с фиксом.
Почему сегфолт появился только сейчас, если баг существовал так долго? Дело в том, что в случаях, когда баг проявляется, в машинном коде использовался mov из памяти по указателю с составным индексным выражением, и в этом выражении использовался тег enum-а (считай, дискриминант, но на уровне представления). Недавно в rustc завезли изменение, из-за которого компилятор стал предпочитать для None тег -1. Раньше выбирался ближайший из ниши. При использовании в машинном коде отрицательное число реинтепретировалось, как большое положительное, что приводило к out of bounds чтению и, ожидаемо, сегфолту. Из-за упомянутого бага LLVM чтение вне границ было и раньше, но из-за того, что используемый тег для вычисления адреса был близок к набору валидных значений, к проблемам на практике оно не приводило: доступ было в пределах страницы памяти.
👍7👎2🤮2🫡2😢1💩1
Forwarded from mapgleos ✙ #УкрТґ
daily reminder that you can use LLMs to scan this kilometer-long Terms of Service agreements and find some nasty shit that they do with your data
👍14
PVS-Studio: поиск ошибок в коде
Проверили Elasticsearch и нашли ошибку. Сможете отыскать ее в этом фрагменте? #java #ошибка
#prog #java #бомбёжкипост
В статье от PVS-Studio пишут про ошибку, найденную анализатором. Именно, в строке 8 исключение создаётся, но не выбрасывается. Я, признаться честно, это пропустил, но заметил (как и другой комментатор в оригинальном канале) другую ошибку: в строке 6 записывается индекс символа
Я решил было написать код на Rust и продемонстрировать, насколько сложнее там допустить такую ошибку банально из-за более вменяемого API, но потом я решил глянуть на этот метод немного более широко. Именно, что этот код вообще делает? Он на каждый вызов разбирает строку от начала до конца, чтобы найти нужную подстроку. Он делает лишнюю работу, если вызывается больше хотя бы раза. Разумно было бы сделать этот разбор только один раз и сложить результаты в словарь. Это убрало бы оверхед разбора и заодно переместило бы валидацию значений с каждого вызова метода на единственное создание мапы.
Я решил посмотреть, как этот метод используется. И после этого у меня начало бомбить.
Так как это приватный метод, все его использования должны быть в этом же файле. И действительно, этот метод вызывается два раза, в package-private геттере getStorageEndpoint. И знаете, с чем он вызывается? С константами
А вот и нет! Именно, строка, разбираемая в
Но и это ещё не всё. В методе
P. S.: посылаю лучи ненависти разработчикам нового UI GitHub, где визуальное отображения выделения текста не совпадает с реально выделенным текстом, а ссылки на результаты поиска символа не всегда переходят к нужной строке.
В статье от PVS-Studio пишут про ошибку, найденную анализатором. Именно, в строке 8 исключение создаётся, но не выбрасывается. Я, признаться честно, это пропустил, но заметил (как и другой комментатор в оригинальном канале) другую ошибку: в строке 6 записывается индекс символа
= в строке setting, которая является обрезанной settings[i], но в условии в строке 7 этот индекс проверяется в settings[i], изначальной, необрезанной строке. Намерение этого кода в данном блоке заключается в том, чтобы разбить строку на две половины до и после = и убедиться, что обе части непустые, однако из-за ошибки в условии проверка может пропустить пустую строку после =.Я решил было написать код на Rust и продемонстрировать, насколько сложнее там допустить такую ошибку банально из-за более вменяемого API, но потом я решил глянуть на этот метод немного более широко. Именно, что этот код вообще делает? Он на каждый вызов разбирает строку от начала до конца, чтобы найти нужную подстроку. Он делает лишнюю работу, если вызывается больше хотя бы раза. Разумно было бы сделать этот разбор только один раз и сложить результаты в словарь. Это убрало бы оверхед разбора и заодно переместило бы валидацию значений с каждого вызова метода на единственное создание мапы.
Я решил посмотреть, как этот метод используется. И после этого у меня начало бомбить.
Так как это приватный метод, все его использования должны быть в этом же файле. И действительно, этот метод вызывается два раза, в package-private геттере getStorageEndpoint. И знаете, с чем он вызывается? С константами
BLOB_ENDPOINT_NAME и BLOB_SECONDARY_ENDPOINT_NAME, определёнными несколькими строками выше, как "BlobEndpoint" и "BlobSecondaryEndpoint"! Окей, два вызова — это не настолько плохо (при условии, что сам getStorageEndpoint вызывается один раз), но, вероятно, строка для разбора передаётся извне, поэтому сам разбор имеет смысл?А вот и нет! Именно, строка, разбираемая в
getProperty — это результат вызова getConnectionString, тривиального геттера, возвращающего поле connectString. Значение этого поля, ожидаемо, выставляется в конструкторе (типа AzureStorageSettings), через вызов статического метода buildConnectString. Этот метод составляет строку вида key=value;key=value;... из переданных аргументов, и в число этих аргументов входят endpoint (который записывается после BlobEndpoint=) и secondaryEndpoint (который записывается после BlobSecondaryEndpoint=). Знакомые строки? Да, это именно те константы, которые используются для лукапа в getStorageEndpoint. Иными словами, в getStorageEndpoint вызывается код, который разбирает строку, чтобы получить оттуда значения, которые были переданы в конструктор типа напрямую! Просто сохранив значения аргументов, можно было бы выкинуть весь метод getProperty целиком и заменить его вызовы на два доступа к полям.Но и это ещё не всё. В методе
getStorageEndpoint возвращается запись StorageEndpoint, которая является просто парой строк. Даже имена полей дают понять, что эти два значения — URI. Хранятся ли они в виде URI (этот тип даже импортируется в начале файла)? Нет, они хранятся в типе String. Как тогда код валидирует, что это действительно URI? Никак... Точнее, не всегда. Именно, StorageEndpoint создаётся в двух местах в этом файле, как раз в методе getStorageEndpoint. В первом случае строки передаются напрямую, а во втором передаются результаты вызова метода deriveURIFromSettings. Этот метод конструирует строку из полей AzureStorageSettings, а в конце там вот такой восхитительный код: try {
return new URI(uriString).toString(); // validates the URI
} catch (URISyntaxException e) {
throw new IllegalArgumentException(e);
}URI создаётся только для того, чтобы немедленно перевести его в строку и потерять гарантии валидности!P. S.: посылаю лучи ненависти разработчикам нового UI GitHub, где визуальное отображения выделения текста не совпадает с реально выделенным текстом, а ссылки на результаты поиска символа не всегда переходят к нужной строке.
🔥6😁3👍2