[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <201104252114.HID65107.FOHOQFMVJtOSFL@I-love.SAKURA.ne.jp>
Date: Mon, 25 Apr 2011 21:14:10 +0900
From: Tetsuo Handa <penguin-kernel@...ove.SAKURA.ne.jp>
To: penberg@...nel.org, bonbons@...ux-vserver.org
Cc: vapier.adi@...il.com, kosaki.motohiro@...fujitsu.com,
linux-kernel@...r.kernel.org, linux-mm@...ck.org,
linux-fsdevel@...r.kernel.org, catalin.marinas@....com,
adobriyan@...il.com, torvalds@...ux-foundation.org,
viro@...iv.linux.org.uk, nickpiggin@...oo.com.au
Subject: Re: 2.6.39-rc4+: Kernel leaking memory during FS scanning, regression?
I don't know whether below is related with this bug. But...
static struct dentry *proc_pident_instantiate(struct inode *dir,
struct dentry *dentry, struct task_struct *task, const void *ptr)
{
const struct pid_entry *p = ptr;
struct inode *inode;
struct proc_inode *ei;
struct dentry *error = ERR_PTR(-ENOENT);
inode = proc_pid_make_inode(dir->i_sb, task);
if (!inode)
goto out;
ei = PROC_I(inode);
inode->i_mode = p->mode;
if (S_ISDIR(inode->i_mode))
inode->i_nlink = 2; /* Use getattr to fix if necessary */
if (p->iop)
inode->i_op = p->iop;
if (p->fop)
inode->i_fop = p->fop;
ei->op = p->op;
d_set_d_op(dentry, &pid_dentry_operations);
d_add(dentry, inode);
/* Close the race of the process dying before we return the dentry */
if (pid_revalidate(dentry, NULL))
error = NULL;
out:
return error;
}
proc_pid_make_inode() gets a ref on task, but return value of pid_revalidate()
(one of 0, 1, -ECHILD) may not be what above 'if (pid_revalidate(dentry, NULL))'
part expects. (-ECHILD is a new return value introduced by LOOKUP_RCU.)
static int pid_revalidate(struct dentry *dentry, struct nameidata *nd)
{
struct inode *inode;
struct task_struct *task;
const struct cred *cred;
if (nd && nd->flags & LOOKUP_RCU)
return -ECHILD;
inode = dentry->d_inode;
task = get_proc_task(inode);
if (task) {
if ((inode->i_mode == (S_IFDIR|S_IRUGO|S_IXUGO)) ||
task_dumpable(task)) {
rcu_read_lock();
cred = __task_cred(task);
inode->i_uid = cred->euid;
inode->i_gid = cred->egid;
rcu_read_unlock();
} else {
inode->i_uid = 0;
inode->i_gid = 0;
}
inode->i_mode &= ~(S_ISUID | S_ISGID);
security_task_to_inode(task, inode);
put_task_struct(task);
return 1;
}
d_drop(dentry);
return 0;
}
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@...r.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Powered by blists - more mailing lists