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


_______________________________________________
lttng-dev mailing list
[email protected]
http://lists.lttng.org/cgi-bin/mailman/listinfo/lttng-dev

Reply via email to