[RFC][PATCH 2/3] Process events biarch bug: Process events timestamp bug

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



The event sent by Process Events from a 64-bit kernel is not compatible with
what a 32-bit userspace program would expect to recieve because the timespec
struct (used to send a timestamp) is not the same. This means that fields stored
after the timestamp are offset and programs that don't take this into account
break under these circumstances.

This is a problem on ppc64, s390, x86-64.. any "biarch" system where it's
possible for a 64-bit kernel to run 32-bit userspace programs.

This patch adds a comment highlighting the problem and a Documentation file
showing a userspace workaround.

Signed-off-by: Matt Helsley <[email protected]>
---
 Documentation/connector/process_events.txt |   75 +++++++++++++++++++++++++++++
 drivers/connector/Kconfig                  |    3 +
 include/linux/cn_proc.h                    |    7 ++
 3 files changed, 85 insertions(+)

Index: linux-2.6.17-mm3-biarch/include/linux/cn_proc.h
===================================================================
--- linux-2.6.17-mm3-biarch.orig/include/linux/cn_proc.h
+++ linux-2.6.17-mm3-biarch/include/linux/cn_proc.h
@@ -55,11 +55,18 @@ struct proc_event {
 		/* "next" should be 0x00000400 */
 		/* "last" is the last process event: exit */
 		PROC_EVENT_EXIT = 0x80000000
 	} what;
 	__u32 cpu;
+
+ 	/*
+ 	 * UGH! timespec is biarch incompatible. See
+ 	 * Documentation/connector/process_events.txt if you're going to listen
+ 	 * for process events in userspace.
+ 	 */
 	struct timespec timestamp;
+
 	union process_event_data { /* must be last field of proc_event struct */
 		struct {
 			__u32 err;
 		} ack;
 
Index: linux-2.6.17-mm3-biarch/Documentation/connector/process_events.txt
===================================================================
--- /dev/null
+++ linux-2.6.17-mm3-biarch/Documentation/connector/process_events.txt
@@ -0,0 +1,75 @@
+NOTES:
+
+To safely use process events on biarch systems it's necessary to account for
+the difference in size of the events returned by 64-bit kernels to 32-bit
+applications. This size difference is caused by use of a struct timespec for
+the timestamp field.
+
+There are multiple ways of doing this. However, few of them account for the
+fact that the size of the process event structure may change in the future.
+
+#include "linux/cn_proc.h"
+
+{
+	...
+	struct process_event *ev;
+	union process_event_data *evdata;
+	struct timespec ts;
+
+	ev = cn_msg->data;
+	if ((cn_msg->len - sizeof(struct process_event)) == sizeof(__u64)) {
+		__u64 *v;
+
+		/* kernel is sending 64-bit timestamps to 32-bit userspace */
+
+		v = (*__u64)&ev->timestamp;
+		ts.tv_sec = *v;
+		v++;
+		ts.tv_nsec = *v;
+		v++;
+		evdata = (union process_event_data*)v;
+	} else {
+		evdata = &ev->event_data;
+		ts = ev->timestamp;
+	}
+
+	switch(ev->what) {
+	case PROCESS_EVENT_EXIT:
+		... evdata->exit.exit_code ...
+		break;
+	}
+}
+
+Alternately, you can compare the size of the message length to the known
+size of the two structure variations and thus determine which structure to
+use to access the data:
+
+struct pev32 {
+	enum what what;
+	__u32 cpu;
+	__u32 timestamp[2];
+	union process_event_data event_data;
+};
+
+struct pev64 {
+	enum what what;
+	__u32 cpu;
+	__u64 timestamp[2];
+	union process_event_data event_data;
+};
+
+...
+if (cn_msg->len == sizeof(struct pev64)) {
+	...
+} else if (cn_msg->len == sizeof(struct pev32)) {
+	...
+}
+
+Both approaches assume that the process events structure will never change
+size.
+
+To limit the number of times you need to test which format is being sent use
+the acknowledgement message returned by the kernel after sending
+PROC_CN_MCAST_LISTEN. Use any of the techniques described above on the
+acknowledgement message and then set function pointers, flags, etc. to avoid
+the test in the future.
Index: linux-2.6.17-mm3-biarch/drivers/connector/Kconfig
===================================================================
--- linux-2.6.17-mm3-biarch.orig/drivers/connector/Kconfig
+++ linux-2.6.17-mm3-biarch/drivers/connector/Kconfig
@@ -16,6 +16,9 @@ config PROC_EVENTS
 	depends on CONNECTOR
 	help
 	  Provide a connector that reports process events to userspace. Send
 	  events such as fork, exec, id change (uid, gid, suid, etc), and exit.
 
+	  See Documentation/connector/process_events.txt if you're going to
+	  listen for process events in userspace.
+
 endmenu

--

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux