Изменение всех strcpy на strscpy

Вопрос или проблема

Я изучаю разработку ядра Linux. Я клонировал стабильную ветку Linux. Я посмотрел учебное видео от Greg KH на YouTube, где объясняется, что можно использовать скрипт checkpatch.pl, чтобы обнаружить код, не соответствующий текущим стандартам. Я только новичок, и поэтому у меня нет какого-то конкретного файла для тестирования. Я решил протестировать тот, с которого все начинается: main.c в init/:

./scripts/checkpatch.pl --file --terse init/main.c

Выводом был длинный список различных ошибок в файле main.c:

homie@vmi2410184:~/git/kernels/staging$ ./scripts/checkpatch.pl --file --terse init/main.c
Traceback (most recent call last):
  File "/home/homie/git/kernels/staging/scripts/spdxcheck.py", line 6, in <module>
    from ply import lex, yacc
ModuleNotFoundError: No module named 'ply'
init/main.c:3: WARNING: It's generally not useful to have the filename in the file
init/main.c:107: WARNING: Use #include <linux/io.h> instead of <asm/io.h>
init/main.c:110: WARNING: Use #include <linux/cacheflush.h> instead of <asm/cacheflush.h>
init/main.c:203: WARNING: Missing a blank line after declarations
init/main.c:208: WARNING: Block comments use a trailing */ on a separate line
init/main.c:401: WARNING: braces {} are not necessary for single statement blocks
init/main.c:469: WARNING: void function return statements are not generally useful
init/main.c:567: WARNING: Missing a blank line after declarations
init/main.c:579: WARNING: Missing a blank line after declarations
init/main.c:659: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:660: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:662: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:663: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:675: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:677: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:681: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:683: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:1158: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:1196: WARNING: Prefer using '"%s...", __func__' to using 'initcall_blacklist', this function's name, in a string
init/main.c:1212: WARNING: Prefer [subsystem eg: netdev]_dbg([subsystem]dev, ... then dev_dbg(dev, ... then pr_debug(...  to printk(KERN_DEBUG ...
init/main.c:1222: WARNING: Prefer [subsystem eg: netdev]_dbg([subsystem]dev, ... then dev_dbg(dev, ... then pr_debug(...  to printk(KERN_DEBUG ...
init/main.c:1299: ERROR: Use of const init definition must use __initconst
init/main.c:1339: WARNING: Possible unnecessary 'out of memory' message
init/main.c:1343: WARNING: Prefer strscpy over strcpy - see: https://github.com/KSPP/linux/issues/88
init/main.c:1529: WARNING: quoted string split across lines
total: 1 errors, 24 warnings, 1603 lines checked

Это может быть глупый вопрос. Почему они не исправлены?

Одна из таковых, которую легко изменить, это заменить все strcpy на strscpy. Учтите, что strscpy принимает еще один аргумент по сравнению с strcpy.

Практика разработки ядра меняется со временем, но само ядро слишком велико, чтобы эти изменения могли быть быстро применены ко всему его коду. checkpatch.pl используется для проверки предлагаемых патчей для ядра, а не существующего кода — это гарантирует, что ядро постепенно улучшается, но как вы обнаружили, это не помогает с кодом, к которому редко обращаются.

Как видно из упомянутой в выводе проблемы, работа по миграции на strscpy активно ведется, и патчи регулярно сливаются. Патч, который изменяет это в init/main.c, вероятно, был бы приветствован; добавьте Киса Кука в качестве сопровождающего для помощи в его рецензировании, если это будет необходимо.

Вы все равно должны убедиться, что изменения корректны и оправданы. Поскольку существует заявленная цель исключить использование strcpy, замена этого имеет хорошие шансы быть принятой. Некоторые из других изменений, предлагаемых checkpatch.pl, такие как структура комментариев, пустые строки и ненужные скобки, вряд ли будут приняты, если вы не изменяете затронутые строки по другим (действительным) причинам.

.

Ответ или решение

Замена strcpy на strscpy в коде ядра Linux является актуальным вопросом, обусловленным стремлением к улучшению безопасности и надежности системы. Давайте рассмотрим теоретические аспекты этого изменения, проанализируем конкретный пример и обсудим его применение на практике.

Теоретическая часть

Почему strcpy вызывает проблемы?

Функция strcpy принадлежит к стандартной библиотеке C и используется для копирования строк. Однако она имеет критический недостаток — не проверяет размер буфера назначения. Это может привести к переполнению буфера, что, в свою очередь, открывает возможность для эксплойтов и других проблем в безопасности. В современном компьютерном программировании такие уязвимости считаются недопустимыми, особенно в таком критически важном проекте, как ядро Linux.

Что такое strscpy и какие его преимущества?

strscpy — это альтернатива strcpy, которая была разработана специально для повышения безопасности в ядре Linux. Основное отличие заключается в том, что strscpy включает в себя параметр, указывающий размер буфера назначения. Это позволяет безопасно копировать строки, избегая переполнений. Также функция возвращает длину строки, что упрощает последующую обработку без необходимости дополнительных вызовов таких функций, как strlen.

Пример

Возьмем ваш пример из файла init/main.c, где checkpatch.pl сообщает, что следует заменить strcpy на strscpy. Давайте рассмотрим, как это сделать.

Допустим, у нас имеется следующий код:

strcpy(dest, src);

Для замены данной функции на strscpy, необходимо выполнить следующие изменения:

  1. Добавить третий параметр, указывающий на размер буфера:
size_t dest_size = sizeof(dest);
strscpy(dest, src, dest_size);
  1. Протестировать, чтобы убедиться, что поведение программы остается корректным.

Применение

Когда и как стоит проводить замену?

Замену strcpy на strscpy необходимо выполнять, когда мы вносим изменения в код, например, в процессе исправления багов или добавления нового функционала, чтобы быть уверенными в поддержании безопасности и надежности. Стоит отметить, что массовые изменения strcpy в strscpy во всем коде ядра сразу не всегда практичны, поскольку могут привести к непредвиденным ошибкам. Поэтому разумно учитывать этот момент в процессе естественного рефакторинга кода.

Как это поможет сообществу ядра Linux?

Внесение таких изменений положительно скажется на безопасности всего проекта. Это позволит снизить риск уязвимостей и улучшить общую надежность кодовой базы. Поскольку ядро Linux используется в различных критически важных системах — от серверов до встроенных систем — безопасность ядра является приоритетной задачей для сообщества.

Работа с сообществом

Как упоминалось, при внесении изменений в код ядра стоит обратиться за помощью к основным мейнтейнерам или активным участникам проекта, как например, Кису Куку (Kees Cook), который может помочь с рассмотрением вашего патча. Это полезно для быстрого и корректного внедрения изменений.

Заключение

Замена strcpy на strscpy является важным шагом в развитии ядра Linux в контексте повышения его безопасности. С помощью функции strscpy мы сможем избежать уязвимостей, связанных с переполнением буфера. Важно делать такие изменения тщательно и ответственно, сотрудничать с сообществом и следовать современным стандартам разработки ПО.

Оцените материал
Добавить комментарий

Капча загружается...