From: Alan T. DeKok Date: Mon, 17 Oct 2022 19:03:20 +0000 (-0400) Subject: add maximum instruction count for failure testing X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=78910a74db059873a8a631fb9fb626bf2b330288;p=thirdparty%2Ffreeradius-server.git add maximum instruction count for failure testing --- diff --git a/src/lib/server/request.h b/src/lib/server/request.h index fbc63f686df..8461a0923c0 100644 --- a/src/lib/server/request.h +++ b/src/lib/server/request.h @@ -156,6 +156,10 @@ struct request_s { #ifndef NDEBUG uint32_t magic; //!< Magic number used to detect memory corruption, //!< or request structs that have not been properly initialised. + + uint64_t ins_count; //!< count of instructions we've ran + uint64_t ins_max; //!< max instruction to bail out at + #endif void *stack; //!< unlang interpreter stack. diff --git a/src/lib/unlang/interpret.c b/src/lib/unlang/interpret.c index 15bea9e6968..1309194e0c5 100644 --- a/src/lib/unlang/interpret.c +++ b/src/lib/unlang/interpret.c @@ -457,6 +457,20 @@ unlang_frame_action_t frame_eval(request_t *request, unlang_stack_frame_t *frame yielded_clear(frame); } +#ifndef NDEBUG + /* + * Failure testing! + */ + if (request->ins_max && (request->master_state != REQUEST_STOP_PROCESSING)) { + request->ins_count++; + + if (request->ins_count >= request->ins_max) { + request->master_state = REQUEST_STOP_PROCESSING; + RERROR("Failing request due to maximum instruction count %" PRIu64, request->ins_max); + } + } +#endif + /* * unlang_interpret_signal() takes care of * marking the requests as STOP on a CANCEL diff --git a/src/lib/unlang/interpret_synchronous.c b/src/lib/unlang/interpret_synchronous.c index 60127080392..94e89238ab3 100644 --- a/src/lib/unlang/interpret_synchronous.c +++ b/src/lib/unlang/interpret_synchronous.c @@ -50,21 +50,23 @@ static void _request_init_internal(request_t *request, void *uctx) */ static void _request_done_external(request_t *request, UNUSED rlm_rcode_t rcode, UNUSED void *uctx) { - /* - * If we're running a real request, then the final - * indentation MUST be zero. Otherwise we skipped - * something! - * - * Also check that the request is NOT marked as - * "yielded", but is in fact done. - * - * @todo - check that the stack is at frame 0, otherwise - * more things have gone wrong. - */ - fr_assert_msg(request->parent || (request->log.unlang_indent == 0), - "Request %s bad log indentation - expected 0 got %u", request->name, request->log.unlang_indent); - fr_assert_msg(!unlang_interpret_is_resumable(request), - "Request %s is marked as yielded at end of processing", request->name); + if (request->master_state != REQUEST_STOP_PROCESSING) { + /* + * If we're running a real request, then the final + * indentation MUST be zero. Otherwise we skipped + * something! + * + * Also check that the request is NOT marked as + * "yielded", but is in fact done. + * + * @todo - check that the stack is at frame 0, otherwise + * more things have gone wrong. + */ + fr_assert_msg(request->parent || (request->log.unlang_indent == 0), + "Request %s bad log indentation - expected 0 got %u", request->name, request->log.unlang_indent); + fr_assert_msg(!unlang_interpret_is_resumable(request), + "Request %s is marked as yielded at end of processing", request->name); + } RDEBUG3("Synchronous done external request"); }