LINUX.ORG.RU

Переполнение кучи в glibc и другое

 ,


0

4

Рунет сегодня ожил, а тут свежачок подвезли:

https://sourceware.org/git/?p=glibc.git;a=commitdiff;h=6bd0e4efcc78f3c0115e5ea9739a1642807450da;hp=8aeec0eb5a18f9614d18156f9d6092b3525b818c

И ещё другие баги в glibc 2.37 типа порчи памяти в qsort.

Если бегло взглянуть на код исправления по ссылке, ясно, что это не что-то совсем уж тривиальное, т.е. именно те случаи, ради которых выдумываются и продвигаются все эти ады и расты. Но так же понятно, что в существенное количество устройств такие баги даже не смогут теоретически попасть, потому что будут исправлены ещё до того, как конторы дойдут до версии glibc 2022г.в.

Перемещено hobbit из talks

★★★★★

Ответ на: комментарий от cumvillain

Да кстати нет. Тот же kencc в принципе норм и при этом слезает в пару десятков тысяч строк. Только там на стандарты и совместимость с gcc авторы положили болт и пилят как считают нужным. По производительности в среднем выходит примерно на уровне руста и в худших случаях раза в два медленнее гцц, что в принципе норм.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Да кстати нет. Тот же kencc в принципе норм и при этом слезает в пару десятков тысяч строк. Только там на стандарты и совместимость с gcc авторы положили болт и пилят как считают нужным. По производительности в среднем выходит примерно на уровне руста и в худших случаях раза в два медленнее гцц, что в принципе норм.

Пруфов бы.

cumvillain
()
Ответ на: комментарий от hateyoufeel

Только там на стандарты и совместимость с gcc авторы положили болт и пилят как считают нужным

Одобряю - всмысле, что «пилят как считают нужным» приоритетнее всего остального. Старый gcc тоже такой идеологии был, новый уже не всегда. Надо посмотреть что за проект.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

То, что ты пишешь - это особенность х86-32 и х86-64, а Си просто прозрачно эту нативную архитектуру передаёт. Впрочем, под х86-32 ещё можно сделать ОС с сегментами.

Прозрачно СИ передает лишь выход за границы выделенной адресной области, со всем остальным нужно помудиться.

Скажите, вас не смущает что в языке есть обычные указатели, указатели на указатели, даже умные указатели (auto_ptr) и тд, но нет кольцевого указателя, хотя он бы решил большинство проблем с эксплуатацией уязвимостей?

Ответ прост - гордыня. Гордыня авторов языка которые решили что и так справятся, никакой утечки памяти не будет, никаких выходов за границы выделенного адресного пространства и тд. они не допустят своей волей и лучше чуть быстрее чем чуть безопаснее. Что они - молодцы и справятся. Не справились.

Не удивлюсь, если через пару тройку лет появится какой-нибудь std::ring_ptr что будет объявлено нифига себе каким прорывом, ну как обычно.

Obezyan
()
Ответ на: комментарий от firkax

Если самое сложное оптимизатор то отличия между разными диалектами языка незначительно влияют на сложность компилятора.

Если нет пруфов на amd64, значит нет пруфов на современном железе.

cumvillain
()
Ответ на: комментарий от Obezyan

У меня возникло подозрение что на Си ты ничего всерьёз не писал. Си-указатель это нативный указатель проца, такой же как в ассемблере. За двумя исключениями: 1) NULL иногда обрабатывается особым образом, особенно на старых экзотических архитектурах мог, 2) современные веяния оптимизации иногда приписывают указателям неожиданную логику, но это скорее не в указателях уже дел.

указатели на указатели

Это и есть обычные указатели.

умные указатели (auto_ptr)

Такого в Си нет.

Прозрачно СИ передает лишь выход за границы выделенной адресной области, со всем остальным нужно помудиться.

Нет, он прозрачно передаёт всю процовую логику обработки указателей.

firkax ★★★★★
()
Ответ на: комментарий от firkax

У меня возникло подозрение что на Си ты ничего всерьёз не писал.

В этом году я не написал ни строчки на Си и пока не собираюсь.

Си-указатель это нативный указатель проца, такой же как в ассемблере.

В этом и проблема.

Такого в Си нет.

Я про то что в С это таки есть хоть и виде тех немногих С-программистов кто смог эволюционировать и посмотреть на все это сбоку. Но потом приходит понимание «а зачем?» и они переходят в С++ или в другие ЯП.

Obezyan
()
Последнее исправление: Obezyan (всего исправлений: 1)
Ответ на: комментарий от cumvillain

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

firkax ★★★★★
()
Ответ на: комментарий от Obezyan

В этом и проблема.

Проблем тут нет. Просто у кого-то ожидания от языка не соответствуют действительности и они начинают винить в этом язык.

Я про то что в С это таки есть

Это не в Си, а в какой-то библиотеке.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Проблем тут нет. Просто у кого-то ожидания от языка не соответствуют действительности и они начинают винить в этом язык.

Ну тут либо винить язык и его непродуманную архитектуру либо как @cumvillain винить тех кто его использует.

