From 78e35f2fabbf31b158b4f15ffaff9ab0915a305d Mon Sep 17 00:00:00 2001 From: David Herrmann Date: Wed, 7 Jan 2015 20:38:02 +0100 Subject: [PATCH] metadata: fix seqnum on kernel notifications The seqnum ID is passed together with the timestamps. Therefore, move the "u64 seq" argument to kdbus_meta_add_timestamp(). As the seqnum is not known at message allocation time, we now also move the kdbus_meta_add_timestamp() to the time we actually allocate the ID. This fixes seqnum IDs on kernel notifications. Signed-off-by: David Herrmann --- bus.c | 8 +++----- connection.c | 6 +++--- message.c | 29 ++++++++--------------------- metadata.c | 14 ++++++-------- metadata.h | 5 ++--- notify.c | 1 + 6 files changed, 23 insertions(+), 40 deletions(-) diff --git a/bus.c b/bus.c index 9e7aeb2..2227c4f 100644 --- a/bus.c +++ b/bus.c @@ -196,7 +196,7 @@ struct kdbus_bus *kdbus_bus_new(struct kdbus_domain *domain, goto exit_unref; } - ret = kdbus_meta_add_current(b->meta, 0, + ret = kdbus_meta_add_current(b->meta, KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS | KDBUS_ATTACH_AUXGROUPS | @@ -415,8 +415,7 @@ void kdbus_bus_broadcast(struct kdbus_bus *bus, * requested metadata. It's up to the receiver to drop * messages that lack expected metadata. */ - kdbus_meta_add_current(kmsg->meta, kmsg->seq, - attach_flags); + kdbus_meta_add_current(kmsg->meta, attach_flags); kdbus_meta_add_conn_info(kmsg->meta, conn_src, attach_flags); } else { @@ -472,8 +471,7 @@ void kdbus_bus_eavesdrop(struct kdbus_bus *bus, attach_flags = kdbus_meta_calc_attach_flags(conn_src, conn_dst); - kdbus_meta_add_current(kmsg->meta, kmsg->seq, - attach_flags); + kdbus_meta_add_current(kmsg->meta, attach_flags); kdbus_meta_add_conn_info(kmsg->meta, conn_src, attach_flags); } diff --git a/connection.c b/connection.c index 550d1b6..3d93097 100644 --- a/connection.c +++ b/connection.c @@ -836,6 +836,7 @@ int kdbus_cmd_msg_send(struct kdbus_conn *conn_src, } kmsg->seq = atomic64_inc_return(&bus->domain->msg_seq_last); + kdbus_meta_add_timestamp(kmsg->meta, kmsg->seq); if (msg->dst_id == KDBUS_DST_ID_BROADCAST) { kdbus_bus_broadcast(bus, conn_src, kmsg); @@ -948,8 +949,7 @@ int kdbus_cmd_msg_send(struct kdbus_conn *conn_src, * metadata */ if (!conn_src->faked_meta) { - ret = kdbus_meta_add_current(kmsg->meta, kmsg->seq, - attach_flags); + ret = kdbus_meta_add_current(kmsg->meta, attach_flags); if (ret < 0) goto exit_unref; } @@ -1818,7 +1818,7 @@ struct kdbus_conn *kdbus_conn_new(struct kdbus_ep *ep, conn->faked_meta = true; } else { - ret = kdbus_meta_add_current(conn->meta, 0, + ret = kdbus_meta_add_current(conn->meta, KDBUS_ATTACH_CREDS | KDBUS_ATTACH_PIDS | KDBUS_ATTACH_AUXGROUPS | diff --git a/message.c b/message.c index 229aa6b..4124e4b 100644 --- a/message.c +++ b/message.c @@ -118,21 +118,6 @@ void kdbus_kmsg_free(struct kdbus_kmsg *kmsg) kfree(kmsg); } -static int kdbus_kmsg_init(struct kdbus_kmsg *kmsg) -{ - int ret; - - kmsg->meta = kdbus_meta_new(); - if (IS_ERR(kmsg->meta)) { - ret = PTR_ERR(kmsg->meta); - kmsg->meta = NULL; - return ret; - } - - kdbus_meta_add_timestamp(kmsg->meta); - return 0; -} - /** * kdbus_kmsg_new() - allocate message * @extra_size: Additional size to reserve for data @@ -143,7 +128,6 @@ struct kdbus_kmsg *kdbus_kmsg_new(size_t extra_size) { struct kdbus_kmsg *m; size_t size; - int ret; size = sizeof(struct kdbus_kmsg) + KDBUS_ITEM_SIZE(extra_size); m = kzalloc(size, GFP_KERNEL); @@ -153,10 +137,10 @@ struct kdbus_kmsg *kdbus_kmsg_new(size_t extra_size) m->msg.size = size - KDBUS_KMSG_HEADER_SIZE; m->msg.items[0].size = KDBUS_ITEM_SIZE(extra_size); - ret = kdbus_kmsg_init(m); - if (ret < 0) { + m->meta = kdbus_meta_new(); + if (IS_ERR(m->meta)) { kfree(m); - return ERR_PTR(ret); + return ERR_CAST(m->meta); } return m; @@ -507,9 +491,12 @@ struct kdbus_kmsg *kdbus_kmsg_new_from_cmd(struct kdbus_conn *conn, memset(m, 0, KDBUS_KMSG_HEADER_SIZE); - ret = kdbus_kmsg_init(m); - if (ret < 0) + m->meta = kdbus_meta_new(); + if (IS_ERR(m->meta)) { + ret = PTR_ERR(m->meta); + m->meta = NULL; goto exit_free; + } if (copy_from_user(&m->msg, KDBUS_PTR(cmd_send->msg_address), size)) { ret = -EFAULT; diff --git a/metadata.c b/metadata.c index 83e96b1..77089d4 100644 --- a/metadata.c +++ b/metadata.c @@ -38,7 +38,6 @@ * struct kdbus_meta - metadata buffer * @kref: Reference counter * @collected: Flags for already collected and valid data - * @seq: Sequence number passed in at collect time * @uid: Task uid * @euid: Task euid * @suid: Task suid @@ -60,6 +59,7 @@ * @ppid: Pinned PPID * @ts_monotonic_ns: Monotonic timestamp taken at collect time * @ts_realtime_ns: Realtime timestamp taken at collect time + * @seq: Sequence number passed in at collect time * @exe: Task's executable file, pinned * @cmdline: Task's cmdline * @cgroup: Cgroup path @@ -83,8 +83,6 @@ struct kdbus_meta { u64 collected; - u64 seq; - kuid_t uid; kuid_t euid; kuid_t suid; @@ -112,6 +110,7 @@ struct kdbus_meta { s64 ts_monotonic_ns; s64 ts_realtime_ns; + u64 seq; struct file *exe; char *cmdline; @@ -282,7 +281,7 @@ int kdbus_meta_add_fake(struct kdbus_meta *meta, * This function does nothing if the time stamp was already recorded * in the metadata object. */ -void kdbus_meta_add_timestamp(struct kdbus_meta *meta) +void kdbus_meta_add_timestamp(struct kdbus_meta *meta, u64 seq) { struct timespec ts; @@ -295,13 +294,14 @@ void kdbus_meta_add_timestamp(struct kdbus_meta *meta) ktime_get_real_ts(&ts); meta->ts_realtime_ns = timespec_to_ns(&ts); + meta->seq = seq; + meta->collected |= KDBUS_ATTACH_TIMESTAMP; } /** * kdbus_meta_add_current() - collect metadata from current process * @meta: Metadata object - * @seq: Message sequence number * @which: KDBUS_ATTACH_* mask * * Collect the data specified in @which from the 'current', and store the @@ -310,7 +310,7 @@ void kdbus_meta_add_timestamp(struct kdbus_meta *meta) * * Return: 0 on success, negative errno on failure. */ -int kdbus_meta_add_current(struct kdbus_meta *meta, u64 seq, u64 which) +int kdbus_meta_add_current(struct kdbus_meta *meta, u64 which) { u64 mask; int i; @@ -320,8 +320,6 @@ int kdbus_meta_add_current(struct kdbus_meta *meta, u64 seq, u64 which) if (mask == 0) return 0; - meta->seq = seq; - if (mask & KDBUS_ATTACH_CREDS) { meta->uid = current_uid(); meta->euid = current_euid(); diff --git a/metadata.h b/metadata.h index 1762edd..dac5ccb 100644 --- a/metadata.h +++ b/metadata.h @@ -26,9 +26,8 @@ struct kdbus_meta *kdbus_meta_new(void); struct kdbus_meta *kdbus_meta_ref(struct kdbus_meta *meta); struct kdbus_meta *kdbus_meta_unref(struct kdbus_meta *meta); -void kdbus_meta_add_timestamp(struct kdbus_meta *meta); -int kdbus_meta_add_current(struct kdbus_meta *meta, - u64 seq, u64 which); +void kdbus_meta_add_timestamp(struct kdbus_meta *meta, u64 seq); +int kdbus_meta_add_current(struct kdbus_meta *meta, u64 which); int kdbus_meta_add_conn_info(struct kdbus_meta *meta, struct kdbus_conn *conn_src, u64 which); int kdbus_meta_add_fake(struct kdbus_meta *meta, diff --git a/notify.c b/notify.c index 47f91da..335679c 100644 --- a/notify.c +++ b/notify.c @@ -205,6 +205,7 @@ void kdbus_notify_flush(struct kdbus_bus *bus) list_for_each_entry_safe(kmsg, tmp, ¬ify_list, notify_entry) { kmsg->seq = atomic64_inc_return(&bus->domain->msg_seq_last); + kdbus_meta_add_timestamp(kmsg->meta, kmsg->seq); if (kmsg->msg.dst_id != KDBUS_DST_ID_BROADCAST) { struct kdbus_conn *conn; -- 2.34.1