diff --git a/SOURCES/dbus-1.10.24-dbus-launch-chdir.patch b/SOURCES/dbus-1.10.24-dbus-launch-chdir.patch new file mode 100644 index 0000000..adafa1a --- /dev/null +++ b/SOURCES/dbus-1.10.24-dbus-launch-chdir.patch @@ -0,0 +1,501 @@ +From dc2074588d3e7b5a216cb8c0b82094157c3cf773 Mon Sep 17 00:00:00 2001 +From: David King +Date: Mon, 25 Jun 2018 14:46:14 -0400 +Subject: [PATCH] daemon: use HOME as the working directory + +Session buses started as part of a systemd --user session are launched +with the current working directory being the home directory of the user. +Applications which are launched via dbus activation inherit the working +directory from the session bus dbus-daemon. + +When dbus-launch is used to start dbus-daemon, as is commonly the case +with a session manager such as gnome-session, this leads to applications +having a default working directory of "/", which is undesirable (as an +example, the default directory in a GTK+ save dialog becomes "/"). + +As an improvement, make dbus-launch use the value of the environment +variable HOME, if it is set, as the current working directory. + +Signed-off-by: David King +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=106987 +Bug-RedHat: https://bugzilla.redhat.com/show_bug.cgi?id=1470310 +--- + bus/bus.c | 9 +++++++++ + dbus/dbus-sysdeps-util-unix.c | 8 +++++--- + dbus/dbus-sysdeps-util-win.c | 2 ++ + dbus/dbus-sysdeps.h | 1 + + doc/dbus-launch.1.xml.in | 4 ++++ + tools/dbus-launch.c | 22 ++++++++++++++-------- + 6 files changed, 35 insertions(+), 11 deletions(-) + +diff --git a/bus/bus.c b/bus/bus.c +index f788e677..da2b2c1f 100644 +--- a/bus/bus.c ++++ b/bus/bus.c +@@ -870,63 +870,72 @@ bus_context_new (const DBusString *config_file, + + context->matchmaker = bus_matchmaker_new (); + if (context->matchmaker == NULL) + { + BUS_SET_OOM (error); + goto failed; + } + + /* check user before we fork */ + if (context->user != NULL) + { + if (!_dbus_verify_daemon_user (context->user)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Could not get UID and GID for username \"%s\"", + context->user); + goto failed; + } + } + + /* Now become a daemon if appropriate and write out pid file in any case */ + { + DBusString u; + + if (context->pidfile) + _dbus_string_init_const (&u, context->pidfile); + + if (((flags & BUS_CONTEXT_FLAG_FORK_NEVER) == 0 && context->fork) || + (flags & BUS_CONTEXT_FLAG_FORK_ALWAYS)) + { ++ const char *working_dir = NULL; ++ + _dbus_verbose ("Forking and becoming daemon\n"); + ++ if (context->type != NULL && strcmp (context->type, "session") == 0) ++ working_dir = _dbus_getenv ("HOME"); ++ ++ if (working_dir == NULL) ++ working_dir = "/"; ++ + if (!_dbus_become_daemon (context->pidfile ? &u : NULL, ++ working_dir, + print_pid_pipe, + error, + context->keep_umask)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + } + else + { + _dbus_verbose ("Fork not requested\n"); + + /* Need to write PID file and to PID pipe for ourselves, + * not for the child process. This is a no-op if the pidfile + * is NULL and print_pid_pipe is NULL. + */ + if (!_dbus_write_pid_to_file_and_pipe (context->pidfile ? &u : NULL, + print_pid_pipe, + _dbus_getpid (), + error)) + { + _DBUS_ASSERT_ERROR_IS_SET (error); + goto failed; + } + } + } + + if (print_pid_pipe && _dbus_pipe_is_valid (print_pid_pipe) && + !_dbus_pipe_is_stdout_or_stderr (print_pid_pipe)) + _dbus_pipe_close (print_pid_pipe, NULL); +diff --git a/dbus/dbus-sysdeps-util-unix.c b/dbus/dbus-sysdeps-util-unix.c +index 9b724cc9..30bb1441 100644 +--- a/dbus/dbus-sysdeps-util-unix.c ++++ b/dbus/dbus-sysdeps-util-unix.c +@@ -49,82 +49,84 @@ + #include + #include + #include + + #ifdef HAVE_SYSLOG_H + #include + #endif + + #ifdef HAVE_SYS_SYSLIMITS_H + #include + #endif + + #ifdef HAVE_SYSTEMD + #include + #endif + + #ifndef O_BINARY + #define O_BINARY 0 + #endif + + /** + * @addtogroup DBusInternalsUtils + * @{ + */ + + + /** + * Does the chdir, fork, setsid, etc. to become a daemon process. + * + * @param pidfile #NULL, or pidfile to create ++ * @param working_dir directory to chdir to + * @param print_pid_pipe pipe to print daemon's pid to, or -1 for none + * @param error return location for errors + * @param keep_umask #TRUE to keep the original umask + * @returns #FALSE on failure + */ + dbus_bool_t + _dbus_become_daemon (const DBusString *pidfile, ++ const char *working_dir, + DBusPipe *print_pid_pipe, + DBusError *error, + dbus_bool_t keep_umask) + { + const char *s; + pid_t child_pid; + int dev_null_fd; + + _dbus_verbose ("Becoming a daemon...\n"); + +- _dbus_verbose ("chdir to /\n"); +- if (chdir ("/") < 0) ++ _dbus_verbose ("chdir to %s\n", working_dir); ++ if (chdir (working_dir) < 0) + { + dbus_set_error (error, DBUS_ERROR_FAILED, +- "Could not chdir() to root directory"); ++ "Could not chdir() to working directory (%s)", working_dir); + return FALSE; + } + + _dbus_verbose ("forking...\n"); + switch ((child_pid = fork ())) + { + case -1: + _dbus_verbose ("fork failed\n"); + dbus_set_error (error, _dbus_error_from_errno (errno), + "Failed to fork daemon: %s", _dbus_strerror (errno)); + return FALSE; + break; + + case 0: + _dbus_verbose ("in child, closing std file descriptors\n"); + + /* silently ignore failures here, if someone + * doesn't have /dev/null we may as well try + * to continue anyhow + */ + + dev_null_fd = open ("/dev/null", O_RDWR); + if (dev_null_fd >= 0) + { + dup2 (dev_null_fd, 0); + dup2 (dev_null_fd, 1); + + s = _dbus_getenv ("DBUS_DEBUG_OUTPUT"); + if (s == NULL || *s == '\0') + dup2 (dev_null_fd, 2); +diff --git a/dbus/dbus-sysdeps-util-win.c b/dbus/dbus-sysdeps-util-win.c +index 3b754dbf..bfc1cb90 100644 +--- a/dbus/dbus-sysdeps-util-win.c ++++ b/dbus/dbus-sysdeps-util-win.c +@@ -27,67 +27,69 @@ + #define STRSAFE_NO_DEPRECATE + + #include "dbus-sysdeps.h" + #include "dbus-internals.h" + #include "dbus-protocol.h" + #include "dbus-string.h" + #include "dbus-sysdeps.h" + #include "dbus-sysdeps-win.h" + #include "dbus-sockets-win.h" + #include "dbus-memory.h" + #include "dbus-pipe.h" + + #include + #include + #if HAVE_ERRNO_H + #include + #endif + #include // WSA error codes + + #ifndef DBUS_WINCE + #include + #include + #include + #endif + + + /** + * Does the chdir, fork, setsid, etc. to become a daemon process. + * + * @param pidfile #NULL, or pidfile to create ++ * @param working_dir directory to chdir to + * @param print_pid_pipe file descriptor to print daemon's pid to, or -1 for none + * @param error return location for errors + * @param keep_umask #TRUE to keep the original umask + * @returns #FALSE on failure + */ + dbus_bool_t + _dbus_become_daemon (const DBusString *pidfile, ++ const char *working_dir, + DBusPipe *print_pid_pipe, + DBusError *error, + dbus_bool_t keep_umask) + { + dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, + "Cannot daemonize on Windows"); + return FALSE; + } + + /** + * Creates a file containing the process ID. + * + * @param filename the filename to write to + * @param pid our process ID + * @param error return location for errors + * @returns #FALSE on failure + */ + static dbus_bool_t + _dbus_write_pid_file (const DBusString *filename, + unsigned long pid, + DBusError *error) + { + const char *cfilename; + HANDLE hnd; + char pidstr[20]; + int total; + int bytes_to_write; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + +diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h +index 0ee45c97..e569b545 100644 +--- a/dbus/dbus-sysdeps.h ++++ b/dbus/dbus-sysdeps.h +@@ -498,60 +498,61 @@ int _dbus_printf_string_upper_bound (const char *format, + va_list args); + + + /** + * Portable struct with stat() results + */ + typedef struct + { + unsigned long mode; /**< File mode */ + unsigned long nlink; /**< Number of hard links */ + dbus_uid_t uid; /**< User owning file */ + dbus_gid_t gid; /**< Group owning file */ + unsigned long size; /**< Size of file */ + unsigned long atime; /**< Access time */ + unsigned long mtime; /**< Modify time */ + unsigned long ctime; /**< Creation time */ + } DBusStat; + + dbus_bool_t _dbus_stat (const DBusString *filename, + DBusStat *statbuf, + DBusError *error); + DBUS_PRIVATE_EXPORT + dbus_bool_t _dbus_socketpair (DBusSocket *fd1, + DBusSocket *fd2, + dbus_bool_t blocking, + DBusError *error); + + void _dbus_print_backtrace (void); + + dbus_bool_t _dbus_become_daemon (const DBusString *pidfile, ++ const char *working_dir, + DBusPipe *print_pid_pipe, + DBusError *error, + dbus_bool_t keep_umask); + + dbus_bool_t _dbus_verify_daemon_user (const char *user); + dbus_bool_t _dbus_change_to_daemon_user (const char *user, + DBusError *error); + + dbus_bool_t _dbus_write_pid_to_file_and_pipe (const DBusString *pidfile, + DBusPipe *print_pid_pipe, + dbus_pid_t pid_to_write, + DBusError *error); + + dbus_bool_t _dbus_command_for_pid (unsigned long pid, + DBusString *str, + int max_len, + DBusError *error); + + /** A UNIX signal handler */ + typedef void (* DBusSignalHandler) (int sig); + + void _dbus_set_signal_handler (int sig, + DBusSignalHandler handler); + + dbus_bool_t _dbus_user_at_console (const char *username, + DBusError *error); + + void _dbus_init_system_log (dbus_bool_t is_daemon); + + typedef enum { +diff --git a/doc/dbus-launch.1.xml.in b/doc/dbus-launch.1.xml.in +index 5135d9ca..606c65be 100644 +--- a/doc/dbus-launch.1.xml.in ++++ b/doc/dbus-launch.1.xml.in +@@ -23,60 +23,64 @@ + dbus-launch + --version + --help + --sh-syntax + --csh-syntax + --auto-syntax + --binary-syntax + --close-stderr + --exit-with-session + --autolaunch=MACHINEID + --config-file=FILENAME + PROGRAM + ARGS + + + + + + DESCRIPTION + The dbus-launch command is used to start a session bus + instance of dbus-daemon from a shell script. + It would normally be called from a user's login + scripts. Unlike the daemon itself, dbus-launch exits, so + backticks or the $() construct can be used to read information from + dbus-launch. + + With no arguments, dbus-launch will launch a session bus + instance and print the address and PID of that instance to standard + output. + ++If the environment variable HOME is set, it is used as the current ++working directory. Otherwise, the root directory (/) is ++used. ++ + You may specify a program to be run; in this case, dbus-launch + will launch a session bus instance, set the appropriate environment + variables so the specified program can find the bus, and then execute the + specified program, with the specified arguments. See below for + examples. + + If you launch a program, dbus-launch will not print the + information about the new bus to standard output. + + When dbus-launch prints bus information to standard output, by + default it is in a simple key-value pairs format. However, you may + request several alternate syntaxes using the --sh-syntax, --csh-syntax, + --binary-syntax, or + --auto-syntax options. Several of these cause dbus-launch to emit shell code + to set up the environment. + + With the --auto-syntax option, dbus-launch looks at the value + of the SHELL environment variable to determine which shell syntax + should be used. If SHELL ends in "csh", then csh-compatible code is + emitted; otherwise Bourne shell code is emitted. Instead of passing + --auto-syntax, you may explicitly specify a particular one by using + --sh-syntax for Bourne syntax, or --csh-syntax for csh syntax. + In scripts, it's more robust to avoid --auto-syntax and you hopefully + know which shell your script is written in. + + + See http://www.freedesktop.org/software/dbus/ for more information + about D-Bus. See also the man page for dbus-daemon. + + +diff --git a/tools/dbus-launch.c b/tools/dbus-launch.c +index 80e4a241..a956684c 100644 +--- a/tools/dbus-launch.c ++++ b/tools/dbus-launch.c +@@ -592,71 +592,77 @@ kill_bus_when_session_ends (void) + /* This shouldn't happen I don't think; to avoid + * spinning on the fd forever we exit. + */ + fprintf (stderr, "dbus-launch: error reading from stdin: %s\n", + strerror (errno)); + kill_bus_and_exit (0); + } + } + else if (FD_ISSET (tty_fd, &err_set)) + { + verbose ("TTY has error condition\n"); + + kill_bus_and_exit (0); + } + } + } + } + + static void + babysit (int exit_with_session, + pid_t child_pid, + int read_bus_pid_fd) /* read pid from here */ + { + int ret; + int dev_null_fd; + const char *s; + + verbose ("babysitting, exit_with_session = %d, child_pid = %ld, read_bus_pid_fd = %d\n", + exit_with_session, (long) child_pid, read_bus_pid_fd); + +- /* We chdir ("/") since we are persistent and daemon-like, and fork +- * again so dbus-launch can reap the parent. However, we don't +- * setsid() or close fd 0 because the idea is to remain attached +- * to the tty and the X server in order to kill the message bus +- * when the session ends. ++ /* We chdir () since we are persistent and daemon-like, either to $HOME ++ * to match the behaviour of a session bus started by systemd --user, or ++ * otherwise "/". We fork again so dbus-launch can reap the parent. ++ * However, we don't setsid() or close fd 0 because the idea is to ++ * remain attached to the tty and the X server in order to kill the ++ * message bus when the session ends. + */ + +- if (chdir ("/") < 0) ++ s = getenv ("HOME"); ++ ++ if (s == NULL || *s == '\0') ++ s = "/"; ++ ++ if (chdir (s) < 0) + { +- fprintf (stderr, "Could not change to root directory: %s\n", +- strerror (errno)); ++ fprintf (stderr, "Could not change to working directory \"%s\": %s\n", ++ s, strerror (errno)); + exit (1); + } + + /* Close stdout/stderr so we don't block an "eval" or otherwise + * lock up. stdout is still chaining through to dbus-launch + * and in turn to the parent shell. + */ + dev_null_fd = open ("/dev/null", O_RDWR); + if (dev_null_fd >= 0) + { + if (!exit_with_session) + dup2 (dev_null_fd, 0); + dup2 (dev_null_fd, 1); + s = getenv ("DBUS_DEBUG_OUTPUT"); + if (s == NULL || *s == '\0') + dup2 (dev_null_fd, 2); + close (dev_null_fd); + } + else + { + fprintf (stderr, "Failed to open /dev/null: %s\n", + strerror (errno)); + /* continue, why not */ + } + + ret = fork (); + + if (ret < 0) + { + fprintf (stderr, "fork() failed in babysitter: %s\n", +-- +2.17.1 + diff --git a/SPECS/dbus.spec b/SPECS/dbus.spec index 886583d..3e328ad 100644 --- a/SPECS/dbus.spec +++ b/SPECS/dbus.spec @@ -18,7 +18,7 @@ Name: dbus Epoch: 1 Version: 1.10.24 -Release: 7%{?dist} +Release: 12%{?dist} Summary: D-BUS message bus Group: System Environment/Libraries @@ -42,6 +42,8 @@ Patch3: dbus-1.6.12-avoid-selinux-context-translation.patch Patch4: dbus-1.10.24-dbus-send-man-page-typo.patch # https://bugzilla.redhat.com/show_bug.cgi?id=1529044 Patch5: 0001-bus-raise-fd-limits-before-dropping-privs.patch +# https://bugzilla.redhat.com/show_bug.cgi?id=1470310 +Patch6: dbus-1.10.24-dbus-launch-chdir.patch BuildRequires: libtool BuildRequires: expat-devel >= %{expat_version} @@ -142,6 +144,7 @@ in this separate package so server systems need not install X. %patch3 -p1 %patch4 -p1 %patch5 -p1 +%patch6 -p1 %build # Avoid rpath. @@ -184,6 +187,7 @@ install -Dp -m755 %{SOURCE1} %{buildroot}%{_sysconfdir}/X11/xinit/xinitrc.d/00-s install --directory %{buildroot}%{_sysconfdir}/dbus-1/session.d install --directory %{buildroot}%{_sysconfdir}/dbus-1/system.d +# This directory is a somewhat unofficial downstream addition install --directory %{buildroot}%{_datadir}/dbus-1/interfaces # Make sure that when somebody asks for D-Bus under the name of the @@ -369,6 +373,12 @@ popd %{_includedir}/* %changelog +* Tue Aug 21 2018 Ray Strode - 1:1.10.24-12 +- Use HOME as dbus-daemon --session working directory (#1470310) + +* Fri Jun 22 2018 David King - 1:1.10.24-11 +- Use HOME as dbus-launch working directory (#1470310) + * Thu Feb 15 2018 David King - 1:1.10.24-7 - Improve permissions on /run/dbus (#1510773)