When running a sequence of commands out of which some fail the
prerequisites check, ovn-dbctl didn't completely initialize the rest
of the commands.  This in turn caused the cleanup code to try to
access random memory.

Caught by AddressSanitizer when running:
  ovn-nbctl -- set logical_switch_port ln tag-request 100 -- show

  ==1857349==ERROR: AddressSanitizer: SEGV on unknown address (...)
  ==1857349==The signal is caused by a READ memory access.
  ==1857349==Hint: this fault was caused by a dereference of a high value 
address...
      #0 0x000000403d5b in __asan::Allocator::Deallocate(...)
      #1 0x0000004a4a9f in free (utilities/ovn-nbctl+0x4a4a9f)
      #2 0x00000095855b in ds_destroy ovs/lib/dynamic-string.c:371:5
      #3 0x0000004ea6e1 in ovn_dbctl_main utilities/ovn-dbctl.c:246:13
      #4 0x0000004f5bee in main utilities/ovn-nbctl.c:9096:12
      #5 0x7fe6873e5574 in __libc_start_call_main (/lib64/libc.so.6+0x3574)
      #6 0x7fe6873e5627 in __libc_start_main@GLIBC_2.2.5 
(/lib64/libc.so.6+0x3627)
      #7 0x0000004011c4 in _start (utilities/ovn-nbctl+0x4011c4)

Fixes: 8fb54e16378c ("ovn-nbctl: Cleanup allocated memory to keep valgrind 
happy.")
Signed-off-by: Dumitru Ceara <[email protected]>
---
 tests/ovn-nbctl.at    |  4 ++++
 utilities/ovn-dbctl.c | 18 ++++++++++--------
 2 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/tests/ovn-nbctl.at b/tests/ovn-nbctl.at
index 64f87b1fae..479e0db590 100644
--- a/tests/ovn-nbctl.at
+++ b/tests/ovn-nbctl.at
@@ -3000,6 +3000,10 @@ AT_CHECK([ovn-nbctl --id=@ls create logical_switch 
name=foo -- \
          [1], [], [dnl
 ovn-nbctl: no row "foo1" in table Logical_Switch
 ])
+AT_CHECK([ovn-nbctl -- set logical_switch_port ln tag-request 100 -- show],
+         [1], [], [dnl
+ovn-nbctl: Logical_Switch_Port does not contain a column whose name matches 
"100"
+])
 ])
 
 dnl ---------------------------------------------------------------------
diff --git a/utilities/ovn-dbctl.c b/utilities/ovn-dbctl.c
index afa88a071b..4a6e579f31 100644
--- a/utilities/ovn-dbctl.c
+++ b/utilities/ovn-dbctl.c
@@ -654,14 +654,20 @@ run_prerequisites(const struct ovn_dbctl_options 
*dbctl_options,
 {
     dbctl_options->add_base_prerequisites(idl, wait_type);
 
+    /* Make sure all commands are properly initialized before checking
+     * prerequisites. */
+    for (size_t i = 0; i < n_commands; i++) {
+        struct ctl_command *c = &commands[i];
+
+        ds_init(&c->output);
+        c->table = NULL;
+    }
+
     for (size_t i = 0; i < n_commands; i++) {
         struct ctl_command *c = &commands[i];
         if (c->syntax->prerequisites) {
             struct ctl_context ctx;
 
-            ds_init(&c->output);
-            c->table = NULL;
-
             ctl_context_init(&ctx, c, idl, NULL, NULL, NULL);
             (c->syntax->prerequisites)(&ctx);
             if (ctx.error) {
@@ -735,11 +741,7 @@ do_dbctl(const struct ovn_dbctl_options *dbctl_options,
     dbctl_options->pre_execute(idl, txn, wait_type);
 
     symtab = ovsdb_symbol_table_create();
-    for (size_t i = 0; i < n_commands; i++) {
-        struct ctl_command *c = &commands[i];
-        ds_init(&c->output);
-        c->table = NULL;
-    }
+
     struct ctl_context *ctx = dbctl_options->ctx_create();
     ctl_context_init(ctx, NULL, idl, txn, symtab, NULL);
     for (size_t i = 0; i < n_commands; i++) {
-- 
2.51.0

_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to