Bug#1012046: /usr/libexec/gnome-terminal-server: gnome-terminal-server writes on disk data when a program output data on term

Ludovic Pouzenc bugreports at pouzenc.fr
Sun May 29 11:01:59 BST 2022


Package: gnome-terminal
Version: 3.44.0-1
Severity: normal
File: /usr/libexec/gnome-terminal-server
X-Debbugs-Cc: bugreports at pouzenc.fr

Dear Maintainer,

I see on debian 10, 11 and testing a potential security problem with
gnome-terminal-server. It makes IO on disk when some program output on terminal.

It uses deleted files in /tmp instead of no files or files in RAM in /run.

My use case is sysadmin a lot of machines, with sometimes confidential
data displayed on terminal. For me everything should be in RAM as
xterm does.

The simplest way to spot code path that seems to be bad for me is :
   * install debian 10, 11 or testing on a physical amd64 computer
   * open a gnome session with a normal user
   * open a gnome-terminal
   * wait until there is not significant activity on IO physical LED
   * start the following command : yes
   * terminal starts to scroll fast
   * IO LED should go to "solid on" now, because many IO
   * sudo apt install iotop strace
   * sudo iotop should display something like :

Total DISK READ:         0.00 B/s | Total DISK WRITE:         2.21 M/s
Current DISK READ:       0.00 B/s | Current DISK WRITE:     191.00 K/s
    TID  PRIO  USER     DISK READ  DISK WRITE  SWAPIN     IO>    COMMAND
   2260 be/4 lpouzenc    0.00 B/s  176.86 K/s  ?unavailable?  gnome-terminal-server
      1 be/4 root        0.00 B/s    0.00 B/s  ?unavailable?  init
      2 be/4 root        0.00 B/s    0.00 B/s  ?unavailable?  [kthreadd]

   * sudo strace -p2260 -fc # for 10 seconds or so
strace: Process 2260 attached with 4 threads
^Cstrace: Process 2260 detached
strace: Process 2315 detached
strace: Process 2316 detached
strace: Process 2327 detached
% time     seconds  usecs/call     calls    errors syscall
------ ----------- ----------- --------- --------- ----------------
 66,59    0,999115        1546       646           poll
 32,06    0,480939           4    100426         4 read
  0,31    0,004600           2      2156           pread64
  0,26    0,003925           4       915       593 recvmsg
  0,19    0,002921           1      2334           pwrite64
  0,16    0,002460           1      1898           ftruncate
  0,13    0,001926           6       312           write
  0,08    0,001240          10       116           fallocate
  0,07    0,001086           7       136        31 futex
  0,05    0,000774         774         1           restart_syscall
  0,04    0,000645          11        57           sendmsg
  0,04    0,000550           7        75           writev
  0,01    0,000109          13         8           ioctl
  0,00    0,000045           2        20           clock_nanosleep
------ ----------- ----------- --------- --------- ----------------
100,00    1,500335          13    109100       628 total

   * sudo strace -p2260 -fo /dev/shm/gts
   * less /dev/shm/gts
[...]
2260  write(14, "\r", 1)                = 1
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POLLIN|POLLPRI}, {fd=19, events=POLLIN|POLLPRI}], 6, 600) = 1 ([{fd=14, revents=POLLIN}])
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  read(14, "\0\r\n\33[?2004l\r", 8136) = 12
2260  read(14, 0x562c26142083, 8125)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POLLIN|POLLPRI}, {fd=19, events=POLLIN|POLLPRI}], 6, 10) = 1 ([{fd=4, revents=POLLIN}])
2260  read(4, "\2\0\0\0\0\0\0\0", 16)   = 8
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POLLIN|POLLPRI}, {fd=19, events=POLLIN|POLLPRI}], 6, 10) = 1 ([{fd=14, revents=POLLIN}])
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  read(14, "\0y\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny"..., 8125) = 1361
2260  read(14, "\0\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r"..., 6765) = 289
2260  read(14, "\0\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r"..., 6477) = 295
2260  read(14, "\0\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r"..., 6183) = 292
2260  read(14, "\0\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r"..., 5892) = 292
2260  read(14, "\0\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r"..., 5601) = 288
2260  read(14, "\0y\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny\r\ny"..., 5314) = 262
[...]

   * sudo lsof -np 2260 |  grep -v mem
lsof: WARNING: can't stat() fuse.gvfsd-fuse file system /run/user/1000/gvfs
      Output information may be incomplete.
lsof: WARNING: can't stat() fuse.portal file system /run/user/1000/doc
      Output information may be incomplete.
