Comments 30
Скрытый текст
О чем статья? Что хотел сказать автор? Что существуют небезопасные функции, которые приводят к уязвимостям в коде? Или это статья от ИИ🤔?
memcpy + '\0' с проверкой размера
Люди не зря же придумали strncpy. Можно передать длину на 1 меньше - будет человекочитаемо.
Да, но у strncpy тоже свои подводные камни — она может не дописать '\0', и тогда придётся вручную проверять. Поэтому многие используют memcpy + ‘\0’ с контролем размера.
Не может, если использовать n-1. Вы все равно точно так делаете, только замороченно.
Именно. strncpy задумывалась под fixed-size поля, а не как безопасная замена strcpy. Поэтому предсказуемее и быстрее самому сделать memcpy + '\0' с контролем размера, чем ловить сюрпризы.
В вашем сценарии strncpy
имеет сложность O(1) - так как скопируется не больше 32 байт, а вот предложенный вами алгоритм - O(n), где n
- длина входных данных, так как вычисление strlen
- О(n).
Как выше уже написали, понятно как написать понятный и безопасный код с использованием strncpy
.
А ваш код получается более многословным, зато с заведомой ухудшенной асимптотикой
Чего не придумают лишь бы не вычислять n-1
подождите strlcpy обзор
Можно после strncpy безусловно класть 0 в sizeof(buf) - 1. Будет две простые строчки вместо своего алгоритма копирования, где выше риск ошибки
Сегодня я узнал, что, ура, можно не проверять буфер и RCE всё равно не будет. Как камень с души.
(Не уверен, что это то, что хотел донести до меня автор).
Не совсем 🙂 Защиты мешают сделать RCE, но переполнение всё равно = баг: краши, утечки, нестабильность. Проверять буфер надо обязательно — тем более защиты не идеальны, их иногда удаётся обходить в связке с другими ошибками.
#include <stdio.h>
#include <string.h>
void greet(const char *name) {
char buf[8];
strcpy(buf, name); // переполнение
printf("Привет, %s\n", buf);
}
int main(int argc, char **argv) {
greet(argc > 1 ? argv[1] : "user");
return 0;
}
Даже если включены ASLR, NX, canaries и прочие защиты:
1) при вводе строки длиннее 8 символов программа гарантированно упадёт (Segfault);
2) это уже отказ в обслуживании (DoS);
3) а в отчёте об ошибке или дампе памяти может утечь лишняя информация (например, кусок стека)
так правильно если я правильно понял, теперь тут надо проверку написать и написать что случилось, и получается суть сводится к тому что при том когда сигфалт перед ним надо очистить память и очистить ресурс и закрыть или написать что случилось, тоесть придётся делать проверки на переполнение и или обрабатывать или падать
Да, суть в этом: сигфолт — уже поздно что-то чистить. Нужно не допускать переполнения: проверять длину, корректно завершаться и освобождать ресурсы в ветке ошибки
Начиная с С11 появились strcpy_s и компания.
Не раскрыта тема проверки корректности адресов возврата/перехода в железе (Intel CET, ARM PAC/BTI).
Кликбейтный заголовокг а в тексте просто пшик. В чем эксплойт? Ну вылетела программа. Ну поймали стектрейсом. А как это проэксплуатировать? Да ни как. Это и близко не эксплойт.
ну ведь были обзоры тут я не видел, вы хотели чтобы вам обьяснили как это работает, я когда смотрел некоторые туториалы(вот я лично помню 1 как раз про то как делать игры в консоли, там даже обьясняется почему надо аккуратным с этим быть) всегда говорили что мол бла-бла-бла для безопасности относитесь осторожно с переполнением(вообще-то на пути всего обучения это говорят и вообще с этим столкнуться можно поидее, пробой стека, переполнение ), надо тогда CVE читать конкретно
Ну во времена более простых компиляторов это эксплуатировалось на ура: строка формируется таким образом, чтобы а) дожить до возврата из функции любой ценой б) на стэке в адрес возврата положить фиксированный адрес в программе, по которому будет лежать инструкция jmp esp. Дальше небольшой трамплин и поехали.
Василий Тёркин открыл для себя -fsanitize
. Чтож, похвально. Но я полагаю, общественности было бы интересней почитать как эти санитайзеры работаю и причем тут "канарейка".
Ну даёт жипити
#include <stdio.h>
#include <string.h>
char buf[32] = {0}; // {0} - заполнение гарантирует ноль в конце
void greet(const char *name) {
memcpy(buf, name, sizeof(buf-1));
printf("hi, %s\n", name); // пример был хорош
}
int main(int argc, char **argv) {
const char *name = (argc > 1) ? argv[1] : "world";
greet(name);
return 0;
}
5 сентября только была статья от securitylab про strncpy и переполнение буфера :)
https://www.securitylab.ru/news/563145.php
Простите за глупый вопрос. Но с учит только в информационной безопасности или компьютер инженеринг
Минимальный «эксплойт» на Си, который научил меня любить защиты