* [PATCH v3 0/6] [RFC] copy_strtok_from_user
@ 2009-02-26 18:54 Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 1/6] uaccess: move probe_kernel_* functions to lib/uaccess.c Steven Rostedt
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin
Changes in v3:
- created strtok_r for kernel.
- Simplified copy_strtok_from_user by using strtok_r
- updated the rest of the code to handle the above changes
I tested both the strtok_r and copy_strtok_from_user with this user app:
http://www.kernel.org/pub/linux/kernel/people/rostedt/copy_strtok_from_user.c
Results of the test are here:
http://www.kernel.org/pub/linux/kernel/people/rostedt/copy_strtok_test.txt
I added a "#undef strtok_r" after the strtok_r function and ran it again
to make sure the output was still the same, and it was.
Andrew, If this version is fine with you, could you ack the patches that
create the strtok_r and copy_strtok_from_user functions.
Thanks,
-- Steve
The following patches are in:
git://git.kernel.org/pub/scm/linux/kernel/git/rostedt/linux-2.6-trace.git
branch: tip/tracing/uaccess
Steven Rostedt (6):
uaccess: move probe_kernel_* functions to lib/uaccess.c
string: add strtok_r to kernel
uaccess: add copy_strtok_from_user
tracing: convert event_trace to use copy_strtok_from_user
tracing: convert ftrace_regex_write to use copy_strtok_from_user
tracing: convert ftrace_graph_write to use copy_strtok_from_user
----
include/linux/string.h | 3 +
include/linux/uaccess.h | 4 +
kernel/trace/ftrace.c | 149 ++++++++++++++++---------------
kernel/trace/trace.h | 2 +
kernel/trace/trace_events.c | 69 +++++---------
lib/Makefile | 3 +-
lib/string.c | 43 +++++++++
lib/uaccess.c | 205 +++++++++++++++++++++++++++++++++++++++++++
mm/Makefile | 2 +-
mm/maccess.c | 55 ------------
10 files changed, 361 insertions(+), 174 deletions(-)
--
^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH v3 1/6] uaccess: move probe_kernel_* functions to lib/uaccess.c
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
@ 2009-02-26 18:54 ` Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 2/6] string: add strtok_r to kernel Steven Rostedt
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin, Steven Rostedt
[-- Attachment #1: 0001-uaccess-move-probe_kernel_-functions-to-lib-uacces.patch --]
[-- Type: text/plain, Size: 4955 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
This patch moves the file mm/maccess.c to lib/uaccess.c. This
is a more generic location to find lib utils. Since probe_kernel_*
are declared in linux/uaccess.h, having them in a file named uaccess.c
seems to be a better place.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
lib/Makefile | 3 ++-
lib/uaccess.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
mm/Makefile | 2 +-
mm/maccess.c | 55 -------------------------------------------------------
4 files changed, 58 insertions(+), 57 deletions(-)
create mode 100644 lib/uaccess.c
delete mode 100644 mm/maccess.c
diff --git a/lib/Makefile b/lib/Makefile
index 32b0e64..46ce28c 100644
--- a/lib/Makefile
+++ b/lib/Makefile
@@ -11,7 +11,8 @@ lib-y := ctype.o string.o vsprintf.o cmdline.o \
rbtree.o radix-tree.o dump_stack.o \
idr.o int_sqrt.o extable.o prio_tree.o \
sha1.o irq_regs.o reciprocal_div.o argv_split.o \
- proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o
+ proportions.o prio_heap.o ratelimit.o show_mem.o is_single_threaded.o \
+ uaccess.o
lib-$(CONFIG_MMU) += ioremap.o
lib-$(CONFIG_SMP) += cpumask.o
diff --git a/lib/uaccess.c b/lib/uaccess.c
new file mode 100644
index 0000000..ac40796
--- /dev/null
+++ b/lib/uaccess.c
@@ -0,0 +1,55 @@
+/*
+ * Access kernel memory without faulting.
+ */
+#include <linux/uaccess.h>
+#include <linux/module.h>
+#include <linux/mm.h>
+
+/**
+ * probe_kernel_read(): safely attempt to read from a location
+ * @dst: pointer to the buffer that shall take the data
+ * @src: address to read from
+ * @size: size of the data chunk
+ *
+ * Safely read from address @src to the buffer at @dst. If a kernel fault
+ * happens, handle that and return -EFAULT.
+ */
+long probe_kernel_read(void *dst, void *src, size_t size)
+{
+ long ret;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+ pagefault_disable();
+ ret = __copy_from_user_inatomic(dst,
+ (__force const void __user *)src, size);
+ pagefault_enable();
+ set_fs(old_fs);
+
+ return ret ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(probe_kernel_read);
+
+/**
+ * probe_kernel_write(): safely attempt to write to a location
+ * @dst: address to write to
+ * @src: pointer to the data that shall be written
+ * @size: size of the data chunk
+ *
+ * Safely write to address @dst from the buffer at @src. If a kernel fault
+ * happens, handle that and return -EFAULT.
+ */
+long probe_kernel_write(void *dst, void *src, size_t size)
+{
+ long ret;
+ mm_segment_t old_fs = get_fs();
+
+ set_fs(KERNEL_DS);
+ pagefault_disable();
+ ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
+ pagefault_enable();
+ set_fs(old_fs);
+
+ return ret ? -EFAULT : 0;
+}
+EXPORT_SYMBOL_GPL(probe_kernel_write);
diff --git a/mm/Makefile b/mm/Makefile
index 72255be..90323d1 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -8,7 +8,7 @@ mmu-$(CONFIG_MMU) := fremap.o highmem.o madvise.o memory.o mincore.o \
vmalloc.o
obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
- maccess.o page_alloc.o page-writeback.o pdflush.o \
+ page_alloc.o page-writeback.o pdflush.o \
readahead.o swap.o truncate.o vmscan.o shmem.o \
prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
page_isolation.o mm_init.o $(mmu-y)
diff --git a/mm/maccess.c b/mm/maccess.c
deleted file mode 100644
index ac40796..0000000
--- a/mm/maccess.c
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Access kernel memory without faulting.
- */
-#include <linux/uaccess.h>
-#include <linux/module.h>
-#include <linux/mm.h>
-
-/**
- * probe_kernel_read(): safely attempt to read from a location
- * @dst: pointer to the buffer that shall take the data
- * @src: address to read from
- * @size: size of the data chunk
- *
- * Safely read from address @src to the buffer at @dst. If a kernel fault
- * happens, handle that and return -EFAULT.
- */
-long probe_kernel_read(void *dst, void *src, size_t size)
-{
- long ret;
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- pagefault_disable();
- ret = __copy_from_user_inatomic(dst,
- (__force const void __user *)src, size);
- pagefault_enable();
- set_fs(old_fs);
-
- return ret ? -EFAULT : 0;
-}
-EXPORT_SYMBOL_GPL(probe_kernel_read);
-
-/**
- * probe_kernel_write(): safely attempt to write to a location
- * @dst: address to write to
- * @src: pointer to the data that shall be written
- * @size: size of the data chunk
- *
- * Safely write to address @dst from the buffer at @src. If a kernel fault
- * happens, handle that and return -EFAULT.
- */
-long probe_kernel_write(void *dst, void *src, size_t size)
-{
- long ret;
- mm_segment_t old_fs = get_fs();
-
- set_fs(KERNEL_DS);
- pagefault_disable();
- ret = __copy_to_user_inatomic((__force void __user *)dst, src, size);
- pagefault_enable();
- set_fs(old_fs);
-
- return ret ? -EFAULT : 0;
-}
-EXPORT_SYMBOL_GPL(probe_kernel_write);
--
1.5.6.5
--
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 2/6] string: add strtok_r to kernel
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 1/6] uaccess: move probe_kernel_* functions to lib/uaccess.c Steven Rostedt
@ 2009-02-26 18:54 ` Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 3/6] uaccess: add copy_strtok_from_user Steven Rostedt
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin, Steven Rostedt
[-- Attachment #1: 0002-string-add-strtok_r-to-kernel.patch --]
[-- Type: text/plain, Size: 2491 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
This patch adds the function strtok_r to the kernel. This acts just like
the strtok_r that is implemented in glibc, but trimmed down.
Note, this is strtok_r and not strtok. The _r version is reentrant,
where as strtok is not, and thus not suitable for the kernel.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
include/linux/string.h | 3 +++
lib/string.c | 43 +++++++++++++++++++++++++++++++++++++++++++
2 files changed, 46 insertions(+), 0 deletions(-)
diff --git a/include/linux/string.h b/include/linux/string.h
index d18fc19..c5973a5 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -76,6 +76,9 @@ extern char * strpbrk(const char *,const char *);
#ifndef __HAVE_ARCH_STRSEP
extern char * strsep(char **,const char *);
#endif
+#ifndef __HAVE_ARCH_STRTOK_R
+extern char *strtok_r(char *, const char *, char **);
+#endif
#ifndef __HAVE_ARCH_STRSPN
extern __kernel_size_t strspn(const char *,const char *);
#endif
diff --git a/lib/string.c b/lib/string.c
index b19b87a..04461b0 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -493,6 +493,49 @@ char *strsep(char **s, const char *ct)
EXPORT_SYMBOL(strsep);
#endif
+#ifndef __HAVE_ARCH_STRTOK_R
+/**
+ * strtok_r - extract tokens from strings
+ * @s: The string to be searched
+ * @ct: The characters to deliminate the tokens
+ * @saveptr: The pointer to the next token
+ *
+ * It returns the next token found outside of the @ct delimiters.
+ * Multiple occurrences of @ct characters will be considered
+ * a single delimiter. In other words, the returned token will
+ * always have a size greater than 0 (or NULL if no token found).
+ *
+ * A '\0' is placed at the end of the found token, and
+ * @saveptr is updated to point to the location after that.
+ */
+char *strtok_r(char *s, const char *ct, char **saveptr)
+{
+ char *ret;
+ int skip;
+
+ if (!s)
+ return NULL;
+
+ /* Find start of first token */
+ skip = strspn(s, ct);
+ *saveptr = s + skip;
+
+ /* return NULL if we found no token */
+ if (!*saveptr[0])
+ return NULL;
+
+ /*
+ * strsep is different than strtok, where as saveptr will be NULL
+ * if token not found. strtok makes it point to the end of the string.
+ */
+ ret = strsep(saveptr, ct);
+ if (!*saveptr)
+ *saveptr = &ret[strlen(ret)];
+ return ret;
+}
+EXPORT_SYMBOL(strtok_r);
+#endif
+
/**
* sysfs_streq - return true if strings are equal, modulo trailing newline
* @s1: one string
--
1.5.6.5
--
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 3/6] uaccess: add copy_strtok_from_user
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 1/6] uaccess: move probe_kernel_* functions to lib/uaccess.c Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 2/6] string: add strtok_r to kernel Steven Rostedt
@ 2009-02-26 18:54 ` Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 4/6] tracing: convert event_trace to use copy_strtok_from_user Steven Rostedt
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin, Steven Rostedt
[-- Attachment #1: 0003-uaccess-add-copy_strtok_from_user.patch --]
[-- Type: text/plain, Size: 6289 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
The ftrace utility reads delimited tokens from user space.
Andrew Morton did not like how ftrace open coded this. He had
a good point since more than one location performed this feature.
This patch creates a copy_strtok_from_user function that can copy
a delimited token from user space. This puts the code in the
lib/uaccess.c file. This keeps the code in a single location
and may be optimized in the future.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
include/linux/uaccess.h | 4 +
lib/uaccess.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 155 insertions(+), 1 deletions(-)
diff --git a/include/linux/uaccess.h b/include/linux/uaccess.h
index 6b58367..0a3faf5 100644
--- a/include/linux/uaccess.h
+++ b/include/linux/uaccess.h
@@ -106,4 +106,8 @@ extern long probe_kernel_read(void *dst, void *src, size_t size);
*/
extern long probe_kernel_write(void *dst, void *src, size_t size);
+extern int copy_strtok_from_user(void *to, const void __user *from,
+ unsigned int copy, unsigned int read,
+ unsigned int *copied, const char *delim);
+
#endif /* __LINUX_UACCESS_H__ */
diff --git a/lib/uaccess.c b/lib/uaccess.c
index ac40796..a55db23 100644
--- a/lib/uaccess.c
+++ b/lib/uaccess.c
@@ -1,8 +1,19 @@
/*
- * Access kernel memory without faulting.
+ * lib/uaccess.c
+ * Generic memory access without faulting.
+ *
+ * Copyright (C) 2008 Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ *
+ * Added copy_strtok_from_user -
+ * Copyright (C) 2009 Red Hat, Inc., Steven Rostedt <srostedt@redhat.com>
+ *
+ * This source code is licensed under the GNU General Public License,
+ * Version 2. See the file COPYING for more details.
+ *
*/
#include <linux/uaccess.h>
#include <linux/module.h>
+#include <linux/ctype.h>
#include <linux/mm.h>
/**
@@ -53,3 +64,142 @@ long probe_kernel_write(void *dst, void *src, size_t size)
return ret ? -EFAULT : 0;
}
EXPORT_SYMBOL_GPL(probe_kernel_write);
+
+#define USER_BUF_SIZE 127
+
+/**
+ * copy_strtok_from_user - copy a delimited token from user space
+ * @to: The location to copy to
+ * @from: The location to copy from
+ * @copy: The number of bytes to copy
+ * @read: The number of bytes to read
+ * @copied: The number of bytes actually written to @to
+ * @delim: NULL terminated string of character delimiters
+ *
+ * This reads from a user buffer, a delimited token.
+ * It places the token into @to if one is found, up to the number of
+ * bytes specified by @copy. It adds a "\0" terminating character
+ * into @to if a delimiter is found after the token. Otherwise the
+ * @to does not end with a \0 delimiter.
+ * If only delimiters are found, @to is not modified and
+ * @copied will be zero.
+ *
+ * It reads at most @read bytes from the user @from buffer, and
+ * will copy at most @copy bytes into the kernel @to buffer.
+ *
+ * Example of use:
+ *
+ * in user space a write(fd, "foo bar zot", 12) is done. We want to
+ * read three words.
+ *
+ * len = 12; - length of user buffer
+ * ret = copy_strtok_from_user(buf, ubuf, 100, len, @copied, " ");
+ * ret will equal 3 ("foo" read - " " is also read but not counted.)
+ * buf will contain "foo\0"
+ * copied will equal 4 ("foo\0" written)
+ *
+ * len -= ret; - 3 bytes was read
+ * read = ret;
+ * ret = copy_strtok_from_user(buf, ubuf+read, 100, len, @copied, " ");
+ * ret will equal 5 (" bar" read, notice the double space between
+ * foo and bar in the original write.)
+ * buf will contain "bar\0"
+ * copied will equal 4 ("bar\0" written)
+ *
+ * len -= ret; - 5 bytes read
+ * read += ret;
+ * ret = copy_strtok_from_user(buf, ubuf+read, 100, len, @copied, " ");
+ * ret = 4 (" zot" read)
+ * buf will contain "zot" (notice that it does not contain \0)
+ * copied will equal 3 ("zot" written)
+ * The buf only has "zot" because no terminating delimiter was
+ * encountered.
+ *
+ * Returns:
+ * The number of bytes read from user space (@from). This may or may not
+ * be the same as what was copied into @to.
+ *
+ * if (@to[*@copied - 1] == '\0')
+ * token ended with a delimiter
+ * else
+ * token in @from was not followed by a delimiter
+ *
+ * @copied will contain the number of bytes written into @to.
+ *
+ * Note, if the token that was found was bigger than @to,
+ * @copied will equal copy, and @to[*@copied - 1] will not be '\0'
+ *
+ * -EFAULT, if we faulted during any part of the copy.
+ * @copied will be undefined.
+ */
+int copy_strtok_from_user(void *to, const void __user *from,
+ unsigned int copy, unsigned int read,
+ unsigned int *copied, const char *delim)
+{
+ unsigned int have_read = 0;
+ unsigned int have_copied = 0;
+ char user[USER_BUF_SIZE + 1];
+ char *token, *ptr;
+ int ret, cnt;
+
+ do {
+ cnt = USER_BUF_SIZE;
+
+ if (cnt > read - have_read)
+ cnt = read - have_read;
+
+ ret = copy_from_user(user, from + have_read, cnt);
+ if (ret)
+ return ret;
+
+ user[cnt] = 0;
+ ptr = user;
+ have_read += cnt;
+
+ token = strtok_r(ptr, delim, &ptr);
+ if (token) {
+ strncpy(to + have_copied, token, copy - have_copied);
+ have_copied += strlen(token);
+
+ /*
+ * We do not want to report that we read past the
+ * token.
+ */
+ have_read -= cnt - (ptr - user);
+
+ /*
+ * Check if the token was larger than the supplied
+ * buffer.
+ */
+ if (have_copied >= copy) {
+ /* do not report the part not copied */
+ have_read -= have_copied - copy;
+ /* account for the delim read by ptr */
+ if (ptr[-1] == '\0')
+ have_read--;
+ have_copied = copy;
+ break;
+ }
+
+ /*
+ * Now the tricky part. We must determine if the token
+ * was split between two reads from userspace.
+ * If strtok_r found a delimiter after the token, then
+ * the previous character to ptr would be NULL.
+ * Note: if strtok_r returned a token, ptr must be
+ * greater than user.
+ */
+ if (!ptr[-1]) {
+ /* add '\0' */
+ have_copied++;
+ break;
+ }
+ }
+
+ } while (have_read < read && have_copied < copy);
+
+ *copied = have_copied;
+
+ return have_read;
+}
+EXPORT_SYMBOL_GPL(copy_strtok_from_user);
--
1.5.6.5
--
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 4/6] tracing: convert event_trace to use copy_strtok_from_user
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
` (2 preceding siblings ...)
2009-02-26 18:54 ` [PATCH v3 3/6] uaccess: add copy_strtok_from_user Steven Rostedt
@ 2009-02-26 18:54 ` Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 5/6] tracing: convert ftrace_regex_write " Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 6/6] tracing: convert ftrace_graph_write " Steven Rostedt
5 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin, Steven Rostedt
[-- Attachment #1: 0004-tracing-convert-event_trace-to-use-copy_strtok_from.patch --]
[-- Type: text/plain, Size: 2658 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
Impact: clean up
This patch converts the open coded retrieving of a word from user
space to use copy_strtok_from_user.
Also removed a cnt < 0 check that Andrew Morton pointed out saying
that it was irrelevant since cnt is unsigned.
Also changed file->pos += to (*ppos) += which is the proper way
to modify positions of the file.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
kernel/trace/trace.h | 2 +
kernel/trace/trace_events.c | 69 +++++++++++++++---------------------------
2 files changed, 27 insertions(+), 44 deletions(-)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 6321917..e75b673 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -720,4 +720,6 @@ static inline void trace_branch_disable(void)
}
#endif /* CONFIG_BRANCH_TRACER */
+#define SPACES " \t\r\n"
+
#endif /* _LINUX_KERNEL_TRACE_H */
diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c
index 3bcb9df..9e71755 100644
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -80,62 +80,43 @@ static ssize_t
ftrace_event_write(struct file *file, const char __user *ubuf,
size_t cnt, loff_t *ppos)
{
- size_t read = 0;
- int i, set = 1;
+ unsigned int copied;
+ size_t read;
ssize_t ret;
+ int set = 1;
char *buf;
- char ch;
- if (!cnt || cnt < 0)
+ if (!cnt)
return 0;
- ret = get_user(ch, ubuf++);
- if (ret)
- return ret;
- read++;
- cnt--;
-
- /* skip white space */
- while (cnt && isspace(ch)) {
- ret = get_user(ch, ubuf++);
- if (ret)
- return ret;
- read++;
- cnt--;
- }
-
- /* Only white space found? */
- if (isspace(ch)) {
- file->f_pos += read;
- ret = read;
- return ret;
- }
-
buf = kmalloc(EVENT_BUF_SIZE+1, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- if (cnt > EVENT_BUF_SIZE)
- cnt = EVENT_BUF_SIZE;
-
- i = 0;
- while (cnt && !isspace(ch)) {
- if (!i && ch == '!')
- set = 0;
- else
- buf[i++] = ch;
-
- ret = get_user(ch, ubuf++);
- if (ret)
- goto out_free;
- read++;
- cnt--;
+ ret = copy_strtok_from_user(buf, ubuf, EVENT_BUF_SIZE,
+ cnt, &copied, SPACES);
+ if (ret < 0)
+ goto out_free;
+
+ if (!copied) {
+ ret = cnt;
+ (*ppos) += cnt;
+
+ /* TODO, handle split words */
+ goto out_free;
}
- buf[i] = 0;
- file->f_pos += read;
+ if (buf[0] == '!')
+ set = 0;
+
+ (*ppos) += ret;
+ read = ret;
- ret = ftrace_set_clr_event(buf, set);
+ /*
+ * A little hack here. If set is true, we want to use buf.
+ * Otherwise, we want to use buf+1 (to skip the '!').
+ */
+ ret = ftrace_set_clr_event(buf + !set, set);
if (ret)
goto out_free;
--
1.5.6.5
--
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 5/6] tracing: convert ftrace_regex_write to use copy_strtok_from_user
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
` (3 preceding siblings ...)
2009-02-26 18:54 ` [PATCH v3 4/6] tracing: convert event_trace to use copy_strtok_from_user Steven Rostedt
@ 2009-02-26 18:54 ` Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 6/6] tracing: convert ftrace_graph_write " Steven Rostedt
5 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin, Steven Rostedt
[-- Attachment #1: 0005-tracing-convert-ftrace_regex_write-to-use-copy_strt.patch --]
[-- Type: text/plain, Size: 3496 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
Impact: clean up
This removes the open coded parsing of a word sent in by the user
and replaces it with copy_strtok_from_user.
Also removes cnt < 0 check since cnt is unsigned.
Also uses (*ppos) += cnt, instead of file->pos += cnt.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
kernel/trace/ftrace.c | 101 +++++++++++++++++++++++++++++--------------------
1 files changed, 60 insertions(+), 41 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 5a3a06b..963dc14 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -1690,11 +1690,13 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
size_t cnt, loff_t *ppos, int enable)
{
struct ftrace_iterator *iter;
- char ch;
+ unsigned int copied;
size_t read = 0;
+ int len, skip;
ssize_t ret;
+ char *buf;
- if (!cnt || cnt < 0)
+ if (!cnt)
return 0;
mutex_lock(&ftrace_regex_lock);
@@ -1710,58 +1712,75 @@ ftrace_regex_write(struct file *file, const char __user *ubuf,
iter->buffer_idx = 0;
}
- ret = get_user(ch, ubuf++);
- if (ret)
- goto out;
- read++;
- cnt--;
+ if (iter->flags & FTRACE_ITER_CONT) {
+ /*
+ * We split on a word, continue from where
+ * we left off.
+ */
+ buf = &iter->buffer[iter->buffer_idx];
+ len = FTRACE_BUFF_MAX - iter->buffer_idx;
+ /* do not handle leading spaces. */
+ skip = 0;
+ } else {
+ buf = iter->buffer;
+ /* iter->buffer is size of FTRACE_BUFF_MAX + 1 */
+ len = FTRACE_BUFF_MAX;
+ iter->buffer_idx = 0;
+ /* Skip over any leading spaces */
+ skip = 1;
+ }
- if (!(iter->flags & ~FTRACE_ITER_CONT)) {
- /* skip white space */
- while (cnt && isspace(ch)) {
- ret = get_user(ch, ubuf++);
- if (ret)
- goto out;
- read++;
- cnt--;
- }
+ ret = copy_strtok_from_user(buf, ubuf, len, cnt, &copied, SPACES);
+ if (ret < 0)
+ goto out;
- if (isspace(ch)) {
- file->f_pos += read;
- ret = read;
- goto out;
+ if (!skip) {
+ /*
+ * This is a continuation. If we read spaces, then
+ * we need to truncate all that was read.
+ */
+ if (ret > copied) {
+ /* leading spaces were found */
+ iter->buffer[iter->buffer_idx] = 0;
+ /* make it look like we are ready to process */
+ buf = iter->buffer;
+ copied = iter->buffer_idx + 1;
}
+ }
- iter->buffer_idx = 0;
+ /* We only read white space. */
+ if (!copied) {
+ (*ppos) += cnt;
+ ret = cnt;
+ goto out;
}
- while (cnt && !isspace(ch)) {
- if (iter->buffer_idx < FTRACE_BUFF_MAX)
- iter->buffer[iter->buffer_idx++] = ch;
- else {
+ /* Check if we hit a terminating space */
+ if (buf[copied - 1] != 0) {
+ /* we split on a word */
+ iter->buffer_idx += copied;
+ if (iter->buffer_idx >= FTRACE_BUFF_MAX) {
+ /* too big of a word */
+ iter->buffer_idx = 0;
+ iter->flags &= ~FTRACE_ITER_CONT;
ret = -EINVAL;
goto out;
}
- ret = get_user(ch, ubuf++);
- if (ret)
- goto out;
- read++;
- cnt--;
- }
- if (isspace(ch)) {
- iter->filtered++;
- iter->buffer[iter->buffer_idx] = 0;
- ret = ftrace_process_regex(iter->buffer,
- iter->buffer_idx, enable);
- if (ret)
- goto out;
- iter->buffer_idx = 0;
- } else
+ (*ppos) += cnt;
+ ret = cnt;
iter->flags |= FTRACE_ITER_CONT;
+ goto out;
+ }
+ read = ret;
- file->f_pos += read;
+ ret = ftrace_process_regex(iter->buffer, iter->buffer_idx, enable);
+ if (ret)
+ goto out;
+ iter->buffer_idx = 0;
+
+ (*ppos) += read;
ret = read;
out:
--
1.5.6.5
--
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH v3 6/6] tracing: convert ftrace_graph_write to use copy_strtok_from_user
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
` (4 preceding siblings ...)
2009-02-26 18:54 ` [PATCH v3 5/6] tracing: convert ftrace_regex_write " Steven Rostedt
@ 2009-02-26 18:54 ` Steven Rostedt
5 siblings, 0 replies; 7+ messages in thread
From: Steven Rostedt @ 2009-02-26 18:54 UTC (permalink / raw)
To: linux-kernel
Cc: Ingo Molnar, Andrew Morton, Peter Zijlstra, Frederic Weisbecker,
H. Peter Anvin, Steven Rostedt
[-- Attachment #1: 0006-tracing-convert-ftrace_graph_write-to-use-copy_strt.patch --]
[-- Type: text/plain, Size: 2117 bytes --]
From: Steven Rostedt <srostedt@redhat.com>
Impact: clean up
This removes the open coded parsing of a word sent in by the user
and replaces it with copy_strtok_from_user.
Also removes cnt < 0 check since cnt is unsigned.
Also uses (*ppos) += cnt, instead of file->pos += cnt.
Signed-off-by: Steven Rostedt <srostedt@redhat.com>
---
kernel/trace/ftrace.c | 48 ++++++++++++++++--------------------------------
1 files changed, 16 insertions(+), 32 deletions(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 963dc14..4ed0a8e 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -2083,10 +2083,9 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
unsigned long *array;
size_t read = 0;
ssize_t ret;
- int index = 0;
- char ch;
+ int copied;
- if (!cnt || cnt < 0)
+ if (!cnt)
return 0;
mutex_lock(&graph_lock);
@@ -2102,48 +2101,33 @@ ftrace_graph_write(struct file *file, const char __user *ubuf,
} else
array = file->private_data;
- ret = get_user(ch, ubuf++);
- if (ret)
+ ret = copy_strtok_from_user(buffer, ubuf, FTRACE_BUFF_MAX + 1,
+ cnt, &copied, SPACES);
+ if (ret < 0)
goto out;
- read++;
- cnt--;
- /* skip white space */
- while (cnt && isspace(ch)) {
- ret = get_user(ch, ubuf++);
- if (ret)
- goto out;
- read++;
- cnt--;
+ /* We only read white space. */
+ if (!copied) {
+ (*ppos) += cnt;
+ ret = cnt;
+ goto out;
}
- if (isspace(ch)) {
- *ppos += read;
- ret = read;
+ /* Check if we hit a terminating space */
+ if (buffer[copied - 1] != 0) {
+ /* This does not deal with split words */
+ ret = -EINVAL;
goto out;
}
- while (cnt && !isspace(ch)) {
- if (index < FTRACE_BUFF_MAX)
- buffer[index++] = ch;
- else {
- ret = -EINVAL;
- goto out;
- }
- ret = get_user(ch, ubuf++);
- if (ret)
- goto out;
- read++;
- cnt--;
- }
- buffer[index] = 0;
+ read = ret;
/* we allow only one expression at a time */
ret = ftrace_set_func(array, &ftrace_graph_count, buffer);
if (ret)
goto out;
- file->f_pos += read;
+ (*ppos) += read;
ret = read;
out:
--
1.5.6.5
--
^ permalink raw reply related [flat|nested] 7+ messages in thread
end of thread, other threads:[~2009-02-26 19:01 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-02-26 18:54 [PATCH v3 0/6] [RFC] copy_strtok_from_user Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 1/6] uaccess: move probe_kernel_* functions to lib/uaccess.c Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 2/6] string: add strtok_r to kernel Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 3/6] uaccess: add copy_strtok_from_user Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 4/6] tracing: convert event_trace to use copy_strtok_from_user Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 5/6] tracing: convert ftrace_regex_write " Steven Rostedt
2009-02-26 18:54 ` [PATCH v3 6/6] tracing: convert ftrace_graph_write " Steven Rostedt
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).