COMMAND    PID     USER   FD      TYPE             DEVICE SIZE/OFF    NODE NAME
gnome-ter 2260 lpouzenc  cwd       DIR               8,20     4096 3014658 /home/lpouzenc
gnome-ter 2260 lpouzenc  rtd       DIR               8,20     4096       2 /
gnome-ter 2260 lpouzenc  txt       REG               8,20   395968 1105162 /usr/libexec/gnome-terminal-server
gnome-ter 2260 lpouzenc  DEL       REG                0,1               13 /SYSV00000000
gnome-ter 2260 lpouzenc    0r      CHR                1,3      0t0       4 /dev/null
gnome-ter 2260 lpouzenc    1u     unix 0x000000003b37b6a7      0t0   25426 type=STREAM (CONNECTED)
gnome-ter 2260 lpouzenc    2u     unix 0x000000003b37b6a7      0t0   25426 type=STREAM (CONNECTED)
gnome-ter 2260 lpouzenc    3u     unix 0x0000000079cc544f      0t0   28206 type=STREAM (CONNECTED)
gnome-ter 2260 lpouzenc    4u  a_inode               0,14        0    8545 [eventfd:76]
gnome-ter 2260 lpouzenc    5u     unix 0x00000000b44afd39      0t0   25450 type=STREAM (CONNECTED)
gnome-ter 2260 lpouzenc    6u  a_inode               0,14        0    8545 [eventfd:77]
gnome-ter 2260 lpouzenc    7u  a_inode               0,14        0    8545 [eventfd:78]
gnome-ter 2260 lpouzenc    8u     unix 0x00000000c4fab42c      0t0   27266 type=STREAM (CONNECTED)
gnome-ter 2260 lpouzenc    9u  a_inode               0,14        0    8545 [eventfd:79]
gnome-ter 2260 lpouzenc   10u  a_inode               0,14        0    8545 [eventfd:82]
gnome-ter 2260 lpouzenc   11r  a_inode               0,14        0    8545 inotify
gnome-ter 2260 lpouzenc   12u     unix 0x000000004ea08462      0t0   52405 type=STREAM (CONNECTED)
gnome-ter 2260 lpouzenc   13u      CHR                5,2      0t0      85 /dev/ptmx
gnome-ter 2260 lpouzenc   14u      CHR                5,2      0t0      85 /dev/ptmx
gnome-ter 2260 lpouzenc   15u      REG               8,20    65536 2753222 /tmp/#2753222 (deleted)
gnome-ter 2260 lpouzenc   16u      REG               8,20   196608 2752545 /tmp/#2752545 (deleted)
gnome-ter 2260 lpouzenc   17u      REG               8,20   196608 2752546 /tmp/#2752546 (deleted)
gnome-ter 2260 lpouzenc   18u      REG               8,20    65536 2753227 /tmp/#2753227 (deleted)
gnome-ter 2260 lpouzenc   19u      CHR                5,2      0t0      85 /dev/ptmx
gnome-ter 2260 lpouzenc   20u      REG               8,20  1507328 2752519 /tmp/#2752519 (deleted)
gnome-ter 2260 lpouzenc   21u      REG               8,20   196608 2752522 /tmp/#2752522 (deleted)

    * grep -vF 'read(14' /dev/shm/gts | less
[...]
2260  write(14, "\r", 1)                = 1
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POLLIN|POLLPRI}, {fd=19, events=POLLIN|POLLPRI}], 6, 600) = 1 ([{fd=14, revents=POLLIN}])
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POLLIN|POLLPRI}, {fd=19, events=POLLIN|POLLPRI}], 6, 10) = 1 ([{fd=4, revents=POLLIN}])
2260  read(4, "\2\0\0\0\0\0\0\0", 16)   = 8
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}, {fd=13, events=POLLIN|POLLPRI}, {fd=14, events=POLLIN|POLLPRI}, {fd=19, events=POLLIN|POLLPRI}], 6, 10) = 1 ([{fd=14, revents=POLLIN}])
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  recvmsg(3, {msg_namelen=0}, 0)    = -1 EAGAIN (Ressource temporairement non disponible)
2260  poll([{fd=3, events=POLLIN}, {fd=4, events=POLLIN}, {fd=5, events=POLLIN}], 3, 0) = 1 ([{fd=4, revents=POLLIN}])
2260  read(4, "\3\0\0\0\0\0\0\0", 16)   = 8
2260  write(4, "\1\0\0\0\0\0\0\0", 8)   = 8
2260  pread64(17, "}\24\0\0\1\0\0\0,_\242\332_\r\325\214\277*\3;%Q\310_\3162\344.\222\212\340\247"..., 65536, 262144) = 65536
2260  pwrite64(17, "\305\25\0\0\1\0\0\0\7h\354\266[\236n\323\356\375\225\3076\225\346\243\240\235\240\321<\201\231\37"..., 5597, 0) = 5597
2260  ftruncate(18, 0)                  = 0
2260  pread64(17, "\200\24\0\0\1\0\0\0E%\243\2032x\30%\306\2636S\201\3673\360\213\210\v\263\324y\200."..., 65536, 327680) = 65536
2260  pwrite64(17, "\204\24\0\0\1\0\0\0\363)CS\371}\317ay\367\361\377\367\3V&z\6%vf*\311\222"..., 5276, 65536) = 5276
2260  pread64(17, "\203\24\0\0\1\0\0\09\205\225\336b\2\223\270@\00275\263\26\306t0\234\244\204e\206\266\221"..., 65536, 393216) = 65536
2260  pwrite64(17, "\206\24\0\0\1\0\0\0\304\273\35\267\234\245\255\224\t at w0Rn\324\335\205MGG.\360\262\363"..., 5278, 131072) = 5278
2260  pread64(17, "\305\25\0\0\1\0\0\0\7h\354\266[\236n\323\356\375\225\3076\225\346\243\240\235\240\321<\201\231\37"..., 65536, 0) = 65536
2260  ftruncate(17, 196608)             = 0
[...]


    * echo 'deb http://debug.mirrors.debian.org/debian-debug/ bookworm-debug main' | sudo tee /etc/apt/sources.list.d/dbgsym.list
    * sudo apt install gnome-terminal-dbgsym libvte*-dbgsym ddd
    * cd /tmp
    * apt source gnome-terminal
    * cd gnome-term*/src # there is some ../ is path from dbgsym
    * ddd /usr/libexec/gnome-terminal-server 2260
    * in gdb prompt
        * catch syscall pwrite64
	* cont
    * I have to redo that with libvte sources
    * cd /tmp
    * apt source libvte-2.91-0
    * cd vte2.91-0.68.0/src
    * ddd /usr/libexec/gnome-terminal-server 2260
    * in gdb prompt
        * catch syscall pwrite64
	* cont

