diff mbox series

[ovs-dev,v12,4/8] ovsdb: Assert and check return values of `ovsdb_table_schema_get_column`

Message ID 20230613183443.31540-5-jamestiotio@gmail.com
State Accepted, archived
Commit e71f1a2da130a09c798c57ac9681b1eb3f0be050
Headers show
Series treewide: Fix multiple Coverity defects | expand

Checks

Context Check Description
ovsrobot/apply-robot success apply and check: success
ovsrobot/github-robot-_Build_and_Test fail github build: failed
ovsrobot/intel-ovs-compilation fail test: fail

Commit Message

James Raphael Tiovalen June 13, 2023, 6:34 p.m. UTC
This commit adds a few null pointer assertions and checks to some return
values of `ovsdb_table_schema_get_column`. If a null pointer is
encountered in these blocks, either the assertion will fail or the
control flow will now be redirected to alternative paths which will
output the appropriate error messages.

A few ovsdb-rbac and ovsdb-server tests are also updated to verify the
expected warning logs by adding said logs to the ALLOWLIST of the
OVSDB_SERVER_SHUTDOWN statements.

Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>
---
 ovsdb/condition.c     | 5 ++++-
 ovsdb/ovsdb-client.c  | 7 +++++--
 ovsdb/ovsdb-util.c    | 6 ++++++
 tests/ovsdb-rbac.at   | 4 +++-
 tests/ovsdb-server.at | 8 ++++++--
 5 files changed, 24 insertions(+), 6 deletions(-)

Comments

Simon Horman June 14, 2023, 12:45 p.m. UTC | #1
On Wed, Jun 14, 2023 at 02:34:39AM +0800, James Raphael Tiovalen wrote:
> This commit adds a few null pointer assertions and checks to some return
> values of `ovsdb_table_schema_get_column`. If a null pointer is
> encountered in these blocks, either the assertion will fail or the
> control flow will now be redirected to alternative paths which will
> output the appropriate error messages.
> 
> A few ovsdb-rbac and ovsdb-server tests are also updated to verify the
> expected warning logs by adding said logs to the ALLOWLIST of the
> OVSDB_SERVER_SHUTDOWN statements.
> 
> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>

Reviewed-by: Simon Horman <simon.horman@corigine.com>
Eelco Chaudron July 11, 2023, 10:13 a.m. UTC | #2
On 13 Jun 2023, at 20:34, James Raphael Tiovalen wrote:

> This commit adds a few null pointer assertions and checks to some return
> values of `ovsdb_table_schema_get_column`. If a null pointer is
> encountered in these blocks, either the assertion will fail or the
> control flow will now be redirected to alternative paths which will
> output the appropriate error messages.
>
> A few ovsdb-rbac and ovsdb-server tests are also updated to verify the
> expected warning logs by adding said logs to the ALLOWLIST of the
> OVSDB_SERVER_SHUTDOWN statements.
>
> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>

In general, this looks good, however, I’m not a ovsdb guy, so I’m wondering if the asserts could not cause any additional crashes that can be avoided by a different type of error handling. Also is there an easy way to make this crash happen by giving some invalid input?

Ilya any comments here?

//Eelco

