summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to '0045-tools-xenstore-Fail-a-transaction-if-it-is-not-possi.patch')
-rw-r--r--0045-tools-xenstore-Fail-a-transaction-if-it-is-not-possi.patch145
1 files changed, 0 insertions, 145 deletions
diff --git a/0045-tools-xenstore-Fail-a-transaction-if-it-is-not-possi.patch b/0045-tools-xenstore-Fail-a-transaction-if-it-is-not-possi.patch
deleted file mode 100644
index 4ca6c93..0000000
--- a/0045-tools-xenstore-Fail-a-transaction-if-it-is-not-possi.patch
+++ /dev/null
@@ -1,145 +0,0 @@
-From 427e86b48836a9511f57004ca367283cd85cd30f Mon Sep 17 00:00:00 2001
-From: Julien Grall <jgrall@amazon.com>
-Date: Tue, 13 Sep 2022 07:35:06 +0200
-Subject: [PATCH 45/87] tools/xenstore: Fail a transaction if it is not
- possible to create a node
-
-Commit f2bebf72c4d5 "xenstore: rework of transaction handling" moved
-out from copying the entire database everytime a new transaction is
-opened to track the list of nodes changed.
-
-The content of all the nodes accessed during a transaction will be
-temporarily stored in TDB using a different key.
-
-The function create_node() may write/update multiple nodes if the child
-doesn't exist. In case of a failure, the function will revert any
-changes (this include any update to TDB). Unfortunately, the function
-which reverts the changes (i.e. destroy_node()) will not use the correct
-key to delete any update or even request the transaction to fail.
-
-This means that if a client decide to go ahead with committing the
-transaction, orphan nodes will be created because they were not linked
-to an existing node (create_node() will write the nodes backwards).
-
-Once some nodes have been partially updated in a transaction, it is not
-easily possible to undo any changes. So rather than continuing and hit
-weird issue while committing, it is much saner to fail the transaction.
-
-This will have an impact on any client that decides to commit even if it
-can't write a node. Although, it is not clear why a normal client would
-want to do that...
-
-Lastly, update destroy_node() to use the correct key for deleting the
-node. Rather than recreating it (this will allocate memory and
-therefore fail), stash the key in the structure node.
-
-This is XSA-415 / CVE-2022-42310.
-
-Signed-off-by: Julien Grall <jgrall@amazon.com>
-Reviewed-by: Juergen Gross <jgross@suse.com>
-(cherry picked from commit 5d71766bd1a4a3a8b2fe952ca2be80e02fe48f34)
----
- tools/xenstore/xenstored_core.c | 23 +++++++++++++++--------
- tools/xenstore/xenstored_core.h | 2 ++
- tools/xenstore/xenstored_transaction.c | 5 +++++
- tools/xenstore/xenstored_transaction.h | 3 +++
- 4 files changed, 25 insertions(+), 8 deletions(-)
-
-diff --git a/tools/xenstore/xenstored_core.c b/tools/xenstore/xenstored_core.c
-index 29947c3020c3..e9c9695fd16e 100644
---- a/tools/xenstore/xenstored_core.c
-+++ b/tools/xenstore/xenstored_core.c
-@@ -566,15 +566,17 @@ int write_node_raw(struct connection *conn, TDB_DATA *key, struct node *node,
- return 0;
- }
-
-+/*
-+ * Write the node. If the node is written, caller can find the key used in
-+ * node->key. This can later be used if the change needs to be reverted.
-+ */
- static int write_node(struct connection *conn, struct node *node,
- bool no_quota_check)
- {
-- TDB_DATA key;
--
-- if (access_node(conn, node, NODE_ACCESS_WRITE, &key))
-+ if (access_node(conn, node, NODE_ACCESS_WRITE, &node->key))
- return errno;
-
-- return write_node_raw(conn, &key, node, no_quota_check);
-+ return write_node_raw(conn, &node->key, node, no_quota_check);
- }
-
- unsigned int perm_for_conn(struct connection *conn,
-@@ -1090,16 +1092,21 @@ nomem:
-
- static int destroy_node(struct connection *conn, struct node *node)
- {
-- TDB_DATA key;
--
- if (streq(node->name, "/"))
- corrupt(NULL, "Destroying root node!");
-
-- set_tdb_key(node->name, &key);
-- tdb_delete(tdb_ctx, key);
-+ tdb_delete(tdb_ctx, node->key);
-
- domain_entry_dec(conn, node);
-
-+ /*
-+ * It is not possible to easily revert the changes in a transaction.
-+ * So if the failure happens in a transaction, mark it as fail to
-+ * prevent any commit.
-+ */
-+ if ( conn->transaction )
-+ fail_transaction(conn->transaction);
-+
- return 0;
- }
-
-diff --git a/tools/xenstore/xenstored_core.h b/tools/xenstore/xenstored_core.h
-index 07d861d92499..0004fa848c83 100644
---- a/tools/xenstore/xenstored_core.h
-+++ b/tools/xenstore/xenstored_core.h
-@@ -155,6 +155,8 @@ struct node_perms {
-
- struct node {
- const char *name;
-+ /* Key used to update TDB */
-+ TDB_DATA key;
-
- /* Parent (optional) */
- struct node *parent;
-diff --git a/tools/xenstore/xenstored_transaction.c b/tools/xenstore/xenstored_transaction.c
-index cd07fb0f218b..faf6c930e42a 100644
---- a/tools/xenstore/xenstored_transaction.c
-+++ b/tools/xenstore/xenstored_transaction.c
-@@ -580,6 +580,11 @@ void transaction_entry_dec(struct transaction *trans, unsigned int domid)
- list_add_tail(&d->list, &trans->changed_domains);
- }
-
-+void fail_transaction(struct transaction *trans)
-+{
-+ trans->fail = true;
-+}
-+
- void conn_delete_all_transactions(struct connection *conn)
- {
- struct transaction *trans;
-diff --git a/tools/xenstore/xenstored_transaction.h b/tools/xenstore/xenstored_transaction.h
-index 43a162bea3f3..14062730e3c9 100644
---- a/tools/xenstore/xenstored_transaction.h
-+++ b/tools/xenstore/xenstored_transaction.h
-@@ -46,6 +46,9 @@ int access_node(struct connection *conn, struct node *node,
- int transaction_prepend(struct connection *conn, const char *name,
- TDB_DATA *key);
-
-+/* Mark the transaction as failed. This will prevent it to be committed. */
-+void fail_transaction(struct transaction *trans);
-+
- void conn_delete_all_transactions(struct connection *conn);
- int check_transactions(struct hashtable *hash);
-
---
-2.37.4
-