Reported by UB Sanitizer:
  lib/actions.c:2309:54: runtime error: applying zero offset to null pointer
      #0 0x4fa41b in free_gen_options /root/ovn/lib/actions.c:2309:54
      #1 0x4d6f87 in ovnact_free /root/ovn/lib/actions.c:4297:9
      #2 0x4d6f87 in ovnacts_free /root/ovn/lib/actions.c:4315:13
      #3 0x4d67b6 in ovnacts_parse /root/ovn/lib/actions.c:4189:9
      #4 0x4d74a7 in ovnacts_parse_string /root/ovn/lib/actions.c:4208:5
      #5 0x49d3e7 in test_parse_actions /root/ovn/tests/test-ovn.c:1324:17

  utilities/ovn-dbctl.c:467:16: runtime error: applying zero offset to null 
pointer
      #0 0x498a56 in has_option /root/ovn/utilities/ovn-dbctl.c:467:16
      #1 0x497f91 in ovn_dbctl_main /root/ovn/utilities/ovn-dbctl.c:167:13
      #2 0x4a0b46 in main /root/ovn/utilities/ovn-sbctl.c:1526:12
      #3 0x7ff3cdd56b74 in __libc_start_main (/lib64/libc.so.6+0x27b74)
      #4 0x47147d in _start (/root/ovn/utilities/ovn-sbctl+0x47147d)

  utilities/ovn-dbctl.c:1063:29: runtime error: applying zero offset to null 
pointer
      #0 0x4bf407 in server_cmd_run /root/ovn/utilities/ovn-dbctl.c:1063:29
      #1 0x739bdc in process_command /root/ovs/lib/unixctl.c:310:13
      #2 0x73853e in run_connection /root/ovs/lib/unixctl.c:344:17
      #3 0x738228 in unixctl_server_run /root/ovs/lib/unixctl.c:395:21
      #4 0x4badf5 in server_loop /root/ovn/utilities/ovn-dbctl.c:1128:9
      #5 0x4badf5 in ovn_dbctl_main /root/ovn/utilities/ovn-dbctl.c:196:9

Signed-off-by: Dumitru Ceara <[email protected]>
---
v2: remove trailing whitespace.
---
 lib/actions.c         | 44 +++++++++++++++++++++++--------------------
 utilities/ovn-dbctl.c | 39 +++++++++++++++++++++-----------------
 2 files changed, 46 insertions(+), 37 deletions(-)