На какой стул сами сядете, на какой Си посадите?

Obezyan
()
Ответ на: комментарий от cumvillain

Компилятор на C (которым можно реально пользоваться, а не просто упражнение) это несколько миллионов строк чрезвычайно упоротого движка по оптимизации.

Это не надолго. Скоро научат нейросеть оптимизировать и не нужны станут компиляторы забубенные

это шутка, еслив чо

или нет

FishHook
()
Ответ на: комментарий от Obezyan

Ну тут либо винить язык и его непродуманную архитектуру либо как @cumvillain винить тех кто его использует.

Я виню тех кто его фанатично использует в том что они не видят его непродуманную архитектуру. Я тут всех сразу виню :D

cumvillain
()
Ответ на: комментарий от firkax

Теперь про компилятор. Вот используют СИ программисты gcc компилятор (как пример). А они как-то верифицируют то что он скомпилировал? Какие оптимизации он сделал? Чем они отличаются от «promt-инженеров» вся работа которых в правильной формулировке вопроса к нейронной сети.

При этом использование выхлопа нейронок мы все осуждаем тк неверифицируемо. А про выхлоп gcc, особенно с ключами оптимизации - скромно молчим.

Да, есть компилятор CompCert C, который предоставляет машинную проверку того, что сгенерированный код ведёт себя так же, как и исходный код, но скорее всего вы о нем узнали только что из моего сообщения (буду рад если не так, хотелось бы более высокого уровня дискуссии). А больше-то Си компиляторов с формальной верификацией-то и нет.

Так чем же вы, Си-программисты, отличаетесь от тех кто пишет код используя chatGPT? :)

Obezyan
()
Ответ на: комментарий от Obezyan

Нет, винить надо тех кто почему-то свои фантазии считает за требования к языку.

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

firkax ★★★★★
()
Ответ на: комментарий от firkax

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

Лулз в том что в userspace это не нужно, что прекрасно доказал тот же раст.

cumvillain
()
Ответ на: комментарий от firkax

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

А ассемблер напрямую регистры дает щупать. Но на нем пишут все меньше (и то в основном ассемблерные вставки), таже участь ждет и Си. По той же причине.

Obezyan
()
Ответ на: комментарий от firkax

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

В любом языке указатель является нативным указателем проца. Ссылки в жабе – нативные указатели проца. Все вообще значения в хачкелле – нативные указатели проца. Твоё утверждение не значит буквально вообще нихрена в данном контексте.

hateyoufeel ★★★★★
()
Ответ на: комментарий от cumvillain

Вот растопрограммистам и не нужно, порадуемся за них. Но не надо лезть с нелепой критикой к тем, кому нужно.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от firkax

ВОт растопрограммистам и не нужно, порадуемся за них. Но не надо лезть с нелепой критикой к тем, кому нужно.

Тебе тоже не нужно. Если я сегодня заменю твои сырые указатели на ссылки, ты даже не заметишь.

cumvillain
()
Ответ на: комментарий от cumvillain

Он путает ссылки с указателями. Типичная сишная ограниченность.

Тут как бы лулз в том, что в C даже нельзя любой возможный адрес в указатель сунуть, потому что это будет UB.

И это мы забываем о том, что C притворяется, что вся вообще память одинаковая и ровная, что уже лет 30 не так. А про процессорные кеши в C неизвестно вообще ничего.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от hateyoufeel

Нет, в джаве нативных указателей нет, они используются её внутренностями для реализации ссылок, но напрямую джава-приложению они недоступны. Ты же не можешь прибавить к джавовой ссылке единицу, чтобы оказаться на следующем байте памяти? Не может вообще стайпкастить 0x12345678 в ссылку чтоб прочитать байт по этому адресу? Более того, сборщик мусора может в любой момент переместить твои данные в другое место, но на уровне языка это не заметно. Вот это оно.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
Ответ на: комментарий от cumvillain

Где-то может и не замечу, но много где вовсе нет, на первом же *(uint32*)(buf+123) рассыпется. Или, ещё проще, на инкременте указателя на строку чтоб попасть в следующий символ.

firkax ★★★★★
()
Ответ на: комментарий от hateyoufeel

И это мы забываем о том, что C притворяется, что вся вообще память одинаковая и ровная, что уже лет 30 не так. А про процессорные кеши в C неизвестно вообще ничего.

Мы не забываем, а оставляем это в беседе на сладкое, когда адепт Си будет равномерно разогрет по всей поверхности.

Obezyan
()
Ответ на: комментарий от firkax

Где-то может и не замечу, но много где вовсе нет, на первом же (uint32)(buf+123) рассыпется.

С чего бы?

Или, ещё проще, на инкременте указателя на строку чтоб попасть в следующий символ.

С чего бы, лол?

cumvillain
()
Ответ на: комментарий от firkax

Нет, в джаве нативных указателей нет

Есть.

они используются её внутренностями для реализации ссылок, но напрямую джава-приложению они недоступны

Доступны.

