ovsdb-idl: Don't even try to modify synthetic rows, instead of segfaulting.
authorBen Pfaff <blp@nicira.com>
Wed, 26 Oct 2011 22:46:48 +0000 (15:46 -0700)
committerBen Pfaff <blp@nicira.com>
Thu, 27 Oct 2011 17:36:30 +0000 (10:36 -0700)
Synthetic rows lack a lot of important metadata that the IDL adds to rows
actually obtained from the database, and it's impractical to add that
metadata to synthetic rows.  This means that the IDL functions to modify
these rows dereference null pointers and segfault.  So, it's really
important not to pass synthetic rows to such functions.  However, we've
screwed this up a number of times now and in the end it seems that it's
probably better to just ignore attempts to modify these rows.  This commit
implements that.

Feature #8013.
Reported-by: Ethan Jackson <ethan@nicira.com>
lib/ovsdb-idl.c

index 11ca6b9..56b4328 100644 (file)
@@ -1705,8 +1705,15 @@ ovsdb_idl_txn_write(const struct ovsdb_idl_row *row_,
                     struct ovsdb_datum *datum)
 {
     struct ovsdb_idl_row *row = (struct ovsdb_idl_row *) row_;
-    const struct ovsdb_idl_table_class *class = row->table->class;
-    size_t column_idx = column - class->columns;
+    const struct ovsdb_idl_table_class *class;
+    size_t column_idx;
+
+    if (ovsdb_idl_row_is_synthetic(row)) {
+        return;
+    }
+
+    class = row->table->class;
+    column_idx = column - class->columns;
 
     assert(row->new != NULL);
     assert(column_idx < class->n_columns);
@@ -1782,8 +1789,15 @@ ovsdb_idl_txn_verify(const struct ovsdb_idl_row *row_,
                      const struct ovsdb_idl_column *column)
 {
     struct ovsdb_idl_row *row = (struct ovsdb_idl_row *) row_;
-    const struct ovsdb_idl_table_class *class = row->table->class;
-    size_t column_idx = column - class->columns;
+    const struct ovsdb_idl_table_class *class;
+    size_t column_idx;
+
+    if (ovsdb_idl_row_is_synthetic(row)) {
+        return;
+    }
+
+    class = row->table->class;
+    column_idx = column - class->columns;
 
     assert(row->new != NULL);
     assert(row->old == NULL ||
@@ -1815,6 +1829,10 @@ ovsdb_idl_txn_delete(const struct ovsdb_idl_row *row_)
 {
     struct ovsdb_idl_row *row = (struct ovsdb_idl_row *) row_;
 
+    if (ovsdb_idl_row_is_synthetic(row)) {
+        return;
+    }
+
     assert(row->new != NULL);
     if (!row->old) {
         ovsdb_idl_row_unparse(row);