diff --git a/lib/actions.c b/lib/actions.c
index a78d01198..d5d8391bb 100644
--- a/lib/actions.c
+++ b/lib/actions.c
@@ -133,7 +133,8 @@ encode_setup_args(const struct arg args[], size_t n_args,
                   struct ofpbuf *ofpacts)
 {
     /* 1. Save all of the destinations that will be modified. */
-    for (const struct arg *a = args; a < &args[n_args]; a++) {
+    for (size_t i = 0; i < n_args; i++) {
+        const struct arg *a = &args[i];
         ovs_assert(a->src.n_bits == mf_from_id(a->dst)->n_bits);
         if (a->src.field->id != a->dst) {
             init_stack(ofpact_put_STACK_PUSH(ofpacts), a->dst);
@@ -149,7 +150,8 @@ encode_setup_args(const struct arg args[], size_t n_args,
     }
 
     /* 3. Pop the sources into the destinations. */
-    for (const struct arg *a = args; a < &args[n_args]; a++) {
+    for (size_t i = 0; i < n_args; i++) {
+        const struct arg *a = &args[i];
         if (a->src.field->id != a->dst) {
             init_stack(ofpact_put_STACK_POP(ofpacts), a->dst);
         }
@@ -1686,8 +1688,8 @@ format_TRIGGER_EVENT(const struct ovnact_controller_event 
*event,
 {
     ds_put_format(s, "trigger_event(event = \"%s\"",
                   event_to_string(event->event_type));
-    for (const struct ovnact_gen_option *o = event->options;
-         o < &event->options[event->n_options]; o++) {
+    for (size_t i = 0; i < event->n_options; i++) {
+        const struct ovnact_gen_option *o = &event->options[i];
         ds_put_cstr(s, ", ");
         ds_put_format(s, "%s = ", o->option->name);
         expr_constant_set_format(&o->value, s);
@@ -1840,8 +1842,8 @@ static void
 encode_event_empty_lb_backends_opts(struct ofpbuf *ofpacts,
         const struct ovnact_controller_event *event)
 {
-    for (const struct ovnact_gen_option *o = event->options;
-         o < &event->options[event->n_options]; o++) {
+    for (size_t i = 0; i < event->n_options; i++) {
+        const struct ovnact_gen_option *o = &event->options[i];
 
         /* All empty_lb_backends fields are of type 'str' */
         ovs_assert(!strcmp(o->option->type, "str"));
@@ -2295,7 +2297,8 @@ parse_gen_opt(struct action_context *ctx, struct 
ovnact_gen_option *o,
 static const struct ovnact_gen_option *
 find_opt(const struct ovnact_gen_option *options, size_t n, size_t code)
 {
-    for (const struct ovnact_gen_option *o = options; o < &options[n]; o++) {
+    for (size_t i = 0; i < n; i++) {
+        const struct ovnact_gen_option *o = &options[i];
         if (o->option->code == code) {
             return o;
         }
@@ -2306,7 +2309,8 @@ find_opt(const struct ovnact_gen_option *options, size_t 
n, size_t code)
 static void
 free_gen_options(struct ovnact_gen_option *options, size_t n)
 {
-    for (struct ovnact_gen_option *o = options; o < &options[n]; o++) {
+    for (size_t i = 0; i < n; i++) {
+        struct ovnact_gen_option *o = &options[i];
         expr_constant_set_destroy(&o->value);
     }
     free(options);
@@ -2317,8 +2321,8 @@ validate_empty_lb_backends(struct action_context *ctx,
                            const struct ovnact_gen_option *options,
                            size_t n_options)
 {
-    for (const struct ovnact_gen_option *o = options;
-         o < &options[n_options]; o++) {
+    for (size_t i = 0; i < n_options; i++) {
+        const struct ovnact_gen_option *o = &options[i];
         const union expr_constant *c = o->value.values;
         struct sockaddr_storage ss;
         struct uuid uuid;
@@ -2492,8 +2496,8 @@ format_put_opts(const char *name, const struct 
ovnact_put_opts *pdo,
 {
     expr_field_format(&pdo->dst, s);
     ds_put_format(s, " = %s(", name);
-    for (const struct ovnact_gen_option *o = pdo->options;
-         o < &pdo->options[pdo->n_options]; o++) {
+    for (size_t i = 0; i < pdo->n_options; i++) {
+        const struct ovnact_gen_option *o = &pdo->options[i];
         if (o != pdo->options) {
             ds_put_cstr(s, ", ");
         }
@@ -2754,8 +2758,8 @@ encode_PUT_DHCPV4_OPTS(const struct ovnact_put_opts *pdo,
         ofpbuf_put(ofpacts, c->string, opt_header[1]);
     }
 
-    for (const struct ovnact_gen_option *o = pdo->options;
-         o < &pdo->options[pdo->n_options]; o++) {
+    for (size_t i = 0; i < pdo->n_options; i++) {
+        const struct ovnact_gen_option *o = &pdo->options[i];
         if (o != offerip_opt && o != boot_opt && o != boot_alt_opt) {
             encode_put_dhcpv4_option(o, ofpacts);
         }
@@ -2777,8 +2781,8 @@ encode_PUT_DHCPV6_OPTS(const struct ovnact_put_opts *pdo,
     ovs_be32 ofs = htonl(dst.ofs);
     ofpbuf_put(ofpacts, &ofs, sizeof ofs);
 
-    for (const struct ovnact_gen_option *o = pdo->options;
-         o < &pdo->options[pdo->n_options]; o++) {
+    for (size_t i = 0; i < pdo->n_options; i++) {
+        const struct ovnact_gen_option *o = &pdo->options[i];
         encode_put_dhcpv6_option(o, ofpacts);
     }
 
@@ -2949,8 +2953,8 @@ parse_put_nd_ra_opts(struct action_context *ctx, const 
struct expr_field *dst,
     bool prefix_set = false;
     bool slla_present = false;
     /* Let's validate the options. */
-    for (struct ovnact_gen_option *o = po->options;
-            o < &po->options[po->n_options]; o++) {
+    for (size_t i = 0; i < po->n_options; i++) {
+        const struct ovnact_gen_option *o = &po->options[i];
         const union expr_constant *c = o->value.values;
         if (o->value.n_values > 1) {
             lexer_error(ctx->lexer, "Invalid value for \"%s\" option",
@@ -3120,8 +3124,8 @@ encode_PUT_ND_RA_OPTS(const struct ovnact_put_opts *po,
     ra->mo_flags = 0;
     ra->router_lifetime = htons(IPV6_ND_RA_LIFETIME);
 
-    for (const struct ovnact_gen_option *o = po->options;
-         o < &po->options[po->n_options]; o++) {
+    for (size_t i = 0; i < po->n_options; i++) {
+        const struct ovnact_gen_option *o = &po->options[i];
         encode_put_nd_ra_option(o, ofpacts, ra_offset);
     }
 
diff --git a/utilities/ovn-dbctl.c b/utilities/ovn-dbctl.c
index 791caabb2..a292e589d 100644
--- a/utilities/ovn-dbctl.c
+++ b/utilities/ovn-dbctl.c
@@ -221,8 +221,8 @@ ovn_dbctl_main(int argc, char *argv[],
 cleanup:
         free(args);
 
-        struct ctl_command *c;
-        for (c = commands; c < &commands[n_commands]; c++) {
+        for (size_t i = 0; i < n_commands; i++) {
+            struct ctl_command *c = &commands[i];
             ds_destroy(&c->output);
             table_destroy(c->table);
             free(c->table);
@@ -463,8 +463,8 @@ static bool
 has_option(const struct ovs_cmdl_parsed_option *parsed_options, size_t n,
            int option)
 {
-    for (const struct ovs_cmdl_parsed_option *po = parsed_options;
-         po < &parsed_options[n]; po++) {
+    for (size_t i = 0; i < n; i++) {
+        const struct ovs_cmdl_parsed_option *po = &parsed_options[i];
         if (po->o->val == option) {
             return true;
         }
@@ -510,8 +510,8 @@ apply_options_direct(const struct ovn_dbctl_options 
*dbctl_options,
                      const struct ovs_cmdl_parsed_option *parsed_options,
                      size_t n, struct shash *local_options)
 {
-    for (const struct ovs_cmdl_parsed_option *po = parsed_options;
-         po < &parsed_options[n]; po++) {
+    for (size_t i = 0; i < n; i++) {
+        const struct ovs_cmdl_parsed_option *po = &parsed_options[i];
         bool handled;
         char *error = handle_main_loop_option(dbctl_options,
                                               po->o->val, po->arg, &handled);
@@ -620,7 +620,8 @@ run_prerequisites(const struct ovn_dbctl_options 
*dbctl_options,
 {
     dbctl_options->add_base_prerequisites(idl, wait_type);
 
-    for (struct ctl_command *c = commands; c < &commands[n_commands]; c++) {
+    for (size_t i = 0; i < n_commands; i++) {
+        struct ctl_command *c = &commands[i];
         if (c->syntax->prerequisites) {
             struct ctl_context ctx;
 
@@ -685,7 +686,6 @@ do_dbctl(const struct ovn_dbctl_options *dbctl_options,
     struct ovsdb_idl_txn *txn;
     enum ovsdb_idl_txn_status status;
     struct ovsdb_symbol_table *symtab;
-    struct ctl_command *c;
     struct shash_node *node;
     char *error = NULL;
 
@@ -701,13 +701,15 @@ do_dbctl(const struct ovn_dbctl_options *dbctl_options,
     dbctl_options->pre_execute(idl, txn, wait_type);
 
     symtab = ovsdb_symbol_table_create();
-    for (c = commands; c < &commands[n_commands]; c++) {
+    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 (c = commands; c < &commands[n_commands]; c++) {
+    for (size_t i = 0; i < n_commands; i++) {
+        struct ctl_command *c = &commands[i];
         ctl_context_init_command(ctx, c);
         if (c->syntax->run) {
             (c->syntax->run)(ctx);
@@ -750,7 +752,8 @@ do_dbctl(const struct ovn_dbctl_options *dbctl_options,
     long long int start_time = time_wall_msec();
     status = ovsdb_idl_txn_commit_block(txn);
     if (status == TXN_UNCHANGED || status == TXN_SUCCESS) {
-        for (c = commands; c < &commands[n_commands]; c++) {
+        for (size_t i = 0; i < n_commands; i++) {
+            struct ctl_command *c = &commands[i];
             if (c->syntax->postprocess) {
                 ctl_context_init(ctx, c, idl, txn, symtab, NULL);
                 (c->syntax->postprocess)(ctx);
@@ -795,7 +798,8 @@ do_dbctl(const struct ovn_dbctl_options *dbctl_options,
         OVS_NOT_REACHED();
     }
 
-    for (c = commands; c < &commands[n_commands]; c++) {
+    for (size_t i = 0; i < n_commands; i++) {
+        struct ctl_command *c = &commands[i];
         struct ds *ds = &c->output;
 
         if (c->table) {
@@ -1043,7 +1047,8 @@ server_cmd_run(struct unixctl_conn *conn, int argc, const 
char **argv_,
 
     struct ds output = DS_EMPTY_INITIALIZER;
     table_format_reset();
-    for (struct ctl_command *c = commands; c < &commands[n_commands]; c++) {
+    for (size_t i = 0; i < n_commands; i++) {
+        struct ctl_command *c = &commands[i];
         if (c->table) {
             table_format(c->table, &table_style, &output);
         } else if (oneline) {
@@ -1058,8 +1063,8 @@ server_cmd_run(struct unixctl_conn *conn, int argc, const 
char **argv_,
 out:
     free(error);
 
-    struct ctl_command *c;
-    for (c = commands; c < &commands[n_commands]; c++) {
+    for (size_t i = 0; i < n_commands; i++) {
+        struct ctl_command *c = &commands[i];
         ds_destroy(&c->output);
         table_destroy(c->table);
         free(c->table);
@@ -1147,8 +1152,8 @@ dbctl_client(const struct ovn_dbctl_options 
*dbctl_options,
 {
     struct svec args = SVEC_EMPTY_INITIALIZER;
 
-    for (const struct ovs_cmdl_parsed_option *po = parsed_options;
-         po < &parsed_options[n]; po++) {
+    for (size_t i = 0; i < n; i++) {
+        const struct ovs_cmdl_parsed_option *po = &parsed_options[i];
         optarg = po->arg;
         switch (po->o->val) {
         case OPT_DB:
-- 
2.27.0

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

Reply via email to