diff options
Diffstat (limited to 'meta/recipes-core')
29 files changed, 2292 insertions, 13 deletions
diff --git a/meta/recipes-core/busybox/busybox.inc b/meta/recipes-core/busybox/busybox.inc index bf6ddae7d1..33c84bc2c1 100644 --- a/meta/recipes-core/busybox/busybox.inc +++ b/meta/recipes-core/busybox/busybox.inc | |||
@@ -431,6 +431,32 @@ fi | |||
431 | d.prependVar('pkg_postinst_%s' % pkg, postinst) | 431 | d.prependVar('pkg_postinst_%s' % pkg, postinst) |
432 | } | 432 | } |
433 | 433 | ||
434 | pkg_postinst_${PN}_prepend () { | ||
435 | # Need path to saved utils, but they may have be removed on upgrade of busybox | ||
436 | # Only use shell to get paths. Also capture if busybox was saved. | ||
437 | BUSYBOX="" | ||
438 | if [ "x$D" = "x" ] ; then | ||
439 | for busybox_rmdir in /tmp/busyboxrm-*; do | ||
440 | if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then | ||
441 | export PATH=$busybox_rmdir:$PATH | ||
442 | if [ -e $busybox_rmdir/busybox* ] ; then | ||
443 | BUSYBOX="$busybox_rmdir/busybox*" | ||
444 | fi | ||
445 | fi | ||
446 | done | ||
447 | fi | ||
448 | } | ||
449 | |||
450 | pkg_postinst_${PN}_append () { | ||
451 | # If busybox exists in the remove directory it is because it was the only shell left. | ||
452 | if [ "x$D" = "x" ] ; then | ||
453 | if [ "x$BUSYBOX" != "x" ] ; then | ||
454 | update-alternatives --remove sh $BUSYBOX | ||
455 | rm -f $BUSYBOX | ||
456 | fi | ||
457 | fi | ||
458 | } | ||
459 | |||
434 | pkg_prerm_${PN} () { | 460 | pkg_prerm_${PN} () { |
435 | # This is so you can make busybox commit suicide - removing busybox with no other packages | 461 | # This is so you can make busybox commit suicide - removing busybox with no other packages |
436 | # providing its files, this will make update-alternatives work, but the update-rc.d part | 462 | # providing its files, this will make update-alternatives work, but the update-rc.d part |
@@ -451,9 +477,26 @@ pkg_prerm_${PN} () { | |||
451 | ln -s ${base_bindir}/busybox $tmpdir/grep | 477 | ln -s ${base_bindir}/busybox $tmpdir/grep |
452 | ln -s ${base_bindir}/busybox $tmpdir/tail | 478 | ln -s ${base_bindir}/busybox $tmpdir/tail |
453 | export PATH=$PATH:$tmpdir | 479 | export PATH=$PATH:$tmpdir |
480 | |||
481 | # If busybox is the shell, we need to save it since its the lowest priority shell | ||
482 | # Register saved bitbake as the lowest priority shell possible as back up. | ||
483 | if [ -n "$(readlink -f /bin/sh | grep busybox)" ] ; then | ||
484 | BUSYBOX=$(readlink -f /bin/sh) | ||
485 | cp $BUSYBOX $tmpdir/$(basename $BUSYBOX) | ||
486 | update-alternatives --install /bin/sh sh $tmpdir/$(basename $BUSYBOX) 1 | ||
487 | fi | ||
454 | } | 488 | } |
455 | 489 | ||
456 | pkg_postrm_${PN} () { | 490 | pkg_postrm_${PN} () { |
491 | # Add path to remove dir in case we removed our only grep | ||
492 | if [ "x$D" = "x" ] ; then | ||
493 | for busybox_rmdir in /tmp/busyboxrm-*; do | ||
494 | if [ "$busybox_rmdir" != '/tmp/busyboxrm-*' ] ; then | ||
495 | export PATH=$busybox_rmdir:$PATH | ||
496 | fi | ||
497 | done | ||
498 | fi | ||
499 | |||
457 | if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links* && [ ! -e $D${base_bindir}/bash ]; then | 500 | if grep -q "^${base_bindir}/bash$" $D${sysconfdir}/busybox.links* && [ ! -e $D${base_bindir}/bash ]; then |
458 | printf "$(grep -v "^${base_bindir}/bash$" $D${sysconfdir}/shells)\n" > $D${sysconfdir}/shells | 501 | printf "$(grep -v "^${base_bindir}/bash$" $D${sysconfdir}/shells)\n" > $D${sysconfdir}/shells |
459 | fi | 502 | fi |
diff --git a/meta/recipes-core/dbus/dbus/CVE-2020-12049.patch b/meta/recipes-core/dbus/dbus/CVE-2020-12049.patch new file mode 100644 index 0000000000..ac7a4b7a71 --- /dev/null +++ b/meta/recipes-core/dbus/dbus/CVE-2020-12049.patch | |||
@@ -0,0 +1,78 @@ | |||
1 | From 872b085f12f56da25a2dbd9bd0b2dff31d5aea63 Mon Sep 17 00:00:00 2001 | ||
2 | From: Simon McVittie <smcv@collabora.com> | ||
3 | Date: Thu, 16 Apr 2020 14:45:11 +0100 | ||
4 | Subject: [PATCH] sysdeps-unix: On MSG_CTRUNC, close the fds we did receive | ||
5 | |||
6 | MSG_CTRUNC indicates that we have received fewer fds that we should | ||
7 | have done because the buffer was too small, but we were treating it | ||
8 | as though it indicated that we received *no* fds. If we received any, | ||
9 | we still have to make sure we close them, otherwise they will be leaked. | ||
10 | |||
11 | On the system bus, if an attacker can induce us to leak fds in this | ||
12 | way, that's a local denial of service via resource exhaustion. | ||
13 | |||
14 | Reported-by: Kevin Backhouse, GitHub Security Lab | ||
15 | Fixes: dbus#294 | ||
16 | Fixes: CVE-2020-12049 | ||
17 | Fixes: GHSL-2020-057 | ||
18 | |||
19 | Upstream-Status: Backport [https://gitlab.freedesktop.org/dbus/dbus/-/commit/872b085f12f56da25a2dbd9bd0b2dff31d5aea63] | ||
20 | CVE: CVE-2020-12049 | ||
21 | Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com> | ||
22 | --- | ||
23 | dbus/dbus-sysdeps-unix.c | 32 ++++++++++++++++++++------------ | ||
24 | 1 file changed, 20 insertions(+), 12 deletions(-) | ||
25 | |||
26 | diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c | ||
27 | index b5fc2466..b176dae1 100644 | ||
28 | --- a/dbus/dbus-sysdeps-unix.c | ||
29 | +++ b/dbus/dbus-sysdeps-unix.c | ||
30 | @@ -435,18 +435,6 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd, | ||
31 | struct cmsghdr *cm; | ||
32 | dbus_bool_t found = FALSE; | ||
33 | |||
34 | - if (m.msg_flags & MSG_CTRUNC) | ||
35 | - { | ||
36 | - /* Hmm, apparently the control data was truncated. The bad | ||
37 | - thing is that we might have completely lost a couple of fds | ||
38 | - without chance to recover them. Hence let's treat this as a | ||
39 | - serious error. */ | ||
40 | - | ||
41 | - errno = ENOSPC; | ||
42 | - _dbus_string_set_length (buffer, start); | ||
43 | - return -1; | ||
44 | - } | ||
45 | - | ||
46 | for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm)) | ||
47 | if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS) | ||
48 | { | ||
49 | @@ -501,6 +489,26 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd, | ||
50 | if (!found) | ||
51 | *n_fds = 0; | ||
52 | |||
53 | + if (m.msg_flags & MSG_CTRUNC) | ||
54 | + { | ||
55 | + unsigned int i; | ||
56 | + | ||
57 | + /* Hmm, apparently the control data was truncated. The bad | ||
58 | + thing is that we might have completely lost a couple of fds | ||
59 | + without chance to recover them. Hence let's treat this as a | ||
60 | + serious error. */ | ||
61 | + | ||
62 | + /* We still need to close whatever fds we *did* receive, | ||
63 | + * otherwise they'll never get closed. (CVE-2020-12049) */ | ||
64 | + for (i = 0; i < *n_fds; i++) | ||
65 | + close (fds[i]); | ||
66 | + | ||
67 | + *n_fds = 0; | ||
68 | + errno = ENOSPC; | ||
69 | + _dbus_string_set_length (buffer, start); | ||
70 | + return -1; | ||
71 | + } | ||
72 | + | ||
73 | /* put length back (doesn't actually realloc) */ | ||
74 | _dbus_string_set_length (buffer, start + bytes_read); | ||
75 | |||
76 | -- | ||
77 | 2.25.1 | ||
78 | |||
diff --git a/meta/recipes-core/dbus/dbus_1.12.16.bb b/meta/recipes-core/dbus/dbus_1.12.16.bb index cfdbec09d0..92508cbeb8 100644 --- a/meta/recipes-core/dbus/dbus_1.12.16.bb +++ b/meta/recipes-core/dbus/dbus_1.12.16.bb | |||
@@ -16,6 +16,7 @@ SRC_URI = "https://dbus.freedesktop.org/releases/dbus/dbus-${PV}.tar.gz \ | |||
16 | file://tmpdir.patch \ | 16 | file://tmpdir.patch \ |
17 | file://dbus-1.init \ | 17 | file://dbus-1.init \ |
18 | file://clear-guid_from_server-if-send_negotiate_unix_f.patch \ | 18 | file://clear-guid_from_server-if-send_negotiate_unix_f.patch \ |
19 | file://CVE-2020-12049.patch \ | ||
19 | " | 20 | " |
20 | 21 | ||
21 | SRC_URI[md5sum] = "2dbeae80dfc9e3632320c6a53d5e8890" | 22 | SRC_URI[md5sum] = "2dbeae80dfc9e3632320c6a53d5e8890" |
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/0020-meson.build-do-not-hardcode-linux-as-the-host-system.patch b/meta/recipes-core/glib-2.0/glib-2.0/0020-meson.build-do-not-hardcode-linux-as-the-host-system.patch new file mode 100644 index 0000000000..9c311f1c90 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/0020-meson.build-do-not-hardcode-linux-as-the-host-system.patch | |||
@@ -0,0 +1,49 @@ | |||
1 | From d5e82cd0b6076f33b86e0285ef1c0dba8a14112e Mon Sep 17 00:00:00 2001 | ||
2 | From: Ahmad Fatoum <a.fatoum@pengutronix.de> | ||
3 | Date: Thu, 9 Jul 2020 13:00:16 +0200 | ||
4 | Subject: [PATCH] meson.build: do not hardcode 'linux' as the host system | ||
5 | |||
6 | OE build system can set this to other values that include 'linux', | ||
7 | e.g. 'linux-gnueabi'. This led to glib always being built without | ||
8 | libmount, mkostemp and selinux support. | ||
9 | |||
10 | Upstream-Status: Inappropriate [other] | ||
11 | Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de> | ||
12 | --- | ||
13 | meson.build | 6 +++--- | ||
14 | 1 file changed, 3 insertions(+), 3 deletions(-) | ||
15 | |||
16 | diff --git a/meson.build b/meson.build | ||
17 | index dd95c750b5ea..8bcacaf3c7e1 100644 | ||
18 | --- a/meson.build | ||
19 | +++ b/meson.build | ||
20 | @@ -604,7 +604,7 @@ else | ||
21 | endif | ||
22 | message('Checking whether to use statfs or statvfs .. ' + stat_func_to_use) | ||
23 | |||
24 | -if host_system == 'linux' | ||
25 | +if host_system.contains('linux') | ||
26 | if cc.has_function('mkostemp', | ||
27 | prefix: '''#define _GNU_SOURCE | ||
28 | #include <stdlib.h>''') | ||
29 | @@ -1810,7 +1810,7 @@ glib_conf.set_quoted('GLIB_LOCALE_DIR', join_paths(glib_datadir, 'locale')) | ||
30 | # libmount is only used by gio, but we need to fetch the libs to generate the | ||
31 | # pkg-config file below | ||
32 | libmount_dep = [] | ||
33 | -if host_system == 'linux' and get_option('libmount') | ||
34 | +if host_system.contains('linux') and get_option('libmount') | ||
35 | libmount_dep = [dependency('mount', version : '>=2.23', required : true)] | ||
36 | glib_conf.set('HAVE_LIBMOUNT', 1) | ||
37 | endif | ||
38 | @@ -1820,7 +1820,7 @@ if host_system == 'windows' | ||
39 | endif | ||
40 | |||
41 | selinux_dep = [] | ||
42 | -if host_system == 'linux' | ||
43 | +if host_system.contains('linux') | ||
44 | selinux_dep = dependency('libselinux', required: get_option('selinux')) | ||
45 | |||
46 | glib_conf.set('HAVE_SELINUX', selinux_dep.found()) | ||
47 | -- | ||
48 | 2.27.0 | ||
49 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0/CVE-2020-6750.patch b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2020-6750.patch new file mode 100644 index 0000000000..6db3934978 --- /dev/null +++ b/meta/recipes-core/glib-2.0/glib-2.0/CVE-2020-6750.patch | |||
@@ -0,0 +1,741 @@ | |||
1 | From 747f2c646f5a86ac58ad59be08036e81388e971d Mon Sep 17 00:00:00 2001 | ||
2 | From: Patrick Griffis <tingping@tingping.se> | ||
3 | Date: Thu, 23 Jan 2020 19:58:41 -0800 | ||
4 | Subject: [PATCH] Refactor g_socket_client_connect_async() | ||
5 | |||
6 | This is a fairly large refactoring. The highlights are: | ||
7 | |||
8 | - Removing in-progress connections/addresses from GSocketClientAsyncConnectData: | ||
9 | |||
10 | This caused issues where multiple ConnectionAttempt's would step over eachother | ||
11 | and modify shared state causing bugs like accidentally bypassing a set proxy. | ||
12 | |||
13 | Fixes #1871 | ||
14 | Fixes #1989 | ||
15 | Fixes #1902 | ||
16 | |||
17 | - Cancelling address enumeration on error/completion | ||
18 | |||
19 | - Queuing successful TCP connections and doing application layer work serially: | ||
20 | |||
21 | This is more in the spirit of Happy Eyeballs but it also greatly simplifies | ||
22 | the flow of connection handling so fewer tasks are happening in parallel | ||
23 | when they don't need to be. | ||
24 | |||
25 | The behavior also should more closely match that of g_socket_client_connect(). | ||
26 | |||
27 | - Better track the state of address enumeration: | ||
28 | |||
29 | Previously we were over eager to treat enumeration finishing as an error. | ||
30 | |||
31 | Fixes #1872 | ||
32 | See also #1982 | ||
33 | |||
34 | - Add more detailed documentation and logging. | ||
35 | |||
36 | Closes #1995 | ||
37 | |||
38 | CVE: CVE-2020-6750 | ||
39 | |||
40 | Upstream-Status: Backport [ https://gitlab.gnome.org/GNOME/glib.git; | ||
41 | commit=2722620e3291b930a3a228100d7c0e07b69534e3 ] | ||
42 | |||
43 | Signed-off-by: Haiqing Bai <Haiqing.Bai@windriver.com> | ||
44 | --- | ||
45 | gio/gsocketclient.c | 459 ++++++++++++++++++++++++++++---------------- | ||
46 | 1 file changed, 296 insertions(+), 163 deletions(-) | ||
47 | |||
48 | diff --git a/gio/gsocketclient.c b/gio/gsocketclient.c | ||
49 | index 81767c0..b1d5f6c 100644 | ||
50 | --- a/gio/gsocketclient.c | ||
51 | +++ b/gio/gsocketclient.c | ||
52 | @@ -1332,13 +1332,15 @@ typedef struct | ||
53 | |||
54 | GSocketConnectable *connectable; | ||
55 | GSocketAddressEnumerator *enumerator; | ||
56 | - GProxyAddress *proxy_addr; | ||
57 | - GSocket *socket; | ||
58 | - GIOStream *connection; | ||
59 | + GCancellable *enumeration_cancellable; | ||
60 | |||
61 | GSList *connection_attempts; | ||
62 | + GSList *successful_connections; | ||
63 | GError *last_error; | ||
64 | |||
65 | + gboolean enumerated_at_least_once; | ||
66 | + gboolean enumeration_completed; | ||
67 | + gboolean connection_in_progress; | ||
68 | gboolean completed; | ||
69 | } GSocketClientAsyncConnectData; | ||
70 | |||
71 | @@ -1350,10 +1352,9 @@ g_socket_client_async_connect_data_free (GSocketClientAsyncConnectData *data) | ||
72 | data->task = NULL; | ||
73 | g_clear_object (&data->connectable); | ||
74 | g_clear_object (&data->enumerator); | ||
75 | - g_clear_object (&data->proxy_addr); | ||
76 | - g_clear_object (&data->socket); | ||
77 | - g_clear_object (&data->connection); | ||
78 | + g_clear_object (&data->enumeration_cancellable); | ||
79 | g_slist_free_full (data->connection_attempts, connection_attempt_unref); | ||
80 | + g_slist_free_full (data->successful_connections, connection_attempt_unref); | ||
81 | |||
82 | g_clear_error (&data->last_error); | ||
83 | |||
84 | @@ -1365,6 +1366,7 @@ typedef struct | ||
85 | GSocketAddress *address; | ||
86 | GSocket *socket; | ||
87 | GIOStream *connection; | ||
88 | + GProxyAddress *proxy_addr; | ||
89 | GSocketClientAsyncConnectData *data; /* unowned */ | ||
90 | GSource *timeout_source; | ||
91 | GCancellable *cancellable; | ||
92 | @@ -1396,6 +1398,7 @@ connection_attempt_unref (gpointer pointer) | ||
93 | g_clear_object (&attempt->socket); | ||
94 | g_clear_object (&attempt->connection); | ||
95 | g_clear_object (&attempt->cancellable); | ||
96 | + g_clear_object (&attempt->proxy_addr); | ||
97 | if (attempt->timeout_source) | ||
98 | { | ||
99 | g_source_destroy (attempt->timeout_source); | ||
100 | @@ -1413,37 +1416,59 @@ connection_attempt_remove (ConnectionAttempt *attempt) | ||
101 | } | ||
102 | |||
103 | static void | ||
104 | -g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data) | ||
105 | +cancel_all_attempts (GSocketClientAsyncConnectData *data) | ||
106 | { | ||
107 | - g_assert (data->connection); | ||
108 | + GSList *l; | ||
109 | |||
110 | - if (!G_IS_SOCKET_CONNECTION (data->connection)) | ||
111 | + for (l = data->connection_attempts; l; l = g_slist_next (l)) | ||
112 | { | ||
113 | - GSocketConnection *wrapper_connection; | ||
114 | - | ||
115 | - wrapper_connection = g_tcp_wrapper_connection_new (data->connection, data->socket); | ||
116 | - g_object_unref (data->connection); | ||
117 | - data->connection = (GIOStream *)wrapper_connection; | ||
118 | + ConnectionAttempt *attempt_entry = l->data; | ||
119 | + g_cancellable_cancel (attempt_entry->cancellable); | ||
120 | + connection_attempt_unref (attempt_entry); | ||
121 | } | ||
122 | + g_slist_free (data->connection_attempts); | ||
123 | + data->connection_attempts = NULL; | ||
124 | |||
125 | - if (!data->completed) | ||
126 | + g_slist_free_full (data->successful_connections, connection_attempt_unref); | ||
127 | + data->successful_connections = NULL; | ||
128 | + | ||
129 | + g_cancellable_cancel (data->enumeration_cancellable); | ||
130 | +} | ||
131 | + | ||
132 | +static void | ||
133 | +g_socket_client_async_connect_complete (ConnectionAttempt *attempt) | ||
134 | +{ | ||
135 | + GSocketClientAsyncConnectData *data = attempt->data; | ||
136 | + GError *error = NULL; | ||
137 | + g_assert (attempt->connection); | ||
138 | + g_assert (!data->completed); | ||
139 | + | ||
140 | + if (!G_IS_SOCKET_CONNECTION (attempt->connection)) | ||
141 | { | ||
142 | - GError *error = NULL; | ||
143 | + GSocketConnection *wrapper_connection; | ||
144 | |||
145 | - if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error)) | ||
146 | - { | ||
147 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); | ||
148 | - g_task_return_error (data->task, g_steal_pointer (&error)); | ||
149 | - } | ||
150 | - else | ||
151 | - { | ||
152 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, data->connection); | ||
153 | - g_task_return_pointer (data->task, g_steal_pointer (&data->connection), g_object_unref); | ||
154 | - } | ||
155 | + wrapper_connection = g_tcp_wrapper_connection_new (attempt->connection, attempt->socket); | ||
156 | + g_object_unref (attempt->connection); | ||
157 | + attempt->connection = (GIOStream *)wrapper_connection; | ||
158 | + } | ||
159 | |||
160 | - data->completed = TRUE; | ||
161 | + data->completed = TRUE; | ||
162 | + cancel_all_attempts (data); | ||
163 | + | ||
164 | + if (g_cancellable_set_error_if_cancelled (g_task_get_cancellable (data->task), &error)) | ||
165 | + { | ||
166 | + g_debug ("GSocketClient: Connection cancelled!"); | ||
167 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); | ||
168 | + g_task_return_error (data->task, g_steal_pointer (&error)); | ||
169 | + } | ||
170 | + else | ||
171 | + { | ||
172 | + g_debug ("GSocketClient: Connection successful!"); | ||
173 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, attempt->connection); | ||
174 | + g_task_return_pointer (data->task, g_steal_pointer (&attempt->connection), g_object_unref); | ||
175 | } | ||
176 | |||
177 | + connection_attempt_unref (attempt); | ||
178 | g_object_unref (data->task); | ||
179 | } | ||
180 | |||
181 | @@ -1465,59 +1490,63 @@ static void | ||
182 | enumerator_next_async (GSocketClientAsyncConnectData *data, | ||
183 | gboolean add_task_ref) | ||
184 | { | ||
185 | - /* We need to cleanup the state */ | ||
186 | - g_clear_object (&data->socket); | ||
187 | - g_clear_object (&data->proxy_addr); | ||
188 | - g_clear_object (&data->connection); | ||
189 | - | ||
190 | /* Each enumeration takes a ref. This arg just avoids repeated unrefs when | ||
191 | an enumeration starts another enumeration */ | ||
192 | if (add_task_ref) | ||
193 | g_object_ref (data->task); | ||
194 | |||
195 | g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVING, data->connectable, NULL); | ||
196 | + g_debug ("GSocketClient: Starting new address enumeration"); | ||
197 | g_socket_address_enumerator_next_async (data->enumerator, | ||
198 | - g_task_get_cancellable (data->task), | ||
199 | + data->enumeration_cancellable, | ||
200 | g_socket_client_enumerator_callback, | ||
201 | data); | ||
202 | } | ||
203 | |||
204 | +static void try_next_connection_or_finish (GSocketClientAsyncConnectData *, gboolean); | ||
205 | + | ||
206 | static void | ||
207 | g_socket_client_tls_handshake_callback (GObject *object, | ||
208 | GAsyncResult *result, | ||
209 | gpointer user_data) | ||
210 | { | ||
211 | - GSocketClientAsyncConnectData *data = user_data; | ||
212 | + ConnectionAttempt *attempt = user_data; | ||
213 | + GSocketClientAsyncConnectData *data = attempt->data; | ||
214 | |||
215 | if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (object), | ||
216 | result, | ||
217 | &data->last_error)) | ||
218 | { | ||
219 | - g_object_unref (data->connection); | ||
220 | - data->connection = G_IO_STREAM (object); | ||
221 | + g_object_unref (attempt->connection); | ||
222 | + attempt->connection = G_IO_STREAM (object); | ||
223 | |||
224 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, data->connection); | ||
225 | - g_socket_client_async_connect_complete (data); | ||
226 | + g_debug ("GSocketClient: TLS handshake succeeded"); | ||
227 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_TLS_HANDSHAKED, data->connectable, attempt->connection); | ||
228 | + g_socket_client_async_connect_complete (attempt); | ||
229 | } | ||
230 | else | ||
231 | { | ||
232 | g_object_unref (object); | ||
233 | - enumerator_next_async (data, FALSE); | ||
234 | + connection_attempt_unref (attempt); | ||
235 | + g_debug ("GSocketClient: TLS handshake failed: %s", data->last_error->message); | ||
236 | + try_next_connection_or_finish (data, TRUE); | ||
237 | } | ||
238 | } | ||
239 | |||
240 | static void | ||
241 | -g_socket_client_tls_handshake (GSocketClientAsyncConnectData *data) | ||
242 | +g_socket_client_tls_handshake (ConnectionAttempt *attempt) | ||
243 | { | ||
244 | + GSocketClientAsyncConnectData *data = attempt->data; | ||
245 | GIOStream *tlsconn; | ||
246 | |||
247 | if (!data->client->priv->tls) | ||
248 | { | ||
249 | - g_socket_client_async_connect_complete (data); | ||
250 | + g_socket_client_async_connect_complete (attempt); | ||
251 | return; | ||
252 | } | ||
253 | |||
254 | - tlsconn = g_tls_client_connection_new (data->connection, | ||
255 | + g_debug ("GSocketClient: Starting TLS handshake"); | ||
256 | + tlsconn = g_tls_client_connection_new (attempt->connection, | ||
257 | data->connectable, | ||
258 | &data->last_error); | ||
259 | if (tlsconn) | ||
260 | @@ -1529,11 +1558,12 @@ g_socket_client_tls_handshake (GSocketClientAsyncConnectData *data) | ||
261 | G_PRIORITY_DEFAULT, | ||
262 | g_task_get_cancellable (data->task), | ||
263 | g_socket_client_tls_handshake_callback, | ||
264 | - data); | ||
265 | + attempt); | ||
266 | } | ||
267 | else | ||
268 | { | ||
269 | - enumerator_next_async (data, FALSE); | ||
270 | + connection_attempt_unref (attempt); | ||
271 | + try_next_connection_or_finish (data, TRUE); | ||
272 | } | ||
273 | } | ||
274 | |||
275 | @@ -1542,23 +1572,38 @@ g_socket_client_proxy_connect_callback (GObject *object, | ||
276 | GAsyncResult *result, | ||
277 | gpointer user_data) | ||
278 | { | ||
279 | - GSocketClientAsyncConnectData *data = user_data; | ||
280 | + ConnectionAttempt *attempt = user_data; | ||
281 | + GSocketClientAsyncConnectData *data = attempt->data; | ||
282 | |||
283 | - g_object_unref (data->connection); | ||
284 | - data->connection = g_proxy_connect_finish (G_PROXY (object), | ||
285 | - result, | ||
286 | - &data->last_error); | ||
287 | - if (data->connection) | ||
288 | + g_object_unref (attempt->connection); | ||
289 | + attempt->connection = g_proxy_connect_finish (G_PROXY (object), | ||
290 | + result, | ||
291 | + &data->last_error); | ||
292 | + if (attempt->connection) | ||
293 | { | ||
294 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, data->connection); | ||
295 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATED, data->connectable, attempt->connection); | ||
296 | } | ||
297 | else | ||
298 | { | ||
299 | - enumerator_next_async (data, FALSE); | ||
300 | + connection_attempt_unref (attempt); | ||
301 | + try_next_connection_or_finish (data, TRUE); | ||
302 | return; | ||
303 | } | ||
304 | |||
305 | - g_socket_client_tls_handshake (data); | ||
306 | + g_socket_client_tls_handshake (attempt); | ||
307 | +} | ||
308 | + | ||
309 | +static void | ||
310 | +complete_connection_with_error (GSocketClientAsyncConnectData *data, | ||
311 | + GError *error) | ||
312 | +{ | ||
313 | + g_debug ("GSocketClient: Connection failed: %s", error->message); | ||
314 | + g_assert (!data->completed); | ||
315 | + | ||
316 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); | ||
317 | + data->completed = TRUE; | ||
318 | + cancel_all_attempts (data); | ||
319 | + g_task_return_error (data->task, error); | ||
320 | } | ||
321 | |||
322 | static gboolean | ||
323 | @@ -1572,15 +1617,114 @@ task_completed_or_cancelled (GSocketClientAsyncConnectData *data) | ||
324 | return TRUE; | ||
325 | else if (g_cancellable_set_error_if_cancelled (cancellable, &error)) | ||
326 | { | ||
327 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); | ||
328 | - g_task_return_error (task, g_steal_pointer (&error)); | ||
329 | - data->completed = TRUE; | ||
330 | + complete_connection_with_error (data, g_steal_pointer (&error)); | ||
331 | return TRUE; | ||
332 | } | ||
333 | else | ||
334 | return FALSE; | ||
335 | } | ||
336 | |||
337 | +static gboolean | ||
338 | +try_next_successful_connection (GSocketClientAsyncConnectData *data) | ||
339 | +{ | ||
340 | + ConnectionAttempt *attempt; | ||
341 | + const gchar *protocol; | ||
342 | + GProxy *proxy; | ||
343 | + | ||
344 | + if (data->connection_in_progress) | ||
345 | + return FALSE; | ||
346 | + | ||
347 | + g_assert (data->successful_connections != NULL); | ||
348 | + attempt = data->successful_connections->data; | ||
349 | + g_assert (attempt != NULL); | ||
350 | + data->successful_connections = g_slist_remove (data->successful_connections, attempt); | ||
351 | + data->connection_in_progress = TRUE; | ||
352 | + | ||
353 | + g_debug ("GSocketClient: Starting application layer connection"); | ||
354 | + | ||
355 | + if (!attempt->proxy_addr) | ||
356 | + { | ||
357 | + g_socket_client_tls_handshake (g_steal_pointer (&attempt)); | ||
358 | + return TRUE; | ||
359 | + } | ||
360 | + | ||
361 | + protocol = g_proxy_address_get_protocol (attempt->proxy_addr); | ||
362 | + | ||
363 | + /* The connection should not be anything other than TCP, | ||
364 | + * but let's put a safety guard in case | ||
365 | + */ | ||
366 | + if (!G_IS_TCP_CONNECTION (attempt->connection)) | ||
367 | + { | ||
368 | + g_critical ("Trying to proxy over non-TCP connection, this is " | ||
369 | + "most likely a bug in GLib IO library."); | ||
370 | + | ||
371 | + g_set_error_literal (&data->last_error, | ||
372 | + G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, | ||
373 | + _("Proxying over a non-TCP connection is not supported.")); | ||
374 | + } | ||
375 | + else if (g_hash_table_contains (data->client->priv->app_proxies, protocol)) | ||
376 | + { | ||
377 | + /* Simply complete the connection, we don't want to do TLS handshake | ||
378 | + * as the application proxy handling may need proxy handshake first */ | ||
379 | + g_socket_client_async_connect_complete (g_steal_pointer (&attempt)); | ||
380 | + return TRUE; | ||
381 | + } | ||
382 | + else if ((proxy = g_proxy_get_default_for_protocol (protocol))) | ||
383 | + { | ||
384 | + GIOStream *connection = attempt->connection; | ||
385 | + GProxyAddress *proxy_addr = attempt->proxy_addr; | ||
386 | + | ||
387 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, attempt->connection); | ||
388 | + g_debug ("GSocketClient: Starting proxy connection"); | ||
389 | + g_proxy_connect_async (proxy, | ||
390 | + connection, | ||
391 | + proxy_addr, | ||
392 | + g_task_get_cancellable (data->task), | ||
393 | + g_socket_client_proxy_connect_callback, | ||
394 | + g_steal_pointer (&attempt)); | ||
395 | + g_object_unref (proxy); | ||
396 | + return TRUE; | ||
397 | + } | ||
398 | + else | ||
399 | + { | ||
400 | + g_clear_error (&data->last_error); | ||
401 | + | ||
402 | + g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, | ||
403 | + _("Proxy protocol “%s” is not supported."), | ||
404 | + protocol); | ||
405 | + } | ||
406 | + | ||
407 | + data->connection_in_progress = FALSE; | ||
408 | + g_clear_pointer (&attempt, connection_attempt_unref); | ||
409 | + return FALSE; /* All non-return paths are failures */ | ||
410 | +} | ||
411 | + | ||
412 | +static void | ||
413 | +try_next_connection_or_finish (GSocketClientAsyncConnectData *data, | ||
414 | + gboolean end_current_connection) | ||
415 | +{ | ||
416 | + if (end_current_connection) | ||
417 | + data->connection_in_progress = FALSE; | ||
418 | + | ||
419 | + if (data->connection_in_progress) | ||
420 | + return; | ||
421 | + | ||
422 | + /* Keep trying successful connections until one works, each iteration pops one */ | ||
423 | + while (data->successful_connections) | ||
424 | + { | ||
425 | + if (try_next_successful_connection (data)) | ||
426 | + return; | ||
427 | + } | ||
428 | + | ||
429 | + if (!data->enumeration_completed) | ||
430 | + { | ||
431 | + enumerator_next_async (data, FALSE); | ||
432 | + return; | ||
433 | + } | ||
434 | + | ||
435 | + complete_connection_with_error (data, data->last_error); | ||
436 | +} | ||
437 | + | ||
438 | static void | ||
439 | g_socket_client_connected_callback (GObject *source, | ||
440 | GAsyncResult *result, | ||
441 | @@ -1588,10 +1732,7 @@ g_socket_client_connected_callback (GObject *source, | ||
442 | { | ||
443 | ConnectionAttempt *attempt = user_data; | ||
444 | GSocketClientAsyncConnectData *data = attempt->data; | ||
445 | - GSList *l; | ||
446 | GError *error = NULL; | ||
447 | - GProxy *proxy; | ||
448 | - const gchar *protocol; | ||
449 | |||
450 | if (task_completed_or_cancelled (data) || g_cancellable_is_cancelled (attempt->cancellable)) | ||
451 | { | ||
452 | @@ -1613,11 +1754,12 @@ g_socket_client_connected_callback (GObject *source, | ||
453 | { | ||
454 | clarify_connect_error (error, data->connectable, attempt->address); | ||
455 | set_last_error (data, error); | ||
456 | + g_debug ("GSocketClient: Connection attempt failed: %s", error->message); | ||
457 | connection_attempt_remove (attempt); | ||
458 | - enumerator_next_async (data, FALSE); | ||
459 | connection_attempt_unref (attempt); | ||
460 | + try_next_connection_or_finish (data, FALSE); | ||
461 | } | ||
462 | - else | ||
463 | + else /* Silently ignore cancelled attempts */ | ||
464 | { | ||
465 | g_clear_error (&error); | ||
466 | g_object_unref (data->task); | ||
467 | @@ -1627,74 +1769,21 @@ g_socket_client_connected_callback (GObject *source, | ||
468 | return; | ||
469 | } | ||
470 | |||
471 | - data->socket = g_steal_pointer (&attempt->socket); | ||
472 | - data->connection = g_steal_pointer (&attempt->connection); | ||
473 | - | ||
474 | - for (l = data->connection_attempts; l; l = g_slist_next (l)) | ||
475 | - { | ||
476 | - ConnectionAttempt *attempt_entry = l->data; | ||
477 | - g_cancellable_cancel (attempt_entry->cancellable); | ||
478 | - connection_attempt_unref (attempt_entry); | ||
479 | - } | ||
480 | - g_slist_free (data->connection_attempts); | ||
481 | - data->connection_attempts = NULL; | ||
482 | - connection_attempt_unref (attempt); | ||
483 | - | ||
484 | - g_socket_connection_set_cached_remote_address ((GSocketConnection*)data->connection, NULL); | ||
485 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, data->connection); | ||
486 | + g_socket_connection_set_cached_remote_address ((GSocketConnection*)attempt->connection, NULL); | ||
487 | + g_debug ("GSocketClient: TCP connection successful"); | ||
488 | + g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTED, data->connectable, attempt->connection); | ||
489 | |||
490 | /* wrong, but backward compatible */ | ||
491 | - g_socket_set_blocking (data->socket, TRUE); | ||
492 | + g_socket_set_blocking (attempt->socket, TRUE); | ||
493 | |||
494 | - if (!data->proxy_addr) | ||
495 | - { | ||
496 | - g_socket_client_tls_handshake (data); | ||
497 | - return; | ||
498 | - } | ||
499 | - | ||
500 | - protocol = g_proxy_address_get_protocol (data->proxy_addr); | ||
501 | - | ||
502 | - /* The connection should not be anything other than TCP, | ||
503 | - * but let's put a safety guard in case | ||
504 | + /* This ends the parallel "happy eyeballs" portion of connecting. | ||
505 | + Now that we have a successful tcp connection we will attempt to connect | ||
506 | + at the TLS/Proxy layer. If those layers fail we will move on to the next | ||
507 | + connection. | ||
508 | */ | ||
509 | - if (!G_IS_TCP_CONNECTION (data->connection)) | ||
510 | - { | ||
511 | - g_critical ("Trying to proxy over non-TCP connection, this is " | ||
512 | - "most likely a bug in GLib IO library."); | ||
513 | - | ||
514 | - g_set_error_literal (&data->last_error, | ||
515 | - G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, | ||
516 | - _("Proxying over a non-TCP connection is not supported.")); | ||
517 | - | ||
518 | - enumerator_next_async (data, FALSE); | ||
519 | - } | ||
520 | - else if (g_hash_table_contains (data->client->priv->app_proxies, protocol)) | ||
521 | - { | ||
522 | - /* Simply complete the connection, we don't want to do TLS handshake | ||
523 | - * as the application proxy handling may need proxy handshake first */ | ||
524 | - g_socket_client_async_connect_complete (data); | ||
525 | - } | ||
526 | - else if ((proxy = g_proxy_get_default_for_protocol (protocol))) | ||
527 | - { | ||
528 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_PROXY_NEGOTIATING, data->connectable, data->connection); | ||
529 | - g_proxy_connect_async (proxy, | ||
530 | - data->connection, | ||
531 | - data->proxy_addr, | ||
532 | - g_task_get_cancellable (data->task), | ||
533 | - g_socket_client_proxy_connect_callback, | ||
534 | - data); | ||
535 | - g_object_unref (proxy); | ||
536 | - } | ||
537 | - else | ||
538 | - { | ||
539 | - g_clear_error (&data->last_error); | ||
540 | - | ||
541 | - g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, | ||
542 | - _("Proxy protocol “%s” is not supported."), | ||
543 | - protocol); | ||
544 | - | ||
545 | - enumerator_next_async (data, FALSE); | ||
546 | - } | ||
547 | + connection_attempt_remove (attempt); | ||
548 | + data->successful_connections = g_slist_append (data->successful_connections, g_steal_pointer (&attempt)); | ||
549 | + try_next_connection_or_finish (data, FALSE); | ||
550 | } | ||
551 | |||
552 | static gboolean | ||
553 | @@ -1702,7 +1791,11 @@ on_connection_attempt_timeout (gpointer data) | ||
554 | { | ||
555 | ConnectionAttempt *attempt = data; | ||
556 | |||
557 | - enumerator_next_async (attempt->data, TRUE); | ||
558 | + if (!attempt->data->enumeration_completed) | ||
559 | + { | ||
560 | + g_debug ("GSocketClient: Timeout reached, trying another enumeration"); | ||
561 | + enumerator_next_async (attempt->data, TRUE); | ||
562 | + } | ||
563 | |||
564 | g_clear_pointer (&attempt->timeout_source, g_source_unref); | ||
565 | return G_SOURCE_REMOVE; | ||
566 | @@ -1712,9 +1805,9 @@ static void | ||
567 | on_connection_cancelled (GCancellable *cancellable, | ||
568 | gpointer data) | ||
569 | { | ||
570 | - GCancellable *attempt_cancellable = data; | ||
571 | + GCancellable *linked_cancellable = G_CANCELLABLE (data); | ||
572 | |||
573 | - g_cancellable_cancel (attempt_cancellable); | ||
574 | + g_cancellable_cancel (linked_cancellable); | ||
575 | } | ||
576 | |||
577 | static void | ||
578 | @@ -1738,39 +1831,49 @@ g_socket_client_enumerator_callback (GObject *object, | ||
579 | result, &error); | ||
580 | if (address == NULL) | ||
581 | { | ||
582 | - if (data->connection_attempts) | ||
583 | + if (G_UNLIKELY (data->enumeration_completed)) | ||
584 | + return; | ||
585 | + | ||
586 | + data->enumeration_completed = TRUE; | ||
587 | + g_debug ("GSocketClient: Address enumeration completed (out of addresses)"); | ||
588 | + | ||
589 | + /* As per API docs: We only care about error if its the first call, | ||
590 | + after that the enumerator is done. | ||
591 | + | ||
592 | + Note that we don't care about cancellation errors because | ||
593 | + task_completed_or_cancelled() above should handle that. | ||
594 | + | ||
595 | + If this fails and nothing is in progress then we will complete task here. | ||
596 | + */ | ||
597 | + if ((data->enumerated_at_least_once && !data->connection_attempts && !data->connection_in_progress) || | ||
598 | + !data->enumerated_at_least_once) | ||
599 | { | ||
600 | - g_object_unref (data->task); | ||
601 | - return; | ||
602 | + g_debug ("GSocketClient: Address enumeration failed: %s", error ? error->message : NULL); | ||
603 | + if (data->last_error) | ||
604 | + { | ||
605 | + g_clear_error (&error); | ||
606 | + error = data->last_error; | ||
607 | + data->last_error = NULL; | ||
608 | + } | ||
609 | + else if (!error) | ||
610 | + { | ||
611 | + g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, | ||
612 | + _("Unknown error on connect")); | ||
613 | + } | ||
614 | + | ||
615 | + complete_connection_with_error (data, error); | ||
616 | } | ||
617 | |||
618 | - g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_COMPLETE, data->connectable, NULL); | ||
619 | - data->completed = TRUE; | ||
620 | - if (!error) | ||
621 | - { | ||
622 | - if (data->last_error) | ||
623 | - { | ||
624 | - error = data->last_error; | ||
625 | - data->last_error = NULL; | ||
626 | - } | ||
627 | - else | ||
628 | - { | ||
629 | - g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED, | ||
630 | - _("Unknown error on connect")); | ||
631 | - } | ||
632 | - } | ||
633 | - g_task_return_error (data->task, error); | ||
634 | + /* Enumeration should never trigger again, drop our ref */ | ||
635 | g_object_unref (data->task); | ||
636 | return; | ||
637 | } | ||
638 | |||
639 | + data->enumerated_at_least_once = TRUE; | ||
640 | + g_debug ("GSocketClient: Address enumeration succeeded"); | ||
641 | g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_RESOLVED, | ||
642 | data->connectable, NULL); | ||
643 | |||
644 | - if (G_IS_PROXY_ADDRESS (address) && | ||
645 | - data->client->priv->enable_proxy) | ||
646 | - data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address)); | ||
647 | - | ||
648 | g_clear_error (&data->last_error); | ||
649 | |||
650 | socket = create_socket (data->client, address, &data->last_error); | ||
651 | @@ -1788,6 +1891,10 @@ g_socket_client_enumerator_callback (GObject *object, | ||
652 | attempt->cancellable = g_cancellable_new (); | ||
653 | attempt->connection = (GIOStream *)g_socket_connection_factory_create_connection (socket); | ||
654 | attempt->timeout_source = g_timeout_source_new (HAPPY_EYEBALLS_CONNECTION_ATTEMPT_TIMEOUT_MS); | ||
655 | + | ||
656 | + if (G_IS_PROXY_ADDRESS (address) && data->client->priv->enable_proxy) | ||
657 | + attempt->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address)); | ||
658 | + | ||
659 | g_source_set_callback (attempt->timeout_source, on_connection_attempt_timeout, attempt, NULL); | ||
660 | g_source_attach (attempt->timeout_source, g_main_context_get_thread_default ()); | ||
661 | data->connection_attempts = g_slist_append (data->connection_attempts, attempt); | ||
662 | @@ -1797,6 +1904,7 @@ g_socket_client_enumerator_callback (GObject *object, | ||
663 | g_object_ref (attempt->cancellable), g_object_unref); | ||
664 | |||
665 | g_socket_connection_set_cached_remote_address ((GSocketConnection *)attempt->connection, address); | ||
666 | + g_debug ("GSocketClient: Starting TCP connection attempt"); | ||
667 | g_socket_client_emit_event (data->client, G_SOCKET_CLIENT_CONNECTING, data->connectable, attempt->connection); | ||
668 | g_socket_connection_connect_async (G_SOCKET_CONNECTION (attempt->connection), | ||
669 | address, | ||
670 | @@ -1849,24 +1957,48 @@ g_socket_client_connect_async (GSocketClient *client, | ||
671 | else | ||
672 | data->enumerator = g_socket_connectable_enumerate (connectable); | ||
673 | |||
674 | - /* The flow and ownership here isn't quite obvious: | ||
675 | - - The task starts an async attempt to connect. | ||
676 | - - Each attempt holds a single ref on task. | ||
677 | - - Each attempt may create new attempts by timing out (not a failure) so | ||
678 | - there are multiple attempts happening in parallel. | ||
679 | - - Upon failure an attempt will start a new attempt that steals its ref | ||
680 | - until there are no more attempts left and it drops its ref. | ||
681 | - - Upon success it will cancel all other attempts and continue on | ||
682 | - to the rest of the connection (tls, proxies, etc) which do not | ||
683 | - happen in parallel and at the very end drop its ref. | ||
684 | - - Upon cancellation an attempt drops its ref. | ||
685 | - */ | ||
686 | + /* This function tries to match the behavior of g_socket_client_connect () | ||
687 | + which is simple enough but much of it is done in parallel to be as responsive | ||
688 | + as possible as per Happy Eyeballs (RFC 8305). This complicates flow quite a | ||
689 | + bit but we can describe it in 3 sections: | ||
690 | + | ||
691 | + Firstly we have address enumeration (DNS): | ||
692 | + - This may be triggered multiple times by enumerator_next_async(). | ||
693 | + - It also has its own cancellable (data->enumeration_cancellable). | ||
694 | + - Enumeration is done lazily because GNetworkAddressAddressEnumerator | ||
695 | + also does work in parallel and may lazily add new addresses. | ||
696 | + - If the first enumeration errors then the task errors. Otherwise all enumerations | ||
697 | + will potentially be used (until task or enumeration is cancelled). | ||
698 | + | ||
699 | + Then we start attempting connections (TCP): | ||
700 | + - Each connection is independent and kept in a ConnectionAttempt object. | ||
701 | + - They each hold a ref on the main task and have their own cancellable. | ||
702 | + - Multiple attempts may happen in parallel as per Happy Eyeballs. | ||
703 | + - Upon failure or timeouts more connection attempts are made. | ||
704 | + - If no connections succeed the task errors. | ||
705 | + - Upon success they are kept in a list of successful connections. | ||
706 | + | ||
707 | + Lastly we connect at the application layer (TLS, Proxies): | ||
708 | + - These are done in serial. | ||
709 | + - The reasoning here is that Happy Eyeballs is about making bad connections responsive | ||
710 | + at the IP/TCP layers. Issues at the application layer are generally not due to | ||
711 | + connectivity issues but rather misconfiguration. | ||
712 | + - Upon failure it will try the next TCP connection until it runs out and | ||
713 | + the task errors. | ||
714 | + - Upon success it cancels everything remaining (enumeration and connections) | ||
715 | + and returns the connection. | ||
716 | + */ | ||
717 | |||
718 | data->task = g_task_new (client, cancellable, callback, user_data); | ||
719 | g_task_set_check_cancellable (data->task, FALSE); /* We handle this manually */ | ||
720 | g_task_set_source_tag (data->task, g_socket_client_connect_async); | ||
721 | g_task_set_task_data (data->task, data, (GDestroyNotify)g_socket_client_async_connect_data_free); | ||
722 | |||
723 | + data->enumeration_cancellable = g_cancellable_new (); | ||
724 | + if (cancellable) | ||
725 | + g_cancellable_connect (cancellable, G_CALLBACK (on_connection_cancelled), | ||
726 | + g_object_ref (data->enumeration_cancellable), g_object_unref); | ||
727 | + | ||
728 | enumerator_next_async (data, FALSE); | ||
729 | } | ||
730 | |||
731 | @@ -1985,6 +2117,7 @@ g_socket_client_connect_to_uri_async (GSocketClient *client, | ||
732 | } | ||
733 | else | ||
734 | { | ||
735 | + g_debug("g_socket_client_connect_to_uri_async"); | ||
736 | g_socket_client_connect_async (client, | ||
737 | connectable, cancellable, | ||
738 | callback, user_data); | ||
739 | -- | ||
740 | 2.23.0 | ||
741 | |||
diff --git a/meta/recipes-core/glib-2.0/glib-2.0_2.60.7.bb b/meta/recipes-core/glib-2.0/glib-2.0_2.60.7.bb index 5aefa6ad8b..af8ded76d5 100644 --- a/meta/recipes-core/glib-2.0/glib-2.0_2.60.7.bb +++ b/meta/recipes-core/glib-2.0/glib-2.0_2.60.7.bb | |||
@@ -16,6 +16,8 @@ SRC_URI = "${GNOME_MIRROR}/glib/${SHRT_VER}/glib-${PV}.tar.xz \ | |||
16 | file://0001-Do-not-write-bindir-into-pkg-config-files.patch \ | 16 | file://0001-Do-not-write-bindir-into-pkg-config-files.patch \ |
17 | file://0001-meson.build-do-not-hardcode-linux-as-the-host-system.patch \ | 17 | file://0001-meson.build-do-not-hardcode-linux-as-the-host-system.patch \ |
18 | file://0001-meson-do-a-build-time-check-for-strlcpy-before-attem.patch \ | 18 | file://0001-meson-do-a-build-time-check-for-strlcpy-before-attem.patch \ |
19 | file://CVE-2020-6750.patch \ | ||
20 | file://0020-meson.build-do-not-hardcode-linux-as-the-host-system.patch \ | ||
19 | " | 21 | " |
20 | 22 | ||
21 | SRC_URI_append_class-native = " file://relocate-modules.patch" | 23 | SRC_URI_append_class-native = " file://relocate-modules.patch" |
diff --git a/meta/recipes-core/glibc/glibc-testsuite_2.30.bb b/meta/recipes-core/glibc/glibc-testsuite_2.30.bb index 657fd4dbc1..d887aeff79 100644 --- a/meta/recipes-core/glibc/glibc-testsuite_2.30.bb +++ b/meta/recipes-core/glibc/glibc-testsuite_2.30.bb | |||
@@ -1,5 +1,7 @@ | |||
1 | require glibc_${PV}.bb | 1 | require glibc_${PV}.bb |
2 | 2 | ||
3 | EXCLUDE_FROM_WORLD = "1" | ||
4 | |||
3 | # handle PN differences | 5 | # handle PN differences |
4 | FILESEXTRAPATHS_prepend := "${THISDIR}/glibc:" | 6 | FILESEXTRAPATHS_prepend := "${THISDIR}/glibc:" |
5 | 7 | ||
@@ -58,3 +60,4 @@ addtask do_check after do_compile | |||
58 | 60 | ||
59 | inherit nopackages | 61 | inherit nopackages |
60 | deltask do_stash_locale | 62 | deltask do_stash_locale |
63 | deltask do_install | ||
diff --git a/meta/recipes-core/glibc/glibc/0005-nativesdk-glibc-Make-relocatable-install-for-locales.patch b/meta/recipes-core/glibc/glibc/0005-nativesdk-glibc-Make-relocatable-install-for-locales.patch index 3aad603ada..5cd235f6ac 100644 --- a/meta/recipes-core/glibc/glibc/0005-nativesdk-glibc-Make-relocatable-install-for-locales.patch +++ b/meta/recipes-core/glibc/glibc/0005-nativesdk-glibc-Make-relocatable-install-for-locales.patch | |||
@@ -65,6 +65,35 @@ index 7c1cc3eecb..53cb8bfc59 100644 | |||
65 | 65 | ||
66 | /* Load the locale data for CATEGORY from the file specified by *NAME. | 66 | /* Load the locale data for CATEGORY from the file specified by *NAME. |
67 | If *NAME is "", use environment variables as specified by POSIX, and | 67 | If *NAME is "", use environment variables as specified by POSIX, and |
68 | -- | 68 | Index: git/locale/programs/locale.c |
69 | 2.22.0 | 69 | =================================================================== |
70 | 70 | --- git.orig/locale/programs/locale.c | |
71 | +++ git/locale/programs/locale.c | ||
72 | @@ -632,6 +632,7 @@ nameentcmp (const void *a, const void *b | ||
73 | ((const struct nameent *) b)->name); | ||
74 | } | ||
75 | |||
76 | +static char _write_archive_locales_path[4096] attribute_hidden __attribute__ ((section (".gccrelocprefix"))) = ARCHIVE_NAME; | ||
77 | |||
78 | static int | ||
79 | write_archive_locales (void **all_datap, char *linebuf) | ||
80 | @@ -645,7 +646,7 @@ write_archive_locales (void **all_datap, | ||
81 | int fd, ret = 0; | ||
82 | uint32_t cnt; | ||
83 | |||
84 | - fd = open64 (ARCHIVE_NAME, O_RDONLY); | ||
85 | + fd = open64 (_write_archive_locales_path, O_RDONLY); | ||
86 | if (fd < 0) | ||
87 | return 0; | ||
88 | |||
89 | @@ -700,8 +701,8 @@ write_archive_locales (void **all_datap, | ||
90 | if (cnt) | ||
91 | putchar_unlocked ('\n'); | ||
92 | |||
93 | - printf ("locale: %-15.15s archive: " ARCHIVE_NAME "\n%s\n", | ||
94 | - names[cnt].name, linebuf); | ||
95 | + printf ("locale: %-15.15s archive: %s\n%s\n", | ||
96 | + names[cnt].name, _write_archive_locales_path, linebuf); | ||
97 | |||
98 | locrec = (struct locrecent *) (addr + names[cnt].locrec_offset); | ||
99 | |||
diff --git a/meta/recipes-core/glibc/glibc/CVE-2020-10029.patch b/meta/recipes-core/glibc/glibc/CVE-2020-10029.patch new file mode 100644 index 0000000000..606b691bcf --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2020-10029.patch | |||
@@ -0,0 +1,128 @@ | |||
1 | From ce265ec5bc25ec35fba53807abac1b0c8469895e Mon Sep 17 00:00:00 2001 | ||
2 | From: Joseph Myers <joseph@codesourcery.com> | ||
3 | Date: Wed, 12 Feb 2020 23:31:56 +0000 | ||
4 | Subject: [PATCH] Avoid ldbl-96 stack corruption from range reduction of | ||
5 | |||
6 | pseudo-zero (bug 25487). | ||
7 | |||
8 | Bug 25487 reports stack corruption in ldbl-96 sinl on a pseudo-zero | ||
9 | argument (an representation where all the significand bits, including | ||
10 | the explicit high bit, are zero, but the exponent is not zero, which | ||
11 | is not a valid representation for the long double type). | ||
12 | |||
13 | Although this is not a valid long double representation, existing | ||
14 | practice in this area (see bug 4586, originally marked invalid but | ||
15 | subsequently fixed) is that we still seek to avoid invalid memory | ||
16 | accesses as a result, in case of programs that treat arbitrary binary | ||
17 | data as long double representations, although the invalid | ||
18 | representations of the ldbl-96 format do not need to be consistently | ||
19 | handled the same as any particular valid representation. | ||
20 | |||
21 | This patch makes the range reduction detect pseudo-zero and unnormal | ||
22 | representations that would otherwise go to __kernel_rem_pio2, and | ||
23 | returns a NaN for them instead of continuing with the range reduction | ||
24 | process. (Pseudo-zero and unnormal representations whose unbiased | ||
25 | exponent is less than -1 have already been safely returned from the | ||
26 | function before this point without going through the rest of range | ||
27 | reduction.) Pseudo-zero representations would previously result in | ||
28 | the value passed to __kernel_rem_pio2 being all-zero, which is | ||
29 | definitely unsafe; unnormal representations would previously result in | ||
30 | a value passed whose high bit is zero, which might well be unsafe | ||
31 | since that is not a form of input expected by __kernel_rem_pio2. | ||
32 | |||
33 | Tested for x86_64. | ||
34 | |||
35 | CVE: CVE-2020-10029 | ||
36 | Upstream-Status: Backport [https://sourceware.org/git/gitweb.cgi?p=glibc.git; | ||
37 | a=patch;h=9333498794cde1d5cca518badf79533a24114b6f] | ||
38 | Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> | ||
39 | |||
40 | --- | ||
41 | sysdeps/ieee754/ldbl-96/Makefile | 3 ++- | ||
42 | sysdeps/ieee754/ldbl-96/e_rem_pio2l.c | 12 +++++++++ | ||
43 | sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c | 41 ++++++++++++++++++++++++++++++ | ||
44 | 3 files changed, 55 insertions(+), 1 deletion(-) | ||
45 | create mode 100644 sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c | ||
46 | |||
47 | diff --git a/sysdeps/ieee754/ldbl-96/Makefile b/sysdeps/ieee754/ldbl-96/Makefile | ||
48 | index b103254..052c1c7 100644 | ||
49 | --- a/sysdeps/ieee754/ldbl-96/Makefile | ||
50 | +++ b/sysdeps/ieee754/ldbl-96/Makefile | ||
51 | @@ -17,5 +17,6 @@ | ||
52 | # <http://www.gnu.org/licenses/>. | ||
53 | |||
54 | ifeq ($(subdir),math) | ||
55 | -tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 | ||
56 | +tests += test-canonical-ldbl-96 test-totalorderl-ldbl-96 test-sinl-pseudo | ||
57 | +CFLAGS-test-sinl-pseudo.c += -fstack-protector-all | ||
58 | endif | ||
59 | diff --git a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c | ||
60 | index 805de22..1aeccb4 100644 | ||
61 | --- a/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c | ||
62 | +++ b/sysdeps/ieee754/ldbl-96/e_rem_pio2l.c | ||
63 | @@ -210,6 +210,18 @@ __ieee754_rem_pio2l (long double x, long double *y) | ||
64 | return 0; | ||
65 | } | ||
66 | |||
67 | + if ((i0 & 0x80000000) == 0) | ||
68 | + { | ||
69 | + /* Pseudo-zero and unnormal representations are not valid | ||
70 | + representations of long double. We need to avoid stack | ||
71 | + corruption in __kernel_rem_pio2, which expects input in a | ||
72 | + particular normal form, but those representations do not need | ||
73 | + to be consistently handled like any particular floating-point | ||
74 | + value. */ | ||
75 | + y[1] = y[0] = __builtin_nanl (""); | ||
76 | + return 0; | ||
77 | + } | ||
78 | + | ||
79 | /* Split the 64 bits of the mantissa into three 24-bit integers | ||
80 | stored in a double array. */ | ||
81 | exp = j0 - 23; | ||
82 | diff --git a/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c | ||
83 | new file mode 100644 | ||
84 | index 0000000..f59b977 | ||
85 | --- /dev/null | ||
86 | +++ b/sysdeps/ieee754/ldbl-96/test-sinl-pseudo.c | ||
87 | @@ -0,0 +1,41 @@ | ||
88 | +/* Test sinl for pseudo-zeros and unnormals for ldbl-96 (bug 25487). | ||
89 | + Copyright (C) 2020 Free Software Foundation, Inc. | ||
90 | + This file is part of the GNU C Library. | ||
91 | + | ||
92 | + The GNU C Library is free software; you can redistribute it and/or | ||
93 | + modify it under the terms of the GNU Lesser General Public | ||
94 | + License as published by the Free Software Foundation; either | ||
95 | + version 2.1 of the License, or (at your option) any later version. | ||
96 | + | ||
97 | + The GNU C Library is distributed in the hope that it will be useful, | ||
98 | + but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
99 | + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
100 | + Lesser General Public License for more details. | ||
101 | + | ||
102 | + You should have received a copy of the GNU Lesser General Public | ||
103 | + License along with the GNU C Library; if not, see | ||
104 | + <https://www.gnu.org/licenses/>. */ | ||
105 | + | ||
106 | +#include <math.h> | ||
107 | +#include <math_ldbl.h> | ||
108 | +#include <stdint.h> | ||
109 | + | ||
110 | +static int | ||
111 | +do_test (void) | ||
112 | +{ | ||
113 | + for (int i = 0; i < 64; i++) | ||
114 | + { | ||
115 | + uint64_t sig = i == 63 ? 0 : 1ULL << i; | ||
116 | + long double ld; | ||
117 | + SET_LDOUBLE_WORDS (ld, 0x4141, | ||
118 | + sig >> 32, sig & 0xffffffffULL); | ||
119 | + /* The requirement is that no stack overflow occurs when the | ||
120 | + pseudo-zero or unnormal goes through range reduction. */ | ||
121 | + volatile long double ldr; | ||
122 | + ldr = sinl (ld); | ||
123 | + (void) ldr; | ||
124 | + } | ||
125 | + return 0; | ||
126 | +} | ||
127 | + | ||
128 | +#include <support/test-driver.c> | ||
diff --git a/meta/recipes-core/glibc/glibc/CVE-2020-1751.patch b/meta/recipes-core/glibc/glibc/CVE-2020-1751.patch new file mode 100644 index 0000000000..0ed92d50e9 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2020-1751.patch | |||
@@ -0,0 +1,70 @@ | |||
1 | From d93769405996dfc11d216ddbe415946617b5a494 Mon Sep 17 00:00:00 2001 | ||
2 | From: Andreas Schwab <schwab@suse.de> | ||
3 | Date: Mon, 20 Jan 2020 17:01:50 +0100 | ||
4 | Subject: [PATCH] Fix array overflow in backtrace on PowerPC (bug 25423) | ||
5 | |||
6 | When unwinding through a signal frame the backtrace function on PowerPC | ||
7 | didn't check array bounds when storing the frame address. Fixes commit | ||
8 | d400dcac5e ("PowerPC: fix backtrace to handle signal trampolines"). | ||
9 | |||
10 | CVE: CVE-2020-1751 | ||
11 | Upstream-Status: Backport [git://sourceware.org/git/glibc.git] | ||
12 | Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> | ||
13 | --- | ||
14 | debug/tst-backtrace5.c | 12 ++++++++++++ | ||
15 | sysdeps/powerpc/powerpc32/backtrace.c | 2 ++ | ||
16 | sysdeps/powerpc/powerpc64/backtrace.c | 2 ++ | ||
17 | 3 files changed, 16 insertions(+) | ||
18 | |||
19 | diff --git a/debug/tst-backtrace5.c b/debug/tst-backtrace5.c | ||
20 | index e7ce410845..b2f46160e7 100644 | ||
21 | --- a/debug/tst-backtrace5.c | ||
22 | +++ b/debug/tst-backtrace5.c | ||
23 | @@ -89,6 +89,18 @@ handle_signal (int signum) | ||
24 | } | ||
25 | /* Symbol names are not available for static functions, so we do not | ||
26 | check do_test. */ | ||
27 | + | ||
28 | + /* Check that backtrace does not return more than what fits in the array | ||
29 | + (bug 25423). */ | ||
30 | + for (int j = 0; j < NUM_FUNCTIONS; j++) | ||
31 | + { | ||
32 | + n = backtrace (addresses, j); | ||
33 | + if (n > j) | ||
34 | + { | ||
35 | + FAIL (); | ||
36 | + return; | ||
37 | + } | ||
38 | + } | ||
39 | } | ||
40 | |||
41 | NO_INLINE int | ||
42 | diff --git a/sysdeps/powerpc/powerpc32/backtrace.c b/sysdeps/powerpc/powerpc32/backtrace.c | ||
43 | index 7c2d4726f8..d1456c8ae4 100644 | ||
44 | --- a/sysdeps/powerpc/powerpc32/backtrace.c | ||
45 | +++ b/sysdeps/powerpc/powerpc32/backtrace.c | ||
46 | @@ -114,6 +114,8 @@ __backtrace (void **array, int size) | ||
47 | } | ||
48 | if (gregset) | ||
49 | { | ||
50 | + if (count + 1 == size) | ||
51 | + break; | ||
52 | array[++count] = (void*)((*gregset)[PT_NIP]); | ||
53 | current = (void*)((*gregset)[PT_R1]); | ||
54 | } | ||
55 | diff --git a/sysdeps/powerpc/powerpc64/backtrace.c b/sysdeps/powerpc/powerpc64/backtrace.c | ||
56 | index 65c260ab76..8a53a1088f 100644 | ||
57 | --- a/sysdeps/powerpc/powerpc64/backtrace.c | ||
58 | +++ b/sysdeps/powerpc/powerpc64/backtrace.c | ||
59 | @@ -87,6 +87,8 @@ __backtrace (void **array, int size) | ||
60 | if (is_sigtramp_address (current->return_address)) | ||
61 | { | ||
62 | struct signal_frame_64 *sigframe = (struct signal_frame_64*) current; | ||
63 | + if (count + 1 == size) | ||
64 | + break; | ||
65 | array[++count] = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_NIP]; | ||
66 | current = (void*) sigframe->uc.uc_mcontext.gp_regs[PT_R1]; | ||
67 | } | ||
68 | -- | ||
69 | 2.23.0 | ||
70 | |||
diff --git a/meta/recipes-core/glibc/glibc/CVE-2020-1752.patch b/meta/recipes-core/glibc/glibc/CVE-2020-1752.patch new file mode 100644 index 0000000000..6c347cd414 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2020-1752.patch | |||
@@ -0,0 +1,66 @@ | |||
1 | From ddc650e9b3dc916eab417ce9f79e67337b05035c Mon Sep 17 00:00:00 2001 | ||
2 | From: Andreas Schwab <schwab@suse.de> | ||
3 | Date: Wed, 19 Feb 2020 17:21:46 +0100 | ||
4 | Subject: [PATCH] Fix use-after-free in glob when expanding ~user (bug 25414) | ||
5 | |||
6 | The value of `end_name' points into the value of `dirname', thus don't | ||
7 | deallocate the latter before the last use of the former. | ||
8 | |||
9 | CVE: CVE-2020-1752 | ||
10 | Upstream-Status: Backport [git://sourceware.org/git/glibc.git] | ||
11 | Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> | ||
12 | --- | ||
13 | posix/glob.c | 25 +++++++++++++------------ | ||
14 | 1 file changed, 13 insertions(+), 12 deletions(-) | ||
15 | |||
16 | diff --git a/posix/glob.c b/posix/glob.c | ||
17 | index cba9cd1819..4580cefb9f 100644 | ||
18 | --- a/posix/glob.c | ||
19 | +++ b/posix/glob.c | ||
20 | @@ -827,31 +827,32 @@ __glob (const char *pattern, int flags, int (*errfunc) (const char *, int), | ||
21 | { | ||
22 | size_t home_len = strlen (p->pw_dir); | ||
23 | size_t rest_len = end_name == NULL ? 0 : strlen (end_name); | ||
24 | - char *d; | ||
25 | + char *d, *newp; | ||
26 | + bool use_alloca = glob_use_alloca (alloca_used, | ||
27 | + home_len + rest_len + 1); | ||
28 | |||
29 | - if (__glibc_unlikely (malloc_dirname)) | ||
30 | - free (dirname); | ||
31 | - malloc_dirname = 0; | ||
32 | - | ||
33 | - if (glob_use_alloca (alloca_used, home_len + rest_len + 1)) | ||
34 | - dirname = alloca_account (home_len + rest_len + 1, | ||
35 | - alloca_used); | ||
36 | + if (use_alloca) | ||
37 | + newp = alloca_account (home_len + rest_len + 1, alloca_used); | ||
38 | else | ||
39 | { | ||
40 | - dirname = malloc (home_len + rest_len + 1); | ||
41 | - if (dirname == NULL) | ||
42 | + newp = malloc (home_len + rest_len + 1); | ||
43 | + if (newp == NULL) | ||
44 | { | ||
45 | scratch_buffer_free (&pwtmpbuf); | ||
46 | retval = GLOB_NOSPACE; | ||
47 | goto out; | ||
48 | } | ||
49 | - malloc_dirname = 1; | ||
50 | } | ||
51 | - d = mempcpy (dirname, p->pw_dir, home_len); | ||
52 | + d = mempcpy (newp, p->pw_dir, home_len); | ||
53 | if (end_name != NULL) | ||
54 | d = mempcpy (d, end_name, rest_len); | ||
55 | *d = '\0'; | ||
56 | |||
57 | + if (__glibc_unlikely (malloc_dirname)) | ||
58 | + free (dirname); | ||
59 | + dirname = newp; | ||
60 | + malloc_dirname = !use_alloca; | ||
61 | + | ||
62 | dirlen = home_len + rest_len; | ||
63 | dirname_modified = 1; | ||
64 | } | ||
65 | -- | ||
66 | 2.18.2 | ||
diff --git a/meta/recipes-core/glibc/glibc/CVE-2020-6096-1.patch b/meta/recipes-core/glibc/glibc/CVE-2020-6096-1.patch new file mode 100644 index 0000000000..01c0328362 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2020-6096-1.patch | |||
@@ -0,0 +1,193 @@ | |||
1 | From 79a4fa341b8a89cb03f84564fd72abaa1a2db394 Mon Sep 17 00:00:00 2001 | ||
2 | From: Evgeny Eremin <e.eremin@omprussia.ru> | ||
3 | Date: Wed, 8 Jul 2020 14:18:19 +0200 | ||
4 | Subject: [PATCH 1/2] arm: CVE-2020-6096: fix memcpy and memmove for negative | ||
5 | length [BZ #25620] | ||
6 | |||
7 | Unsigned branch instructions could be used for r2 to fix the wrong | ||
8 | behavior when a negative length is passed to memcpy and memmove. | ||
9 | This commit fixes the generic arm implementation of memcpy amd memmove. | ||
10 | |||
11 | CVE: CVE-2020-6096 | ||
12 | Upstream-Status: Backport [git://sourceware.org/git/glibc.git] | ||
13 | Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> | ||
14 | --- | ||
15 | sysdeps/arm/memcpy.S | 24 ++++++++++-------------- | ||
16 | sysdeps/arm/memmove.S | 24 ++++++++++-------------- | ||
17 | 2 files changed, 20 insertions(+), 28 deletions(-) | ||
18 | |||
19 | diff --git a/sysdeps/arm/memcpy.S b/sysdeps/arm/memcpy.S | ||
20 | index 510e8adaf2..bcfbc51d99 100644 | ||
21 | --- a/sysdeps/arm/memcpy.S | ||
22 | +++ b/sysdeps/arm/memcpy.S | ||
23 | @@ -68,7 +68,7 @@ ENTRY(memcpy) | ||
24 | cfi_remember_state | ||
25 | |||
26 | subs r2, r2, #4 | ||
27 | - blt 8f | ||
28 | + blo 8f | ||
29 | ands ip, r0, #3 | ||
30 | PLD( pld [r1, #0] ) | ||
31 | bne 9f | ||
32 | @@ -82,7 +82,7 @@ ENTRY(memcpy) | ||
33 | cfi_rel_offset (r6, 4) | ||
34 | cfi_rel_offset (r7, 8) | ||
35 | cfi_rel_offset (r8, 12) | ||
36 | - blt 5f | ||
37 | + blo 5f | ||
38 | |||
39 | CALGN( ands ip, r1, #31 ) | ||
40 | CALGN( rsb r3, ip, #32 ) | ||
41 | @@ -98,9 +98,9 @@ ENTRY(memcpy) | ||
42 | #endif | ||
43 | |||
44 | PLD( pld [r1, #0] ) | ||
45 | -2: PLD( subs r2, r2, #96 ) | ||
46 | +2: PLD( cmp r2, #96 ) | ||
47 | PLD( pld [r1, #28] ) | ||
48 | - PLD( blt 4f ) | ||
49 | + PLD( blo 4f ) | ||
50 | PLD( pld [r1, #60] ) | ||
51 | PLD( pld [r1, #92] ) | ||
52 | |||
53 | @@ -108,9 +108,7 @@ ENTRY(memcpy) | ||
54 | 4: ldmia r1!, {r3, r4, r5, r6, r7, r8, ip, lr} | ||
55 | subs r2, r2, #32 | ||
56 | stmia r0!, {r3, r4, r5, r6, r7, r8, ip, lr} | ||
57 | - bge 3b | ||
58 | - PLD( cmn r2, #96 ) | ||
59 | - PLD( bge 4b ) | ||
60 | + bhs 3b | ||
61 | |||
62 | 5: ands ip, r2, #28 | ||
63 | rsb ip, ip, #32 | ||
64 | @@ -222,7 +220,7 @@ ENTRY(memcpy) | ||
65 | strbge r4, [r0], #1 | ||
66 | subs r2, r2, ip | ||
67 | strb lr, [r0], #1 | ||
68 | - blt 8b | ||
69 | + blo 8b | ||
70 | ands ip, r1, #3 | ||
71 | beq 1b | ||
72 | |||
73 | @@ -236,7 +234,7 @@ ENTRY(memcpy) | ||
74 | .macro forward_copy_shift pull push | ||
75 | |||
76 | subs r2, r2, #28 | ||
77 | - blt 14f | ||
78 | + blo 14f | ||
79 | |||
80 | CALGN( ands ip, r1, #31 ) | ||
81 | CALGN( rsb ip, ip, #32 ) | ||
82 | @@ -253,9 +251,9 @@ ENTRY(memcpy) | ||
83 | cfi_rel_offset (r10, 16) | ||
84 | |||
85 | PLD( pld [r1, #0] ) | ||
86 | - PLD( subs r2, r2, #96 ) | ||
87 | + PLD( cmp r2, #96 ) | ||
88 | PLD( pld [r1, #28] ) | ||
89 | - PLD( blt 13f ) | ||
90 | + PLD( blo 13f ) | ||
91 | PLD( pld [r1, #60] ) | ||
92 | PLD( pld [r1, #92] ) | ||
93 | |||
94 | @@ -280,9 +278,7 @@ ENTRY(memcpy) | ||
95 | mov ip, ip, PULL #\pull | ||
96 | orr ip, ip, lr, PUSH #\push | ||
97 | stmia r0!, {r3, r4, r5, r6, r7, r8, r10, ip} | ||
98 | - bge 12b | ||
99 | - PLD( cmn r2, #96 ) | ||
100 | - PLD( bge 13b ) | ||
101 | + bhs 12b | ||
102 | |||
103 | pop {r5 - r8, r10} | ||
104 | cfi_adjust_cfa_offset (-20) | ||
105 | diff --git a/sysdeps/arm/memmove.S b/sysdeps/arm/memmove.S | ||
106 | index 954037ef3a..0d07b76ee6 100644 | ||
107 | --- a/sysdeps/arm/memmove.S | ||
108 | +++ b/sysdeps/arm/memmove.S | ||
109 | @@ -85,7 +85,7 @@ ENTRY(memmove) | ||
110 | add r1, r1, r2 | ||
111 | add r0, r0, r2 | ||
112 | subs r2, r2, #4 | ||
113 | - blt 8f | ||
114 | + blo 8f | ||
115 | ands ip, r0, #3 | ||
116 | PLD( pld [r1, #-4] ) | ||
117 | bne 9f | ||
118 | @@ -99,7 +99,7 @@ ENTRY(memmove) | ||
119 | cfi_rel_offset (r6, 4) | ||
120 | cfi_rel_offset (r7, 8) | ||
121 | cfi_rel_offset (r8, 12) | ||
122 | - blt 5f | ||
123 | + blo 5f | ||
124 | |||
125 | CALGN( ands ip, r1, #31 ) | ||
126 | CALGN( sbcsne r4, ip, r2 ) @ C is always set here | ||
127 | @@ -114,9 +114,9 @@ ENTRY(memmove) | ||
128 | #endif | ||
129 | |||
130 | PLD( pld [r1, #-4] ) | ||
131 | -2: PLD( subs r2, r2, #96 ) | ||
132 | +2: PLD( cmp r2, #96 ) | ||
133 | PLD( pld [r1, #-32] ) | ||
134 | - PLD( blt 4f ) | ||
135 | + PLD( blo 4f ) | ||
136 | PLD( pld [r1, #-64] ) | ||
137 | PLD( pld [r1, #-96] ) | ||
138 | |||
139 | @@ -124,9 +124,7 @@ ENTRY(memmove) | ||
140 | 4: ldmdb r1!, {r3, r4, r5, r6, r7, r8, ip, lr} | ||
141 | subs r2, r2, #32 | ||
142 | stmdb r0!, {r3, r4, r5, r6, r7, r8, ip, lr} | ||
143 | - bge 3b | ||
144 | - PLD( cmn r2, #96 ) | ||
145 | - PLD( bge 4b ) | ||
146 | + bhs 3b | ||
147 | |||
148 | 5: ands ip, r2, #28 | ||
149 | rsb ip, ip, #32 | ||
150 | @@ -237,7 +235,7 @@ ENTRY(memmove) | ||
151 | strbge r4, [r0, #-1]! | ||
152 | subs r2, r2, ip | ||
153 | strb lr, [r0, #-1]! | ||
154 | - blt 8b | ||
155 | + blo 8b | ||
156 | ands ip, r1, #3 | ||
157 | beq 1b | ||
158 | |||
159 | @@ -251,7 +249,7 @@ ENTRY(memmove) | ||
160 | .macro backward_copy_shift push pull | ||
161 | |||
162 | subs r2, r2, #28 | ||
163 | - blt 14f | ||
164 | + blo 14f | ||
165 | |||
166 | CALGN( ands ip, r1, #31 ) | ||
167 | CALGN( rsb ip, ip, #32 ) | ||
168 | @@ -268,9 +266,9 @@ ENTRY(memmove) | ||
169 | cfi_rel_offset (r10, 16) | ||
170 | |||
171 | PLD( pld [r1, #-4] ) | ||
172 | - PLD( subs r2, r2, #96 ) | ||
173 | + PLD( cmp r2, #96 ) | ||
174 | PLD( pld [r1, #-32] ) | ||
175 | - PLD( blt 13f ) | ||
176 | + PLD( blo 13f ) | ||
177 | PLD( pld [r1, #-64] ) | ||
178 | PLD( pld [r1, #-96] ) | ||
179 | |||
180 | @@ -295,9 +293,7 @@ ENTRY(memmove) | ||
181 | mov r4, r4, PUSH #\push | ||
182 | orr r4, r4, r3, PULL #\pull | ||
183 | stmdb r0!, {r4 - r8, r10, ip, lr} | ||
184 | - bge 12b | ||
185 | - PLD( cmn r2, #96 ) | ||
186 | - PLD( bge 13b ) | ||
187 | + bhs 12b | ||
188 | |||
189 | pop {r5 - r8, r10} | ||
190 | cfi_adjust_cfa_offset (-20) | ||
191 | -- | ||
192 | 2.17.0 | ||
193 | |||
diff --git a/meta/recipes-core/glibc/glibc/CVE-2020-6096-2.patch b/meta/recipes-core/glibc/glibc/CVE-2020-6096-2.patch new file mode 100644 index 0000000000..bfb2d7e7f5 --- /dev/null +++ b/meta/recipes-core/glibc/glibc/CVE-2020-6096-2.patch | |||
@@ -0,0 +1,111 @@ | |||
1 | From beea361050728138b82c57dda0c4810402d342b9 Mon Sep 17 00:00:00 2001 | ||
2 | From: Alexander Anisimov <a.anisimov@omprussia.ru> | ||
3 | Date: Wed, 8 Jul 2020 14:18:31 +0200 | ||
4 | Subject: [PATCH 2/2] arm: CVE-2020-6096: Fix multiarch memcpy for negative | ||
5 | length [BZ #25620] | ||
6 | |||
7 | Unsigned branch instructions could be used for r2 to fix the wrong | ||
8 | behavior when a negative length is passed to memcpy. | ||
9 | This commit fixes the armv7 version. | ||
10 | |||
11 | CVE: CVE-2020-6096 | ||
12 | Upstream-Status: Backport [git://sourceware.org/git/glibc.git] | ||
13 | Signed-off-by: Zhixiong Chi <zhixiong.chi@windriver.com> | ||
14 | --- | ||
15 | sysdeps/arm/armv7/multiarch/memcpy_impl.S | 22 +++++++++++----------- | ||
16 | 1 file changed, 11 insertions(+), 11 deletions(-) | ||
17 | |||
18 | diff --git a/sysdeps/arm/armv7/multiarch/memcpy_impl.S b/sysdeps/arm/armv7/multiarch/memcpy_impl.S | ||
19 | index bf4ac7077f..379bb56fc9 100644 | ||
20 | --- a/sysdeps/arm/armv7/multiarch/memcpy_impl.S | ||
21 | +++ b/sysdeps/arm/armv7/multiarch/memcpy_impl.S | ||
22 | @@ -268,7 +268,7 @@ ENTRY(memcpy) | ||
23 | |||
24 | mov dst, dstin /* Preserve dstin, we need to return it. */ | ||
25 | cmp count, #64 | ||
26 | - bge .Lcpy_not_short | ||
27 | + bhs .Lcpy_not_short | ||
28 | /* Deal with small copies quickly by dropping straight into the | ||
29 | exit block. */ | ||
30 | |||
31 | @@ -351,10 +351,10 @@ ENTRY(memcpy) | ||
32 | |||
33 | 1: | ||
34 | subs tmp2, count, #64 /* Use tmp2 for count. */ | ||
35 | - blt .Ltail63aligned | ||
36 | + blo .Ltail63aligned | ||
37 | |||
38 | cmp tmp2, #512 | ||
39 | - bge .Lcpy_body_long | ||
40 | + bhs .Lcpy_body_long | ||
41 | |||
42 | .Lcpy_body_medium: /* Count in tmp2. */ | ||
43 | #ifdef USE_VFP | ||
44 | @@ -378,7 +378,7 @@ ENTRY(memcpy) | ||
45 | add src, src, #64 | ||
46 | vstr d1, [dst, #56] | ||
47 | add dst, dst, #64 | ||
48 | - bge 1b | ||
49 | + bhs 1b | ||
50 | tst tmp2, #0x3f | ||
51 | beq .Ldone | ||
52 | |||
53 | @@ -412,7 +412,7 @@ ENTRY(memcpy) | ||
54 | ldrd A_l, A_h, [src, #64]! | ||
55 | strd A_l, A_h, [dst, #64]! | ||
56 | subs tmp2, tmp2, #64 | ||
57 | - bge 1b | ||
58 | + bhs 1b | ||
59 | tst tmp2, #0x3f | ||
60 | bne 1f | ||
61 | ldr tmp2,[sp], #FRAME_SIZE | ||
62 | @@ -482,7 +482,7 @@ ENTRY(memcpy) | ||
63 | add src, src, #32 | ||
64 | |||
65 | subs tmp2, tmp2, #prefetch_lines * 64 * 2 | ||
66 | - blt 2f | ||
67 | + blo 2f | ||
68 | 1: | ||
69 | cpy_line_vfp d3, 0 | ||
70 | cpy_line_vfp d4, 64 | ||
71 | @@ -494,7 +494,7 @@ ENTRY(memcpy) | ||
72 | add dst, dst, #2 * 64 | ||
73 | add src, src, #2 * 64 | ||
74 | subs tmp2, tmp2, #prefetch_lines * 64 | ||
75 | - bge 1b | ||
76 | + bhs 1b | ||
77 | |||
78 | 2: | ||
79 | cpy_tail_vfp d3, 0 | ||
80 | @@ -615,8 +615,8 @@ ENTRY(memcpy) | ||
81 | 1: | ||
82 | pld [src, #(3 * 64)] | ||
83 | subs count, count, #64 | ||
84 | - ldrmi tmp2, [sp], #FRAME_SIZE | ||
85 | - bmi .Ltail63unaligned | ||
86 | + ldrlo tmp2, [sp], #FRAME_SIZE | ||
87 | + blo .Ltail63unaligned | ||
88 | pld [src, #(4 * 64)] | ||
89 | |||
90 | #ifdef USE_NEON | ||
91 | @@ -633,7 +633,7 @@ ENTRY(memcpy) | ||
92 | neon_load_multi d0-d3, src | ||
93 | neon_load_multi d4-d7, src | ||
94 | subs count, count, #64 | ||
95 | - bmi 2f | ||
96 | + blo 2f | ||
97 | 1: | ||
98 | pld [src, #(4 * 64)] | ||
99 | neon_store_multi d0-d3, dst | ||
100 | @@ -641,7 +641,7 @@ ENTRY(memcpy) | ||
101 | neon_store_multi d4-d7, dst | ||
102 | neon_load_multi d4-d7, src | ||
103 | subs count, count, #64 | ||
104 | - bpl 1b | ||
105 | + bhs 1b | ||
106 | 2: | ||
107 | neon_store_multi d0-d3, dst | ||
108 | neon_store_multi d4-d7, dst | ||
109 | -- | ||
110 | 2.17.0 | ||
111 | |||
diff --git a/meta/recipes-core/glibc/glibc_2.30.bb b/meta/recipes-core/glibc/glibc_2.30.bb index 7913bc2812..b674b02706 100644 --- a/meta/recipes-core/glibc/glibc_2.30.bb +++ b/meta/recipes-core/glibc/glibc_2.30.bb | |||
@@ -42,6 +42,11 @@ SRC_URI = "${GLIBC_GIT_URI};branch=${SRCBRANCH};name=glibc \ | |||
42 | file://0027-inject-file-assembly-directives.patch \ | 42 | file://0027-inject-file-assembly-directives.patch \ |
43 | file://0028-locale-prevent-maybe-uninitialized-errors-with-Os-BZ.patch \ | 43 | file://0028-locale-prevent-maybe-uninitialized-errors-with-Os-BZ.patch \ |
44 | file://CVE-2019-19126.patch \ | 44 | file://CVE-2019-19126.patch \ |
45 | file://CVE-2020-10029.patch \ | ||
46 | file://CVE-2020-1751.patch \ | ||
47 | file://CVE-2020-1752.patch \ | ||
48 | file://CVE-2020-6096-1.patch \ | ||
49 | file://CVE-2020-6096-2.patch \ | ||
45 | " | 50 | " |
46 | S = "${WORKDIR}/git" | 51 | S = "${WORKDIR}/git" |
47 | B = "${WORKDIR}/build-${TARGET_SYS}" | 52 | B = "${WORKDIR}/build-${TARGET_SYS}" |
diff --git a/meta/recipes-core/images/build-appliance-image_15.0.0.bb b/meta/recipes-core/images/build-appliance-image_15.0.0.bb index f071f6cf14..e993bde2d7 100644 --- a/meta/recipes-core/images/build-appliance-image_15.0.0.bb +++ b/meta/recipes-core/images/build-appliance-image_15.0.0.bb | |||
@@ -24,7 +24,7 @@ IMAGE_FSTYPES = "wic.vmdk" | |||
24 | 24 | ||
25 | inherit core-image module-base setuptools3 | 25 | inherit core-image module-base setuptools3 |
26 | 26 | ||
27 | SRCREV ?= "36520aa3829288e561f160f679c06246904591b6" | 27 | SRCREV ?= "f4b1c01110bf6cf7691aa6f214cecd89a52d5661" |
28 | SRC_URI = "git://git.yoctoproject.org/poky;branch=zeus \ | 28 | SRC_URI = "git://git.yoctoproject.org/poky;branch=zeus \ |
29 | file://Yocto_Build_Appliance.vmx \ | 29 | file://Yocto_Build_Appliance.vmx \ |
30 | file://Yocto_Build_Appliance.vmxf \ | 30 | file://Yocto_Build_Appliance.vmxf \ |
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2019-20388.patch b/meta/recipes-core/libxml/libxml2/CVE-2019-20388.patch new file mode 100644 index 0000000000..4ee2d4fe62 --- /dev/null +++ b/meta/recipes-core/libxml/libxml2/CVE-2019-20388.patch | |||
@@ -0,0 +1,37 @@ | |||
1 | From 7ffcd44d7e6c46704f8af0321d9314cd26e0e18a Mon Sep 17 00:00:00 2001 | ||
2 | From: Zhipeng Xie <xiezhipeng1@huawei.com> | ||
3 | Date: Tue, 20 Aug 2019 16:33:06 +0800 | ||
4 | Subject: [PATCH] Fix memory leak in xmlSchemaValidateStream | ||
5 | |||
6 | When ctxt->schema is NULL, xmlSchemaSAXPlug->xmlSchemaPreRun | ||
7 | alloc a new schema for ctxt->schema and set vctxt->xsiAssemble | ||
8 | to 1. Then xmlSchemaVStart->xmlSchemaPreRun initialize | ||
9 | vctxt->xsiAssemble to 0 again which cause the alloced schema | ||
10 | can not be freed anymore. | ||
11 | |||
12 | Found with libFuzzer. | ||
13 | |||
14 | Upstream-Status: Accepted [https://gitlab.gnome.org/GNOME/libxml2/commit/7ffcd44d7e6c46704f8af0321d9314cd26e0e18a] | ||
15 | CVE: CVE-2019-20388 | ||
16 | |||
17 | Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com> | ||
18 | Signed-off-by: Lee Chee Yang <chee.yang.lee@intel.com> | ||
19 | --- | ||
20 | xmlschemas.c | 1 - | ||
21 | 1 file changed, 1 deletion(-) | ||
22 | |||
23 | diff --git a/xmlschemas.c b/xmlschemas.c | ||
24 | index 301c8449..39d92182 100644 | ||
25 | --- a/xmlschemas.c | ||
26 | +++ b/xmlschemas.c | ||
27 | @@ -28090,7 +28090,6 @@ xmlSchemaPreRun(xmlSchemaValidCtxtPtr vctxt) { | ||
28 | vctxt->nberrors = 0; | ||
29 | vctxt->depth = -1; | ||
30 | vctxt->skipDepth = -1; | ||
31 | - vctxt->xsiAssemble = 0; | ||
32 | vctxt->hasKeyrefs = 0; | ||
33 | #ifdef ENABLE_IDC_NODE_TABLES_TEST | ||
34 | vctxt->createIDCNodeTables = 1; | ||
35 | -- | ||
36 | 2.24.1 | ||
37 | |||
diff --git a/meta/recipes-core/libxml/libxml2/CVE-2020-7595.patch b/meta/recipes-core/libxml/libxml2/CVE-2020-7595.patch new file mode 100644 index 0000000000..facfefd362 --- /dev/null +++ b/meta/recipes-core/libxml/libxml2/CVE-2020-7595.patch | |||
@@ -0,0 +1,36 @@ | |||
1 | From 0e1a49c8907645d2e155f0d89d4d9895ac5112b5 Mon Sep 17 00:00:00 2001 | ||
2 | From: Zhipeng Xie <xiezhipeng1@huawei.com> | ||
3 | Date: Thu, 12 Dec 2019 17:30:55 +0800 | ||
4 | Subject: [PATCH] Fix infinite loop in xmlStringLenDecodeEntities | ||
5 | |||
6 | When ctxt->instate == XML_PARSER_EOF,xmlParseStringEntityRef | ||
7 | return NULL which cause a infinite loop in xmlStringLenDecodeEntities | ||
8 | |||
9 | Found with libFuzzer. | ||
10 | |||
11 | Signed-off-by: Zhipeng Xie <xiezhipeng1@huawei.com> | ||
12 | |||
13 | Upstream-Status: Backport [https://gitlab.gnome.org/GNOME/libxml2/commit/0e1a49c89076] | ||
14 | CVE: CVE-2020-7595 | ||
15 | Signed-off-by: Anuj Mittal <anuj.mittal@intel.com> | ||
16 | --- | ||
17 | parser.c | 3 ++- | ||
18 | 1 file changed, 2 insertions(+), 1 deletion(-) | ||
19 | |||
20 | diff --git a/parser.c b/parser.c | ||
21 | index d1c31963..a34bb6cd 100644 | ||
22 | --- a/parser.c | ||
23 | +++ b/parser.c | ||
24 | @@ -2646,7 +2646,8 @@ xmlStringLenDecodeEntities(xmlParserCtxtPtr ctxt, const xmlChar *str, int len, | ||
25 | else | ||
26 | c = 0; | ||
27 | while ((c != 0) && (c != end) && /* non input consuming loop */ | ||
28 | - (c != end2) && (c != end3)) { | ||
29 | + (c != end2) && (c != end3) && | ||
30 | + (ctxt->instate != XML_PARSER_EOF)) { | ||
31 | |||
32 | if (c == 0) break; | ||
33 | if ((c == '&') && (str[1] == '#')) { | ||
34 | -- | ||
35 | 2.24.1 | ||
36 | |||
diff --git a/meta/recipes-core/libxml/libxml2_2.9.9.bb b/meta/recipes-core/libxml/libxml2_2.9.9.bb index c44a90b1c2..1d898ab020 100644 --- a/meta/recipes-core/libxml/libxml2_2.9.9.bb +++ b/meta/recipes-core/libxml/libxml2_2.9.9.bb | |||
@@ -21,6 +21,8 @@ SRC_URI = "http://www.xmlsoft.org/sources/libxml2-${PV}.tar.gz;name=libtar \ | |||
21 | file://0001-Make-ptest-run-the-python-tests-if-python-is-enabled.patch \ | 21 | file://0001-Make-ptest-run-the-python-tests-if-python-is-enabled.patch \ |
22 | file://fix-execution-of-ptests.patch \ | 22 | file://fix-execution-of-ptests.patch \ |
23 | file://Fix-CVE-2019-19956.patch \ | 23 | file://Fix-CVE-2019-19956.patch \ |
24 | file://CVE-2020-7595.patch \ | ||
25 | file://CVE-2019-20388.patch \ | ||
24 | " | 26 | " |
25 | 27 | ||
26 | SRC_URI[libtar.md5sum] = "c04a5a0a042eaa157e8e8c9eabe76bd6" | 28 | SRC_URI[libtar.md5sum] = "c04a5a0a042eaa157e8e8c9eabe76bd6" |
diff --git a/meta/recipes-core/meta/buildtools-extended-tarball.bb b/meta/recipes-core/meta/buildtools-extended-tarball.bb new file mode 100644 index 0000000000..94ed57585b --- /dev/null +++ b/meta/recipes-core/meta/buildtools-extended-tarball.bb | |||
@@ -0,0 +1,36 @@ | |||
1 | require recipes-core/meta/buildtools-tarball.bb | ||
2 | |||
3 | DESCRIPTION = "SDK type target for building a standalone tarball containing build-essentials, python3, chrpath, \ | ||
4 | make, git and tar. The tarball can be used to run bitbake builds on systems which don't meet the \ | ||
5 | usual version requirements and have ancient compilers." | ||
6 | SUMMARY = "Standalone tarball for running builds on systems with inadequate software and ancient compilers" | ||
7 | LICENSE = "MIT" | ||
8 | |||
9 | # Add nativesdk equivalent of build-essentials | ||
10 | TOOLCHAIN_HOST_TASK += "\ | ||
11 | nativesdk-automake \ | ||
12 | nativesdk-autoconf \ | ||
13 | nativesdk-binutils \ | ||
14 | nativesdk-binutils-symlinks \ | ||
15 | nativesdk-cpp \ | ||
16 | nativesdk-cpp-symlinks \ | ||
17 | nativesdk-gcc \ | ||
18 | nativesdk-gcc-symlinks \ | ||
19 | nativesdk-g++ \ | ||
20 | nativesdk-g++-symlinks \ | ||
21 | nativesdk-gettext \ | ||
22 | nativesdk-libatomic \ | ||
23 | nativesdk-libgcc \ | ||
24 | nativesdk-libstdc++ \ | ||
25 | nativesdk-libstdc++-dev \ | ||
26 | nativesdk-libstdc++-staticdev \ | ||
27 | nativesdk-libtool \ | ||
28 | nativesdk-pkgconfig \ | ||
29 | nativesdk-glibc-utils \ | ||
30 | nativesdk-python \ | ||
31 | nativesdk-libxcrypt-dev \ | ||
32 | " | ||
33 | |||
34 | TOOLCHAIN_OUTPUTNAME = "${SDK_ARCH}-buildtools-extended-nativesdk-standalone-${DISTRO_VERSION}" | ||
35 | |||
36 | SDK_TITLE = "Extended Build tools" | ||
diff --git a/meta/recipes-core/meta/buildtools-tarball.bb b/meta/recipes-core/meta/buildtools-tarball.bb index 66201514d7..ceb60b0e48 100644 --- a/meta/recipes-core/meta/buildtools-tarball.bb +++ b/meta/recipes-core/meta/buildtools-tarball.bb | |||
@@ -73,7 +73,13 @@ create_sdk_files_append () { | |||
73 | toolchain_create_sdk_version ${SDK_OUTPUT}/${SDKPATH}/version-${SDK_SYS} | 73 | toolchain_create_sdk_version ${SDK_OUTPUT}/${SDKPATH}/version-${SDK_SYS} |
74 | 74 | ||
75 | echo 'export GIT_SSL_CAINFO="${SDKPATHNATIVE}${sysconfdir}/ssl/certs/ca-certificates.crt"' >>$script | 75 | echo 'export GIT_SSL_CAINFO="${SDKPATHNATIVE}${sysconfdir}/ssl/certs/ca-certificates.crt"' >>$script |
76 | echo 'export SSL_CERT_FILE="${SDKPATHNATIVE}${sysconfdir}/ssl/certs/ca-certificates.crt"' >>$script | ||
77 | echo 'export OPENSSL_CONF="${SDKPATHNATIVE}${sysconfdir}/ssl/openssl.cnf"' >>$script | ||
76 | 78 | ||
79 | mkdir -p ${SDK_OUTPUT}/${SDKPATHNATIVE}${sysconfdir}/ | ||
80 | echo '${SDKPATHNATIVE}${libdir} | ||
81 | ${SDKPATHNATIVE}${base_libdir} | ||
82 | include /etc/ld.so.conf' > ${SDK_OUTPUT}/${SDKPATHNATIVE}${sysconfdir}/ld.so.conf | ||
77 | if [ "${SDKMACHINE}" = "i686" ]; then | 83 | if [ "${SDKMACHINE}" = "i686" ]; then |
78 | echo 'export NO32LIBS="0"' >>$script | 84 | echo 'export NO32LIBS="0"' >>$script |
79 | echo 'echo "$BB_ENV_EXTRAWHITE" | grep -q "NO32LIBS"' >>$script | 85 | echo 'echo "$BB_ENV_EXTRAWHITE" | grep -q "NO32LIBS"' >>$script |
diff --git a/meta/recipes-core/meta/cve-update-db-native.bb b/meta/recipes-core/meta/cve-update-db-native.bb index 575254af40..0577a5ccac 100644 --- a/meta/recipes-core/meta/cve-update-db-native.bb +++ b/meta/recipes-core/meta/cve-update-db-native.bb | |||
@@ -13,8 +13,15 @@ deltask do_install | |||
13 | deltask do_populate_sysroot | 13 | deltask do_populate_sysroot |
14 | 14 | ||
15 | python () { | 15 | python () { |
16 | if not d.getVar("CVE_CHECK_DB_FILE"): | 16 | cve_check_db_file = d.getVar("CVE_CHECK_DB_FILE") |
17 | if not cve_check_db_file: | ||
17 | raise bb.parse.SkipRecipe("Skip recipe when cve-check class is not loaded.") | 18 | raise bb.parse.SkipRecipe("Skip recipe when cve-check class is not loaded.") |
19 | |||
20 | if os.path.exists("%s-journal" % cve_check_db_file ): | ||
21 | os.remove("%s-journal" % cve_check_db_file) | ||
22 | |||
23 | if os.path.exists(cve_check_db_file): | ||
24 | os.remove(cve_check_db_file) | ||
18 | } | 25 | } |
19 | 26 | ||
20 | python do_populate_cve_db() { | 27 | python do_populate_cve_db() { |
@@ -122,7 +129,7 @@ def parse_node_and_insert(c, node, cveId): | |||
122 | product = cpe23[4] | 129 | product = cpe23[4] |
123 | version = cpe23[5] | 130 | version = cpe23[5] |
124 | 131 | ||
125 | if version != '*': | 132 | if version != '*' and version != '-': |
126 | # Version is defined, this is a '=' match | 133 | # Version is defined, this is a '=' match |
127 | yield [cveId, vendor, product, version, '=', '', ''] | 134 | yield [cveId, vendor, product, version, '=', '', ''] |
128 | else: | 135 | else: |
@@ -160,15 +167,20 @@ def update_db(c, jsondata): | |||
160 | if not elt['impact']: | 167 | if not elt['impact']: |
161 | continue | 168 | continue |
162 | 169 | ||
170 | accessVector = None | ||
163 | cveId = elt['cve']['CVE_data_meta']['ID'] | 171 | cveId = elt['cve']['CVE_data_meta']['ID'] |
164 | cveDesc = elt['cve']['description']['description_data'][0]['value'] | 172 | cveDesc = elt['cve']['description']['description_data'][0]['value'] |
165 | date = elt['lastModifiedDate'] | 173 | date = elt['lastModifiedDate'] |
166 | accessVector = elt['impact']['baseMetricV2']['cvssV2']['accessVector'] | ||
167 | cvssv2 = elt['impact']['baseMetricV2']['cvssV2']['baseScore'] | ||
168 | |||
169 | try: | 174 | try: |
175 | accessVector = elt['impact']['baseMetricV2']['cvssV2']['accessVector'] | ||
176 | cvssv2 = elt['impact']['baseMetricV2']['cvssV2']['baseScore'] | ||
177 | except KeyError: | ||
178 | cvssv2 = 0.0 | ||
179 | try: | ||
180 | accessVector = accessVector or elt['impact']['baseMetricV3']['cvssV3']['attackVector'] | ||
170 | cvssv3 = elt['impact']['baseMetricV3']['cvssV3']['baseScore'] | 181 | cvssv3 = elt['impact']['baseMetricV3']['cvssV3']['baseScore'] |
171 | except: | 182 | except KeyError: |
183 | accessVector = accessVector or "UNKNOWN" | ||
172 | cvssv3 = 0.0 | 184 | cvssv3 = 0.0 |
173 | 185 | ||
174 | c.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)", | 186 | c.execute("insert or replace into NVD values (?, ?, ?, ?, ?, ?)", |
diff --git a/meta/recipes-core/meta/dummy-sdk-package.inc b/meta/recipes-core/meta/dummy-sdk-package.inc index 4d653706b1..0d15a37c35 100644 --- a/meta/recipes-core/meta/dummy-sdk-package.inc +++ b/meta/recipes-core/meta/dummy-sdk-package.inc | |||
@@ -17,6 +17,9 @@ ALLOW_EMPTY_${PN} = "1" | |||
17 | 17 | ||
18 | PR[vardeps] += "DUMMYPROVIDES" | 18 | PR[vardeps] += "DUMMYPROVIDES" |
19 | 19 | ||
20 | DUMMYPROVIDES_PACKAGES ??= "" | ||
21 | DUMMYPROVIDES += "${@' '.join([multilib_pkg_extend(d, pkg) for pkg in d.getVar('DUMMYPROVIDES_PACKAGES').split()])}" | ||
22 | |||
20 | python populate_packages_prepend() { | 23 | python populate_packages_prepend() { |
21 | p = d.getVar("PN") | 24 | p = d.getVar("PN") |
22 | d.appendVar("RPROVIDES_%s" % p, "${DUMMYPROVIDES}") | 25 | d.appendVar("RPROVIDES_%s" % p, "${DUMMYPROVIDES}") |
diff --git a/meta/recipes-core/meta/nativesdk-buildtools-perl-dummy.bb b/meta/recipes-core/meta/nativesdk-buildtools-perl-dummy.bb index 6a8748acdf..cfa41c4ae6 100644 --- a/meta/recipes-core/meta/nativesdk-buildtools-perl-dummy.bb +++ b/meta/recipes-core/meta/nativesdk-buildtools-perl-dummy.bb | |||
@@ -1,6 +1,6 @@ | |||
1 | DUMMYARCH = "buildtools-dummy-${SDKPKGSUFFIX}" | 1 | DUMMYARCH = "buildtools-dummy-${SDKPKGSUFFIX}" |
2 | 2 | ||
3 | DUMMYPROVIDES = "\ | 3 | DUMMYPROVIDES_PACKAGES = "\ |
4 | nativesdk-perl \ | 4 | nativesdk-perl \ |
5 | nativesdk-libxml-parser-perl \ | 5 | nativesdk-libxml-parser-perl \ |
6 | nativesdk-perl-module-bytes \ | 6 | nativesdk-perl-module-bytes \ |
@@ -15,12 +15,18 @@ DUMMYPROVIDES = "\ | |||
15 | nativesdk-perl-module-file-find \ | 15 | nativesdk-perl-module-file-find \ |
16 | nativesdk-perl-module-file-glob \ | 16 | nativesdk-perl-module-file-glob \ |
17 | nativesdk-perl-module-file-path \ | 17 | nativesdk-perl-module-file-path \ |
18 | nativesdk-perl-module-file-spec \ | ||
18 | nativesdk-perl-module-file-stat \ | 19 | nativesdk-perl-module-file-stat \ |
19 | nativesdk-perl-module-getopt-long \ | 20 | nativesdk-perl-module-getopt-long \ |
20 | nativesdk-perl-module-io-file \ | 21 | nativesdk-perl-module-io-file \ |
22 | nativesdk-perl-module-overloading \ | ||
21 | nativesdk-perl-module-posix \ | 23 | nativesdk-perl-module-posix \ |
22 | nativesdk-perl-module-thread-queue \ | 24 | nativesdk-perl-module-thread-queue \ |
23 | nativesdk-perl-module-threads \ | 25 | nativesdk-perl-module-threads \ |
26 | nativesdk-perl-module-warnings \ | ||
27 | " | ||
28 | |||
29 | DUMMYPROVIDES = "\ | ||
24 | /usr/bin/perl \ | 30 | /usr/bin/perl \ |
25 | " | 31 | " |
26 | 32 | ||
diff --git a/meta/recipes-core/meta/nativesdk-sdk-provides-dummy.bb b/meta/recipes-core/meta/nativesdk-sdk-provides-dummy.bb index b891efa5ef..29f4dd3633 100644 --- a/meta/recipes-core/meta/nativesdk-sdk-provides-dummy.bb +++ b/meta/recipes-core/meta/nativesdk-sdk-provides-dummy.bb | |||
@@ -1,10 +1,13 @@ | |||
1 | DUMMYARCH = "sdk-provides-dummy-${SDKPKGSUFFIX}" | 1 | DUMMYARCH = "sdk-provides-dummy-${SDKPKGSUFFIX}" |
2 | 2 | ||
3 | DUMMYPROVIDES_PACKAGES = "\ | ||
4 | pkgconfig \ | ||
5 | " | ||
6 | |||
3 | # Add /bin/sh? | 7 | # Add /bin/sh? |
4 | DUMMYPROVIDES = "\ | 8 | DUMMYPROVIDES = "\ |
5 | /bin/bash \ | 9 | /bin/bash \ |
6 | /usr/bin/env \ | 10 | /usr/bin/env \ |
7 | pkgconfig \ | ||
8 | libGL.so()(64bit) \ | 11 | libGL.so()(64bit) \ |
9 | libGL.so \ | 12 | libGL.so \ |
10 | " | 13 | " |
diff --git a/meta/recipes-core/meta/target-sdk-provides-dummy.bb b/meta/recipes-core/meta/target-sdk-provides-dummy.bb index 87b8bfab9c..e3beeb796c 100644 --- a/meta/recipes-core/meta/target-sdk-provides-dummy.bb +++ b/meta/recipes-core/meta/target-sdk-provides-dummy.bb | |||
@@ -48,7 +48,6 @@ DUMMYPROVIDES_PACKAGES = "\ | |||
48 | " | 48 | " |
49 | 49 | ||
50 | DUMMYPROVIDES = "\ | 50 | DUMMYPROVIDES = "\ |
51 | ${@' '.join([multilib_pkg_extend(d, pkg) for pkg in d.getVar('DUMMYPROVIDES_PACKAGES').split()])} \ | ||
52 | /bin/sh \ | 51 | /bin/sh \ |
53 | /bin/bash \ | 52 | /bin/bash \ |
54 | /usr/bin/env \ | 53 | /usr/bin/env \ |
diff --git a/meta/recipes-core/ncurses/ncurses_6.1+20190803.bb b/meta/recipes-core/ncurses/ncurses_6.1+20190803.bb index e638a3737c..c3a89f1c4f 100644 --- a/meta/recipes-core/ncurses/ncurses_6.1+20190803.bb +++ b/meta/recipes-core/ncurses/ncurses_6.1+20190803.bb | |||
@@ -10,3 +10,5 @@ SRCREV = "3c9b2677c96c645496997321bf2fe465a5e7e21f" | |||
10 | S = "${WORKDIR}/git" | 10 | S = "${WORKDIR}/git" |
11 | EXTRA_OECONF += "--with-abi-version=5 --cache-file=${B}/config.cache" | 11 | EXTRA_OECONF += "--with-abi-version=5 --cache-file=${B}/config.cache" |
12 | UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+(\.\d+)+(\+\d+)*)" | 12 | UPSTREAM_CHECK_GITTAGREGEX = "(?P<pver>\d+(\.\d+)+(\+\d+)*)" |
13 | |||
14 | CVE_VERSION = "6.1.${@d.getVar("PV").split('+')[1]}" | ||
diff --git a/meta/recipes-core/systemd/systemd/0001-Merge-branch-polkit-ref-count.patch b/meta/recipes-core/systemd/systemd/0001-Merge-branch-polkit-ref-count.patch new file mode 100644 index 0000000000..e684ab8755 --- /dev/null +++ b/meta/recipes-core/systemd/systemd/0001-Merge-branch-polkit-ref-count.patch | |||
@@ -0,0 +1,520 @@ | |||
1 | From 0062d795bf29301ae054e1826a7189198a2565c4 Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> | ||
3 | Date: Tue, 14 Apr 2020 09:06:53 +0000 | ||
4 | Subject: [PATCH] Merge branch 'polkit-ref-count' | ||
5 | |||
6 | Upsteam-Status: Backport [https://github.com/systemd/systemd/commit/ea0d0ede03c6f18dbc5036c5e9cccf97e415ccc2] | ||
7 | CVE: CVE-2020-1712 | ||
8 | |||
9 | Signed-off-by: Wenlin Kang <wenlin.kang@windriver.com> | ||
10 | --- | ||
11 | TODO | 2 +- | ||
12 | man/rules/meson.build | 1 + | ||
13 | man/sd_bus_enqueue_for_read.xml | 88 ++++++++++++++++ | ||
14 | src/libsystemd/libsystemd.sym | 1 + | ||
15 | src/libsystemd/sd-bus/sd-bus.c | 24 +++++ | ||
16 | src/shared/bus-util.c | 179 +++++++++++++++++++++----------- | ||
17 | src/systemd/sd-bus.h | 1 + | ||
18 | 7 files changed, 235 insertions(+), 61 deletions(-) | ||
19 | create mode 100644 man/sd_bus_enqueue_for_read.xml | ||
20 | |||
21 | diff --git a/TODO b/TODO | ||
22 | index c5b5b86057..5c5ea1f568 100644 | ||
23 | --- a/TODO | ||
24 | +++ b/TODO | ||
25 | @@ -184,7 +184,7 @@ Features: | ||
26 | |||
27 | * the a-posteriori stopping of units bound to units that disappeared logic | ||
28 | should be reworked: there should be a queue of units, and we should only | ||
29 | - enqeue stop jobs from a defer event that processes queue instead of | ||
30 | + enqueue stop jobs from a defer event that processes queue instead of | ||
31 | right-away when we find a unit that is bound to one that doesn't exist | ||
32 | anymore. (similar to how the stop-unneeded queue has been reworked the same | ||
33 | way) | ||
34 | diff --git a/man/rules/meson.build b/man/rules/meson.build | ||
35 | index 3b63311d7b..e80ed98c34 100644 | ||
36 | --- a/man/rules/meson.build | ||
37 | +++ b/man/rules/meson.build | ||
38 | @@ -192,6 +192,7 @@ manpages = [ | ||
39 | 'sd_bus_open_user_with_description', | ||
40 | 'sd_bus_open_with_description'], | ||
41 | ''], | ||
42 | + ['sd_bus_enqueue_for_read', '3', [], ''], | ||
43 | ['sd_bus_error', | ||
44 | '3', | ||
45 | ['SD_BUS_ERROR_MAKE_CONST', | ||
46 | diff --git a/man/sd_bus_enqueue_for_read.xml b/man/sd_bus_enqueue_for_read.xml | ||
47 | new file mode 100644 | ||
48 | index 0000000000..3318a3031b | ||
49 | --- /dev/null | ||
50 | +++ b/man/sd_bus_enqueue_for_read.xml | ||
51 | @@ -0,0 +1,88 @@ | ||
52 | +<?xml version='1.0'?> | ||
53 | +<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN" | ||
54 | + "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd"> | ||
55 | +<!-- SPDX-License-Identifier: LGPL-2.1+ --> | ||
56 | + | ||
57 | +<refentry id="sd_bus_enqueue_for_read" | ||
58 | + xmlns:xi="http://www.w3.org/2001/XInclude"> | ||
59 | + | ||
60 | + <refentryinfo> | ||
61 | + <title>sd_bus_enqueue_for_read</title> | ||
62 | + <productname>systemd</productname> | ||
63 | + </refentryinfo> | ||
64 | + | ||
65 | + <refmeta> | ||
66 | + <refentrytitle>sd_bus_enqueue_for_read</refentrytitle> | ||
67 | + <manvolnum>3</manvolnum> | ||
68 | + </refmeta> | ||
69 | + | ||
70 | + <refnamediv> | ||
71 | + <refname>sd_bus_enqueue_for_read</refname> | ||
72 | + | ||
73 | + <refpurpose>Re-enqueue a bus message on a bus connection, for reading.</refpurpose> | ||
74 | + </refnamediv> | ||
75 | + | ||
76 | + <refsynopsisdiv> | ||
77 | + <funcsynopsis> | ||
78 | + <funcsynopsisinfo>#include <systemd/sd-bus.h></funcsynopsisinfo> | ||
79 | + | ||
80 | + <funcprototype> | ||
81 | + <funcdef>int <function>sd_bus_enqueue_for_read</function></funcdef> | ||
82 | + <paramdef>sd_bus *<parameter>bus</parameter></paramdef> | ||
83 | + <paramdef>sd_bus_message *<parameter>message</parameter></paramdef> | ||
84 | + </funcprototype> | ||
85 | + | ||
86 | + </funcsynopsis> | ||
87 | + </refsynopsisdiv> | ||
88 | + | ||
89 | + <refsect1> | ||
90 | + <title>Description</title> | ||
91 | + | ||
92 | + <para><function>sd_bus_enqueue_for_read()</function> may be used to re-enqueue an incoming bus message on | ||
93 | + the local read queue, so that it is processed and dispatched locally again, similar to how an incoming | ||
94 | + message from the peer is processed. Takes a bus connection object and the message to enqueue. A reference | ||
95 | + is taken of the message and the caller's reference thus remains in possession of the caller. The message | ||
96 | + is enqueued at the end of the queue, thus will be dispatched after all other already queued messages are | ||
97 | + dispatched.</para> | ||
98 | + | ||
99 | + <para>This call is primarily useful for dealing with incoming method calls that may be processed only | ||
100 | + after an additional asynchronous operation completes. One example are PolicyKit authorization requests | ||
101 | + that are determined to be necessary to authorize a newly incoming method call: when the PolicyKit response | ||
102 | + is received the original method call may be re-enqueued to process it again, this time with the | ||
103 | + authorization result known.</para> | ||
104 | + </refsect1> | ||
105 | + | ||
106 | + <refsect1> | ||
107 | + <title>Return Value</title> | ||
108 | + | ||
109 | + <para>On success, this function return 0 or a positive integer. On failure, it returns a negative errno-style | ||
110 | + error code.</para> | ||
111 | + | ||
112 | + <refsect2> | ||
113 | + <title>Errors</title> | ||
114 | + | ||
115 | + <para>Returned errors may indicate the following problems:</para> | ||
116 | + | ||
117 | + <variablelist> | ||
118 | + <varlistentry> | ||
119 | + <term><constant>-ECHILD</constant></term> | ||
120 | + | ||
121 | + <listitem><para>The bus connection has been created in a different process.</para></listitem> | ||
122 | + </varlistentry> | ||
123 | + </variablelist> | ||
124 | + </refsect2> | ||
125 | + </refsect1> | ||
126 | + | ||
127 | + <xi:include href="libsystemd-pkgconfig.xml" /> | ||
128 | + | ||
129 | + <refsect1> | ||
130 | + <title>See Also</title> | ||
131 | + | ||
132 | + <para> | ||
133 | + <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>, | ||
134 | + <citerefentry><refentrytitle>sd-bus</refentrytitle><manvolnum>3</manvolnum></citerefentry>, | ||
135 | + <citerefentry><refentrytitle>sd_bus_send</refentrytitle><manvolnum>3</manvolnum></citerefentry>, | ||
136 | + </para> | ||
137 | + </refsect1> | ||
138 | + | ||
139 | +</refentry> | ||
140 | diff --git a/src/libsystemd/libsystemd.sym b/src/libsystemd/libsystemd.sym | ||
141 | index 5ec42e0f1f..c40f1b7d1a 100644 | ||
142 | --- a/src/libsystemd/libsystemd.sym | ||
143 | +++ b/src/libsystemd/libsystemd.sym | ||
144 | @@ -679,6 +679,7 @@ global: | ||
145 | |||
146 | LIBSYSTEMD_243 { | ||
147 | global: | ||
148 | + sd_bus_enqueue_for_read; | ||
149 | sd_bus_object_vtable_format; | ||
150 | sd_event_source_disable_unref; | ||
151 | } LIBSYSTEMD_241; | ||
152 | diff --git a/src/libsystemd/sd-bus/sd-bus.c b/src/libsystemd/sd-bus/sd-bus.c | ||
153 | index 026ac8cb94..07bc145f37 100644 | ||
154 | --- a/src/libsystemd/sd-bus/sd-bus.c | ||
155 | +++ b/src/libsystemd/sd-bus/sd-bus.c | ||
156 | @@ -4194,3 +4194,27 @@ _public_ int sd_bus_get_close_on_exit(sd_bus *bus) { | ||
157 | |||
158 | return bus->close_on_exit; | ||
159 | } | ||
160 | + | ||
161 | +_public_ int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m) { | ||
162 | + int r; | ||
163 | + | ||
164 | + assert_return(bus, -EINVAL); | ||
165 | + assert_return(bus = bus_resolve(bus), -ENOPKG); | ||
166 | + assert_return(m, -EINVAL); | ||
167 | + assert_return(m->sealed, -EINVAL); | ||
168 | + assert_return(!bus_pid_changed(bus), -ECHILD); | ||
169 | + | ||
170 | + if (!BUS_IS_OPEN(bus->state)) | ||
171 | + return -ENOTCONN; | ||
172 | + | ||
173 | + /* Re-enqueue a message for reading. This is primarily useful for PolicyKit-style authentication, | ||
174 | + * where we accept a message, then determine we need to interactively authenticate the user, and then | ||
175 | + * we want to process the message again. */ | ||
176 | + | ||
177 | + r = bus_rqueue_make_room(bus); | ||
178 | + if (r < 0) | ||
179 | + return r; | ||
180 | + | ||
181 | + bus->rqueue[bus->rqueue_size++] = bus_message_ref_queued(m, bus); | ||
182 | + return 0; | ||
183 | +} | ||
184 | diff --git a/src/shared/bus-util.c b/src/shared/bus-util.c | ||
185 | index e9b0b8a99d..88cad9cd0a 100644 | ||
186 | --- a/src/shared/bus-util.c | ||
187 | +++ b/src/shared/bus-util.c | ||
188 | @@ -212,6 +212,34 @@ static int check_good_user(sd_bus_message *m, uid_t good_user) { | ||
189 | return sender_uid == good_user; | ||
190 | } | ||
191 | |||
192 | +#if ENABLE_POLKIT | ||
193 | +static int bus_message_append_strv_key_value( | ||
194 | + sd_bus_message *m, | ||
195 | + const char **l) { | ||
196 | + | ||
197 | + const char **k, **v; | ||
198 | + int r; | ||
199 | + | ||
200 | + assert(m); | ||
201 | + | ||
202 | + r = sd_bus_message_open_container(m, 'a', "{ss}"); | ||
203 | + if (r < 0) | ||
204 | + return r; | ||
205 | + | ||
206 | + STRV_FOREACH_PAIR(k, v, l) { | ||
207 | + r = sd_bus_message_append(m, "{ss}", *k, *v); | ||
208 | + if (r < 0) | ||
209 | + return r; | ||
210 | + } | ||
211 | + | ||
212 | + r = sd_bus_message_close_container(m); | ||
213 | + if (r < 0) | ||
214 | + return r; | ||
215 | + | ||
216 | + return r; | ||
217 | +} | ||
218 | +#endif | ||
219 | + | ||
220 | int bus_test_polkit( | ||
221 | sd_bus_message *call, | ||
222 | int capability, | ||
223 | @@ -219,7 +247,7 @@ int bus_test_polkit( | ||
224 | const char **details, | ||
225 | uid_t good_user, | ||
226 | bool *_challenge, | ||
227 | - sd_bus_error *e) { | ||
228 | + sd_bus_error *ret_error) { | ||
229 | |||
230 | int r; | ||
231 | |||
232 | @@ -242,7 +270,7 @@ int bus_test_polkit( | ||
233 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *request = NULL; | ||
234 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; | ||
235 | int authorized = false, challenge = false; | ||
236 | - const char *sender, **k, **v; | ||
237 | + const char *sender; | ||
238 | |||
239 | sender = sd_bus_message_get_sender(call); | ||
240 | if (!sender) | ||
241 | @@ -266,17 +294,7 @@ int bus_test_polkit( | ||
242 | if (r < 0) | ||
243 | return r; | ||
244 | |||
245 | - r = sd_bus_message_open_container(request, 'a', "{ss}"); | ||
246 | - if (r < 0) | ||
247 | - return r; | ||
248 | - | ||
249 | - STRV_FOREACH_PAIR(k, v, details) { | ||
250 | - r = sd_bus_message_append(request, "{ss}", *k, *v); | ||
251 | - if (r < 0) | ||
252 | - return r; | ||
253 | - } | ||
254 | - | ||
255 | - r = sd_bus_message_close_container(request); | ||
256 | + r = bus_message_append_strv_key_value(request, details); | ||
257 | if (r < 0) | ||
258 | return r; | ||
259 | |||
260 | @@ -284,11 +302,11 @@ int bus_test_polkit( | ||
261 | if (r < 0) | ||
262 | return r; | ||
263 | |||
264 | - r = sd_bus_call(call->bus, request, 0, e, &reply); | ||
265 | + r = sd_bus_call(call->bus, request, 0, ret_error, &reply); | ||
266 | if (r < 0) { | ||
267 | /* Treat no PK available as access denied */ | ||
268 | - if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN)) { | ||
269 | - sd_bus_error_free(e); | ||
270 | + if (sd_bus_error_has_name(ret_error, SD_BUS_ERROR_SERVICE_UNKNOWN)) { | ||
271 | + sd_bus_error_free(ret_error); | ||
272 | return -EACCES; | ||
273 | } | ||
274 | |||
275 | @@ -319,15 +337,17 @@ int bus_test_polkit( | ||
276 | #if ENABLE_POLKIT | ||
277 | |||
278 | typedef struct AsyncPolkitQuery { | ||
279 | + char *action; | ||
280 | + char **details; | ||
281 | + | ||
282 | sd_bus_message *request, *reply; | ||
283 | - sd_bus_message_handler_t callback; | ||
284 | - void *userdata; | ||
285 | sd_bus_slot *slot; | ||
286 | + | ||
287 | Hashmap *registry; | ||
288 | + sd_event_source *defer_event_source; | ||
289 | } AsyncPolkitQuery; | ||
290 | |||
291 | static void async_polkit_query_free(AsyncPolkitQuery *q) { | ||
292 | - | ||
293 | if (!q) | ||
294 | return; | ||
295 | |||
296 | @@ -339,9 +359,25 @@ static void async_polkit_query_free(AsyncPolkitQuery *q) { | ||
297 | sd_bus_message_unref(q->request); | ||
298 | sd_bus_message_unref(q->reply); | ||
299 | |||
300 | + free(q->action); | ||
301 | + strv_free(q->details); | ||
302 | + | ||
303 | + sd_event_source_disable_unref(q->defer_event_source); | ||
304 | free(q); | ||
305 | } | ||
306 | |||
307 | +static int async_polkit_defer(sd_event_source *s, void *userdata) { | ||
308 | + AsyncPolkitQuery *q = userdata; | ||
309 | + | ||
310 | + assert(s); | ||
311 | + | ||
312 | + /* This is called as idle event source after we processed the async polkit reply, hopefully after the | ||
313 | + * method call we re-enqueued has been properly processed. */ | ||
314 | + | ||
315 | + async_polkit_query_free(q); | ||
316 | + return 0; | ||
317 | +} | ||
318 | + | ||
319 | static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_error *error) { | ||
320 | _cleanup_(sd_bus_error_free) sd_bus_error error_buffer = SD_BUS_ERROR_NULL; | ||
321 | AsyncPolkitQuery *q = userdata; | ||
322 | @@ -350,21 +386,46 @@ static int async_polkit_callback(sd_bus_message *reply, void *userdata, sd_bus_e | ||
323 | assert(reply); | ||
324 | assert(q); | ||
325 | |||
326 | + assert(q->slot); | ||
327 | q->slot = sd_bus_slot_unref(q->slot); | ||
328 | + | ||
329 | + assert(!q->reply); | ||
330 | q->reply = sd_bus_message_ref(reply); | ||
331 | |||
332 | + /* Now, let's dispatch the original message a second time be re-enqueing. This will then traverse the | ||
333 | + * whole message processing again, and thus re-validating and re-retrieving the "userdata" field | ||
334 | + * again. | ||
335 | + * | ||
336 | + * We install an idle event loop event to clean-up the PolicyKit request data when we are idle again, | ||
337 | + * i.e. after the second time the message is processed is complete. */ | ||
338 | + | ||
339 | + assert(!q->defer_event_source); | ||
340 | + r = sd_event_add_defer(sd_bus_get_event(sd_bus_message_get_bus(reply)), &q->defer_event_source, async_polkit_defer, q); | ||
341 | + if (r < 0) | ||
342 | + goto fail; | ||
343 | + | ||
344 | + r = sd_event_source_set_priority(q->defer_event_source, SD_EVENT_PRIORITY_IDLE); | ||
345 | + if (r < 0) | ||
346 | + goto fail; | ||
347 | + | ||
348 | + r = sd_event_source_set_enabled(q->defer_event_source, SD_EVENT_ONESHOT); | ||
349 | + if (r < 0) | ||
350 | + goto fail; | ||
351 | + | ||
352 | r = sd_bus_message_rewind(q->request, true); | ||
353 | - if (r < 0) { | ||
354 | - r = sd_bus_reply_method_errno(q->request, r, NULL); | ||
355 | - goto finish; | ||
356 | - } | ||
357 | + if (r < 0) | ||
358 | + goto fail; | ||
359 | |||
360 | - r = q->callback(q->request, q->userdata, &error_buffer); | ||
361 | - r = bus_maybe_reply_error(q->request, r, &error_buffer); | ||
362 | + r = sd_bus_enqueue_for_read(sd_bus_message_get_bus(q->request), q->request); | ||
363 | + if (r < 0) | ||
364 | + goto fail; | ||
365 | |||
366 | -finish: | ||
367 | - async_polkit_query_free(q); | ||
368 | + return 1; | ||
369 | |||
370 | +fail: | ||
371 | + log_debug_errno(r, "Processing asynchronous PolicyKit reply failed, ignoring: %m"); | ||
372 | + (void) sd_bus_reply_method_errno(q->request, r, NULL); | ||
373 | + async_polkit_query_free(q); | ||
374 | return r; | ||
375 | } | ||
376 | |||
377 | @@ -378,16 +439,14 @@ int bus_verify_polkit_async( | ||
378 | bool interactive, | ||
379 | uid_t good_user, | ||
380 | Hashmap **registry, | ||
381 | - sd_bus_error *error) { | ||
382 | + sd_bus_error *ret_error) { | ||
383 | |||
384 | #if ENABLE_POLKIT | ||
385 | _cleanup_(sd_bus_message_unrefp) sd_bus_message *pk = NULL; | ||
386 | AsyncPolkitQuery *q; | ||
387 | - const char *sender, **k, **v; | ||
388 | - sd_bus_message_handler_t callback; | ||
389 | - void *userdata; | ||
390 | int c; | ||
391 | #endif | ||
392 | + const char *sender; | ||
393 | int r; | ||
394 | |||
395 | assert(call); | ||
396 | @@ -403,11 +462,17 @@ int bus_verify_polkit_async( | ||
397 | if (q) { | ||
398 | int authorized, challenge; | ||
399 | |||
400 | - /* This is the second invocation of this function, and | ||
401 | - * there's already a response from polkit, let's | ||
402 | - * process it */ | ||
403 | + /* This is the second invocation of this function, and there's already a response from | ||
404 | + * polkit, let's process it */ | ||
405 | assert(q->reply); | ||
406 | |||
407 | + /* If the operation we want to authenticate changed between the first and the second time, | ||
408 | + * let's not use this authentication, it might be out of date as the object and context we | ||
409 | + * operate on might have changed. */ | ||
410 | + if (!streq(q->action, action) || | ||
411 | + !strv_equal(q->details, (char**) details)) | ||
412 | + return -ESTALE; | ||
413 | + | ||
414 | if (sd_bus_message_is_method_error(q->reply, NULL)) { | ||
415 | const sd_bus_error *e; | ||
416 | |||
417 | @@ -418,7 +483,7 @@ int bus_verify_polkit_async( | ||
418 | return -EACCES; | ||
419 | |||
420 | /* Copy error from polkit reply */ | ||
421 | - sd_bus_error_copy(error, e); | ||
422 | + sd_bus_error_copy(ret_error, e); | ||
423 | return -sd_bus_error_get_errno(e); | ||
424 | } | ||
425 | |||
426 | @@ -433,7 +498,7 @@ int bus_verify_polkit_async( | ||
427 | return 1; | ||
428 | |||
429 | if (challenge) | ||
430 | - return sd_bus_error_set(error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required."); | ||
431 | + return sd_bus_error_set(ret_error, SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED, "Interactive authentication required."); | ||
432 | |||
433 | return -EACCES; | ||
434 | } | ||
435 | @@ -445,20 +510,12 @@ int bus_verify_polkit_async( | ||
436 | else if (r > 0) | ||
437 | return 1; | ||
438 | |||
439 | -#if ENABLE_POLKIT | ||
440 | - if (sd_bus_get_current_message(call->bus) != call) | ||
441 | - return -EINVAL; | ||
442 | - | ||
443 | - callback = sd_bus_get_current_handler(call->bus); | ||
444 | - if (!callback) | ||
445 | - return -EINVAL; | ||
446 | - | ||
447 | - userdata = sd_bus_get_current_userdata(call->bus); | ||
448 | |||
449 | sender = sd_bus_message_get_sender(call); | ||
450 | if (!sender) | ||
451 | return -EBADMSG; | ||
452 | |||
453 | +#if ENABLE_POLKIT | ||
454 | c = sd_bus_message_get_allow_interactive_authorization(call); | ||
455 | if (c < 0) | ||
456 | return c; | ||
457 | @@ -487,17 +544,7 @@ int bus_verify_polkit_async( | ||
458 | if (r < 0) | ||
459 | return r; | ||
460 | |||
461 | - r = sd_bus_message_open_container(pk, 'a', "{ss}"); | ||
462 | - if (r < 0) | ||
463 | - return r; | ||
464 | - | ||
465 | - STRV_FOREACH_PAIR(k, v, details) { | ||
466 | - r = sd_bus_message_append(pk, "{ss}", *k, *v); | ||
467 | - if (r < 0) | ||
468 | - return r; | ||
469 | - } | ||
470 | - | ||
471 | - r = sd_bus_message_close_container(pk); | ||
472 | + r = bus_message_append_strv_key_value(pk, details); | ||
473 | if (r < 0) | ||
474 | return r; | ||
475 | |||
476 | @@ -505,13 +552,25 @@ int bus_verify_polkit_async( | ||
477 | if (r < 0) | ||
478 | return r; | ||
479 | |||
480 | - q = new0(AsyncPolkitQuery, 1); | ||
481 | + q = new(AsyncPolkitQuery, 1); | ||
482 | if (!q) | ||
483 | return -ENOMEM; | ||
484 | |||
485 | - q->request = sd_bus_message_ref(call); | ||
486 | - q->callback = callback; | ||
487 | - q->userdata = userdata; | ||
488 | + *q = (AsyncPolkitQuery) { | ||
489 | + .request = sd_bus_message_ref(call), | ||
490 | + }; | ||
491 | + | ||
492 | + q->action = strdup(action); | ||
493 | + if (!q->action) { | ||
494 | + async_polkit_query_free(q); | ||
495 | + return -ENOMEM; | ||
496 | + } | ||
497 | + | ||
498 | + q->details = strv_copy((char**) details); | ||
499 | + if (!q->details) { | ||
500 | + async_polkit_query_free(q); | ||
501 | + return -ENOMEM; | ||
502 | + } | ||
503 | |||
504 | r = hashmap_put(*registry, call, q); | ||
505 | if (r < 0) { | ||
506 | diff --git a/src/systemd/sd-bus.h b/src/systemd/sd-bus.h | ||
507 | index 84ceb62dc7..0e5c761f83 100644 | ||
508 | --- a/src/systemd/sd-bus.h | ||
509 | +++ b/src/systemd/sd-bus.h | ||
510 | @@ -201,6 +201,7 @@ int sd_bus_process(sd_bus *bus, sd_bus_message **r); | ||
511 | int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r); | ||
512 | int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec); | ||
513 | int sd_bus_flush(sd_bus *bus); | ||
514 | +int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m); | ||
515 | |||
516 | sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus); | ||
517 | sd_bus_message* sd_bus_get_current_message(sd_bus *bus); | ||
518 | -- | ||
519 | 2.23.0 | ||
520 | |||
diff --git a/meta/recipes-core/systemd/systemd/CVE-2020-13776.patch b/meta/recipes-core/systemd/systemd/CVE-2020-13776.patch new file mode 100644 index 0000000000..7b5e3e7f7a --- /dev/null +++ b/meta/recipes-core/systemd/systemd/CVE-2020-13776.patch | |||
@@ -0,0 +1,96 @@ | |||
1 | From 156a5fd297b61bce31630d7a52c15614bf784843 Mon Sep 17 00:00:00 2001 | ||
2 | From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> | ||
3 | Date: Sun, 31 May 2020 18:21:09 +0200 | ||
4 | Subject: [PATCH 1/1] basic/user-util: always use base 10 for user/group | ||
5 | numbers | ||
6 | |||
7 | We would parse numbers with base prefixes as user identifiers. For example, | ||
8 | "0x2b3bfa0" would be interpreted as UID==45334432 and "01750" would be | ||
9 | interpreted as UID==1000. This parsing was used also in cases where either a | ||
10 | user/group name or number may be specified. This means that names like | ||
11 | 0x2b3bfa0 would be ambiguous: they are a valid user name according to our | ||
12 | documented relaxed rules, but they would also be parsed as numeric uids. | ||
13 | |||
14 | This behaviour is definitely not expected by users, since tools generally only | ||
15 | accept decimal numbers (e.g. id, getent passwd), while other tools only accept | ||
16 | user names and thus will interpret such strings as user names without even | ||
17 | attempting to convert them to numbers (su, ssh). So let's follow suit and only | ||
18 | accept numbers in decimal notation. Effectively this means that we will reject | ||
19 | such strings as a username/uid/groupname/gid where strict mode is used, and try | ||
20 | to look up a user/group with such a name in relaxed mode. | ||
21 | |||
22 | Since the function changed is fairly low-level and fairly widely used, this | ||
23 | affects multiple tools: loginctl show-user/enable-linger/disable-linger foo', | ||
24 | the third argument in sysusers.d, fourth and fifth arguments in tmpfiles.d, | ||
25 | etc. | ||
26 | |||
27 | Fixes #15985. | ||
28 | --- | ||
29 | src/basic/user-util.c | 2 +- | ||
30 | src/test/test-user-util.c | 10 ++++++++++ | ||
31 | 2 files changed, 11 insertions(+), 1 deletion(-) | ||
32 | |||
33 | --- end of commit 156a5fd297b61bce31630d7a52c15614bf784843 --- | ||
34 | |||
35 | |||
36 | Add definition of safe_atou32_full() from commit b934ac3d6e7dcad114776ef30ee9098693e7ab7e | ||
37 | |||
38 | CVE: CVE-2020-13776 | ||
39 | |||
40 | Upstream-Status: Backport [https://github.com/systemd/systemd.git] | ||
41 | |||
42 | Signed-off-by: Joe Slater <joe.slater@windriver.com> | ||
43 | |||
44 | |||
45 | |||
46 | --- git.orig/src/basic/user-util.c | ||
47 | +++ git/src/basic/user-util.c | ||
48 | @@ -49,7 +49,7 @@ int parse_uid(const char *s, uid_t *ret) | ||
49 | assert(s); | ||
50 | |||
51 | assert_cc(sizeof(uid_t) == sizeof(uint32_t)); | ||
52 | - r = safe_atou32(s, &uid); | ||
53 | + r = safe_atou32_full(s, 10, &uid); | ||
54 | if (r < 0) | ||
55 | return r; | ||
56 | |||
57 | --- git.orig/src/test/test-user-util.c | ||
58 | +++ git/src/test/test-user-util.c | ||
59 | @@ -48,9 +48,19 @@ static void test_parse_uid(void) { | ||
60 | |||
61 | r = parse_uid("65535", &uid); | ||
62 | assert_se(r == -ENXIO); | ||
63 | + assert_se(uid == 100); | ||
64 | + | ||
65 | + r = parse_uid("0x1234", &uid); | ||
66 | + assert_se(r == -EINVAL); | ||
67 | + assert_se(uid == 100); | ||
68 | + | ||
69 | + r = parse_uid("01234", &uid); | ||
70 | + assert_se(r == 0); | ||
71 | + assert_se(uid == 1234); | ||
72 | |||
73 | r = parse_uid("asdsdas", &uid); | ||
74 | assert_se(r == -EINVAL); | ||
75 | + assert_se(uid == 1234); | ||
76 | } | ||
77 | |||
78 | static void test_uid_ptr(void) { | ||
79 | --- git.orig/src/basic/parse-util.h | ||
80 | +++ git/src/basic/parse-util.h | ||
81 | @@ -45,9 +45,13 @@ static inline int safe_atoux16(const cha | ||
82 | |||
83 | int safe_atoi16(const char *s, int16_t *ret); | ||
84 | |||
85 | -static inline int safe_atou32(const char *s, uint32_t *ret_u) { | ||
86 | +static inline int safe_atou32_full(const char *s, unsigned base, uint32_t *ret_u) { | ||
87 | assert_cc(sizeof(uint32_t) == sizeof(unsigned)); | ||
88 | - return safe_atou(s, (unsigned*) ret_u); | ||
89 | + return safe_atou_full(s, base, (unsigned*) ret_u); | ||
90 | +} | ||
91 | + | ||
92 | +static inline int safe_atou32(const char *s, uint32_t *ret_u) { | ||
93 | + return safe_atou32_full(s, 0, (unsigned*) ret_u); | ||
94 | } | ||
95 | |||
96 | static inline int safe_atoi32(const char *s, int32_t *ret_i) { | ||
diff --git a/meta/recipes-core/systemd/systemd_243.2.bb b/meta/recipes-core/systemd/systemd_243.2.bb index 6e7f95693b..905348176c 100644 --- a/meta/recipes-core/systemd/systemd_243.2.bb +++ b/meta/recipes-core/systemd/systemd_243.2.bb | |||
@@ -24,6 +24,8 @@ SRC_URI += "file://touchscreen.rules \ | |||
24 | file://0005-rules-watch-metadata-changes-in-ide-devices.patch \ | 24 | file://0005-rules-watch-metadata-changes-in-ide-devices.patch \ |
25 | file://0001-unit-file.c-consider-symlink-on-filesystems-like-NFS.patch \ | 25 | file://0001-unit-file.c-consider-symlink-on-filesystems-like-NFS.patch \ |
26 | file://99-default.preset \ | 26 | file://99-default.preset \ |
27 | file://0001-Merge-branch-polkit-ref-count.patch \ | ||
28 | file://CVE-2020-13776.patch \ | ||
27 | " | 29 | " |
28 | 30 | ||
29 | # patches needed by musl | 31 | # patches needed by musl |