From 648b122045182a1ac19d1622817e2a350beb0354 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Feb 2016 22:54:33 +0100 Subject: update TODO --- TODO | 3 +++ 1 file changed, 3 insertions(+) diff --git a/TODO b/TODO index 1d9a6a99a7..7437938bf0 100644 --- a/TODO +++ b/TODO @@ -33,6 +33,9 @@ Janitorial Clean-ups: Features: +* delay activation of logind until somebody logs in, or when /dev/tty0 pulls it + in or lingering is on (so that containers don't bother with it until PAM is used). also exit-on-idle + * cache sd_event_now() result from before the first iteration... * remove Capabilities=, after all AmbientCapabilities= and CapabilityBoundingSet= should be enough. -- cgit v1.2.3-54-g00ecf From cf3bdcfeba48ffef71f1f59e092c4fb9275dcb3a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Feb 2016 22:58:41 +0100 Subject: nss-mymachines: never resolve unmapped UIDs/GIDs Don't ever permit successful user or group lookups if no UID/GID mapping is actually applied. THis way, we can be sure that nss-mymachines cannot be used to insert invalid cache entries into nscd's cache. https://bugzilla.redhat.com/show_bug.cgi?id=1285339 --- src/nss-mymachines/nss-mymachines.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/src/nss-mymachines/nss-mymachines.c b/src/nss-mymachines/nss-mymachines.c index 78133a39bf..1582d702f8 100644 --- a/src/nss-mymachines/nss-mymachines.c +++ b/src/nss-mymachines/nss-mymachines.c @@ -38,6 +38,9 @@ NSS_GETHOSTBYNAME_PROTOTYPES(mymachines); NSS_GETPW_PROTOTYPES(mymachines); NSS_GETGR_PROTOTYPES(mymachines); +#define HOST_UID_LIMIT ((uid_t) UINT32_C(0x10000)) +#define HOST_GID_LIMIT ((gid_t) UINT32_C(0x10000)) + static int count_addresses(sd_bus_message *m, int af, unsigned *ret) { unsigned c = 0; int r; @@ -455,6 +458,10 @@ enum nss_status _nss_mymachines_getpwnam_r( if (r < 0) goto fail; + /* Refuse to work if the mapped address is in the host UID range, or if there was no mapping at all. */ + if (mapped < HOST_UID_LIMIT || mapped == uid) + goto not_found; + l = strlen(name); if (buflen < l+1) { *errnop = ENOMEM; @@ -504,7 +511,7 @@ enum nss_status _nss_mymachines_getpwuid_r( } /* We consider all uids < 65536 host uids */ - if (uid < 0x10000) + if (uid < HOST_UID_LIMIT) goto not_found; r = sd_bus_open_system(&bus); @@ -531,6 +538,9 @@ enum nss_status _nss_mymachines_getpwuid_r( if (r < 0) goto fail; + if (mapped == uid) + goto not_found; + if (snprintf(buffer, buflen, "vu-%s-" UID_FMT, machine, (uid_t) mapped) >= (int) buflen) { *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; @@ -619,6 +629,9 @@ enum nss_status _nss_mymachines_getgrnam_r( if (r < 0) goto fail; + if (mapped < HOST_GID_LIMIT || mapped == gid) + goto not_found; + l = sizeof(char*) + strlen(name) + 1; if (buflen < l) { *errnop = ENOMEM; @@ -666,7 +679,7 @@ enum nss_status _nss_mymachines_getgrgid_r( } /* We consider all gids < 65536 host gids */ - if (gid < 0x10000) + if (gid < HOST_GID_LIMIT) goto not_found; r = sd_bus_open_system(&bus); @@ -693,6 +706,9 @@ enum nss_status _nss_mymachines_getgrgid_r( if (r < 0) goto fail; + if (mapped == gid) + goto not_found; + if (buflen < sizeof(char*) + 1) { *errnop = ENOMEM; return NSS_STATUS_TRYAGAIN; -- cgit v1.2.3-54-g00ecf From 03a78688056e533390992db8adf304c2b6798088 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Feb 2016 23:02:53 +0100 Subject: units: don't try to mount the FUSE fs if we lack the privileges for it See: https://lists.freedesktop.org/archives/systemd-devel/2016-February/035740.html --- units/sys-fs-fuse-connections.mount | 1 + 1 file changed, 1 insertion(+) diff --git a/units/sys-fs-fuse-connections.mount b/units/sys-fs-fuse-connections.mount index ebd93e2cda..e940beb09f 100644 --- a/units/sys-fs-fuse-connections.mount +++ b/units/sys-fs-fuse-connections.mount @@ -11,6 +11,7 @@ Documentation=https://www.kernel.org/doc/Documentation/filesystems/fuse.txt Documentation=http://www.freedesktop.org/wiki/Software/systemd/APIFileSystems DefaultDependencies=no ConditionPathExists=/sys/fs/fuse/connections +ConditionCapability=CAP_SYS_ADMIN After=systemd-modules-load.service Before=sysinit.target -- cgit v1.2.3-54-g00ecf From e903182e5b0daa941de47a9c08c824106cec7fe0 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 10 Feb 2016 23:39:31 +0100 Subject: core: don't choke if a unit another unit triggers vanishes during reload Fixes: #1981 --- src/core/automount.c | 25 ++++++++++++++++++++++--- src/core/path.c | 16 ++++++++++++++-- src/core/timer.c | 30 ++++++++++++++++++++++++++---- 3 files changed, 62 insertions(+), 9 deletions(-) diff --git a/src/core/automount.c b/src/core/automount.c index 772ec222ca..5dc6fd98e7 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -726,7 +726,15 @@ static void automount_enter_runnning(Automount *a) { if (!S_ISDIR(st.st_mode) || st.st_dev != a->dev_id) log_unit_info(UNIT(a), "Automount point already active?"); else { - r = manager_add_job(UNIT(a)->manager, JOB_START, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, &error, NULL); + Unit *trigger; + + trigger = UNIT_TRIGGER(UNIT(a)); + if (!trigger) { + log_unit_error(UNIT(a), "Unit to trigger vanished."); + goto fail; + } + + r = manager_add_job(UNIT(a)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL); if (r < 0) { log_unit_warning(UNIT(a), "Failed to queue mount startup job: %s", bus_error_message(&error, r)); goto fail; @@ -742,6 +750,7 @@ fail: static int automount_start(Unit *u) { Automount *a = AUTOMOUNT(u); + Unit *trigger; assert(a); assert(a->state == AUTOMOUNT_DEAD || a->state == AUTOMOUNT_FAILED); @@ -751,8 +760,11 @@ static int automount_start(Unit *u) { return -EEXIST; } - if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED) + trigger = UNIT_TRIGGER(u); + if (!trigger || trigger->load_state != UNIT_LOADED) { + log_unit_error(u, "Refusing to start, unit to trigger not loaded."); return -ENOENT; + } a->result = AUTOMOUNT_SUCCESS; automount_enter_waiting(a); @@ -899,6 +911,7 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo union autofs_v5_packet_union packet; Automount *a = AUTOMOUNT(userdata); struct stat st; + Unit *trigger; int r; assert(a); @@ -971,7 +984,13 @@ static int automount_dispatch_io(sd_event_source *s, int fd, uint32_t events, vo break; } - r = manager_add_job(UNIT(a)->manager, JOB_STOP, UNIT_TRIGGER(UNIT(a)), JOB_REPLACE, &error, NULL); + trigger = UNIT_TRIGGER(UNIT(a)); + if (!trigger) { + log_unit_error(UNIT(a), "Unit to trigger vanished."); + goto fail; + } + + r = manager_add_job(UNIT(a)->manager, JOB_STOP, trigger, JOB_REPLACE, &error, NULL); if (r < 0) { log_unit_warning(UNIT(a), "Failed to queue umount startup job: %s", bus_error_message(&error, r)); goto fail; diff --git a/src/core/path.c b/src/core/path.c index 610901275c..460c1d3bf2 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -464,6 +464,7 @@ static void path_enter_dead(Path *p, PathResult f) { static void path_enter_running(Path *p) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + Unit *trigger; int r; assert(p); @@ -472,7 +473,14 @@ static void path_enter_running(Path *p) { if (unit_stop_pending(UNIT(p))) return; - r = manager_add_job(UNIT(p)->manager, JOB_START, UNIT_TRIGGER(UNIT(p)), JOB_REPLACE, &error, NULL); + trigger = UNIT_TRIGGER(UNIT(p)); + if (!trigger) { + log_unit_error(UNIT(p), "Unit to trigger vanished."); + path_enter_dead(p, TIMER_FAILURE_RESOURCES); + return; + } + + r = manager_add_job(UNIT(p)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL); if (r < 0) goto fail; @@ -553,12 +561,16 @@ static void path_mkdir(Path *p) { static int path_start(Unit *u) { Path *p = PATH(u); + Unit *trigger; assert(p); assert(p->state == PATH_DEAD || p->state == PATH_FAILED); - if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED) + trigger = UNIT_TRIGGER(u); + if (!trigger || trigger->load_state != UNIT_LOADED) { + log_unit_error(u, "Refusing to start, unit to trigger not loaded."); return -ENOENT; + } path_mkdir(p); diff --git a/src/core/timer.c b/src/core/timer.c index 5dd7df14d1..6f3e6a8db3 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -357,8 +357,18 @@ static void timer_enter_waiting(Timer *t, bool initial) { usec_t base = 0; bool leave_around = false; TimerValue *v; + Unit *trigger; int r; + assert(t); + + trigger = UNIT_TRIGGER(UNIT(t)); + if (!trigger) { + log_unit_error(UNIT(t), "Unit to trigger vanished."); + timer_enter_dead(t, TIMER_FAILURE_RESOURCES); + return; + } + /* If we shall wake the system we use the boottime clock * rather than the monotonic clock. */ @@ -417,7 +427,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { case TIMER_UNIT_ACTIVE: leave_around = true; - base = UNIT_TRIGGER(UNIT(t))->inactive_exit_timestamp.monotonic; + base = trigger->inactive_exit_timestamp.monotonic; if (base <= 0) base = t->last_trigger.monotonic; @@ -429,7 +439,7 @@ static void timer_enter_waiting(Timer *t, bool initial) { case TIMER_UNIT_INACTIVE: leave_around = true; - base = UNIT_TRIGGER(UNIT(t))->inactive_enter_timestamp.monotonic; + base = trigger->inactive_enter_timestamp.monotonic; if (base <= 0) base = t->last_trigger.monotonic; @@ -552,6 +562,7 @@ fail: static void timer_enter_running(Timer *t) { _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; + Unit *trigger; int r; assert(t); @@ -560,7 +571,14 @@ static void timer_enter_running(Timer *t) { if (unit_stop_pending(UNIT(t))) return; - r = manager_add_job(UNIT(t)->manager, JOB_START, UNIT_TRIGGER(UNIT(t)), JOB_REPLACE, &error, NULL); + trigger = UNIT_TRIGGER(UNIT(t)); + if (!trigger) { + log_unit_error(UNIT(t), "Unit to trigger vanished."); + timer_enter_dead(t, TIMER_FAILURE_RESOURCES); + return; + } + + r = manager_add_job(UNIT(t)->manager, JOB_START, trigger, JOB_REPLACE, &error, NULL); if (r < 0) goto fail; @@ -580,12 +598,16 @@ fail: static int timer_start(Unit *u) { Timer *t = TIMER(u); TimerValue *v; + Unit *trigger; assert(t); assert(t->state == TIMER_DEAD || t->state == TIMER_FAILED); - if (UNIT_TRIGGER(u)->load_state != UNIT_LOADED) + trigger = UNIT_TRIGGER(u); + if (!trigger || trigger->load_state != UNIT_LOADED) { + log_unit_error(u, "Refusing to start, unit to trigger not loaded."); return -ENOENT; + } t->last_trigger = DUAL_TIMESTAMP_NULL; -- cgit v1.2.3-54-g00ecf