summaryrefslogtreecommitdiff
path: root/fs/exec.c
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/exec.c
parent9026a8d6da2f5a283b988f0748e6324467e12636 (diff)
[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/exec.c')
-rw-r--r--fs/exec.c23
1 files changed, 20 insertions, 3 deletions
diff --git a/fs/exec.c b/fs/exec.c
index be4366c0a011..92b788cd4394 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();