[lttng-dev] [PATCH] Experiments to use other tp facilities

Francis Giraldeau francis.giraldeau at gmail.com
Thu May 10 09:38:05 EDT 2012


Added two functions to test how to write string events:

  * Using tp_copy_string_from_user
    * can't enforce string length
    * can't enforce '\0' at EOL
    * can't return the number of bytes written to the caller

  * Using tp_memcpy_from_user
    * can't enforce '\0' at EOL
    * this TP doesn't show-up with lttng list -k, maybe miss usage of the
      TRACE_EVENT macro?

Also, adding a small script to quickly test experiments with various files.
---
 do-user-event-experiment.sh                 |   15 ++++
 instrumentation/events/lttng-module/lttng.h |   34 +++++++++
 probes/lttng-user-event.c                   |   97 +++++++++++++++++++++-----
 3 files changed, 127 insertions(+), 19 deletions(-)
 create mode 100755 do-user-event-experiment.sh

diff --git a/do-user-event-experiment.sh b/do-user-event-experiment.sh
new file mode 100755
index 0000000..d41d8e4
--- /dev/null
+++ b/do-user-event-experiment.sh
@@ -0,0 +1,15 @@
+#!/bin/bash 
+
+rmmod lttng-user-event
+modprobe lttng-user-event
+lttng create test
+lttng enable-event lttng_uevent_memcpy -k
+lttng enable-event lttng_uevent_cfu -k
+lttng enable-event lttng_uevent -k
+lttng start
+echo -n "bidon" > /proc/lttng_user_event
+echo -n "bidon" > /proc/lttng_user_event_cfu
+echo -n "bidon" > /proc/lttng_user_event_memcpy
+lttng stop
+lttng view
+lttng destroy
diff --git a/instrumentation/events/lttng-module/lttng.h b/instrumentation/events/lttng-module/lttng.h
index 9da3c7e..e505c21 100644
--- a/instrumentation/events/lttng-module/lttng.h
+++ b/instrumentation/events/lttng-module/lttng.h
@@ -47,6 +47,40 @@ TRACE_EVENT(lttng_uevent,
 	TP_printk("text=%s", __entry->text)
 )
 
+TRACE_EVENT(lttng_uevent_cfu,
+
+	TP_PROTO(const char *str),
+
+	TP_ARGS(str),
+
+	TP_STRUCT__entry(
+		__string_from_user(	str,	str	)
+	),
+
+	TP_fast_assign(
+		tp_copy_string_from_user(str, str)
+	),
+
+	TP_printk()
+)
+
+TRACE_EVENT(lttng_uevent_memcpy,
+
+	TP_PROTO(const char *str, size_t len),
+
+	TP_ARGS(str, len),
+
+	TP_STRUCT__entry(
+		__string(	text,	str	)
+	),
+
+	TP_fast_assign(
+		tp_memcpy_from_user(text, str, len)
+	),
+
+	TP_printk("text=%s", __entry->text)
+)
+
 #endif /*  _TRACE_LTTNG_H */
 
 /* This part must be outside protection */
diff --git a/probes/lttng-user-event.c b/probes/lttng-user-event.c
index d3b66e6..db45ad4 100644
--- a/probes/lttng-user-event.c
+++ b/probes/lttng-user-event.c
@@ -8,7 +8,7 @@
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; only
- * version 2.1 of the License.
+ * version 2 of the License.
  *
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -37,11 +37,12 @@
 #include "../instrumentation/events/lttng-module/lttng.h"
 
 DEFINE_TRACE(lttng_uevent);
+DEFINE_TRACE(lttng_uevent_cfu);
+DEFINE_TRACE(lttng_uevent_memcpy);
 
 #define LTTNG_UEVENT_FILE	"lttng_user_event"
