Commit 02cda956 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] unshare_files

From: Chris Wright <chrisw@osdl.org>

Introduce unshare_files as a helper for use during execve to eliminate
potential leak of the execve'd binary's fd.
parent 3a8d5347
......@@ -1408,5 +1408,8 @@ static inline ino_t parent_ino(struct dentry *dentry)
return res;
}
/* kernel/fork.c */
extern int unshare_files(void);
#endif /* __KERNEL__ */
#endif /* _LINUX_FS_H */
......@@ -642,6 +642,11 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
goto out;
}
/*
* Note: we may be using current for both targets (See exec.c)
* This works because we cache current->files (old) as oldf. Don't
* break this.
*/
tsk->files = NULL;
error = -ENOMEM;
newf = kmem_cache_alloc(files_cachep, SLAB_KERNEL);
......@@ -731,6 +736,35 @@ static int copy_files(unsigned long clone_flags, struct task_struct * tsk)
goto out;
}
/*
* Helper to unshare the files of the current task.
* We don't want to expose copy_files internals to
* the exec layer of the kernel.
*/
int unshare_files(void)
{
struct files_struct *files = current->files;
int rc;
if(!files)
BUG();
/* This can race but the race causes us to copy when we don't
need to and drop the copy */
if(atomic_read(&files->count) == 1)
{
atomic_inc(&files->count);
return 0;
}
rc = copy_files(0, current);
if(rc)
current->files = files;
return rc;
}
EXPORT_SYMBOL(unshare_files);
static inline int copy_sighand(unsigned long clone_flags, struct task_struct * tsk)
{
struct sighand_struct *sig;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment