names: flush policy TALK cache when a connection loses a name
authorDaniel Mack <zonque@gmail.com>
Thu, 14 Aug 2014 14:36:40 +0000 (16:36 +0200)
committerDaniel Mack <zonque@gmail.com>
Thu, 14 Aug 2014 20:12:16 +0000 (22:12 +0200)
When a connection loses a name, make sure cache entries that allow
TALK access to it are properly removed. Upon the next TALK query,
the connection's names will be iterated and checked again.

connection.c
connection.h
names.c

index 342c8705120a23ae10c265e614f54b8ccb41368a..47e526c471c83bb8f7f58a6b3b17a7b44c273966 100644 (file)
@@ -1545,6 +1545,20 @@ bool kdbus_conn_active(const struct kdbus_conn *conn)
        return conn->type != KDBUS_CONN_DISCONNECTED;
 }
 
+/**
+ * kdbus_conn_flush_policy() - flush all cached policy entries that
+ *                            refer to a connecion
+ * @conn:      Connection to check
+ */
+void kdbus_conn_flush_policy(struct kdbus_conn *conn)
+{
+       if (conn->ep->policy_db)
+               kdbus_policy_remove_conn(conn->ep->policy_db, conn);
+
+       if (conn->bus->policy_db)
+               kdbus_policy_remove_conn(conn->bus->policy_db, conn);
+}
+
 static void __kdbus_conn_free(struct kref *kref)
 {
        struct kdbus_conn *conn = container_of(kref, struct kdbus_conn, kref);
@@ -1559,13 +1573,10 @@ static void __kdbus_conn_free(struct kref *kref)
        atomic_dec(&conn->user->connections);
        kdbus_domain_user_unref(conn->user);
 
-       if (conn->ep->policy_db)
-               kdbus_policy_remove_conn(conn->ep->policy_db, conn);
+       kdbus_conn_flush_policy(conn);
 
-       if (conn->bus->policy_db) {
-               kdbus_policy_remove_conn(conn->bus->policy_db, conn);
+       if (conn->bus->policy_db)
                kdbus_policy_remove_owner(conn->bus->policy_db, conn);
-       }
 
        kdbus_meta_free(conn->owner_meta);
        kdbus_match_db_free(conn->match_db);
index 7b61b1a0ed96507f6e25a703bb5e6f2ed0274c7b..12f1df6970eb10cd455fb49eb0b7e55819096288 100644 (file)
@@ -122,6 +122,7 @@ struct kdbus_conn *kdbus_conn_ref(struct kdbus_conn *conn);
 struct kdbus_conn *kdbus_conn_unref(struct kdbus_conn *conn);
 int kdbus_conn_disconnect(struct kdbus_conn *conn, bool ensure_queue_empty);
 bool kdbus_conn_active(const struct kdbus_conn *conn);
+void kdbus_conn_flush_policy(struct kdbus_conn *conn);
 
 int kdbus_cmd_msg_recv(struct kdbus_conn *conn,
                       struct kdbus_cmd_recv *recv);
diff --git a/names.c b/names.c
index 78c5455942b239ad4c2c48411e3137c158fd59b1..f14e80ebb01027e1799177ef047ce5e53b57ed36 100644 (file)
--- a/names.c
+++ b/names.c
@@ -282,6 +282,14 @@ static int kdbus_name_release(struct kdbus_name_registry *reg,
                }
        }
 
+       /*
+        * Now that the connection has lost a name, purge all cached policy
+        * entries, so upon the next message, TALK access will be checked
+        * against the names the connection actually owns.
+        */
+       if (ret == 0)
+               kdbus_conn_flush_policy(conn);
+
 exit_unlock:
        up_write(&reg->rwlock);
        mutex_unlock(&conn->bus->lock);