Ошибка при обновлении glibc: error: format not a string literal and no format arguments [-Werror=format-security]

В платформе rosa2021.1 была версия glibc 2.33, а в новой платформе rosa2023.1, разработку которой начали в самом конце декабря 2022 года, версия glibc 2.36. Компилятор пока что по-прежнему gcc 11. При пересборке некоторых пакетов возникла ошибка:
error: format not a string literal and no format arguments [-Werror=format-security]

Эта ошибка описана здесь. Если кратко, то падает на конструкции вида printf(string), а правильно так: printf("%s", string).

Почему же она появилась? Делаем diff файла /usr/include/stdio.h из обеих платформ и видим, что в rosa2023.1 (glibc 2.36) в нем появилось:

#if __USE_FORTIFY_LEVEL > 0 && defined __fortify_function
/* Declare all functions from bits/stdio2-decl.h first.  */
# include 
#endif

Смотрим файл /usr/include/bits/stdio2-decl.h в rosa2023.1:

#if __USE_FORTIFY_LEVEL > 1

extern int __fprintf_chk (FILE *__restrict __stream, int __flag,
			  const char *__restrict __format, ...);
extern int __printf_chk (int __flag, const char *__restrict __format, ...);
<...>

В файле /usr/include/bits/stdio2.h:

__fortify_function int
printf (const char *__restrict __fmt, ...)
{
  return __printf_chk (__USE_FORTIFY_LEVEL - 1, __fmt, __va_arg_pack ());
}

То есть в glbic закрутили гайки. Это хорошо. Возникает два вопроса:

  1. Нужно ли открутить гайку?
  2. Как ее открутить?

Конечно, лучше поправить пакеты патчами, как описано по ссылке выше, делая подобные замены:

-printf(string)
+printf("%s", string)

Но это чревато человеческими ошибками. Когда пакетов много (а их по результатам масс-билда пока что совсем немного, всего лишь 38, однако все равно это не мало), каждый нормально не протестируешь, а printf такая штука, что можно написать компилируемый, но падающий во время работы код.
Чтобы открутить гайку, достаточно в начале спека написать:
%global Werror_cflags %{nil}
Это уберет -Wformat -Werror=format-security из флагов компилятора. Поможет, если в сборочных скриптах пакета не выставляется этот или более общий и включающий этот флаг -Werror. Попробовать и отключить, и переназначить его (то есть добавить переназначающий вклад после прописанного в скриптах сборки) без правки скриптов можно так:

%global Werror_cflags %{nil}
%global optflags %{optflags} -Wno-error=format-security

В сообщении коммита указать, что это испоравление сборки с glibc 2.36, и можно вставить ссылку на эту статью, даже комментарием в спеке, чтоб при обновлении пакета было легко принять решение об удалении этого костыля.

Отправить ответ

avatar
  Subscribe  
Сообщать по почте