]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
loader: Prevent deadlock using tab completion.
authorNaveen Albert <asterisk@phreaknet.org>
Tue, 3 May 2022 12:44:07 +0000 (12:44 +0000)
committerKevin Harwell <kharwell@digium.com>
Mon, 6 Jun 2022 21:51:55 +0000 (16:51 -0500)
If tab completion using ast_module_helper is attempted
during startup, deadlock will ensue because the CLI
will attempt to lock the module list while it is already
locked by the loader. This causes deadlock because when
the loader tries to acquire the CLI lock, they are blocked
on each other.

Waiting for startup to complete is not feasible because
the CLI lock is acquired while waiting, so deadlock will
ensure regardless of whether or not a lock on the module
list is attempted.

To prevent deadlock, we immediately abort if tab completion
is attempted on the module list before Asterisk is fully
booted.

ASTERISK-30039 #close

Change-Id: Idd468906c512bb196631e366a8f597a0e2e9271d

include/asterisk/module.h
main/loader.c

index cce8735fc1b7910b0894761410e9187efb4f0056..f79dc8eb108464372c1ca516798b4b79d755fc07 100644 (file)
@@ -283,7 +283,7 @@ int ast_loader_unregister(int (*updater)(void));
  * \param type The type of action that will be performed by CLI.
  *
  * \retval A possible completion of the partial match.
- * \retval NULL if no matches were found.
+ * \retval NULL if no matches were found or Asterisk is not yet fully booted.
  */
 char *ast_module_helper(const char *line, const char *word, int pos, int state, int rpos, enum ast_module_helper_type type);
 
index 4c6c2a809ee98e3ed981d7c6c6bb49e3d30663c0..549e3f0e52cd7d912ca60c54e8b4956ce26402c1 100644 (file)
@@ -1382,6 +1382,11 @@ char *ast_module_helper(const char *line, const char *word, int pos, int state,
                return NULL;
        }
 
+       /* Tab completion can't be used during startup, or CLI and loader will deadlock. */
+       if (!ast_test_flag(&ast_options, AST_OPT_FLAG_FULLY_BOOTED)) {
+               return NULL;
+       }
+
        if (type == AST_MODULE_HELPER_LOAD) {
                module_load_helper(word);