Ты же не можешь прибавить к джавовой ссылке единицу, чтобы оказаться на следующем байте памяти?

В общем случае, ты этого и в C сделать не можешь. Потому что правила вокруг strict aliasing и прочее UB.

Не может вообще стайпкастить 0x12345678 в ссылку чтоб прочитать байт по этому адресу?

Это UB в C лол

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

Тут как бы лулз в том, что в C даже нельзя любой возможный адрес в указатель сунуть, потому что это будет UB.

УМВР.

И это мы забываем о том, что C притворяется, что вся вообще память одинаковая и ровная, что уже лет 30 не так. А про процессорные кеши в C неизвестно вообще ничего.

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

Но кстати, как я уже говорил, не везде. Есть архитектуры, где NULL указывает не на нулевую ячейку а куда-то в другое место. То есть:

char *p = NULL;
printf("%d %d\n", (int)p, (int)*(intptr*)&p);

выведет не 0 0 а 0 {какое-то число}, а тайпкаст этого NULL в (int) на уровне асма будет нетривиальным. Но это всего одно исключение и оно большей частью в прошлом.

firkax ★★★★★
()
Ответ на: комментарий от firkax

О каких таких ссылках ты говорил, что к ним можно адресную арифметику применять

Их можно индексировать.

и чем они тогда от указателей отличаются?

Тем, что они обмазаны статическими проверками на уровне компиляции и приправлены рантаймовыми проверками. Чтобы очередной дыры не было :D

cumvillain
()
Ответ на: комментарий от firkax

Тут как бы лулз в том, что в C даже нельзя любой возможный адрес в указатель сунуть, потому что это будет UB.

УМВР.

Потому что ты не знаешь C и пишешь на нём неправильно. В следующей версии компилятора твой код сломается и ты будешь верещать про неправильные компиляторы.

И это мы забываем о том, что C притворяется, что вся вообще память одинаковая и ровная, что уже лет 30 не так. А про процессорные кеши в C неизвестно вообще ничего.

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

Нет, это процессор притворяется, чтобы сишный код работал.

Но кстати, как я уже говорил, не везде. Есть архитектуры, где NULL указывает не на нулевую ячейку а куда-то в другое место.

Нет, нету. Либо это нестандартный порт C, потому что в стандарте C написано, что NULL должен приводиться к 0 и никак иначе.

Но это всего одно исключение и оно большей частью в прошлом.

Так можно сказать, что в C есть умные указатели, потому что они были в Cyclone.

hateyoufeel ★★★★★
()
Ответ на: комментарий от hateyoufeel

В общем случае, ты этого и в C сделать не можешь. Потому что правила вокруг strict aliasing и прочее UB.

Общий случай меня не интересует, мало ли кто что напридумывает. Если пользоваться нормальным компилятором и не включать жёсткие режимы оптимизации то всё норм. Компилятор нужной версии можно в build-dep к проге вписать если опасаешься что её неправильным будут компилировать.

Это UB в C лол

УМВР [2].

firkax ★★★★★
()
Ответ на: комментарий от firkax

Компилятор нужной версии можно в build-dep к проге вписать если опасаешься что её неправильным будут компилировать.

Это UB в C лол

УМВР [2].

Типичный сишник лол. Языка не знает, пишет говнокод который только у него работает и ломается за пределами его сборочной среды.

hateyoufeel ★★★★★
()
Последнее исправление: hateyoufeel (всего исправлений: 1)
Ответ на: комментарий от cumvillain

Если твои ссылки это просто указатели с навязанными проверками то может и много где не замечу, но в проге будет совершенно ненужный оверхед. Впрочем и его можно не заметить, если тот код не узкое место, но всё равно неприятно.

firkax ★★★★★
()
Ответ на: комментарий от firkax

Если твои ссылки это просто указатели с навязанными проверками то может и много где не замечу, но в проге будет совершенно ненужный оверхед.

Измерить ты его, конечно же, не сможешь. Потому что этот оверхед там у тебя и так уже есть, просто ты его пишешь руками :D

Впрочем и его можно не заметить, если тот код не узкое место, но всё равно неприятно.

Это ментальная ловушка. На самом деле, все эти проверки ты сам написал, зачем-то потратив на это бесценное время жизни.

cumvillain
()
Ответ на: комментарий от hateyoufeel

Потому что ты не знаешь C и пишешь на нём неправильно. В следующей версии компилятора твой код сломается и ты будешь верещать про неправильные компиляторы.

Надо просто знать что делаешь и проблем не будет.

Нет, нету. Либо это нестандартный порт C, потому что в стандарте C написано, что NULL должен приводиться к 0 и никак иначе.

Ты не дочитал. NULL приводится к 0, да, но при этом не содержит 0 в своём нативном представлении (на это требования нигде не было). И тайпкаст указателя в int там не no-op как обычно везде, а типа такого if(p==NULL) return 0; else return (native_typecast_int)p;

Типичный сишник лол. Языка не знает, пишет говнокод который только у него работает и ломается за пределами его сборочной среды.

Ты не прав.

firkax ★★★★★
()