aboutsummaryrefslogtreecommitdiffstats
path: root/kernel
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2009-03-16 19:20:15 -0400
committerSteven Rostedt <srostedt@redhat.com>2009-03-16 23:27:06 -0400
commit4ca530852346be239b7c19e7bec5d2b78855bebe (patch)
tree96e5252faaf362115a96ed6df7c4e4f698a027dc /kernel
parent03303549b1695dc024d4a653cc16bd79f78f9750 (diff)
tracing: protect reader of cmdline output
Impact: fix to one cause of incorrect comm outputs in trace The spinlock only protected the creation of a comm <=> pid pair. But it was possible that a reader could look up a pid, and get the wrong comm because it had no locking. This also required changing trace_find_cmdline to copy the comm cache and not just send back a pointer to it. Signed-off-by: Steven Rostedt <srostedt@redhat.com>
Diffstat (limited to 'kernel')
-rw-r--r--kernel/trace/blktrace.c23
-rw-r--r--kernel/trace/trace.c20
-rw-r--r--kernel/trace/trace.h2
-rw-r--r--kernel/trace/trace_functions_graph.c12
-rw-r--r--kernel/trace/trace_output.c18
5 files changed, 49 insertions, 26 deletions
diff --git a/kernel/trace/blktrace.c b/kernel/trace/blktrace.c
index 1f32e4edf490..b171778e3863 100644
--- a/kernel/trace/blktrace.c
+++ b/kernel/trace/blktrace.c
@@ -1027,7 +1027,9 @@ static int blk_log_action_seq(struct trace_seq *s, const struct blk_io_trace *t,
1027 1027
1028static int blk_log_generic(struct trace_seq *s, const struct trace_entry *ent) 1028static int blk_log_generic(struct trace_seq *s, const struct trace_entry *ent)
1029{ 1029{
1030 const char *cmd = trace_find_cmdline(ent->pid); 1030 char cmd[TASK_COMM_LEN];
1031
1032 trace_find_cmdline(ent->pid, cmd);
1031 1033
1032 if (t_sec(ent)) 1034 if (t_sec(ent))
1033 return trace_seq_printf(s, "%llu + %u [%s]\n", 1035 return trace_seq_printf(s, "%llu + %u [%s]\n",
@@ -1057,19 +1059,30 @@ static int blk_log_remap(struct trace_seq *s, const struct trace_entry *ent)
1057 1059
1058static int blk_log_plug(struct trace_seq *s, const struct trace_entry *ent) 1060static int blk_log_plug(struct trace_seq *s, const struct trace_entry *ent)
1059{ 1061{
1060 return trace_seq_printf(s, "[%s]\n", trace_find_cmdline(ent->pid)); 1062 char cmd[TASK_COMM_LEN];
1063
1064 trace_find_cmdline(ent->pid, cmd);
1065
1066 return trace_seq_printf(s, "[%s]\n", cmd);
1061} 1067}
1062 1068
1063static int blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent) 1069static int blk_log_unplug(struct trace_seq *s, const struct trace_entry *ent)
1064{ 1070{
1065 return trace_seq_printf(s, "[%s] %llu\n", trace_find_cmdline(ent->pid), 1071 char cmd[TASK_COMM_LEN];
1066 get_pdu_int(ent)); 1072
1073 trace_find_cmdline(ent->pid, cmd);
1074
1075 return trace_seq_printf(s, "[%s] %llu\n", cmd, get_pdu_int(ent));
1067} 1076}
1068 1077
1069static int blk_log_split(struct trace_seq *s, const struct trace_entry *ent) 1078static int blk_log_split(struct trace_seq *s, const struct trace_entry *ent)
1070{ 1079{
1080 char cmd[TASK_COMM_LEN];
1081
1082 trace_find_cmdline(ent->pid, cmd);
1083
1071 return trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent), 1084 return trace_seq_printf(s, "%llu / %llu [%s]\n", t_sector(ent),
1072 get_pdu_int(ent), trace_find_cmdline(ent->pid)); 1085 get_pdu_int(ent), cmd);
1073} 1086}
1074 1087
1075/* 1088/*
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index efe3202c0209..2796bd2b17e4 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -770,25 +770,29 @@ static void trace_save_cmdline(struct task_struct *tsk)
770 __raw_spin_unlock(&trace_cmdline_lock); 770 __raw_spin_unlock(&trace_cmdline_lock);
771} 771}
772 772
773char *trace_find_cmdline(int pid) 773void trace_find_cmdline(int pid, char comm[])
774{ 774{
775 char *cmdline = "<...>";
776 unsigned map; 775 unsigned map;
777 776
778 if (!pid) 777 if (!pid) {
779 return "<idle>"; 778 strcpy(comm, "<idle>");
779 return;
780 }
780 781
781 if (pid > PID_MAX_DEFAULT) 782 if (pid > PID_MAX_DEFAULT) {
782 goto out; 783 strcpy(comm, "<...>");
784 return;
785 }
783 786
787 __raw_spin_lock(&trace_cmdline_lock);
784 map = map_pid_to_cmdline[pid]; 788 map = map_pid_to_cmdline[pid];
785 if (map >= SAVED_CMDLINES) 789 if (map >= SAVED_CMDLINES)
786 goto out; 790 goto out;
787 791
788 cmdline = saved_cmdlines[map]; 792 strcpy(comm, saved_cmdlines[map]);
789 793
790 out: 794 out:
791 return cmdline; 795 __raw_spin_unlock(&trace_cmdline_lock);
792} 796}
793 797
794void tracing_record_cmdline(struct task_struct *tsk) 798void tracing_record_cmdline(struct task_struct *tsk)
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 56ce34d90b03..b0ecad8ecc34 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -547,7 +547,7 @@ struct tracer_switch_ops {
547}; 547};
548#endif /* CONFIG_CONTEXT_SWITCH_TRACER */ 548#endif /* CONFIG_CONTEXT_SWITCH_TRACER */
549 549
550extern char *trace_find_cmdline(int pid); 550extern void trace_find_cmdline(int pid, char comm[]);
551 551
552#ifdef CONFIG_DYNAMIC_FTRACE 552#ifdef CONFIG_DYNAMIC_FTRACE
553extern unsigned long ftrace_update_tot_cnt; 553extern unsigned long ftrace_update_tot_cnt;
diff --git a/kernel/trace/trace_functions_graph.c b/kernel/trace/trace_functions_graph.c
index 4c388607ed67..6004ccac2dd7 100644
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -190,15 +190,15 @@ print_graph_cpu(struct trace_seq *s, int cpu)
190static enum print_line_t 190static enum print_line_t
191print_graph_proc(struct trace_seq *s, pid_t pid) 191print_graph_proc(struct trace_seq *s, pid_t pid)
192{ 192{
193 int i; 193 char comm[TASK_COMM_LEN];
194 int ret;
195 int len;
196 char comm[8];
197 int spaces = 0;
198 /* sign + log10(MAX_INT) + '\0' */ 194 /* sign + log10(MAX_INT) + '\0' */
199 char pid_str[11]; 195 char pid_str[11];
196 int spaces = 0;
197 int ret;
198 int len;
199 int i;
200 200
201 strncpy(comm, trace_find_cmdline(pid), 7); 201 trace_find_cmdline(pid, comm);
202 comm[7] = '\0'; 202 comm[7] = '\0';
203 sprintf(pid_str, "%d", pid); 203 sprintf(pid_str, "%d", pid);
204 204
diff --git a/kernel/trace/trace_output.c b/kernel/trace/trace_output.c
index ea9d3b410c7a..6a4c9dea191e 100644
--- a/kernel/trace/trace_output.c
+++ b/kernel/trace/trace_output.c
@@ -309,9 +309,9 @@ static int
309lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu) 309lat_print_generic(struct trace_seq *s, struct trace_entry *entry, int cpu)
310{ 310{
311 int hardirq, softirq; 311 int hardirq, softirq;
312 char *comm; 312 char comm[TASK_COMM_LEN];
313 313
314 comm = trace_find_cmdline(entry->pid); 314 trace_find_cmdline(entry->pid, comm);
315 hardirq = entry->flags & TRACE_FLAG_HARDIRQ; 315 hardirq = entry->flags & TRACE_FLAG_HARDIRQ;
316 softirq = entry->flags & TRACE_FLAG_SOFTIRQ; 316 softirq = entry->flags & TRACE_FLAG_SOFTIRQ;
317 317
@@ -346,10 +346,12 @@ int trace_print_context(struct trace_iterator *iter)
346{ 346{
347 struct trace_seq *s = &iter->seq; 347 struct trace_seq *s = &iter->seq;
348 struct trace_entry *entry = iter->ent; 348 struct trace_entry *entry = iter->ent;
349 char *comm = trace_find_cmdline(entry->pid);
350 unsigned long long t = ns2usecs(iter->ts); 349 unsigned long long t = ns2usecs(iter->ts);
351 unsigned long usec_rem = do_div(t, USEC_PER_SEC); 350 unsigned long usec_rem = do_div(t, USEC_PER_SEC);
352 unsigned long secs = (unsigned long)t; 351 unsigned long secs = (unsigned long)t;
352 char comm[TASK_COMM_LEN];
353
354 trace_find_cmdline(entry->pid, comm);
353 355
354 return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ", 356 return trace_seq_printf(s, "%16s-%-5d [%03d] %5lu.%06lu: ",
355 comm, entry->pid, iter->cpu, secs, usec_rem); 357 comm, entry->pid, iter->cpu, secs, usec_rem);
@@ -372,7 +374,10 @@ int trace_print_lat_context(struct trace_iterator *iter)
372 rel_usecs = ns2usecs(next_ts - iter->ts); 374 rel_usecs = ns2usecs(next_ts - iter->ts);
373 375
374 if (verbose) { 376 if (verbose) {
375 char *comm = trace_find_cmdline(entry->pid); 377 char comm[TASK_COMM_LEN];
378
379 trace_find_cmdline(entry->pid, comm);
380
376 ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]" 381 ret = trace_seq_printf(s, "%16s %5d %3d %d %08x %08lx [%08lx]"
377 " %ld.%03ldms (+%ld.%03ldms): ", comm, 382 " %ld.%03ldms (+%ld.%03ldms): ", comm,
378 entry->pid, iter->cpu, entry->flags, 383 entry->pid, iter->cpu, entry->flags,
@@ -577,14 +582,15 @@ static enum print_line_t trace_ctxwake_print(struct trace_iterator *iter,
577 char *delim) 582 char *delim)
578{ 583{
579 struct ctx_switch_entry *field; 584 struct ctx_switch_entry *field;
580 char *comm; 585 char comm[TASK_COMM_LEN];
581 int S, T; 586 int S, T;
582 587
588
583 trace_assign_type(field, iter->ent); 589 trace_assign_type(field, iter->ent);
584 590
585 T = task_state_char(field->next_state); 591 T = task_state_char(field->next_state);
586 S = task_state_char(field->prev_state); 592 S = task_state_char(field->prev_state);
587 comm = trace_find_cmdline(field->next_pid); 593 trace_find_cmdline(field->next_pid, comm);
588 if (!trace_seq_printf(&iter->seq, 594 if (!trace_seq_printf(&iter->seq,
589 " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n", 595 " %5d:%3d:%c %s [%03d] %5d:%3d:%c %s\n",
590 field->prev_pid, 596 field->prev_pid,