X Tutup
Skip to content

Commit 7a77d2a

Browse files
committed
sd-bus: add new call sd_bus_message_sensitive() and SD_BUS_VTABLE_SENSITIVE
This allows marking messages that contain "sensitive" data with a flag. If it's set then the messages are erased from memory when the message is freed. Similar, a flag may be set on vtable entries: incoming/outgoing message matching the entry will then automatically be flagged this way. This is supposed to be an easy method to mark messages containing potentially sensitive data (such as passwords) for proper destruction. (Note that this of course is only is as safe as the broker in between is doing something similar. But let's at least not be the ones at fault here.)
1 parent f9f8268 commit 7a77d2a

File tree

6 files changed

+59
-6
lines changed

6 files changed

+59
-6
lines changed

src/libsystemd/libsystemd.sym

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -685,6 +685,7 @@ global:
685685

686686
LIBSYSTEMD_245 {
687687
global:
688+
sd_bus_message_sensitive;
688689
sd_event_add_child_pidfd;
689690
sd_event_source_get_child_pidfd;
690691
sd_event_source_get_child_pidfd_own;

src/libsystemd/sd-bus/bus-message.c

Lines changed: 31 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,12 +45,24 @@ static void message_free_part(sd_bus_message *m, struct bus_body_part *part) {
4545
assert(m);
4646
assert(part);
4747

48-
if (part->memfd >= 0)
48+
if (part->memfd >= 0) {
49+
/* erase if requested, but ony if the memfd is not sealed yet, i.e. is writable */
50+
if (m->sensitive && !m->sealed)
51+
explicit_bzero_safe(part->data, part->size);
52+
4953
close_and_munmap(part->memfd, part->mmap_begin, part->mapped);
50-
else if (part->munmap_this)
54+
} else if (part->munmap_this)
55+
/* We don't erase sensitive data here, since the data is memory mapped from someone else, and
56+
* we just don't know if it's OK to write to it */
5157
munmap(part->mmap_begin, part->mapped);
52-
else if (part->free_this)
53-
free(part->data);
58+
else {
59+
/* Erase this if that is requested. Since this is regular memory we know we can write it. */
60+
if (m->sensitive)
61+
explicit_bzero_safe(part->data, part->size);
62+
63+
if (part->free_this)
64+
free(part->data);
65+
}
5466

5567
if (part != &m->body)
5668
free(part);
@@ -113,11 +125,11 @@ static void message_reset_containers(sd_bus_message *m) {
113125
static sd_bus_message* message_free(sd_bus_message *m) {
114126
assert(m);
115127

128+
message_reset_parts(m);
129+
116130
if (m->free_header)
117131
free(m->header);
118132

119-
message_reset_parts(m);
120-
121133
/* Note that we don't unref m->bus here. That's already done by sd_bus_message_unref() as each user
122134
* reference to the bus message also is considered a reference to the bus connection itself. */
123135

@@ -727,6 +739,12 @@ static int message_new_reply(
727739
t->dont_send = !!(call->header->flags & BUS_MESSAGE_NO_REPLY_EXPECTED);
728740
t->enforced_reply_signature = call->enforced_reply_signature;
729741

742+
/* let's copy the sensitive flag over. Let's do that as a safety precaution to keep a transaction
743+
* wholly sensitive if already the incoming message was sensitive. This is particularly useful when a
744+
* vtable record sets the SD_BUS_VTABLE_SENSITIVE flag on a method call, since this means it applies
745+
* to both the message call and the reply. */
746+
t->sensitive = call->sensitive;
747+
730748
*m = TAKE_PTR(t);
731749
return 0;
732750
}
@@ -5919,3 +5937,10 @@ _public_ int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) {
59195937
m->priority = priority;
59205938
return 0;
59215939
}
5940+
5941+
_public_ int sd_bus_message_sensitive(sd_bus_message *m) {
5942+
assert_return(m, -EINVAL);
5943+
5944+
m->sensitive = true;
5945+
return 0;
5946+
}

src/libsystemd/sd-bus/bus-message.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ struct sd_bus_message {
8585
bool free_header:1;
8686
bool free_fds:1;
8787
bool poisoned:1;
88+
bool sensitive:1;
8889

8990
/* The first and last bytes of the message */
9091
struct bus_header *header;

src/libsystemd/sd-bus/bus-objects.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,12 @@ static int method_callbacks_run(
353353
if (require_fallback && !c->parent->is_fallback)
354354
return 0;
355355

356+
if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
357+
r = sd_bus_message_sensitive(m);
358+
if (r < 0)
359+
return r;
360+
}
361+
356362
r = check_access(bus, m, c, &error);
357363
if (r < 0)
358364
return bus_maybe_reply_error(m, r, &error);
@@ -577,6 +583,12 @@ static int property_get_set_callbacks_run(
577583
if (require_fallback && !c->parent->is_fallback)
578584
return 0;
579585

586+
if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
587+
r = sd_bus_message_sensitive(m);
588+
if (r < 0)
589+
return r;
590+
}
591+
580592
r = vtable_property_get_userdata(bus, m->path, c, &u, &error);
581593
if (r <= 0)
582594
return bus_maybe_reply_error(m, r, &error);
@@ -591,6 +603,12 @@ static int property_get_set_callbacks_run(
591603
if (r < 0)
592604
return r;
593605

606+
if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
607+
r = sd_bus_message_sensitive(reply);
608+
if (r < 0)
609+
return r;
610+
}
611+
594612
if (is_get) {
595613
/* Note that we do not protect against reexecution
596614
* here (using the last_iteration check, see below),
@@ -692,6 +710,12 @@ static int vtable_append_one_property(
692710
assert(c);
693711
assert(v);
694712

713+
if (FLAGS_SET(c->vtable->flags, SD_BUS_VTABLE_SENSITIVE)) {
714+
r = sd_bus_message_sensitive(reply);
715+
if (r < 0)
716+
return r;
717+
}
718+
695719
r = sd_bus_message_open_container(reply, 'e', "sv");
696720
if (r < 0)
697721
return r;

src/systemd/sd-bus-vtable.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ enum {
4343
SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE = 1ULL << 5,
4444
SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION = 1ULL << 6,
4545
SD_BUS_VTABLE_PROPERTY_EXPLICIT = 1ULL << 7,
46+
SD_BUS_VTABLE_SENSITIVE = 1ULL << 8, /* covers both directions: method call + reply */
4647
_SD_BUS_VTABLE_CAPABILITY_MASK = 0xFFFFULL << 40
4748
};
4849

src/systemd/sd-bus.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,7 @@ int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **content
328328
int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents);
329329
int sd_bus_message_at_end(sd_bus_message *m, int complete);
330330
int sd_bus_message_rewind(sd_bus_message *m, int complete);
331+
int sd_bus_message_sensitive(sd_bus_message *m);
331332

332333
/* Bus management */
333334

0 commit comments

Comments
 (0)
X Tutup