× К оглавлению На главную Об авторе

Дата и время публикации :

Проблемы и пути решения

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.1 How do i patch in yocto?

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

3.6 Как создать и использовать файл-патч в собственном слое

Сайт разработан в соответствии с рекомендациями консорциума W3C для языка разметки HTML5.

Об авторе можно прочитать здесь.

Copyright © 2015-2019 Андрей Ржавсков