-
-struct proc_dir_entry *lttng_root;
-static struct proc_dir_entry *write_file;
+#define LTTNG_UEVENT_FILE_CFU	"lttng_user_event_cfu"
+#define LTTNG_UEVENT_FILE_MEMCPY	"lttng_user_event_memcpy"
 
 /**
  * write_event - write a userspace string into the trace system
@@ -114,41 +115,99 @@ ssize_t write_event(struct file *file, const char __user *user_buf,
 	return written;
 }
 
+/* CFU stands for Copy From User */
+static
+ssize_t write_event_copy_from_user(struct file *file, const char __user *user_buf,
+		    size_t count, loff_t *fpos)
+{
+	/* How do we know how much data is written? Otherwise,
+	 * this function can't return the appropriate value.
+	 *
+	 * If the user string is not null-terminated,
+	 * then could it leak info beyong the string? : yes
+	 *
+	 * Assuming the userspace string is well formated
+	 * seems not appropriate.
+	 */
+	trace_lttng_uevent_cfu(user_buf);
+	return count;
+}
+
+static
+ssize_t write_event_memcpy(struct file *file, const char __user *user_buf,
+		    size_t count, loff_t *fpos)
+{
+	if (count >= LTTNG_UEVENT_SIZE)
+		count = LTTNG_UEVENT_SIZE - 1;
+
+	/*
+	 * still unable to enforce null terminated string
+	 * userspace won't be happy if we change their buffers in-place
+	 */
+	trace_lttng_uevent_memcpy(user_buf, count);
+	return count;
+}
+
 static const struct file_operations write_file_ops = {
 	.owner = THIS_MODULE,
 	.write = write_event
 };
 
-static int __init lttng_user_event_init(void)
+static const struct file_operations write_file_cfu_ops = {
+	.owner = THIS_MODULE,
+	.write = write_event_copy_from_user
+};
+
+static const struct file_operations write_file_memcpy_ops = {
+	.owner = THIS_MODULE,
+	.write = write_event_memcpy
+};
+
+static int init_proc_entry(char *name, const struct file_operations *fops)
 {
-	int err = 0;
+	struct proc_dir_entry *write_file;
 
-	/* lttng is already a file with the current abi, not a directory */
-	/*
-	lttng_root = proc_mkdir("lttng", NULL);
-	if (lttng_root == NULL)
-		return -ENOMEM;
-	*/
-	write_file = create_proc_entry(LTTNG_UEVENT_FILE, 0644, lttng_root);
+	write_file = create_proc_entry(name, 0644, NULL);
 	if (!write_file) {
-		err = -ENOENT;
-		goto err_procfs;
+		return -ENOENT;
 	}
-	write_file->proc_fops = &write_file_ops;
+	write_file->proc_fops = fops;
 	write_file->mode = S_IFREG | S_IWUGO;
 	write_file->uid = 0;
 	write_file->gid = 0;
+	return 0;
+}
+
+static int __init lttng_user_event_init(void)
+{
+	int err = 0;
+
+	if ((err = init_proc_entry(LTTNG_UEVENT_FILE, &write_file_ops)) < 0)
+		goto err_1;
+	if ((err = init_proc_entry(LTTNG_UEVENT_FILE_CFU, &write_file_cfu_ops)) < 0)
+		goto err_2;
+	if ((err = init_proc_entry(LTTNG_UEVENT_FILE_MEMCPY, &write_file_memcpy_ops)) < 0)
+		goto err_3;
+
 	return err;
 
-err_procfs:
-	remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root);
+ err_3:
+	remove_proc_entry(LTTNG_UEVENT_FILE_MEMCPY, NULL);
+ err_2:
+	remove_proc_entry(LTTNG_UEVENT_FILE_CFU, NULL);
+ err_1:
+	remove_proc_entry(LTTNG_UEVENT_FILE, NULL);
 	return err;
 }
 
 static void __exit lttng_user_event_exit(void)
 {
-	remove_proc_entry(LTTNG_UEVENT_FILE, lttng_root);
+	remove_proc_entry(LTTNG_UEVENT_FILE, NULL);
 	printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE);
+	remove_proc_entry(LTTNG_UEVENT_FILE_CFU, NULL);
+	printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE_CFU);
+	remove_proc_entry(LTTNG_UEVENT_FILE_MEMCPY, NULL);
+	printk(KERN_INFO "/proc/%s removed\n", LTTNG_UEVENT_FILE_MEMCPY);
 }
 
 module_init(lttng_user_event_init);
-- 
1.7.5.4




More information about the lttng-dev mailing list