summaryrefslogtreecommitdiff
path: root/ctdb
diff options
context:
space:
mode:
authorMartin Schwenke <martin@meltin.net>2019-05-06 15:22:49 +1000
committerKarolin Seeger <kseeger@samba.org>2019-05-17 07:18:30 +0000
commit1c2c081f439fa7c9b9c5c67978efecf081229a9b (patch)
treed92f06fa049a344b5e11006decc15339f01d7b7d /ctdb
parent24d70220b28f6ee7d629a6900af37ae25ecca296 (diff)
downloadsamba-1c2c081f439fa7c9b9c5c67978efecf081229a9b.tar.gz
ctdb-daemon: Never use 0 as a client ID
ctdb_control_db_attach() and ctdb_control_db_detach() assume that any control with client ID 0 comes from another daemon and treat it specially. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13930 Signed-off-by: Martin Schwenke <martin@meltin.net> Reviewed-by: Amitay Isaacs <amitay@gmail.com> (cherry picked from commit 8663e0a64fbdb9ea16babbfe87d6f5d7a7b72bbd)
Diffstat (limited to 'ctdb')
-rw-r--r--ctdb/server/ctdb_daemon.c48
1 files changed, 47 insertions, 1 deletions
diff --git a/ctdb/server/ctdb_daemon.c b/ctdb/server/ctdb_daemon.c
index 8247859f9b5..ca98be6a100 100644
--- a/ctdb/server/ctdb_daemon.c
+++ b/ctdb/server/ctdb_daemon.c
@@ -928,6 +928,44 @@ static int ctdb_clientpid_destructor(struct ctdb_client_pid_list *client_pid)
return 0;
}
+static int get_new_client_id(struct reqid_context *idr,
+ struct ctdb_client *client,
+ uint32_t *out)
+{
+ uint32_t client_id;
+
+ client_id = reqid_new(idr, client);
+ /*
+ * Some places in the code (e.g. ctdb_control_db_attach(),
+ * ctdb_control_db_detach()) assign a special meaning to
+ * client_id 0. The assumption is that if client_id is 0 then
+ * the control has come from another daemon. Therefore, we
+ * should never return client_id == 0.
+ */
+ if (client_id == 0) {
+ /*
+ * Don't leak ID 0. This is safe because the ID keeps
+ * increasing. A test will be added to ensure that
+ * this doesn't change.
+ */
+ reqid_remove(idr, 0);
+
+ client_id = reqid_new(idr, client);
+ }
+
+ if (client_id == REQID_INVALID) {
+ return EINVAL;
+ }
+
+ if (client_id == 0) {
+ /* Every other ID must have been used and we can't use 0 */
+ reqid_remove(idr, 0);
+ return EINVAL;
+ }
+
+ *out = client_id;
+ return 0;
+}
static void ctdb_accept_client(struct tevent_context *ev,
struct tevent_fd *fde, uint16_t flags,
@@ -971,7 +1009,15 @@ static void ctdb_accept_client(struct tevent_context *ev,
client->ctdb = ctdb;
client->fd = fd;
- client->client_id = reqid_new(ctdb->idr, client);
+
+ ret = get_new_client_id(ctdb->idr, client, &client->client_id);
+ if (ret != 0) {
+ DBG_ERR("Unable to get client ID (%d)\n", ret);
+ close(fd);
+ talloc_free(client);
+ return;
+ }
+
client->pid = peer_pid;
client_pid = talloc(client, struct ctdb_client_pid_list);