1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-22 13:33:56 +03:00

Ensure kdbus isn't used (#3501)

Delete the dbus1 generator and some critical wiring. This prevents
kdbus from being loaded or detected. As such, it will never be used,
even if the user still has a useful kdbus module loaded on their system.

Sort of fixes #3480. Not really, but it's better than the current state.
This commit is contained in:
Dave Reisner 2016-06-10 09:50:16 -04:00 committed by Zbigniew Jędrzejewski-Szmek
parent 6564ab0512
commit 222953e87f
12 changed files with 21 additions and 468 deletions

View File

@ -2902,29 +2902,9 @@ systemd_gpt_auto_generator_CFLAGS = \
endif
# ------------------------------------------------------------------------------
systemgenerator_PROGRAMS += \
systemd-dbus1-generator
systemd_dbus1_generator_SOURCES = \
src/dbus1-generator/dbus1-generator.c
systemd_dbus1_generator_LDADD = \
libshared.la
dbus1-generator-install-hook:
$(AM_V_at)$(MKDIR_P) $(DESTDIR)$(usergeneratordir)
$(AM_V_RM)rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
$(AM_V_LN)$(LN_S) --relative -f $(DESTDIR)$(systemgeneratordir)/systemd-dbus1-generator $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
dbus1-generator-uninstall-hook:
rm -f $(DESTDIR)$(usergeneratordir)/systemd-dbus1-generator
dist_xinitrc_SCRIPTS = \
xorg/50-systemd-user.sh
INSTALL_EXEC_HOOKS += dbus1-generator-install-hook
UNINSTALL_EXEC_HOOKS += dbus1-generator-uninstall-hook
# ------------------------------------------------------------------------------
systemd_sysv_generator_SOURCES = \
src/sysv-generator/sysv-generator.c

View File

@ -55,19 +55,19 @@ fi
cd $oldpwd
if [ "x$1" = "xc" ]; then
$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
$topdir/configure CFLAGS='-g -O0 -ftrapv' $args
make clean
elif [ "x$1" = "xg" ]; then
$topdir/configure CFLAGS='-g -Og -ftrapv' --enable-kdbus $args
$topdir/configure CFLAGS='-g -Og -ftrapv' $args
make clean
elif [ "x$1" = "xa" ]; then
$topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' --enable-kdbus $args
$topdir/configure CFLAGS='-g -O0 -Wsuggest-attribute=pure -Wsuggest-attribute=const -ftrapv' $args
make clean
elif [ "x$1" = "xl" ]; then
$topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args
$topdir/configure CC=clang CFLAGS='-g -O0 -ftrapv' $args
make clean
elif [ "x$1" = "xs" ]; then
scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' --enable-kdbus $args
scan-build $topdir/configure CFLAGS='-std=gnu99 -g -O0 -ftrapv' $args
scan-build make
else
echo
@ -75,6 +75,6 @@ else
echo "Initialized build system. For a common configuration please run:"
echo "----------------------------------------------------------------"
echo
echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' --enable-kdbus $args"
echo "$topdir/configure CFLAGS='-g -O0 -ftrapv' $args"
echo
fi

View File