> ---
>  ovsdb/condition.c     | 5 ++++-
>  ovsdb/ovsdb-client.c  | 7 +++++--
>  ovsdb/ovsdb-util.c    | 6 ++++++
>  tests/ovsdb-rbac.at   | 4 +++-
>  tests/ovsdb-server.at | 8 ++++++--
>  5 files changed, 24 insertions(+), 6 deletions(-)
>
> diff --git a/ovsdb/condition.c b/ovsdb/condition.c
> index 09c89b2a0..5a3eb4e8a 100644
> --- a/ovsdb/condition.c
> +++ b/ovsdb/condition.c
> @@ -47,7 +47,10 @@ ovsdb_clause_from_json(const struct ovsdb_table_schema *ts,
>
>          /* Column and arg fields are not being used with boolean functions.
>           * Use dummy values */
> -        clause->column = ovsdb_table_schema_get_column(ts, "_uuid");
> +        const struct ovsdb_column *uuid_column =
> +                                  ovsdb_table_schema_get_column(ts, "_uuid");
> +        ovs_assert(uuid_column);
> +        clause->column = uuid_column;
>          clause->index = clause->column->index;
>          ovsdb_datum_init_default(&clause->arg, &clause->column->type);
>          return NULL;
> diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
> index bae2c5f04..46484630d 100644
> --- a/ovsdb/ovsdb-client.c
> +++ b/ovsdb/ovsdb-client.c
> @@ -1232,8 +1232,11 @@ parse_monitor_columns(char *arg, const char *server, const char *database,
>          }
>          free(nodes);
>
> -        add_column(server, ovsdb_table_schema_get_column(table, "_version"),
> -                   columns, columns_json);
> +        const struct ovsdb_column *version_column =
> +                            ovsdb_table_schema_get_column(table, "_version");
> +
> +        ovs_assert(version_column);
> +        add_column(server, version_column, columns, columns_json);
>      }
>
>      if (!initial || !insert || !delete || !modify) {
> diff --git a/ovsdb/ovsdb-util.c b/ovsdb/ovsdb-util.c
> index 303191dc8..0b9e1df54 100644
> --- a/ovsdb/ovsdb-util.c
> +++ b/ovsdb/ovsdb-util.c
> @@ -291,9 +291,15 @@ ovsdb_util_write_string_string_column(struct ovsdb_row *row,
>      size_t i;
>
>      column = ovsdb_table_schema_get_column(row->table->schema, column_name);
> +    if (!column) {
> +        VLOG_WARN("No %s column present in the %s table",
> +                 column_name, row->table->schema->name);
> +        goto unwind;
> +    }
>      datum = ovsdb_util_get_datum(row, column_name, OVSDB_TYPE_STRING,
>                                  OVSDB_TYPE_STRING, UINT_MAX);
>      if (!datum) {
> +unwind:
>          for (i = 0; i < n; i++) {
>              free(keys[i]);
>              free(values[i]);
> diff --git a/tests/ovsdb-rbac.at b/tests/ovsdb-rbac.at
> index 7de3711fb..3172e4bf5 100644
> --- a/tests/ovsdb-rbac.at
> +++ b/tests/ovsdb-rbac.at
> @@ -371,5 +371,7 @@ cat stdout >> output
>  AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
>  ], [ignore])
>
> -OVSDB_SERVER_SHUTDOWN
> +OVSDB_SERVER_SHUTDOWN(["
> +  /No status column present in the Connection table/d
> +"])
>  AT_CLEANUP
> diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at
> index b53ab8f52..8ccec80bc 100644
> --- a/tests/ovsdb-server.at
> +++ b/tests/ovsdb-server.at
> @@ -428,7 +428,9 @@ AT_CHECK(
>    [[[{"rows":[{"managers":"punix:socket1"}]},{"rows":[{"is_connected":false,"target":"punix:socket2"}]}]
>  ]],
>    [ignore])
> -OVSDB_SERVER_SHUTDOWN
> +OVSDB_SERVER_SHUTDOWN(["
> +  /No status column present in the Manager table/d
> +"])
>  AT_CLEANUP
>
>  AT_SETUP([ovsdb-server/add-remote and remove-remote])
> @@ -2110,7 +2112,9 @@ AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT \
>  cat stdout >> output
>  AT_CHECK([uuidfilt output], [0], [[[{"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}]]
>  ], [ignore])
> -OVSDB_SERVER_SHUTDOWN
> +OVSDB_SERVER_SHUTDOWN(["
> +  /No status column present in the Manager table/d
> +"])
>  AT_CLEANUP
>
>  AT_SETUP([ovsdb-server replication with schema mismatch])
> -- 
> 2.40.1
>
> _______________________________________________
> dev mailing list
> dev@openvswitch.org
> https://mail.openvswitch.org/mailman/listinfo/ovs-dev
Ilya Maximets July 11, 2023, 2:33 p.m. UTC | #3
On 7/11/23 12:13, Eelco Chaudron wrote:
> 
> 
> On 13 Jun 2023, at 20:34, James Raphael Tiovalen wrote:
> 
>> This commit adds a few null pointer assertions and checks to some return
>> values of `ovsdb_table_schema_get_column`. If a null pointer is
>> encountered in these blocks, either the assertion will fail or the
>> control flow will now be redirected to alternative paths which will
>> output the appropriate error messages.
>>
>> A few ovsdb-rbac and ovsdb-server tests are also updated to verify the
>> expected warning logs by adding said logs to the ALLOWLIST of the
>> OVSDB_SERVER_SHUTDOWN statements.
>>
>> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>
> 
> In general, this looks good, however, I’m not a ovsdb guy, so I’m wondering if the asserts could not cause any additional crashes that can be avoided by a different type of error handling. Also is there an easy way to make this crash happen by giving some invalid input?
> 
> Ilya any comments here?

'_uuid' and '_version' are internal columns that must always exist.
They are not part of the schema, ovsdb-server generates them.  So,
it must be an internal bug if they do not exist.

Best regards, Ilya Maximets.
Eelco Chaudron July 11, 2023, 2:41 p.m. UTC | #4
On 11 Jul 2023, at 16:33, Ilya Maximets wrote:

> On 7/11/23 12:13, Eelco Chaudron wrote:
>>
>>
>> On 13 Jun 2023, at 20:34, James Raphael Tiovalen wrote:
>>
>>> This commit adds a few null pointer assertions and checks to some return
>>> values of `ovsdb_table_schema_get_column`. If a null pointer is
>>> encountered in these blocks, either the assertion will fail or the
>>> control flow will now be redirected to alternative paths which will
>>> output the appropriate error messages.
>>>
>>> A few ovsdb-rbac and ovsdb-server tests are also updated to verify the
>>> expected warning logs by adding said logs to the ALLOWLIST of the
>>> OVSDB_SERVER_SHUTDOWN statements.
>>>
>>> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>
>>
>> In general, this looks good, however, I’m not a ovsdb guy, so I’m wondering if the asserts could not cause any additional crashes that can be avoided by a different type of error handling. Also is there an easy way to make this crash happen by giving some invalid input?
>>
>> Ilya any comments here?
>
> '_uuid' and '_version' are internal columns that must always exist.
> They are not part of the schema, ovsdb-server generates them.  So,
> it must be an internal bug if they do not exist.

Thanks for confirming/clarification. With this;

Acked-by: Eelco Chaudron <echaudro@redhat.com>
Ilya Maximets July 12, 2023, 12:09 a.m. UTC | #5
On 7/11/23 16:41, Eelco Chaudron wrote:
> 
> 
> On 11 Jul 2023, at 16:33, Ilya Maximets wrote:
> 
>> On 7/11/23 12:13, Eelco Chaudron wrote:
>>>
>>>
>>> On 13 Jun 2023, at 20:34, James Raphael Tiovalen wrote:
>>>
>>>> This commit adds a few null pointer assertions and checks to some return
>>>> values of `ovsdb_table_schema_get_column`. If a null pointer is
>>>> encountered in these blocks, either the assertion will fail or the
>>>> control flow will now be redirected to alternative paths which will
>>>> output the appropriate error messages.
>>>>
>>>> A few ovsdb-rbac and ovsdb-server tests are also updated to verify the
>>>> expected warning logs by adding said logs to the ALLOWLIST of the
>>>> OVSDB_SERVER_SHUTDOWN statements.
>>>>
>>>> Signed-off-by: James Raphael Tiovalen <jamestiotio@gmail.com>
>>>
>>> In general, this looks good, however, I’m not a ovsdb guy, so I’m wondering if the asserts could not cause any additional crashes that can be avoided by a different type of error handling. Also is there an easy way to make this crash happen by giving some invalid input?
>>>
>>> Ilya any comments here?
>>
>> '_uuid' and '_version' are internal columns that must always exist.
>> They are not part of the schema, ovsdb-server generates them.  So,
>> it must be an internal bug if they do not exist.
> 
> Thanks for confirming/clarification. With this;
> 
> Acked-by: Eelco Chaudron <echaudro@redhat.com>

Thanks, James, Simon and Eelco!

Applied this one.

Best regards, Ilya Maximets.
diff mbox series

Patch

diff --git a/ovsdb/condition.c b/ovsdb/condition.c
index 09c89b2a0..5a3eb4e8a 100644
--- a/ovsdb/condition.c
+++ b/ovsdb/condition.c
@@ -47,7 +47,10 @@  ovsdb_clause_from_json(const struct ovsdb_table_schema *ts,
 
         /* Column and arg fields are not being used with boolean functions.
          * Use dummy values */
-        clause->column = ovsdb_table_schema_get_column(ts, "_uuid");
+        const struct ovsdb_column *uuid_column =
+                                  ovsdb_table_schema_get_column(ts, "_uuid");
+        ovs_assert(uuid_column);
+        clause->column = uuid_column;
         clause->index = clause->column->index;
         ovsdb_datum_init_default(&clause->arg, &clause->column->type);
         return NULL;
diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
index bae2c5f04..46484630d 100644
--- a/ovsdb/ovsdb-client.c
+++ b/ovsdb/ovsdb-client.c
@@ -1232,8 +1232,11 @@  parse_monitor_columns(char *arg, const char *server, const char *database,
         }
         free(nodes);
 
-        add_column(server, ovsdb_table_schema_get_column(table, "_version"),
-                   columns, columns_json);
+        const struct ovsdb_column *version_column =
+                            ovsdb_table_schema_get_column(table, "_version");
+
+        ovs_assert(version_column);
+        add_column(server, version_column, columns, columns_json);
     }
 
     if (!initial || !insert || !delete || !modify) {
diff --git a/ovsdb/ovsdb-util.c b/ovsdb/ovsdb-util.c
index 303191dc8..0b9e1df54 100644
--- a/ovsdb/ovsdb-util.c
+++ b/ovsdb/ovsdb-util.c
@@ -291,9 +291,15 @@  ovsdb_util_write_string_string_column(struct ovsdb_row *row,
     size_t i;
 
     column = ovsdb_table_schema_get_column(row->table->schema, column_name);
+    if (!column) {
+        VLOG_WARN("No %s column present in the %s table",
+                 column_name, row->table->schema->name);
+        goto unwind;
+    }
     datum = ovsdb_util_get_datum(row, column_name, OVSDB_TYPE_STRING,
                                 OVSDB_TYPE_STRING, UINT_MAX);
     if (!datum) {
+unwind:
         for (i = 0; i < n; i++) {
             free(keys[i]);
             free(values[i]);
diff --git a/tests/ovsdb-rbac.at b/tests/ovsdb-rbac.at
index 7de3711fb..3172e4bf5 100644
--- a/tests/ovsdb-rbac.at
+++ b/tests/ovsdb-rbac.at
@@ -371,5 +371,7 @@  cat stdout >> output
 AT_CHECK([uuidfilt stdout], [0], [[[{"count":1}]]
 ], [ignore])
 
-OVSDB_SERVER_SHUTDOWN
+OVSDB_SERVER_SHUTDOWN(["
+  /No status column present in the Connection table/d
+"])
 AT_CLEANUP
diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at
index b53ab8f52..8ccec80bc 100644
--- a/tests/ovsdb-server.at
+++ b/tests/ovsdb-server.at
@@ -428,7 +428,9 @@  AT_CHECK(
   [[[{"rows":[{"managers":"punix:socket1"}]},{"rows":[{"is_connected":false,"target":"punix:socket2"}]}]
 ]], 
   [ignore])
-OVSDB_SERVER_SHUTDOWN
+OVSDB_SERVER_SHUTDOWN(["
+  /No status column present in the Manager table/d
+"])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server/add-remote and remove-remote])
@@ -2110,7 +2112,9 @@  AT_CHECK([ovsdb-client transact tcp:127.0.0.1:$TCP_PORT \
 cat stdout >> output
 AT_CHECK([uuidfilt output], [0], [[[{"details":"insert operation not allowed when database server is in read only mode","error":"not allowed"}]]
 ], [ignore])
-OVSDB_SERVER_SHUTDOWN
+OVSDB_SERVER_SHUTDOWN(["
+  /No status column present in the Manager table/d
+"])
 AT_CLEANUP
 
 AT_SETUP([ovsdb-server replication with schema mismatch])