Skip to content

Instantly share code, notes, and snippets.

@kwilczynski
Created May 4, 2021 00:15
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save kwilczynski/5228ca49054b01f165c9046e3b5f725f to your computer and use it in GitHub Desktop.
Save kwilczynski/5228ca49054b01f165c9046e3b5f725f to your computer and use it in GitHub Desktop.
systemd 246 systemd-rfkill fix
diff --git a/src/rfkill/rfkill.c b/src/rfkill/rfkill.c
index 5019828..e2b9773 100644
--- a/src/rfkill/rfkill.c
+++ b/src/rfkill/rfkill.c
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: LGPL-2.1+ */
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <fcntl.h>
#include <linux/rfkill.h>
@@ -135,8 +135,6 @@ static int determine_state_file(
static int load_state(Context *c, const struct rfkill_event *event) {
_cleanup_free_ char *state_file = NULL, *value = NULL;
- struct rfkill_event we;
- ssize_t l;
int b, r;
assert(c);
@@ -168,18 +166,22 @@ static int load_state(Context *c, const struct rfkill_event *event) {
if (b < 0)
return log_error_errno(b, "Failed to parse state file %s: %m", state_file);
- we = (struct rfkill_event) {
- .op = RFKILL_OP_CHANGE,
+ struct rfkill_event we = {
.idx = event->idx,
+ .op = RFKILL_OP_CHANGE,
.soft = b,
};
+ assert_cc(offsetof(struct rfkill_event, op) < RFKILL_EVENT_SIZE_V1);
+ assert_cc(offsetof(struct rfkill_event, soft) < RFKILL_EVENT_SIZE_V1);
- l = write(c->rfkill_fd, &we, sizeof(we));
+ ssize_t l = write(c->rfkill_fd, &we, sizeof we);
if (l < 0)
return log_error_errno(errno, "Failed to restore rfkill state for %i: %m", event->idx);
- if (l != sizeof(we))
+ if (l < RFKILL_EVENT_SIZE_V1)
return log_error_errno(SYNTHETIC_ERRNO(EIO),
- "Couldn't write rfkill event structure, too short.");
+ "Couldn't write rfkill event structure, too short (wrote %zd of %zu bytes).",
+ l, sizeof we);
+ log_debug("Writing struct rfkill_event successful (%zd of %zu bytes).", l, sizeof we);
log_debug("Loaded state '%s' from %s.", one_zero(b), state_file);
return 0;
@@ -305,44 +307,45 @@ static int run(int argc, char *argv[]) {
}
for (;;) {
- struct rfkill_event event;
- const char *type;
- ssize_t l;
+ struct rfkill_event event = {};
- l = read(c.rfkill_fd, &event, sizeof(event));
+ ssize_t l = read(c.rfkill_fd, &event, sizeof event);
if (l < 0) {
- if (errno == EAGAIN) {
-
- if (!ready) {
- /* Notify manager that we are
- * now finished with
- * processing whatever was
- * queued */
- (void) sd_notify(false, "READY=1");
- ready = true;
- }
-
- /* Hang around for a bit, maybe there's more coming */
-
- r = fd_wait_for_event(c.rfkill_fd, POLLIN, EXIT_USEC);
- if (r == -EINTR)
- continue;
- if (r < 0)
- return log_error_errno(r, "Failed to poll() on device: %m");
- if (r > 0)
- continue;
-
- log_debug("All events read and idle, exiting.");
- break;
+ if (errno != EAGAIN)
+ return log_error_errno(errno, "Failed to read from /dev/rfkill: %m");
+
+ if (!ready) {
+ /* Notify manager that we are now finished with processing whatever was
+ * queued */
+ (void) sd_notify(false, "READY=1");
+ ready = true;
}
- log_error_errno(errno, "Failed to read from /dev/rfkill: %m");
+ /* Hang around for a bit, maybe there's more coming */
+
+ r = fd_wait_for_event(c.rfkill_fd, POLLIN, EXIT_USEC);
+ if (r == -EINTR)
+ continue;
+ if (r < 0)
+ return log_error_errno(r, "Failed to poll() on device: %m");
+ if (r > 0)
+ continue;
+
+ log_debug("All events read and idle, exiting.");
+ break;
}
- if (l != RFKILL_EVENT_SIZE_V1)
- return log_error_errno(SYNTHETIC_ERRNO(EIO), "Read event structure of invalid size.");
+ if (l < RFKILL_EVENT_SIZE_V1)
+ return log_error_errno(SYNTHETIC_ERRNO(EIO), "Short read of struct rfkill_event: (%zd < %d)",
+ l, RFKILL_EVENT_SIZE_V1);
+ log_debug("Reading struct rfkill_event: got %zd bytes.", l);
+
+ /* The event structure has more fields. We only care about the first few, so it's OK if we
+ * don't read the full structure. */
+ assert_cc(offsetof(struct rfkill_event, op) < RFKILL_EVENT_SIZE_V1);
+ assert_cc(offsetof(struct rfkill_event, type) < RFKILL_EVENT_SIZE_V1);
- type = rfkill_type_to_string(event.type);
+ const char *type = rfkill_type_to_string(event.type);
if (!type) {
log_debug("An rfkill device of unknown type %i discovered, ignoring.", event.type);
continue;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment