From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from lists.gentoo.org (pigeon.gentoo.org [208.92.234.80]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by finch.gentoo.org (Postfix) with ESMTPS id 62E84139085 for ; Tue, 20 Dec 2016 00:30:02 +0000 (UTC) Received: from pigeon.gentoo.org (localhost [127.0.0.1]) by pigeon.gentoo.org (Postfix) with SMTP id 8835921C084; Tue, 20 Dec 2016 00:30:01 +0000 (UTC) Received: from smtp.gentoo.org (smtp.gentoo.org [IPv6:2001:470:ea4a:1:5054:ff:fec7:86e4]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by pigeon.gentoo.org (Postfix) with ESMTPS id 5F01C21C084 for ; Tue, 20 Dec 2016 00:30:01 +0000 (UTC) Received: from oystercatcher.gentoo.org (oystercatcher.gentoo.org [148.251.78.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.gentoo.org (Postfix) with ESMTPS id 0CDA9340DC7 for ; Tue, 20 Dec 2016 00:30:00 +0000 (UTC) Received: from localhost.localdomain (localhost [127.0.0.1]) by oystercatcher.gentoo.org (Postfix) with ESMTP id 3023624DE for ; Tue, 20 Dec 2016 00:29:58 +0000 (UTC) From: "William Hubbs" To: gentoo-commits@lists.gentoo.org Content-Transfer-Encoding: 8bit Content-type: text/plain; charset=UTF-8 Reply-To: gentoo-dev@lists.gentoo.org, "William Hubbs" Message-ID: <1482193471.45aa36cc623eeeb15fb6827b57e0c07a37cdef41.williamh@OpenRC> Subject: [gentoo-commits] proj/openrc:master commit in: src/librc/ X-VCS-Repository: proj/openrc X-VCS-Files: src/librc/librc.c X-VCS-Directories: src/librc/ X-VCS-Committer: williamh X-VCS-Committer-Name: William Hubbs X-VCS-Revision: 45aa36cc623eeeb15fb6827b57e0c07a37cdef41 X-VCS-Branch: master Date: Tue, 20 Dec 2016 00:29:58 +0000 (UTC) Precedence: bulk List-Post: List-Help: List-Unsubscribe: List-Subscribe: List-Id: Gentoo Linux mail X-BeenThere: gentoo-commits@lists.gentoo.org X-Archives-Salt: 7e1e6461-6320-4d8c-8414-34d60d556a02 X-Archives-Hash: 5d4541ac7940a659df3cf043e3022c77 commit: 45aa36cc623eeeb15fb6827b57e0c07a37cdef41 Author: Doug Freed mtu edu> AuthorDate: Mon Dec 19 00:43:27 2016 +0000 Commit: William Hubbs gentoo org> CommitDate: Tue Dec 20 00:24:31 2016 +0000 URL: https://gitweb.gentoo.org/proj/openrc.git/commit/?id=45aa36cc librc: detect loops in stacked runlevels and abort This fixes #109. X-Gentoo-Bug: 558700 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=558700 src/librc/librc.c | 35 +++++++++++++++++++++++++++++------ 1 file changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librc/librc.c b/src/librc/librc.c index fdde3d5..3d3277d 100644 --- a/src/librc/librc.c +++ b/src/librc/librc.c @@ -367,11 +367,12 @@ rc_parse_service_state(RC_SERVICE state) * specified runlevel in dependency order, including the * specified runlevel. */ static void -get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list) +get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list, RC_STRINGLIST *ancestor_list) { char path[PATH_MAX]; RC_STRINGLIST *dirs; - RC_STRING *d, *dn; + RC_STRING *d, *parent; + const char *nextlevel; /* * If we haven't been passed a runlevel or a level list, or @@ -395,8 +396,27 @@ get_runlevel_chain(const char *runlevel, RC_STRINGLIST *level_list) */ snprintf(path, sizeof(path), "%s/%s", RC_RUNLEVELDIR, runlevel); dirs = ls_dir(path, LS_DIR); - TAILQ_FOREACH_SAFE(d, dirs, entries, dn) - get_runlevel_chain(d->value, level_list); + TAILQ_FOREACH(d, dirs, entries) { + nextlevel = d->value; + + /* Check for loop */ + if (rc_stringlist_find(ancestor_list, nextlevel)) { + fprintf(stderr, "Loop detected in stacked runlevels attempting to enter runlevel %s!\n", + nextlevel); + fprintf(stderr, "Ancestors:\n"); + TAILQ_FOREACH(parent, ancestor_list, entries) + fprintf(stderr, "\t%s\n", parent->value); + exit(1); + } + + /* Add new ancestor */ + rc_stringlist_add(ancestor_list, nextlevel); + + get_runlevel_chain(nextlevel, level_list, ancestor_list); + + rc_stringlist_delete(ancestor_list, nextlevel); + } + rc_stringlist_free(dirs); } bool @@ -500,9 +520,12 @@ librc_hidden_def(rc_runlevel_unstack) RC_STRINGLIST * rc_runlevel_stacks(const char *runlevel) { - RC_STRINGLIST *stack; + RC_STRINGLIST *stack, *ancestor_list; stack = rc_stringlist_new(); - get_runlevel_chain(runlevel, stack); + ancestor_list = rc_stringlist_new(); + rc_stringlist_add(ancestor_list, runlevel); + get_runlevel_chain(runlevel, stack, ancestor_list); + rc_stringlist_free(ancestor_list); return stack; } librc_hidden_def(rc_runlevel_stacks)