../src/vtestream-file.h:258
static void
_file_write (int fd, const char *data, gsize len, gsize offset)
{
        gsize ret;
    
        if (G_UNLIKELY (fd == -1))
                return;
    
        while (len) {
-->             ret = pwrite (fd, data, len, offset);
[...]
}

(gdb) up
../src/vtestream-file.h:509

/*
 * offset is either within the stream (overwrite data), or at its head (append data).
 * data is at most VTE_SNAKE_BLOCKSIZE bytes large; if shorter then the remaining amount is skipped.
 * When reading back, that skipped area will contain garbage (e.g. when the FS doesn't support
 * punching holes), the caller needs to deal with it.
 *
 * When appending, the following state transfers can occur:
 * 1->2, 2->3.
 */
static void
_vte_snake_write (VteSnake *snake, gsize offset, const char *data, gsize len)
{
[...]
-->     _file_write (snake->fd, data, len, fd_offset);
}

    
(gdb) up
(gdb) up
(gdb) up
./src/ring.hh:151
        inline void append_row_record(RowRecord const* record,
                                      row_t position)
        {
-->             _vte_stream_append(m_row_stream,
                                   (char const*)record,
                                   sizeof(*record));
        }

(gdb) up
(gdb) up
(gdb) up
./src/ring.hh:254
static inline VteRowData *_vte_ring_insert (VteRing *ring, gulong position, guint8 bidi_flags) { return ring->insert(position, bidi_flags); }


(gdb) up
(gdb) up
(gdb) up
./src/vte.cc:2798
[...]
               } else {
                        /* Scroll up with history. */
                        m_screen->cursor.row++;
-->                     update_insert_delta();
                }
[...]


I think I can't go deeper, I don't know if vte is configurable to *not*
write his fd's to /tmp nor what those files are necessary at first place.

Some thing to check is where is the code that opens those /tmp files.

    * grep tmp vteutils.cc
        fd = open (g_get_tmp_dir (),
        /* Try again with g_file_open_tmp */
        fd = g_file_open_tmp ("vteXXXXXX", &file_name, NULL);
        /* Mark the tmpfile as no-cow on file systems that support it.

    * grep -RF _vte_mkstemp .
./vteutils.cc:_vte_mkstemp (void)
./vteutils.h:int _vte_mkstemp (void);
./vtestream-file.h:        snake->fd = _vte_mkstemp ();


-- System Information:
Debian Release: bookworm/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 5.17.0-1-amd64 (SMP w/12 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, TAINT_UNSIGNED_MODULE
Locale: LANG=fr_FR.UTF-8, LC_CTYPE=fr_FR.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)

Versions of packages gnome-terminal depends on:
ii  dbus-user-session [default-dbus-session-bus]  1.14.0-1
ii  dconf-gsettings-backend [gsettings-backend]   0.40.0-3
ii  gnome-terminal-data                           3.44.0-1
ii  gsettings-desktop-schemas                     42.0-1
ii  libatk1.0-0                                   2.38.0-1
ii  libc6                                         2.33-7
ii  libdconf1                                     0.40.0-3
ii  libgcc-s1                                     12.1.0-2
ii  libglib2.0-0                                  2.72.1-1
ii  libgtk-3-0                                    3.24.33-2
ii  libpango-1.0-0                                1.50.7+ds-1
ii  libstdc++6                                    12.1.0-2
ii  libuuid1                                      2.38-4
ii  libvte-2.91-0                                 0.68.0-1+b1
ii  libx11-6                                      2:1.7.5-1

Versions of packages gnome-terminal recommends:
ii  gvfs                               1.50.1-1
ii  nautilus-extension-gnome-terminal  3.44.0-1
ii  yelp                               42.1-1

gnome-terminal suggests no packages.

-- no debconf information



More information about the pkg-gnome-maintainers mailing list