#1153080 libgweather4: SIGSEGV in libxml2 error path when MET Norway returns malformed XML (kills the gnome-shell session)

#1153080#5
Date:
2026-11-05 09:19:59 UTC
From:
To:
[ Observed on Ubuntu 24.04.5 LTS with gnome-shell
46.0-0ubuntu6~24.04.17. Filing here because the crashing code path is
libgweather's MET Norway XML parser, shipped in Debian as libgweather4
4.4.2-1. Please forward upstream if you consider this an upstream bug. ]

Summary
-------
When the MET Norway API (api.met.no) returns a malformed/truncated XML
body, libgweather's parser raises a libxml2 parse error and the process
segfaults, taking down the whole gnome-shell session. The session then
crash-loops back to the display manager: a pure network-side data
problem makes the desktop unusable.

Environment
-----------
   Ubuntu 24.04.5 LTS (noble), X11 session, GNOME 46 / mutter 46.2
   gnome-shell          46.0-0ubuntu6~24.04.17
   libgweather-4-0t64   4.4.2-1build1
   libxml2              2.9.14+dfsg-1.3ubuntu3.10
   libsoup-3.0-0        3.4.4-5ubuntu0.10
   libxkbregistry0      1.6.0-1build1
   kernel               7.0.0-42-generic

Steps to reproduce
------------------
1. Shell weather enabled (org.gnome.shell.weather automatic-location
true, or a fixed location; here Saint Petersburg/ULLI, 59.9666N 30.3E).
2. api.met.no serves a truncated body for
/weatherapi/locationforecast/2.0/classic (observed 2026-11-05,
07:30-08:51 UTC): HTTP/2 200, content-type application/xml,
content-length 57018, server nginx/1.18.0, via Varnish (dalton-a),
x-backend-host b_157_249_79_168_loc. The body ends mid-attribute at
57018 bytes (exactly the declared length): "...<windSpeed id=\"ff\" mps"
with no closing </weatherdata>; 94 x "<location" vs 93 x "</location>".
xmllint: "-:270: parser error : expected '>'" / "Premature end of data
in tag location line 264". At the same time
/weatherapi/locationforecast/2.0/complete returned HTTP 502.
3. Log in. gnome-shell starts and dies about 2 seconds later: "Running
GNOME Shell (using mutter 46.2) as a X11 window and compositing manager"
then "GNOME Shell crashed with signal 11"; systemd reports
"org.gnome.Shell@x11.service: Main process exited, code=dumped,
status=11/SEGV". The unit restarts the shell 2-3 times, every attempt
crashing, then "Start request repeated too quickly" and the user is back
at the greeter.

Expected behaviour
------------------
A malformed or unavailable weather response must be handled as a normal
error: no weather data, shell keeps running.

Actual behaviour
----------------
SIGSEGV in the libxml2 error-reporting path (gdb, no debug symbols
installed):

   #5  <signal handler called>
   #6  ??? at libxkbregistry.so.0
   #7  ??? at libxkbregistry.so.0
   #8  ??? at libxml2.so.2
   #9  __xmlRaiseError at libxml2.so.2
   #10 ??? at libxml2.so.2
   ...
   #14 xmlParseElement at libxml2.so.2
   #15 xmlParseDocument at libxml2.so.2
   #16 xmlParseMemory at libxml2.so.2
   #17 ??? at libgweather-4.so.0
   #18 ??? at libgio-2.0.so.0
   #20 ??? at libsoup-3.0.so.0

The gnome-shell (gjs) side prints only one JS frame, ui/init.js:21, i.e.
the JS context is idle in the main loop: this is a native crash, not an
extension or script error. Full backtrace attached.

Analysis
--------
libgweather 4.4 links libxml2 (imports xmlParseMemory, xmlXPathEval,
...) and parses the MET Norway document with it. libxml2 2.9's
xmlSetStructuredErrorFunc() is process-global and is not thread-safe. In
this process libxkbregistry also parses XML with libxml2 (XKB rules via
xkb_context). The frames above __xmlRaiseError resolve into
libxkbregistry -- an unrelated module -- which is consistent with the
parse-error callback being invoked with another context's closure/user
data and then dereferencing it.

Suggested fixes (hypothesis, not verified):
   * libgweather: parse with a context-local error handler
(xmlCtxtReadMemory() / xmlCtxtSetErrorHandler() where available), or use
GMarkup for MET Norway XML, and treat a parse failure as an ordinary error;
   * libxkbregistry 1.6.0: do not install a process-global structured
error handler.

Reproducing without waiting for an outage
-----------------------------------------
Point the host at a local server that returns a truncated document and
then log in, e.g. echo "127.0.0.1 api.met.no" >> /etc/hosts plus a
TLS-terminating stub, or truncate a real response after N bytes with
mitmproxy / iptables length matching.

Additional data
---------------
   * 8 crashes in a single boot while the server returned the truncated
document; none after their cache was refreshed to a valid document at
08:51:42 UTC.
   * The cached bad response is attached
(libgweather-cache-truncated.xml.gz); it decompresses to 16138 bytes and
ends with "<windSpeed id=\"ff\" mps".
   * Reproduces with all GNOME Shell extensions disabled (the shell sets
org.gnome.shell disable-user-extensions=true after repeated crashes) and
with all 31 extensions enabled -- extensions are not involved.
   * A standalone gnome-shell on a scratch Xvfb display (same binary,
same dconf) does not crash: the failure needs the shell's weather
client, i.e. the network data, not the graphics stack. GPU (amdgpu / RX
580), OOM (62 GB RAM, swap untouched) and kernel (no amdgpu errors, no
oops) are excluded.
   * Local workaround: disable the shell weather
(org.gnome.shell.weather automatic-location false, locations []).

Regards,
Sergey Nuchev