Дата и время публикации :
Проблемы и пути решения
1. Проблема
Во время сборки пакета исходного кода glib-2.0 (-native) версии 2.54.3 (вероятно в версии 2.58.3) на дистрибутиве Debian/bullsey для одной из старых ветвей Yocto/poky выявлена ошибка, показанная в дампе 1.1
Дамп 1.1
... ERROR: glib-2.0-native-1_2.54.3-r0 do_compile: oe_runmake failed ... | ../../glib-2.54.3/gio/gdbusauth.c: In function ‘_g_dbus_auth_run_server’: | ../../glib-2.54.3/gio/gdbusauth.c:1305:11: error: ‘%s’ directive argument is null [-Werror=format-overflow=] | 1305 | debug_print ("SERVER: WaitingForBegin, read '%s'", line); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ... | cc1: some warnings being treated as errors | make[4]: *** [Makefile:3617: libgio_2_0_la-gdbusauth.lo] Error 1 | make[4]: *** Waiting for unfinished jobs.... | ../../glib-2.54.3/gio/gdbusmessage.c: In function ‘g_dbus_message_to_blob’: | ../../glib-2.54.3/gio/gdbusmessage.c:2700:30: error: ‘%s’ directive argument is null [-Werror=format-overflow=] | 2700 | tupled_signature_str = g_strdup_printf ("(%s)", signature_str); | | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...
Которая указывает на то, что существует возможность, например в строке 1305 файла glib-2.54.3/gio/gdbusauth.c и в строке 2700 glib-2.54.3/gio/gdbusmessage.c, передачи директиве ‘%s’ нулевого указателя, к которому существует вероятность обращения и как следствие – аварийное завершение (CWE-476), что теперь похоже считается критичным начиная с версии GGC-9, а последний по ходу используется для сборки пакетов -native, если верить дампу 1.2
Дамп 1.2
$ bitbake -e | grep "BUILD_CC=" export BUILD_CC="gcc " $ gcc -v ... gcc version 9.3.0 (Debian 9.3.0-14)
2. Решение
Производится следующим образом, перейти в рабочую директорию WORKDIR пакета glib-2.0-native и, как показано в дампе 2.1, создать директорию glib-2.54.3.changed, и последовательно в текстовом редакторе открыть файл glib-2.54.3.changed/gio/gdbusmessage.c и, затем, glib-2.54.3.changed/gio/gdbusauth.c в целях выполнения статического анализа исходного кода и устранения в нем указанных замечаний в листинге 1.1, при этом оставаясь в директории сборки вашего образа.
Дамп 2.1
$ tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/glib-2.54.3.changed $ rsync -aAXvR \ > tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/glib-2.54.3 \ > tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/glib-2.54.3.changed $ (cd tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/glib-2.54.3.changed/ && rsync -aAXv ../glib-2.54.3/* . ) $ gedit tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/glib-2.54.3.changed/gio/gdbusauth.c $ gedit tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/glib-2.54.3.changed/gio/gdbusmessage.c
В ходе статического анализа исходного кода подвергался проверки фрагмент исходного кода glib-2.54.3.changed/gio/gdbusmessage.c в листинге 2.2
Листинг 2.2. Фрагмент исходного кода glib-2.54.3.change/gio/gdbusmessage.c
2693: signature = g_dbus_message_get_header (message, G_DBUS_MESSAGE_HEADER_FIELD_SIGNATURE);
2694: signature_str = NULL;
2695: if (signature != NULL)
2696: signature_str = g_variant_get_string (signature, NULL);
2697: if (message->body != NULL)
2698: {
2699: gchar *tupled_signature_str;
2700: tupled_signature_str = g_strdup_printf ("(%s)", signature_str);
2701: if (signature == NULL)
2702: {
2703: g_set_error (error,
...
После чего, статическому анализу исходного кода подвергался проверки фрагмент исходного кода glib-2.54.3.change/gio/gdbusauth.c в листинге 2.3
Листинг 2.3. Фрагмент исходного кода glib-2.54.3.change/gio/gdbusauth .c
1301: line = _my_g_input_stream_read_line_safe (g_io_stream_get_input_stream (auth->priv->stream),
1302: &line_length,
1303: cancellable,
1304: error);
1305: debug_print ("SERVER: WaitingForBegin, read '%s'", line);
1306: if (line == NULL)
1307: goto out;
Так в обоих случаях, в строке 2700 файла glib-2.54.3.changed/gio/gdbusmessage.c и строке 1305 файла glib-2.54.3.changed/gio/gdbusauth.c, было обнаружено, что существует вероятность обращения к нулевому указателю (CWE-476) по причине отсутствие проверки возвращаемого значения на нулевой указатель (CWE-690) .
В результате, исправления выявленных ошибок в обоих вышеуказанных файлах, был изготовлен патч fix-checked-return-value-to-null-pointer-dereference.patch, текст которого приводится в листинге 2.4
Листинг 2.4
Only in glib-2.54.3: .pc diff -upr glib-2.54.3/gio/gdbusauth.c glib-2.54.3.changed/gio/gdbusauth.c --- glib-2.54.3/gio/gdbusauth.c 2018-01-08 23:00:42.000000000 +0300 +++ glib-2.54.3.changed/gio/gdbusauth.c 2020-07-12 13:19:23.861798850 +0300 @@ -1302,9 +1302,9 @@ _g_dbus_auth_run_server (GDBusAuth &line_length, cancellable, error); - debug_print ("SERVER: WaitingForBegin, read '%s'", line); if (line == NULL) goto out; + debug_print ("SERVER: WaitingForBegin, read '%s'", line); if (g_strcmp0 (line, "BEGIN") == 0) { /* YAY, done! */ diff -upr glib-2.54.3/gio/gdbusmessage.c glib-2.54.3.changed/gio/gdbusmessage.c --- glib-2.54.3/gio/gdbusmessage.c 2018-01-08 23:00:42.000000000 +0300 +++ glib-2.54.3.changed/gio/gdbusmessage.c 2020-07-12 13:24:25.434002026 +0300 @@ -2697,6 +2697,14 @@ g_dbus_message_to_blob (GDBusMessage if (message->body != NULL) { gchar *tupled_signature_str; + if (signature_str == NULL) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_INVALID_ARGUMENT, + _("Can't get a signature string form the message body") ); + goto out; + } tupled_signature_str = g_strdup_printf ("(%s)", signature_str); if (signature == NULL) { @@ -2705,7 +2713,6 @@ g_dbus_message_to_blob (GDBusMessage G_IO_ERROR_INVALID_ARGUMENT, _("Message body has signature “%s” but there is no signature header"), signature_str); - g_free (tupled_signature_str); goto out; } else if (g_strcmp0 (tupled_signature_str, g_variant_get_type_string (message->body)) != 0)
Который был изготовлен командой diff в рабочей директории WORKDIR/fix-checked-return-value-to-null-pointer-dereference.patch пакета glib-2.0, как показано в дампе 2.5
Дамп 2.5
$ ( cd tmp/work/x86_64-linux/glib-2.0-native/1_2.54.3-r0/ && \ LANG=C diff -upr glib-2.54.3 glib-2.54.3.changed > ../fix-checked-return-value-to-null-pointer-dereference.patch )
После чего, в собственном слое meta создать директорию рецепта recipes-core/glib-2.0, куда переложить в него только что созданный патч из рабочей директории WORKDIR/fix-checked-return-value-to-null-pointer-dereference.patch пакета , текст которого приводится в листинге 2.4 . Также в директорию рецепта recipes-core/glib-2.0 добавим файл glib-2.0_2.54.3.bbappend, текст которого приводится в листинге 2.6
Листинг 2.6
1: FILESEXTRAPATHS_prepend := "${THISDIR}:" 2: SRC_URI += "file://fix-checked-return-value-to-null-pointer-dereference.patch"
После чего, останется пересобрать пакет glib-2.0-native, как показано в дампе 2.7
Дамп 2.6
$ bitbake -c cleanall glib-2.0-native $ bitbake glib-2.0-native
\(\infty\)
3. Библиография
3.2 How to apply a patch generated with git format-patch?
3.3 How to know what version of cross compiler I am using on YOCTO?
3.4 [yocto] Forcing GCC version for native compilation
3.5 Build error with GCC9: error: '%s' directive argument is null when using -format-overflow #1324