Size: a a a

2020 May 05

ПК

Побитый Кирпич... in pro.cxx
Constantine Drozdov
да, заметь, что strict aliasing запрещает тебе одновременно использовать buf и info в моей версии (и не запрещает в твоей)
Почему в моей не запрещает? В чем принципиальная разница?
источник

CD

Constantine Drozdov in pro.cxx
Побитый Кирпич
А это валидный?

float* f = new float(0.0f);
hack_cxx(f);
auto* i = (int*)f;
*i = 0;

Где hack_cxx это extern C функция
Да. Ну ты тело strlen видел? Оно границы массива не уважает совсем. (главное чтобы hack_cxx была где-нибудь в dll или прочем недоступном в исходниках месте)
источник

ПК

Побитый Кирпич... in pro.cxx
Constantine Drozdov
Да. Ну ты тело strlen видел? Оно границы массива не уважает совсем. (главное чтобы hack_cxx была где-нибудь в dll или прочем недоступном в исходниках месте)
На валидной строке разве 0 не входит в массив?
источник

ПК

Побитый Кирпич... in pro.cxx
Или она дальше нуля смотрит?
источник

A

Alex in pro.cxx
Constantine Drozdov
Ну вектор если что аллокает массив байт и делает плейсмент нью, это валидный код же
ой вряд ли валидный
источник

CD

Constantine Drozdov in pro.cxx
Побитый Кирпич
Или она дальше нуля смотрит?
Дальше нуля смотрит
источник

ПК

Побитый Кирпич... in pro.cxx
Constantine Drozdov
Дальше нуля смотрит
Зачем?
источник

CD

Constantine Drozdov in pro.cxx
Чтобы по 8 байт читать, а не по 1
источник

CD

Constantine Drozdov in pro.cxx
Автор strlen совершенно точно знает, что из-за особенностей работы страниц при чтении с выравниванием по 8 можно и перечитать малясь строку
источник

ПК

Побитый Кирпич... in pro.cxx
Constantine Drozdov
Автор strlen совершенно точно знает, что из-за особенностей работы страниц при чтении с выравниванием по 8 можно и перечитать малясь строку
Я тут скажу, что strlen не может убать, потому что это часть std, а твой код может
источник

CD

Constantine Drozdov in pro.cxx
Побитый Кирпич
Я тут скажу, что strlen не может убать, потому что это часть std, а твой код может
hack_cxx это не твой код ;)
источник

A

Alex in pro.cxx
любой каст к указателю на несовместимый тип - УБ. TOKEN_INFO* точно не совместим с char*. Остаётся вопрос, в каких именно случаях такой каст может выстрелить, а в каких нет, но код всё равно перестаёт быть валидным С++
источник

CD

Constantine Drozdov in pro.cxx
Alex
любой каст к указателю на несовместимый тип - УБ. TOKEN_INFO* точно не совместим с char*. Остаётся вопрос, в каких именно случаях такой каст может выстрелить, а в каких нет, но код всё равно перестаёт быть валидным С++
еще раз, в GetTokenInfo стоит вызов GetTokenInfoCppEdition где выполняется placement new
источник

ПК

Побитый Кирпич... in pro.cxx
Constantine Drozdov
еще раз, в GetTokenInfo стоит вызов GetTokenInfoCppEdition где выполняется placement new
Я до сих пор не понял как это спасает от алиасинга
источник

A

Alex in pro.cxx
по-моему, никак, Константин неправ
источник

ПК

Побитый Кирпич... in pro.cxx
У нас что теперь тип в рантайме можно менять?
источник

CD

Constantine Drozdov in pro.cxx
Побитый Кирпич
Я до сих пор не понял как это спасает от алиасинга
Ну как вектор создает элемент? Аллокает буфер, размещает в нем объект T и возвращает тебе T&
источник

CD

Constantine Drozdov in pro.cxx
Побитый Кирпич
У нас что теперь тип в рантайме можно менять?
Можно, конечно, variant это делает
источник

SS

Sergey Skvortsov in pro.cxx
Alex
любой каст к указателю на несовместимый тип - УБ. TOKEN_INFO* точно не совместим с char*. Остаётся вопрос, в каких именно случаях такой каст может выстрелить, а в каких нет, но код всё равно перестаёт быть валидным С++
Там запрещен доступ через lvalue неправильного типа, а кастовать сами указатели можно
источник

A

Alex in pro.cxx
std::vector<char> buf;
DWORD size;
GetTokenInformation(nullptr, &size);
buf.resize(size);
GetTokenInformation(buf.data(), &size);
auto* info = (TOKEN_INFO*)buf.data(); // <- !!!UB!!!!
источник