Skip to content

Commit

Permalink
ovsdb: Fix incorrect sharing of UUID and _version columns.
Browse files Browse the repository at this point in the history
Datum of UUID and _version columns is accessed directly via
ovsdb_row_get_uuid_rw() and ovsdb_row_get_version_rw() functions
instead of ovsdb_data_* functions.  Meaning, the data will be
directly modified even if it is shared between rows.

Fix that by unsharing the data whenever RW pointer is taken.

The issue was mostly hidden because weak reference assessment
code always called ovsdb_datum_subtract() even if not needed.
This way all the new transaction rows were always implicitly
unshared.

Also making ovsdb_datum_subtract() call conditional, so the
issue can be hit by existing unit tests.

Fixes: 485ac63 ("ovsdb: Add lazy-copy support for ovsdb_datum objects.")
Signed-off-by: Ilya Maximets <[email protected]>
Signed-off-by: 0-day Robot <[email protected]>
  • Loading branch information
igsilya authored and ovsrobot committed Dec 18, 2023
1 parent 4cbbf56 commit 8085d55
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 2 deletions.
2 changes: 2 additions & 0 deletions ovsdb/row.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ ovsdb_row_get_uuid(const struct ovsdb_row *row)
static inline struct uuid *
ovsdb_row_get_uuid_rw(struct ovsdb_row *row)
{
ovsdb_datum_unshare(&row->fields[OVSDB_COL_UUID], &ovsdb_type_uuid);
return &row->fields[OVSDB_COL_UUID].keys[0].uuid;
}

Expand All @@ -142,6 +143,7 @@ ovsdb_row_get_version(const struct ovsdb_row *row)
static inline struct uuid *
ovsdb_row_get_version_rw(struct ovsdb_row *row)
{
ovsdb_datum_unshare(&row->fields[OVSDB_COL_VERSION], &ovsdb_type_uuid);
return &row->fields[OVSDB_COL_VERSION].keys[0].uuid;
}

Expand Down
6 changes: 4 additions & 2 deletions ovsdb/transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -733,8 +733,10 @@ assess_weak_refs(struct ovsdb_txn *txn, struct ovsdb_txn_row *txn_row)
ovsdb_datum_sort_unique(&deleted_refs, &column->type);

/* Removing elements that references deleted rows. */
ovsdb_datum_subtract(datum, &column->type,
&deleted_refs, &column->type);
if (deleted_refs.n) {
ovsdb_datum_subtract(datum, &column->type,
&deleted_refs, &column->type);
}
ovsdb_datum_destroy(&deleted_refs, &column->type);

/* Generating the difference between old and new data. */
Expand Down

0 comments on commit 8085d55

Please sign in to comment.