@ -1279,16 +1279,6 @@ AC_ARG_WITH(tpm-pcrindex,
AC_DEFINE_UNQUOTED(SD_TPM_PCR, [$SD_TPM_PCR], [TPM PCR register number to use])
# ------------------------------------------------------------------------------
have_kdbus=no
AC_ARG_ENABLE(kdbus, AS_HELP_STRING([--disable-kdbus], [do not connect to kdbus by default]))
if test "x$enable_kdbus" != "xno"; then
AC_DEFINE(ENABLE_KDBUS, 1, [Define if kdbus is to be connected to by default])
have_kdbus=yes
M4_DEFINES="$M4_DEFINES -DENABLE_KDBUS"
fi
AM_CONDITIONAL(ENABLE_KDBUS, [test "$have_kdbus" = "yes"])
# ------------------------------------------------------------------------------
AC_ARG_WITH(rc-local-script-path-start,
AS_HELP_STRING([--with-rc-local-script-path-start=PATH],

View File

@ -998,12 +998,7 @@ static int busname_get_timeout(Unit *u, usec_t *timeout) {
}
static bool busname_supported(void) {
static int supported = -1;
if (supported < 0)
supported = is_kdbus_available();
return supported;
return false;
}
static int busname_control_pid(Unit *u) {

View File

@ -64,9 +64,6 @@ int kmod_setup(void) {
/* this should never be a module */
{ "unix", "/proc/net/unix", true, true, NULL },
/* IPC is needed before we bring up any other services */
{ "kdbus", "/sys/fs/kdbus", false, false, is_kdbus_wanted },
#ifdef HAVE_LIBIPTC
/* netfilter is needed by networkd, nspawn among others, and cannot be autoloaded */
{ "ip_tables", "/proc/net/ip_tables_names", false, false, NULL },

View File

@ -814,28 +814,6 @@ static int manager_setup_cgroups_agent(Manager *m) {
return 0;
}
static int manager_setup_kdbus(Manager *m) {
_cleanup_free_ char *p = NULL;
assert(m);
if (m->test_run || m->kdbus_fd >= 0)
return 0;
if (!is_kdbus_available())
return -ESOCKTNOSUPPORT;
m->kdbus_fd = bus_kernel_create_bus(
MANAGER_IS_SYSTEM(m) ? "system" : "user",
MANAGER_IS_SYSTEM(m), &p);
if (m->kdbus_fd < 0)
return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m");
log_debug("Successfully set up kdbus on %s", p);
return 0;
}
static int manager_connect_bus(Manager *m, bool reexecuting) {
bool try_bus_connect;
@ -1244,7 +1222,6 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
/* We might have deserialized the kdbus control fd, but if we
* didn't, then let's create the bus now. */
manager_setup_kdbus(m);
manager_connect_bus(m, !!serialization);
bus_track_coldplug(m, &m->subscribed, &m->deserialized_subscribed);

View File

@ -108,8 +108,6 @@ static const MountPoint mount_table[] = {
{ "efivarfs", "/sys/firmware/efi/efivars", "efivarfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
is_efi_boot, MNT_NONE },
#endif
{ "kdbusfs", "/sys/fs/kdbus", "kdbusfs", NULL, MS_NOSUID|MS_NOEXEC|MS_NODEV,
is_kdbus_wanted, MNT_IN_CONTAINER },
};
/* These are API file systems that might be mounted by other software,

View File

@ -574,20 +574,9 @@ static int service_setup_bus_name(Service *s) {
if (!s->bus_name)
return 0;
if (is_kdbus_available()) {
const char *n;
n = strjoina(s->bus_name, ".busname");
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, n, NULL, true);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency to .busname unit: %m");
} else {
/* If kdbus is not available, we know the dbus socket is required, hence pull it in, and require it */
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
}
r = unit_add_dependency_by_name(UNIT(s), UNIT_REQUIRES, SPECIAL_DBUS_SOCKET, NULL, true);
if (r < 0)
return log_unit_error_errno(UNIT(s), r, "Failed to add dependency on " SPECIAL_DBUS_SOCKET ": %m");
/* Regardless if kdbus is used or not, we always want to be ordered against dbus.socket if both are in the transaction. */
r = unit_add_dependency_by_name(UNIT(s), UNIT_AFTER, SPECIAL_DBUS_SOCKET, NULL, true);

View File

@ -1,331 +0,0 @@
/***
This file is part of systemd.
Copyright 2013 Lennart Poettering
systemd is free software; you can redistribute it and/or modify it
under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
systemd is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
#include "alloc-util.h"
#include "bus-internal.h"
#include "bus-util.h"
#include "cgroup-util.h"
#include "conf-parser.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "fileio.h"
#include "mkdir.h"
#include "special.h"
#include "unit-name.h"
#include "util.h"
static const char *arg_dest_late = "/tmp", *arg_dest = "/tmp";
static int create_dbus_files(
const char *path,
const char *name,
const char *service,
const char *exec,
const char *user,
const char *type) {
_cleanup_free_ char *b = NULL, *s = NULL, *lnk = NULL;
_cleanup_fclose_ FILE *f = NULL;
int r;
assert(path);
assert(name);
assert(service || exec);
if (!service) {
_cleanup_free_ char *a = NULL;
s = strjoin("dbus-", name, ".service", NULL);
if (!s)
return log_oom();
a = strjoin(arg_dest_late, "/", s, NULL);
if (!a)
return log_oom();
f = fopen(a, "wxe");
if (!f)
return log_error_errno(errno, "Failed to create %s: %m", a);
fprintf(f,
"# Automatically generated by systemd-dbus1-generator\n\n"
"[Unit]\n"
"SourcePath=%s\n"
"Description=DBUS1: %s\n"
"Documentation=man:systemd-dbus1-generator(8)\n\n"
"[Service]\n"
"ExecStart=%s\n"
"Type=dbus\n"
"BusName=%s\n",
path,
name,
exec,
name);
if (user)
fprintf(f, "User=%s\n", user);
if (type) {
fprintf(f, "Environment=DBUS_STARTER_BUS_TYPE=%s\n", type);
if (streq(type, "system"))
fprintf(f, "Environment=DBUS_STARTER_ADDRESS=" DEFAULT_SYSTEM_BUS_ADDRESS "\n");
else if (streq(type, "session")) {
char *run;
run = getenv("XDG_RUNTIME_DIR");
if (!run) {
log_error("XDG_RUNTIME_DIR not set.");
return -EINVAL;
}
fprintf(f, "Environment=DBUS_STARTER_ADDRESS="KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT "\n",
getuid(), run);
}
}
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write %s: %m", a);
f = safe_fclose(f);
service = s;
}
b = strjoin(arg_dest_late, "/", name, ".busname", NULL);
if (!b)
return log_oom();
f = fopen(b, "wxe");
if (!f)
return log_error_errno(errno, "Failed to create %s: %m", b);
fprintf(f,
"# Automatically generated by systemd-dbus1-generator\n\n"
"[Unit]\n"
"SourcePath=%s\n"
"Description=DBUS1: %s\n"
"Documentation=man:systemd-dbus1-generator(8)\n\n"
"[BusName]\n"
"Name=%s\n"
"Service=%s\n"
"AllowWorld=talk\n",
path,
name,
name,
service);
r = fflush_and_check(f);
if (r < 0)
return log_error_errno(r, "Failed to write %s: %m", b);
lnk = strjoin(arg_dest_late, "/" SPECIAL_BUSNAMES_TARGET ".wants/", name, ".busname", NULL);
if (!lnk)
return log_oom();
mkdir_parents_label(lnk, 0755);
if (symlink(b, lnk))
return log_error_errno(errno, "Failed to create symlink %s: %m", lnk);
return 0;
}
static int add_dbus(const char *path, const char *fname, const char *type) {
_cleanup_free_ char *name = NULL, *exec = NULL, *user = NULL, *service = NULL;
const ConfigTableItem table[] = {
{ "D-BUS Service", "Name", config_parse_string, 0, &name },
{ "D-BUS Service", "Exec", config_parse_string, 0, &exec },
{ "D-BUS Service", "User", config_parse_string, 0, &user },
{ "D-BUS Service", "SystemdService", config_parse_string, 0, &service },
{ },
};
char *p;
int r;
assert(path);
assert(fname);
p = strjoina(path, "/", fname);
r = config_parse(NULL, p, NULL,
"D-BUS Service\0",
config_item_table_lookup, table,
true, false, true, NULL);
if (r < 0)
return r;
if (!name) {
log_warning("Activation file %s lacks name setting, ignoring.", p);
return 0;
}
if (!service_name_is_valid(name)) {
log_warning("Bus service name %s is not valid, ignoring.", name);
return 0;
}
if (streq(name, "org.freedesktop.systemd1")) {
log_debug("Skipping %s, identified as systemd.", p);
return 0;
}
if (service) {
if (!unit_name_is_valid(service, UNIT_NAME_PLAIN|UNIT_NAME_INSTANCE)) {
log_warning("Unit name %s is not valid, ignoring.", service);
return 0;
}
if (!endswith(service, ".service")) {
log_warning("Bus names can only activate services, ignoring %s.", p);
return 0;
}
} else {
if (streq(exec, "/bin/false") || !exec) {
log_warning("Neither service name nor binary path specified, ignoring %s.", p);
return 0;
}
if (exec[0] != '/') {
log_warning("Exec= in %s does not start with an absolute path, ignoring.", p);
return 0;
}
}
return create_dbus_files(p, name, service, exec, user, type);
}
static int parse_dbus_fragments(const char *path, const char *type) {
_cleanup_closedir_ DIR *d = NULL;
struct dirent *de;
int r;
assert(path);
assert(type);
d = opendir(path);
if (!d) {
if (errno == -ENOENT)
return 0;
return log_error_errno(errno, "Failed to enumerate D-Bus activated services: %m");
}
r = 0;
FOREACH_DIRENT(de, d, goto fail) {
int q;
if (!endswith(de->d_name, ".service"))
continue;
q = add_dbus(path, de->d_name, type);
if (q < 0)
r = q;
}
return r;
fail:
return log_error_errno(errno, "Failed to read D-Bus services directory: %m");
}
static int link_busnames_target(const char *units) {
const char *f, *t;
f = strjoina(units, "/" SPECIAL_BUSNAMES_TARGET);
t = strjoina(arg_dest, "/" SPECIAL_BASIC_TARGET ".wants/" SPECIAL_BUSNAMES_TARGET);
mkdir_parents_label(t, 0755);
if (symlink(f, t) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", t);
return 0;
}
static int link_compatibility(const char *units) {
const char *f, *t;
f = strjoina(units, "/systemd-bus-proxyd.socket");
t = strjoina(arg_dest, "/" SPECIAL_DBUS_SOCKET);
mkdir_parents_label(t, 0755);
if (symlink(f, t) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", t);
f = strjoina(units, "/systemd-bus-proxyd.socket");
t = strjoina(arg_dest, "/" SPECIAL_SOCKETS_TARGET ".wants/systemd-bus-proxyd.socket");
mkdir_parents_label(t, 0755);
if (symlink(f, t) < 0)
return log_error_errno(errno, "Failed to create symlink %s: %m", t);
t = strjoina(arg_dest, "/" SPECIAL_DBUS_SERVICE);
if (symlink("/dev/null", t) < 0)
return log_error_errno(errno, "Failed to mask %s: %m", t);
return 0;
}
int main(int argc, char *argv[]) {
const char *path, *type, *units;
int r, q;
if (argc > 1 && argc != 4) {
log_error("This program takes three or no arguments.");
return EXIT_FAILURE;
}
if (argc > 1) {
arg_dest = argv[1];
arg_dest_late = argv[3];
}
log_set_target(LOG_TARGET_SAFE);
log_parse_environment();
log_open();
umask(0022);
if (!is_kdbus_available())
return 0;
r = cg_pid_get_owner_uid(0, NULL);
if (r >= 0) {
path = "/usr/share/dbus-1/services";
type = "session";
units = USER_DATA_UNIT_PATH;
} else if (r == -ENXIO) {
path = "/usr/share/dbus-1/system-services";
type = "system";
units = SYSTEM_DATA_UNIT_PATH;
} else
return log_error_errno(r, "Failed to determine whether we are running as user or system instance: %m");
r = parse_dbus_fragments(path, type);
/* FIXME: One day this should just be pulled in statically from basic.target */
q = link_busnames_target(units);
if (q < 0)
r = q;
q = link_compatibility(units);
if (q < 0)
r = q;
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}

View File

@ -182,25 +182,20 @@ static int export_legacy_dbus_address(
_cleanup_free_ char *s = NULL;
int r = PAM_BUF_ERR;
if (is_kdbus_available()) {
if (asprintf(&s, KERNEL_USER_BUS_ADDRESS_FMT ";" UNIX_USER_BUS_ADDRESS_FMT, uid, runtime) < 0)
goto error;
} else {
/* FIXME: We *really* should move the access() check into the
* daemons that spawn dbus-daemon, instead of forcing
* DBUS_SESSION_BUS_ADDRESS= here. */
/* FIXME: We *really* should move the access() check into the
* daemons that spawn dbus-daemon, instead of forcing
* DBUS_SESSION_BUS_ADDRESS= here. */
s = strjoin(runtime, "/bus", NULL);
if (!s)
goto error;
s = strjoin(runtime, "/bus", NULL);
if (!s)
goto error;
if (access(s, F_OK) < 0)
return PAM_SUCCESS;
if (access(s, F_OK) < 0)
return PAM_SUCCESS;
s = mfree(s);
if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, runtime) < 0)
goto error;
}
s = mfree(s);
if (asprintf(&s, UNIX_USER_BUS_ADDRESS_FMT, runtime) < 0)
goto error;
r = pam_misc_setenv(handle, "DBUS_SESSION_BUS_ADDRESS", s, 0);
if (r != PAM_SUCCESS)

View File

@ -1505,40 +1505,6 @@ int bus_path_decode_unique(const char *path, const char *prefix, char **ret_send
return 1;
}
bool is_kdbus_wanted(void) {
_cleanup_free_ char *value = NULL;
#ifdef ENABLE_KDBUS
const bool configured = true;
#else
const bool configured = false;
#endif
int r;
if (get_proc_cmdline_key("kdbus", NULL) > 0)
return true;
r = get_proc_cmdline_key("kdbus=", &value);
if (r <= 0)
return configured;
return parse_boolean(value) == 1;
}
bool is_kdbus_available(void) {
_cleanup_close_ int fd = -1;
struct kdbus_cmd cmd = { .size = sizeof(cmd), .flags = KDBUS_FLAG_NEGOTIATE };
if (!is_kdbus_wanted())
return false;
fd = open("/sys/fs/kdbus/control", O_RDWR | O_CLOEXEC | O_NONBLOCK | O_NOCTTY);
if (fd < 0)
return false;
return ioctl(fd, KDBUS_CMD_BUS_MAKE, &cmd) >= 0;
}
int bus_property_get_rlimit(
sd_bus *bus,
const char *path,

View File

@ -157,7 +157,4 @@ int bus_log_create_error(int r);
int bus_path_encode_unique(sd_bus *b, const char *prefix, const char *sender_id, const char *external_id, char **ret_path);
int bus_path_decode_unique(const char *path, const char *prefix, char **ret_sender, char **ret_external);
bool is_kdbus_wanted(void);
bool is_kdbus_available(void);
int bus_property_get_rlimit(sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *error);