From 563ba9ea6e60774086555998b957edf923e24b46 Mon Sep 17 00:00:00 2001 From: Michal Schmidt Date: Mon, 17 Oct 2011 11:12:12 +0200 Subject: manager: fix a crash in isolating HASHMAP_FOREACH is safe against the removal of the current entry, but not against the removal of other entries. job_finish_and_invalidate() can recursively remove other entries. It triggered an assertion failure: Assertion 'j->installed' failed at src/manager.c:1218, function transaction_apply(). Aborting. Fix the crash by iterating from the beginning when there is a possibility that the iterator could be invalid. It is O(n^2) in the worst case, but that's better than a crash. https://bugzilla.redhat.com/show_bug.cgi?id=717325 --- src/manager.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'src/manager.c') diff --git a/src/manager.c b/src/manager.c index e626347dec..6d20258893 100644 --- a/src/manager.c +++ b/src/manager.c @@ -1214,13 +1214,18 @@ static int transaction_apply(Manager *m, JobMode mode) { /* When isolating first kill all installed jobs which * aren't part of the new transaction */ + rescan: HASHMAP_FOREACH(j, m->jobs, i) { assert(j->installed); if (hashmap_get(m->transaction_jobs, j->unit)) continue; - job_finish_and_invalidate(j, JOB_CANCELED); + /* 'j' itself is safe to remove, but if other jobs + are invalidated recursively, our iterator may become + invalid and we need to start over. */ + if (job_finish_and_invalidate(j, JOB_CANCELED) > 0) + goto rescan; } } -- cgit v1.2.3-54-g00ecf From 5a8d081c58f7b83172ad5031a8fdac0c33072b2a Mon Sep 17 00:00:00 2001 From: Jonathan Nieder Date: Mon, 17 Oct 2011 21:01:40 +0200 Subject: audit: do not complain if kernel lacks audit When running on a kernel without audit support, systemd currently writes a mysterious-sounding error to its log: systemd[1]: Failed to connect to audit log: Protocol not supported Better to suppress the audit_open() failure message when (and only when) it is due to running on a kernel without audit support, since in this case the admin probably does not mind systemd not writing to the audit log. This way, more serious errors like ENOMEM and EACCES will stand out more. --- src/manager.c | 5 ++++- src/update-utmp.c | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) (limited to 'src/manager.c') diff --git a/src/manager.c b/src/manager.c index 6d20258893..111167a8c2 100644 --- a/src/manager.c +++ b/src/manager.c @@ -286,7 +286,10 @@ int manager_new(ManagerRunningAs running_as, Manager **_m) { goto fail; #ifdef HAVE_AUDIT - if ((m->audit_fd = audit_open()) < 0) + if ((m->audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) log_error("Failed to connect to audit log: %m"); #endif diff --git a/src/update-utmp.c b/src/update-utmp.c index f81e7f495f..12e4d11042 100644 --- a/src/update-utmp.c +++ b/src/update-utmp.c @@ -376,7 +376,10 @@ int main(int argc, char *argv[]) { umask(0022); #ifdef HAVE_AUDIT - if ((c.audit_fd = audit_open()) < 0) + if ((c.audit_fd = audit_open()) < 0 && + /* If the kernel lacks netlink or audit support, + * don't worry about it. */ + errno != EAFNOSUPPORT && errno != EPROTONOSUPPORT) log_error("Failed to connect to audit log: %m"); #endif -- cgit v1.2.3-54-g00ecf