Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 9142
b: refs/heads/master
c: 66dcca0
h: refs/heads/master
v: v3
  • Loading branch information
Sripathi Kodi authored and Linus Torvalds committed Sep 21, 2005
1 parent 3eed28d commit b96c002
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 8 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: d79e743e9fcf03f521300a970eb1ab69641910ba
refs/heads/master: 66dcca062847bcd261ebb3ac96d51101f31a8630
84 changes: 77 additions & 7 deletions trunk/fs/proc/base.c
Original file line number Diff line number Diff line change
Expand Up @@ -340,6 +340,52 @@ static int proc_root_link(struct inode *inode, struct dentry **dentry, struct vf
return result;
}


/* Same as proc_root_link, but this addionally tries to get fs from other
* threads in the group */
static int proc_task_root_link(struct inode *inode, struct dentry **dentry, struct vfsmount **mnt)
{
struct fs_struct *fs;
int result = -ENOENT;
struct task_struct *leader = proc_task(inode);

task_lock(leader);
fs = leader->fs;
if (fs) {
atomic_inc(&fs->count);
task_unlock(leader);
} else {
/* Try to get fs from other threads */
task_unlock(leader);
struct task_struct *task = leader;
read_lock(&tasklist_lock);
if (pid_alive(task)) {
while ((task = next_thread(task)) != leader) {
task_lock(task);
fs = task->fs;
if (fs) {
atomic_inc(&fs->count);
task_unlock(task);
break;
}
task_unlock(task);
}
}
read_unlock(&tasklist_lock);
}

if (fs) {
read_lock(&fs->lock);
*mnt = mntget(fs->rootmnt);
*dentry = dget(fs->root);
read_unlock(&fs->lock);
result = 0;
put_fs_struct(fs);
}
return result;
}


#define MAY_PTRACE(task) \
(task == current || \
(task->parent == current && \
Expand Down Expand Up @@ -471,14 +517,14 @@ static int proc_oom_score(struct task_struct *task, char *buffer)

/* permission checks */

static int proc_check_root(struct inode *inode)
/* If the process being read is separated by chroot from the reading process,
* don't let the reader access the threads.
*/
static int proc_check_chroot(struct dentry *root, struct vfsmount *vfsmnt)
{
struct dentry *de, *base, *root;
struct vfsmount *our_vfsmnt, *vfsmnt, *mnt;
struct dentry *de, *base;
struct vfsmount *our_vfsmnt, *mnt;
int res = 0;

if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
return -ENOENT;
read_lock(&current->fs->lock);
our_vfsmnt = mntget(current->fs->rootmnt);
base = dget(current->fs->root);
Expand Down Expand Up @@ -511,13 +557,37 @@ static int proc_check_root(struct inode *inode)
goto exit;
}

static int proc_check_root(struct inode *inode)
{
struct dentry *root;
struct vfsmount *vfsmnt;

if (proc_root_link(inode, &root, &vfsmnt)) /* Ewww... */
return -ENOENT;
return proc_check_chroot(root, vfsmnt);
}

static int proc_permission(struct inode *inode, int mask, struct nameidata *nd)
{
if (generic_permission(inode, mask, NULL) != 0)
return -EACCES;
return proc_check_root(inode);
}

static int proc_task_permission(struct inode *inode, int mask, struct nameidata *nd)
{
struct dentry *root;
struct vfsmount *vfsmnt;

if (generic_permission(inode, mask, NULL) != 0)
return -EACCES;

if (proc_task_root_link(inode, &root, &vfsmnt))
return -ENOENT;

return proc_check_chroot(root, vfsmnt);
}

extern struct seq_operations proc_pid_maps_op;
static int maps_open(struct inode *inode, struct file *file)
{
Expand Down Expand Up @@ -1419,7 +1489,7 @@ static struct inode_operations proc_fd_inode_operations = {

static struct inode_operations proc_task_inode_operations = {
.lookup = proc_task_lookup,
.permission = proc_permission,
.permission = proc_task_permission,
};

#ifdef CONFIG_SECURITY
Expand Down

0 comments on commit b96c002

Please sign in to comment.