Don't allow sudo_ev_loopcont() to override sudo_ev_loopexit()

This commit is contained in:
Todd C. Miller
2014-08-29 09:47:08 -06:00
parent e9370718f9
commit 2b849b2687
3 changed files with 27 additions and 21 deletions

View File

@@ -35,9 +35,10 @@
#define SUDO_EVLOOP_NONBLOCK 0x02 /* Do not block in event loop */ #define SUDO_EVLOOP_NONBLOCK 0x02 /* Do not block in event loop */
/* Event base flags (internal) */ /* Event base flags (internal) */
#define SUDO_EVBASE_LOOPEXIT 0x01 #define SUDO_EVBASE_LOOPONCE SUDO_EVLOOP_ONCE
#define SUDO_EVBASE_LOOPBREAK 0x02 #define SUDO_EVBASE_LOOPEXIT 0x02
#define SUDO_EVBASE_LOOPCONT 0x04 #define SUDO_EVBASE_LOOPBREAK 0x04
#define SUDO_EVBASE_LOOPCONT 0x08
#define SUDO_EVBASE_GOT_EXIT 0x10 #define SUDO_EVBASE_GOT_EXIT 0x10
#define SUDO_EVBASE_GOT_BREAK 0x20 #define SUDO_EVBASE_GOT_BREAK 0x20
#define SUDO_EVBASE_GOT_MASK 0xf0 #define SUDO_EVBASE_GOT_MASK 0xf0

View File

@@ -282,10 +282,10 @@ sudo_ev_loop_v1(struct sudo_event_base *base, int flags)
* If sudo_ev_loopexit() was called when events were not running * If sudo_ev_loopexit() was called when events were not running
* the next invocation of sudo_ev_loop() only runs once. * the next invocation of sudo_ev_loop() only runs once.
* All other base flags are ignored unless we are running events. * All other base flags are ignored unless we are running events.
* Note that SUDO_EVLOOP_ONCE and SUDO_EVBASE_LOOPONCE are equivalent.
*/ */
if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT)) base->flags |= (flags & SUDO_EVLOOP_ONCE);
SET(flags, SUDO_EVLOOP_ONCE); base->flags &= (SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE);
base->flags = 0;
for (;;) { for (;;) {
rescan: rescan:
@@ -352,19 +352,14 @@ rescan:
if (ISSET(base->flags, SUDO_EVBASE_LOOPCONT)) { if (ISSET(base->flags, SUDO_EVBASE_LOOPCONT)) {
/* Rescan events and start polling again. */ /* Rescan events and start polling again. */
CLR(base->flags, SUDO_EVBASE_LOOPCONT); CLR(base->flags, SUDO_EVBASE_LOOPCONT);
if (!ISSET(flags, SUDO_EVLOOP_ONCE)) { sudo_ev_deactivate_all(base);
sudo_ev_deactivate_all(base); goto rescan;
goto rescan;
}
} }
} }
if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT)) { if (ISSET(base->flags, SUDO_EVBASE_LOOPONCE)) {
/* exit loop after once through */ /* SUDO_EVBASE_LOOPEXIT is always set w/ SUDO_EVBASE_LOOPONCE */
SET(base->flags, SUDO_EVBASE_GOT_EXIT); if (ISSET(base->flags, SUDO_EVBASE_LOOPEXIT))
sudo_ev_deactivate_all(base); SET(base->flags, SUDO_EVBASE_GOT_EXIT);
break;
}
if (ISSET(flags, SUDO_EVLOOP_ONCE)) {
sudo_ev_deactivate_all(base); sudo_ev_deactivate_all(base);
break; break;
} }
@@ -378,7 +373,12 @@ void
sudo_ev_loopexit_v1(struct sudo_event_base *base) sudo_ev_loopexit_v1(struct sudo_event_base *base)
{ {
debug_decl(sudo_ev_loopexit, SUDO_DEBUG_EVENT) debug_decl(sudo_ev_loopexit, SUDO_DEBUG_EVENT)
SET(base->flags, SUDO_EVBASE_LOOPEXIT); /* SUDO_EVBASE_LOOPBREAK trumps SUDO_EVBASE_LOOPEXIT */
if (!ISSET(base->flags, SUDO_EVBASE_LOOPBREAK)) {
/* SUDO_EVBASE_LOOPEXIT trumps SUDO_EVBASE_LOOPCONT */
CLR(base->flags, SUDO_EVBASE_LOOPCONT);
SET(base->flags, (SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE));
}
debug_return; debug_return;
} }
@@ -386,6 +386,8 @@ void
sudo_ev_loopbreak_v1(struct sudo_event_base *base) sudo_ev_loopbreak_v1(struct sudo_event_base *base)
{ {
debug_decl(sudo_ev_loopbreak, SUDO_DEBUG_EVENT) debug_decl(sudo_ev_loopbreak, SUDO_DEBUG_EVENT)
/* SUDO_EVBASE_LOOPBREAK trumps SUDO_EVBASE_LOOP{CONT,EXIT,ONCE}. */
CLR(base->flags, (SUDO_EVBASE_LOOPCONT|SUDO_EVBASE_LOOPEXIT|SUDO_EVBASE_LOOPONCE));
SET(base->flags, SUDO_EVBASE_LOOPBREAK); SET(base->flags, SUDO_EVBASE_LOOPBREAK);
debug_return; debug_return;
} }
@@ -394,7 +396,10 @@ void
sudo_ev_loopcontinue_v1(struct sudo_event_base *base) sudo_ev_loopcontinue_v1(struct sudo_event_base *base)
{ {
debug_decl(sudo_ev_loopcontinue, SUDO_DEBUG_EVENT) debug_decl(sudo_ev_loopcontinue, SUDO_DEBUG_EVENT)
SET(base->flags, SUDO_EVBASE_LOOPCONT); /* SUDO_EVBASE_LOOP{BREAK,EXIT} trumps SUDO_EVBASE_LOOPCONT */
if (!ISSET(base->flags, SUDO_EVBASE_LOOPONCE|SUDO_EVBASE_LOOPBREAK)) {
SET(base->flags, SUDO_EVBASE_LOOPCONT);
}
debug_return; debug_return;
} }

View File

@@ -1138,9 +1138,9 @@ handle_sigchld(int backchannel, struct command_status *cstat)
sudo_debug_printf(SUDO_DEBUG_INFO, "command exited: %d", sudo_debug_printf(SUDO_DEBUG_INFO, "command exited: %d",
WEXITSTATUS(status)); WEXITSTATUS(status));
} }
if (!WIFSTOPPED(status))
alive = false;
} }
if (!WIFSTOPPED(status))
alive = false;
} }
debug_return_bool(alive); debug_return_bool(alive);
} }