aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorMike Kravetz <kravetz@us.ibm.com>2004-08-22 22:26:30 -0700
committerLinus Torvalds <torvalds@ppc970.osdl.org>2004-08-22 22:26:30 -0700
commit4b4b699dc55425eb582fb233b7815ce0ecd97147 (patch)
tree1498a69ffae64a8b548c2c9cbadcbabe58fe744c /fs
parent9026a8d6da2f5a283b988f0748e6324467e12636 (diff)
downloadhistory-4b4b699dc55425eb582fb233b7815ce0ecd97147.tar.gz
[PATCH] proc fs task name locking fix
Races have been observed between excec-time overwriting of task->comm and /proc accesses to the same data. This causes environment string information to appear in /proc. Fix that up by taking task_lock() around updates to and accesses to task->comm. Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'fs')
-rw-r--r--fs/exec.c23
-rw-r--r--fs/proc/array.c11
2 files changed, 28 insertions, 6 deletions
diff --git a/fs/exec.c b/fs/exec.c
index be4366c0a01192..92b788cd4394b1 100644
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -786,11 +786,27 @@ static inline void flush_old_files(struct files_struct * files)
spin_unlock(&files->file_lock);
}
+void get_task_comm(char *buf, struct task_struct *tsk)
+{
+ /* buf must be at least sizeof(tsk->comm) in size */
+ task_lock(tsk);
+ memcpy(buf, tsk->comm, sizeof(tsk->comm));
+ task_unlock(tsk);
+}
+
+void set_task_comm(struct task_struct *tsk, char *buf)
+{
+ task_lock(tsk);
+ strlcpy(tsk->comm, buf, sizeof(tsk->comm));
+ task_unlock(tsk);
+}
+
int flush_old_exec(struct linux_binprm * bprm)
{
char * name;
int i, ch, retval;
struct files_struct *files;
+ char tcomm[sizeof(current->comm)];
/*
* Make sure we have a private signal table and that
@@ -831,10 +847,11 @@ int flush_old_exec(struct linux_binprm * bprm)
if (ch == '/')
i = 0;
else
- if (i < 15)
- current->comm[i++] = ch;
+ if (i < (sizeof(tcomm) - 1))
+ tcomm[i++] = ch;
}
- current->comm[i] = '\0';
+ tcomm[i] = '\0';
+ set_task_comm(current, tcomm);
flush_thread();
diff --git a/fs/proc/array.c b/fs/proc/array.c
index fe14439309ab3b..995080fd88d236 100644
--- a/fs/proc/array.c
+++ b/fs/proc/array.c
@@ -88,10 +88,13 @@ static inline char * task_name(struct task_struct *p, char * buf)
{
int i;
char * name;
+ char tcomm[sizeof(p->comm)];
+
+ get_task_comm(tcomm, p);
ADDBUF(buf, "Name:\t");
- name = p->comm;
- i = sizeof(p->comm);
+ name = tcomm;
+ i = sizeof(tcomm);
do {
unsigned char c = *name;
name++;
@@ -309,6 +312,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
int num_threads = 0;
struct mm_struct *mm;
unsigned long long start_time;
+ char tcomm[sizeof(task->comm)];
state = *get_task_state(task);
vsize = eip = esp = 0;
@@ -325,6 +329,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
up_read(&mm->mmap_sem);
}
+ get_task_comm(tcomm, task);
wchan = get_wchan(task);
sigemptyset(&sigign);
@@ -362,7 +367,7 @@ int proc_pid_stat(struct task_struct *task, char * buffer)
%lu %lu %lu %lu %lu %ld %ld %ld %ld %d %ld %llu %lu %ld %lu %lu %lu %lu %lu \
%lu %lu %lu %lu %lu %lu %lu %lu %d %d %lu %lu\n",
task->pid,
- task->comm,
+ tcomm,
state,
ppid,
pgid,