summaryrefslogtreecommitdiff
path: root/src/shared/varlink.c
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2023-04-12 11:21:01 +0200
committerLennart Poettering <lennart@poettering.net>2023-04-12 15:14:21 +0200
commitdb1f7c84ea55441ca3409ac24e0d8be084a5092a (patch)
tree96e8be149355814abac8a60edfd83d2b257b329f /src/shared/varlink.c
parent7947dbe322a922604f3a5b29693e58b370161ad5 (diff)
downloadsystemd-db1f7c84ea55441ca3409ac24e0d8be084a5092a.tar.gz
varlink: honour "sensitive" flag of json variant objects all the way into the socket
Let's honour the flag if it is set, just to be safe. (This only handles the case for the writing side: whenever the client code hands us a json object with the flag set we'll honour it till the it's out of reach for us. This does *not* handle the reading side, which is left for a later patch once needed. We probably should add a per-connection flag that simply globally enables the sensitive logic for all messages coming in on a specific varlink conneciton.)
Diffstat (limited to 'src/shared/varlink.c')
-rw-r--r--src/shared/varlink.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/src/shared/varlink.c b/src/shared/varlink.c
index eb2b3c39b2..d15f50dbb2 100644
--- a/src/shared/varlink.c
+++ b/src/shared/varlink.c
@@ -171,6 +171,8 @@ struct Varlink {
bool allow_fd_passing_input:1;
bool allow_fd_passing_output:1;
+ bool output_buffer_sensitive:1; /* whether to erase the output buffer after writing it to the socket */
+
int af; /* address family if socket; AF_UNSPEC if not socket; negative if not known */
usec_t timestamp;
@@ -453,7 +455,7 @@ static void varlink_clear(Varlink *v) {
varlink_clear_current(v);
v->input_buffer = mfree(v->input_buffer);
- v->output_buffer = mfree(v->output_buffer);
+ v->output_buffer = v->output_buffer_sensitive ? erase_and_free(v->output_buffer) : mfree(v->output_buffer);
varlink_clear_current(v);
@@ -610,11 +612,15 @@ static int varlink_write(Varlink *v) {
return -errno;
}
+ if (v->output_buffer_sensitive)
+ explicit_bzero_safe(v->output_buffer + v->output_buffer_index, n);
+
v->output_buffer_size -= n;
- if (v->output_buffer_size == 0)
+ if (v->output_buffer_size == 0) {
v->output_buffer_index = 0;
- else
+ v->output_buffer_sensitive = false; /* We can reset the sensitive flag once the buffer is empty */
+ } else
v->output_buffer_index += n;
close_many(v->output_fds, v->n_output_fds);
@@ -1437,7 +1443,7 @@ Varlink* varlink_flush_close_unref(Varlink *v) {
}
static int varlink_format_json(Varlink *v, JsonVariant *m) {
- _cleanup_free_ char *text = NULL;
+ _cleanup_(erase_and_freep) char *text = NULL;
int r;
assert(v);
@@ -1467,7 +1473,6 @@ static int varlink_format_json(Varlink *v, JsonVariant *m) {
memcpy(v->output_buffer + v->output_buffer_size, text, r + 1);
v->output_buffer_size += r + 1;
-
} else {
char *n;
const size_t new_size = v->output_buffer_size + r + 1;
@@ -1483,6 +1488,11 @@ static int varlink_format_json(Varlink *v, JsonVariant *m) {
v->output_buffer_index = 0;
}
+ if (json_variant_is_sensitive(m))
+ v->output_buffer_sensitive = true; /* Propagate sensitive flag */
+ else
+ text = mfree(text); /* No point in the erase_and_free() destructor declared above */
+
return 0;
}