summaryrefslogtreecommitdiffstats
path: root/kdbus-forward-ID-notifications-to-everyone.patch
blob: b9cd4daa1279c39729abbdcba16942c6490a7ecf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
From: David Herrmann <dh.herrmann@gmail.com>
Date: Tue, 26 May 2015 09:30:14 +0200
Subject: [PATCH] kdbus: forward ID notifications to everyone

Even if you cannot SEE another peer (eg., if you're behind a private
endpoint), the other peer might be able to TALK to you. Therefore, you
might get messages from them. This works mostly fine, with one major
exception, that you cannot track the remote peer. You will not receive ID
notifications for it, thus, you don't get notified when they disconnect.
This is unforunate and breaks sandboxes kdbus peers.

Fix this by forwarding ID notifications to everyone. Note that those
notifications don't carry _any_ useful information, besides the peer ID.
Therefore, even if you should not able to SEE a peer, you will now still
get ID notifications. This does not reveal any additional information on
the remote peer, besides its lifetime. Hence, it should be fine.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Acked-by: Daniel Mack <daniel@zonque.org>
---
 ipc/kdbus/connection.c                        |  8 +++-----
 tools/testing/selftests/kdbus/test-endpoint.c | 13 ++++++++++++-
 2 files changed, 15 insertions(+), 6 deletions(-)

diff --git a/ipc/kdbus/connection.c b/ipc/kdbus/connection.c
index fb2c6c67c4c1..272b991f36f4 100644
--- a/ipc/kdbus/connection.c
+++ b/ipc/kdbus/connection.c
@@ -1588,10 +1588,8 @@ bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
 	 *     to a peer if, and only if, that peer can see the name this
 	 *     notification is for.
 	 *
-	 * KDBUS_ITEM_ID_{ADD,REMOVE}: As new peers cannot have names, and all
-	 *     names are dropped before a peer is removed, those notifications
-	 *     cannot be seen on custom endpoints. Thus, we only pass them
-	 *     through on default endpoints.
+	 * KDBUS_ITEM_ID_{ADD,REMOVE}: Notifications for ID changes are
+	 *     broadcast to everyone, to allow tracking peers.
 	 */
 
 	switch (kmsg->notify_type) {
@@ -1603,7 +1601,7 @@ bool kdbus_conn_policy_see_notification(struct kdbus_conn *conn,
 
 	case KDBUS_ITEM_ID_ADD:
 	case KDBUS_ITEM_ID_REMOVE:
-		return !conn->ep->user;
+		return true;
 
 	default:
 		WARN(1, "Invalid type for notification broadcast: %llu\n",
diff --git a/tools/testing/selftests/kdbus/test-endpoint.c b/tools/testing/selftests/kdbus/test-endpoint.c
index dcc6ab91c4e6..34a7be49c482 100644
--- a/tools/testing/selftests/kdbus/test-endpoint.c
+++ b/tools/testing/selftests/kdbus/test-endpoint.c
@@ -255,6 +255,13 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
 	ep_conn = kdbus_hello(ep, 0, NULL, 0);
 	ASSERT_RETURN(ep_conn);
 
+	/* Check that the reader got the IdAdd notification */
+	ret = kdbus_msg_recv(reader, &msg, NULL);
+	ASSERT_RETURN(ret == 0);
+	ASSERT_RETURN(msg->items[0].type == KDBUS_ITEM_ID_ADD);
+	ASSERT_RETURN(msg->items[0].id_change.id == ep_conn->id);
+	kdbus_msg_free(msg);
+
 	/*
 	 * Add a name add match on the endpoint connection, acquire name from
 	 * the unfiltered connection, and make sure the filtered connection
@@ -283,7 +290,7 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
 	ret = kdbus_conn_info(ep_conn, 0x0fffffffffffffffULL, NULL, 0, NULL);
 	ASSERT_RETURN(ret == -ENXIO);
 
-	/* Check that the reader did not receive anything */
+	/* Check that the reader did not receive the name notification */
 	ret = kdbus_msg_recv(reader, NULL, NULL);
 	ASSERT_RETURN(ret == -EAGAIN);
 
@@ -295,6 +302,10 @@ int kdbus_test_custom_endpoint(struct kdbus_test_env *env)
 	ret = kdbus_name_release(env->conn, name);
 	ASSERT_RETURN(ret == 0);
 
+	/* Check that the reader did not receive the name notification */
+	ret = kdbus_msg_recv(reader, NULL, NULL);
+	ASSERT_RETURN(ret == -EAGAIN);
+
 	ret = update_endpoint(ep_fd, name);
 	ASSERT_RETURN(ret == 0);