* [PATCH v2 0/3] tracing: Fix the parser when processing strings w/ or w/o terminated '\0' @ 2018-01-15 11:41 changbin.du 2018-01-15 11:41 ` [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string changbin.du ` (2 more replies) 0 siblings, 3 replies; 6+ messages in thread From: changbin.du @ 2018-01-15 11:41 UTC (permalink / raw) To: rostedt Cc: jolsa, peterz, mingo, alexander.shishkin, linux-kernel, linux-perf-users, Changbin Du From: Changbin Du <changbin.du@intel.com> I found there are some problems in the tracing parser when I investiage the root cause of issues mentioned in below patch. https://patchwork.kernel.org/patch/10132953/ This serials can fix them. Changbin Du (3): tracing: detect the string termination character when parsing user input string tracing: clear parser->idx if parser gets nothing tracing: make sure the parsed string always terminates with '\0' kernel/trace/ftrace.c | 2 -- kernel/trace/trace.c | 14 +++++++------- kernel/trace/trace_events.c | 2 -- 3 files changed, 7 insertions(+), 11 deletions(-) -- 2.7.4 ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string 2018-01-15 11:41 [PATCH v2 0/3] tracing: Fix the parser when processing strings w/ or w/o terminated '\0' changbin.du @ 2018-01-15 11:41 ` changbin.du 2018-01-15 23:20 ` Steven Rostedt 2018-01-15 11:41 ` [PATCH v2 2/3] tracing: clear parser->idx if parser gets nothing changbin.du 2018-01-15 11:41 ` [PATCH v2 3/3] tracing: make sure the parsed string always terminates with '\0' changbin.du 2 siblings, 1 reply; 6+ messages in thread From: changbin.du @ 2018-01-15 11:41 UTC (permalink / raw) To: rostedt Cc: jolsa, peterz, mingo, alexander.shishkin, linux-kernel, linux-perf-users, Changbin Du From: Changbin Du <changbin.du@intel.com> The usersapce can give a '\0' terminated C string in the input buffer. Before this change, trace_get_user() will return a parsed string "\0" in below case which is not expected (expects it skip all inputs) and cause the caller failed. open("/sys/kernel/debug/tracing//set_ftrace_pid", O_WRONLY|O_TRUNC) = 3 write(3, " \0", 2) = -1 EINVAL (Invalid argument) while parse can handle spaces, so below works. $ echo "" > set_ftrace_pid $ echo " " > set_ftrace_pid $ echo -n " " > set_ftrace_pid This patch try to make the parser '\0' aware to fix such issue. When parser sees a '\0' it stops further parsing. With this change, write(3, " \0", 2) will work. Signed-off-by: Changbin Du <changbin.du@intel.com> --- v2: Stop parsing when '\0' found. --- kernel/trace/trace.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 2a8d8a2..144d08e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1237,7 +1237,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, } /* only spaces were written */ - if (isspace(ch)) { + if (isspace(ch) || !ch) { *ppos += read; ret = read; goto out; @@ -1247,7 +1247,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, } /* read the non-space input */ - while (cnt && !isspace(ch)) { + while (cnt && !isspace(ch) && ch) { if (parser->idx < parser->size - 1) parser->buffer[parser->idx++] = ch; else { @@ -1262,7 +1262,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, } /* We either got finished input or we have to wait for another call. */ - if (isspace(ch)) { + if (isspace(ch) || !ch) { parser->buffer[parser->idx] = 0; parser->cont = false; } else if (parser->idx < parser->size - 1) { -- 2.7.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string 2018-01-15 11:41 ` [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string changbin.du @ 2018-01-15 23:20 ` Steven Rostedt 2018-01-16 2:41 ` Du, Changbin 0 siblings, 1 reply; 6+ messages in thread From: Steven Rostedt @ 2018-01-15 23:20 UTC (permalink / raw) To: changbin.du Cc: jolsa, peterz, mingo, alexander.shishkin, linux-kernel, linux-perf-users On Mon, 15 Jan 2018 19:41:12 +0800 changbin.du@intel.com wrote: > From: Changbin Du <changbin.du@intel.com> > > The usersapce can give a '\0' terminated C string in the input buffer. > Before this change, trace_get_user() will return a parsed string "\0" in > below case which is not expected (expects it skip all inputs) and cause the > caller failed. The above totally does not parse (no pun intended). Are you trying to say: "User space can pass in a C nul character '\0' along with its input. The function trace_get_user() will try to process it as a normal character, and that will fail to parse. > > open("/sys/kernel/debug/tracing//set_ftrace_pid", O_WRONLY|O_TRUNC) = 3 > write(3, " \0", 2) = -1 EINVAL (Invalid argument) > > while parse can handle spaces, so below works. > > $ echo "" > set_ftrace_pid > $ echo " " > set_ftrace_pid > $ echo -n " " > set_ftrace_pid > > This patch try to make the parser '\0' aware to fix such issue. When parser > sees a '\0' it stops further parsing. With this change, write(3, " \0", 2) > will work. The above should be something like: "Have the parser stop on '\0' and cease any further parsing. Only process the characters up to the nul '\0' character and do not process it." -- Steve > > Signed-off-by: Changbin Du <changbin.du@intel.com> > > --- > v2: Stop parsing when '\0' found. > --- > kernel/trace/trace.c | 6 +++--- > 1 file changed, 3 insertions(+), 3 deletions(-) > > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c > index 2a8d8a2..144d08e 100644 > --- a/kernel/trace/trace.c > +++ b/kernel/trace/trace.c > @@ -1237,7 +1237,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, > } > > /* only spaces were written */ > - if (isspace(ch)) { > + if (isspace(ch) || !ch) { > *ppos += read; > ret = read; > goto out; > @@ -1247,7 +1247,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, > } > > /* read the non-space input */ > - while (cnt && !isspace(ch)) { > + while (cnt && !isspace(ch) && ch) { > if (parser->idx < parser->size - 1) > parser->buffer[parser->idx++] = ch; > else { > @@ -1262,7 +1262,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, > } > > /* We either got finished input or we have to wait for another call. */ > - if (isspace(ch)) { > + if (isspace(ch) || !ch) { > parser->buffer[parser->idx] = 0; > parser->cont = false; > } else if (parser->idx < parser->size - 1) { ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string 2018-01-15 23:20 ` Steven Rostedt @ 2018-01-16 2:41 ` Du, Changbin 0 siblings, 0 replies; 6+ messages in thread From: Du, Changbin @ 2018-01-16 2:41 UTC (permalink / raw) To: Steven Rostedt Cc: changbin.du, jolsa, peterz, mingo, alexander.shishkin, linux-kernel, linux-perf-users Hi Rostedt, Thanks for your polish, let me update commit msg with your words. On Mon, Jan 15, 2018 at 06:20:00PM -0500, Steven Rostedt wrote: > On Mon, 15 Jan 2018 19:41:12 +0800 > changbin.du@intel.com wrote: > > > From: Changbin Du <changbin.du@intel.com> > > > > The usersapce can give a '\0' terminated C string in the input buffer. > > Before this change, trace_get_user() will return a parsed string "\0" in > > below case which is not expected (expects it skip all inputs) and cause the > > caller failed. > > The above totally does not parse (no pun intended). > > Are you trying to say: > > "User space can pass in a C nul character '\0' along with its input. > The function trace_get_user() will try to process it as a normal > character, and that will fail to parse. > > > > > open("/sys/kernel/debug/tracing//set_ftrace_pid", O_WRONLY|O_TRUNC) = 3 > > write(3, " \0", 2) = -1 EINVAL (Invalid argument) > > > > while parse can handle spaces, so below works. > > > > $ echo "" > set_ftrace_pid > > $ echo " " > set_ftrace_pid > > $ echo -n " " > set_ftrace_pid > > > > This patch try to make the parser '\0' aware to fix such issue. When parser > > sees a '\0' it stops further parsing. With this change, write(3, " \0", 2) > > will work. > > The above should be something like: > > "Have the parser stop on '\0' and cease any further parsing. Only > process the characters up to the nul '\0' character and do not process > it." > > -- Steve > > > > > > Signed-off-by: Changbin Du <changbin.du@intel.com> > > > > --- > > v2: Stop parsing when '\0' found. > > --- > > kernel/trace/trace.c | 6 +++--- > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c > > index 2a8d8a2..144d08e 100644 > > --- a/kernel/trace/trace.c > > +++ b/kernel/trace/trace.c > > @@ -1237,7 +1237,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, > > } > > > > /* only spaces were written */ > > - if (isspace(ch)) { > > + if (isspace(ch) || !ch) { > > *ppos += read; > > ret = read; > > goto out; > > @@ -1247,7 +1247,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, > > } > > > > /* read the non-space input */ > > - while (cnt && !isspace(ch)) { > > + while (cnt && !isspace(ch) && ch) { > > if (parser->idx < parser->size - 1) > > parser->buffer[parser->idx++] = ch; > > else { > > @@ -1262,7 +1262,7 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, > > } > > > > /* We either got finished input or we have to wait for another call. */ > > - if (isspace(ch)) { > > + if (isspace(ch) || !ch) { > > parser->buffer[parser->idx] = 0; > > parser->cont = false; > > } else if (parser->idx < parser->size - 1) { > -- Thanks, Changbin Du ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH v2 2/3] tracing: clear parser->idx if parser gets nothing 2018-01-15 11:41 [PATCH v2 0/3] tracing: Fix the parser when processing strings w/ or w/o terminated '\0' changbin.du 2018-01-15 11:41 ` [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string changbin.du @ 2018-01-15 11:41 ` changbin.du 2018-01-15 11:41 ` [PATCH v2 3/3] tracing: make sure the parsed string always terminates with '\0' changbin.du 2 siblings, 0 replies; 6+ messages in thread From: changbin.du @ 2018-01-15 11:41 UTC (permalink / raw) To: rostedt Cc: jolsa, peterz, mingo, alexander.shishkin, linux-kernel, linux-perf-users, Changbin Du From: Changbin Du <changbin.du@intel.com> If only spaces was got in that cycle, we should clear parser->idx to make trace_parser_loaded() return false. Signed-off-by: Changbin Du <changbin.du@intel.com> --- kernel/trace/trace.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index 144d08e..b44926e 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -1236,14 +1236,14 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, cnt--; } + parser->idx = 0; + /* only spaces were written */ if (isspace(ch) || !ch) { *ppos += read; ret = read; goto out; } - - parser->idx = 0; } /* read the non-space input */ -- 2.7.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
* [PATCH v2 3/3] tracing: make sure the parsed string always terminates with '\0' 2018-01-15 11:41 [PATCH v2 0/3] tracing: Fix the parser when processing strings w/ or w/o terminated '\0' changbin.du 2018-01-15 11:41 ` [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string changbin.du 2018-01-15 11:41 ` [PATCH v2 2/3] tracing: clear parser->idx if parser gets nothing changbin.du @ 2018-01-15 11:41 ` changbin.du 2 siblings, 0 replies; 6+ messages in thread From: changbin.du @ 2018-01-15 11:41 UTC (permalink / raw) To: rostedt Cc: jolsa, peterz, mingo, alexander.shishkin, linux-kernel, linux-perf-users, Changbin Du From: Changbin Du <changbin.du@intel.com> Always mark the parsed string with a terminated '\0' even parser expects another input to be parsed. Thus the users needn't append '0' before using parsed string if new input is not given. Signed-off-by: Changbin Du <changbin.du@intel.com> --- kernel/trace/ftrace.c | 2 -- kernel/trace/trace.c | 4 ++-- kernel/trace/trace_events.c | 2 -- 3 files changed, 2 insertions(+), 6 deletions(-) diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c index ccdf366..3addb82 100644 --- a/kernel/trace/ftrace.c +++ b/kernel/trace/ftrace.c @@ -5010,7 +5010,6 @@ int ftrace_regex_release(struct inode *inode, struct file *file) parser = &iter->parser; if (trace_parser_loaded(parser)) { - parser->buffer[parser->idx] = 0; ftrace_match_records(iter->hash, parser->buffer, parser->idx); } @@ -5324,7 +5323,6 @@ ftrace_graph_release(struct inode *inode, struct file *file) parser = &fgd->parser; if (trace_parser_loaded((parser))) { - parser->buffer[parser->idx] = 0; ret = ftrace_graph_set_hash(fgd->new_hash, parser->buffer); } diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c index b44926e..8f7fea2 100644 --- a/kernel/trace/trace.c +++ b/kernel/trace/trace.c @@ -530,8 +530,6 @@ int trace_pid_write(struct trace_pid_list *filtered_pids, ubuf += ret; cnt -= ret; - parser.buffer[parser.idx] = 0; - ret = -EINVAL; if (kstrtoul(parser.buffer, 0, &val)) break; @@ -1268,6 +1266,8 @@ int trace_get_user(struct trace_parser *parser, const char __user *ubuf, } else if (parser->idx < parser->size - 1) { parser->cont = true; parser->buffer[parser->idx++] = ch; + /* Make sure the parsed string always terminates with '\0'. */ + parser->buffer[parser->idx] = 0; } else { ret = -EINVAL; goto out; diff --git a/kernel/trace/trace_events.c b/kernel/trace/trace_events.c index ec0f9aa..7f8027c 100644 --- a/kernel/trace/trace_events.c +++ b/kernel/trace/trace_events.c @@ -885,8 +885,6 @@ ftrace_event_write(struct file *file, const char __user *ubuf, if (*parser.buffer == '!') set = 0; - parser.buffer[parser.idx] = 0; - ret = ftrace_set_clr_event(tr, parser.buffer + !set, set); if (ret) goto out_put; -- 2.7.4 ^ permalink raw reply related [flat|nested] 6+ messages in thread
end of thread, other threads:[~2018-01-16 2:49 UTC | newest] Thread overview: 6+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2018-01-15 11:41 [PATCH v2 0/3] tracing: Fix the parser when processing strings w/ or w/o terminated '\0' changbin.du 2018-01-15 11:41 ` [PATCH v2 1/3] tracing: detect the string termination character when parsing user input string changbin.du 2018-01-15 23:20 ` Steven Rostedt 2018-01-16 2:41 ` Du, Changbin 2018-01-15 11:41 ` [PATCH v2 2/3] tracing: clear parser->idx if parser gets nothing changbin.du 2018-01-15 11:41 ` [PATCH v2 3/3] tracing: make sure the parsed string always terminates with '\0' changbin.du
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).