Package: xscreensaver
Version: 6.06+dfsg1-3+deb12u1
Severity: normal
X-Debbugs-Cc: [email protected]

Dear Maintainer,

I have found that if ~/.xscreensaver is a symbolic link to another file, running
xscreensaver-settings and changing one or more settings before exiting will
cause it to remove the symlink entirely and write a new, regular (non-symlink)
~/.xscreensaver file, rather than resolving the symlink and writing to its
target as one would expect.

Steps to reproduce:
1. Create any valid .xscreensaver file, as by invoking xscreensaver-settings
2. `mv .xscreensaver xscreensaver-target`
3. `ln -s xscreensaver-target .xscreensaver`
4. Run xscreensaver-settings, change a setting (e.g. increase the "Blank After"
   time by 1 minute), and close the application

Expected behavior:
- .xscreensaver is still a symlink to xscreensaver-target
- xscreensaver-target has been updated with the new settings

Observed behavior:
- .xscreensaver is now a regular file with the new settings
- xscreensaver-target is unchanged

The strange thing is that the xscreensaver code purports to already handle this
case, via the chase_symlinks function in driver/prefsw.c, and none of the Debian
patches for this package affect that part of the code.  Additionally, I have
locally built the Debian version of 6.06 with all patches applied, and running
that version of xscreensaver-settings works as expected -- the new settings are
written to the symlink target properly.  Therefore I conclude this is not a bug
in the upstream code itself, but in the Debian-provided binary.

The portions of driver/prefsw.c that appear to be relevant here are:

    /* don't use realpath() on fedora system */
    #ifdef _FORTIFY_SOURCE
    # undef HAVE_REALPATH
    #endif

and

    static char *
    chase_symlinks (const char *file)
    {
    # ifdef HAVE_REALPATH
      if (file)
        {
    # ifndef PATH_MAX
    #  ifdef MAXPATHLEN
    #   define PATH_MAX MAXPATHLEN
    #  else
    #   define PATH_MAX 2048
    #  endif
    # endif
          char buf[PATH_MAX];
          if (realpath (file, buf))
            return strdup (buf);

    /*      sprintf (buf, "%.100s: realpath %.200s", blurb(), file);
          perror(buf);*/
        }
    # endif /* HAVE_REALPATH */
      return 0;
    }

I hazard a guess that HAVE_REALPATH is not being set by the configure script, or
possibly _FORTIFY_SOURCE is being set somewhere, as either of those cases would
cause the observed behavior.

Additional supporting observations:

- `objdump -T /usr/bin/xscreensaver-settings` does not mention realpath(3) at
  all, nor does the 6.09+dfsg1-1 binary from testing, implying that it was
  ifdef'd out at compile time.  In contrast, my (working) locally-built binary
  does reference it:

      $ objdump -T driver/xscreensaver-settings | grep realpath
      0000000000000000      DF *UND*  0000000000000000 (GLIBC_2.3)  realpath

- `strace /usr/bin/xscreensaver-settings` shows no sign of readlink(2) being
  called when performing the reproducer steps above, whereas my locally-built
  binary does:

      $ strace driver/xscreensaver-settings 2>&1 | grep readlink
      readlink("/home", 0x7ffecdde1c90, 1023) = -1 EINVAL (Invalid argument)
      readlink("/home/wisnij", 0x7ffecdde1c90, 1023) = -1 EINVAL (Invalid 
argument)
      readlink("/home/wisnij/.xscreensaver", 
"code/dotfiles/linux/.xscreensave"..., 1023) = 33
      [etc...]


-- System Information:
Debian Release: 12.10
  APT prefers stable-updates
  APT policy: (500, 'stable-updates'), (500, 'stable-security'), (500, 'stable')
Architecture: amd64 (x86_64)
Foreign Architectures: i386

Kernel: Linux 6.1.0-33-amd64 (SMP w/20 CPU threads; PREEMPT)
Kernel taint flags: TAINT_PROPRIETARY_MODULE, TAINT_OOT_MODULE, 
TAINT_UNSIGNED_MODULE
Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8), LANGUAGE not set
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages xscreensaver depends on:
ii  init-system-helpers  1.65.2
ii  libatk1.0-0          2.46.0-5
ii  libc6                2.36-9+deb12u10
ii  libcrypt1            1:4.4.33-2
ii  libglib2.0-0         2.74.6-2+deb12u5
ii  libgtk-3-0           3.24.38-2~deb12u3
ii  libpam0g             1.5.2-6+deb12u1
ii  libsystemd0          252.36-1~deb12u1
ii  libx11-6             2:1.8.4-2+deb12u2
ii  libxext6             2:1.3.4-1+b1
ii  libxft2              2.3.6-1
ii  libxi6               2:1.8-1+b1
ii  libxinerama1         2:1.1.4-3
ii  libxml2              2.9.14+dfsg-1.3~deb12u1
ii  libxrandr2           2:1.5.2-2+b1
ii  libxt6               1:1.2.1-1.1
ii  libxxf86vm1          1:1.1.4-1+b2
ii  xscreensaver-data    6.06+dfsg1-3+deb12u1

Versions of packages xscreensaver recommends:
ii  fonts-urw-base35      20200910-7
ii  libjpeg-turbo-progs   1:2.1.5-2
ii  perl                  5.36.0-7+deb12u2
ii  wamerican [wordlist]  2020.12.07-2
ii  xfonts-100dpi         1:1.0.5

Versions of packages xscreensaver suggests:
ii  chromium [www-browser]     135.0.7049.95-1~deb12u1
ii  firefox-esr [www-browser]  128.9.0esr-1~deb12u1
ii  fortune-mod [fortune]      1:1.99.1-7.3
pn  gdm3 | kdm-gdmcompat       <none>
ii  konqueror [www-browser]    4:22.12.3-1
ii  lynx [www-browser]         2.9.0dev.12-1
pn  qcam | streamer            <none>
ii  w3m [www-browser]          0.5.3+git20230121-2
pn  xdaliclock                 <none>
pn  xfishtank                  <none>
pn  xscreensaver-data-extra    <none>
ii  xscreensaver-gl            6.06+dfsg1-3+deb12u1
pn  xscreensaver-gl-extra      <none>

-- no debconf information

Reply via email to