Bug#940804: libglib-2.0-0: Pidgin sigabrts when trying a new connection (IRC)

Bernhard Übelacker bernhardu at mailbox.org
Thu Aug 20 01:13:04 BST 2020


Dear Maintainer,
the attached file in message #5 contains
a backtrace with this part [1].

I am quite sure that the call to __fdelt_chk in g_spawn_sync is
at this source location [2] in gspawn.c line 442.

Because __fdelt_chk checks if the fd outpipe is either
negative or below FD_SETSIZE, and outpipe is just checked
before to be greater or equal to zero, I would assume that
this process did run out of file descriptors.

If that is really the case might be visible if one checks
the output of 'lsof | grep $(pidof pidgin)'.

Upstream glib has fixed this FD_SETSIZE limitation in [4].
The last link shows a backtrace with the same
g_spawn_sync/__fdelt_chk combination.
Therefore I would assume current testing should not show this fault.

Kind regards,
Bernhard


[1]
    ...
    #5  0x00007fe1c2aca940 in __GI___chk_fail () at chk_fail.c:28
    #6  0x00007fe1c2acc737 in __fdelt_chk (d=<optimized out>) at fdelt_chk.c:25
    #7  0x00007fe1c2f021c5 in g_spawn_sync () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
    #8  0x00007fe1c2f02997 in g_spawn_command_line_sync () from /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0
    #9  0x00007fe1c2db1794 in purple_gnome_proxy_get_parameter (parameter=parameter at entry=0 '\000', gnome_version=gnome_version at entry=1 '\001') at ././libpurple/proxy.c:270
    #10 0x00007fe1c2db1e2b in purple_gnome_proxy_get_parameter (gnome_version=<optimized out>, parameter=0 '\000') at ././libpurple/proxy.c:307
    ...

[2]
    (gdb) list gspawn.c:360,450
    ...
    440           FD_ZERO (&fds);
    441           if (outpipe >= 0)
    442             FD_SET (outpipe, &fds);                 <<<<<<<<<<<<
    443           if (errpipe >= 0)
    444             FD_SET (errpipe, &fds);
    ...
    https://sources.debian.org/src/glib2.0/2.58.3-2+deb10u2/glib/gspawn.c/#L442

[3]
    long int
    __fdelt_chk (long int d)
    {
      if (d < 0 || d >= FD_SETSIZE)
        __chk_fail ();
    
      return d / __NFDBITS;
    }

[4]
    https://gitlab.gnome.org/GNOME/glib/-/issues/954
    https://gitlab.gnome.org/GNOME/glib/-/commit/a7242d4a5e5e5875699bcff2749beac19864943b
    https://gitlab.gnome.org/GNOME/glib/-/issues/2079
-------------- next part --------------

# Buster/stable amd64 qemu VM 2020-08-20


apt update
apt dist-upgrade


apt install systemd-coredump sddm xserver-xorg openbox xterm mc dpkg-dev devscripts gdb pidgin


reboot


cat /proc/sys/kernel/randomize_va_space
echo 0 > /proc/sys/kernel/randomize_va_space


wget https://snapshot.debian.org/archive/debian/20190822T033017Z/pool/main/g/glib2.0/libglib2.0-data_2.58.3-2%2Bdeb10u1_all.deb
wget https://snapshot.debian.org/archive/debian/20190822T033017Z/pool/main/g/glib2.0/libglib2.0-0_2.58.3-2%2Bdeb10u1_amd64.deb
wget https://snapshot.debian.org/archive/debian-debug/20190928T162431Z/pool/main/g/glib2.0/libglib2.0-0-dbgsym_2.58.3-2%2Bdeb10u1_amd64.deb
dpkg -i *.deb


mkdir /home/benutzer/source/libglib2.0-0/orig -p
cd    /home/benutzer/source/libglib2.0-0/orig
dget https://snapshot.debian.org/archive/debian/20190821T220217Z/pool/main/g/glib2.0/glib2.0_2.58.3-2%2Bdeb10u1.dsc
cd

mkdir /home/benutzer/source/pidgin/orig -p
cd    /home/benutzer/source/pidgin/orig
apt source pidgin
cd

mkdir /home/benutzer/source/glibc/orig -p
cd    /home/benutzer/source/glibc/orig
apt source glibc
cd


export DISPLAY=:0
pidgin


gdb -q --pid $(pidof pidgin)

set width 0
set pagination off
directory /home/benutzer/source/libglib2.0-0/orig/glib2.0-2.58.3/glib
disassemble g_spawn_sync
b *0x00007ffff71221c0


(gdb) b *0x00007ffff71221c0
Breakpoint 1 at 0x7ffff71221c0: file ../../../glib/gspawn.c, line 442.

(gdb) list gspawn.c:360,450
360     gboolean
361     g_spawn_sync (const gchar          *working_directory,
362                   gchar               **argv,
363                   gchar               **envp,
364                   GSpawnFlags           flags,
365                   GSpawnChildSetupFunc  child_setup,
366                   gpointer              user_data,
367                   gchar               **standard_output,
368                   gchar               **standard_error,
369                   gint                 *exit_status,
370                   GError              **error)     
371     {
372       gint outpipe = -1;
373       gint errpipe = -1;
374       GPid pid;
375       fd_set fds;
376       gint ret;
377       GString *outstr = NULL;
378       GString *errstr = NULL;
379       gboolean failed;
380       gint status;
381       
382       g_return_val_if_fail (argv != NULL, FALSE);
383       g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE);
384       g_return_val_if_fail (standard_output == NULL ||
385                             !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
386       g_return_val_if_fail (standard_error == NULL ||
387                             !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
388       
389       /* Just to ensure segfaults if callers try to use
390        * these when an error is reported.
391        */
392       if (standard_output)
393         *standard_output = NULL;
394
395       if (standard_error)
396         *standard_error = NULL;
397       
398       if (!fork_exec_with_pipes (FALSE,
399                                  working_directory,
400                                  argv,
401                                  envp,
402                                  !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
403                                  (flags & G_SPAWN_SEARCH_PATH) != 0,
404                                  (flags & G_SPAWN_SEARCH_PATH_FROM_ENVP) != 0,
405                                  (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
406                                  (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
407                                  (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
408                                  (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
409                                  (flags & G_SPAWN_CLOEXEC_PIPES) != 0,
410                                  child_setup,
411                                  user_data,
412                                  &pid,
413                                  NULL,
414                                  standard_output ? &outpipe : NULL,
415                                  standard_error ? &errpipe : NULL,
416                                  error))
417         return FALSE;
418
419       /* Read data from child. */
420       
421       failed = FALSE;
422
423       if (outpipe >= 0)
424         {
425           outstr = g_string_new (NULL);
426         }
427           
428       if (errpipe >= 0)
429         {
430           errstr = g_string_new (NULL);
431         }
432
433       /* Read data until we get EOF on both pipes. */
434       while (!failed &&
435              (outpipe >= 0 ||
436               errpipe >= 0))
437         {
438           ret = 0;
439               
440           FD_ZERO (&fds);
441           if (outpipe >= 0)
442             FD_SET (outpipe, &fds);                 <<<<<<<<<<<<
443           if (errpipe >= 0)
444             FD_SET (errpipe, &fds);
445               
446           ret = select (MAX (outpipe, errpipe) + 1,
447                         &fds,
448                         NULL, NULL,
449                         NULL /* no timeout */);
450


More information about the pkg-gnome-maintainers mailing list