mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2025-01-17 02:36:21 +00:00
debugfs: full_proxy_open(): free proxy on ->open() failure
Debugfs' full_proxy_open(), the ->open() installed at all inodes created through debugfs_create_file(), - grabs a reference to the original struct file_operations instance passed to debugfs_create_file(), - dynamically allocates a proxy struct file_operations instance wrapping the original - and installs this at the file's ->f_op. Afterwards, it calls the original ->open() and passes its return value back to the VFS layer. Now, if that return value indicates failure, the VFS layer won't ever call ->release() and thus, neither the reference to the original file_operations nor the memory for the proxy file_operations will get released, i.e. both are leaked. Upon failure of the original fops' ->open(), undo the proxy installation. That is: - Set the struct file ->f_op to what it had been when full_proxy_open() was entered. - Drop the reference to the original file_operations. - Free the memory holding the proxy file_operations. Fixes: 49d200deaa68 ("debugfs: prevent access to removed files' private data") Signed-off-by: Nicolai Stange <nicstange@gmail.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
df4565f9eb
commit
b10e3e9048
@ -262,8 +262,10 @@ static int full_proxy_open(struct inode *inode, struct file *filp)
|
||||
|
||||
if (real_fops->open) {
|
||||
r = real_fops->open(inode, filp);
|
||||
|
||||
if (filp->f_op != proxy_fops) {
|
||||
if (r) {
|
||||
replace_fops(filp, d_inode(dentry)->i_fop);
|
||||
goto free_proxy;
|
||||
} else if (filp->f_op != proxy_fops) {
|
||||
/* No protection against file removal anymore. */
|
||||
WARN(1, "debugfs file owner replaced proxy fops: %pd",
|
||||
dentry);
|
||||
|
Loading…
x
Reference in New Issue
Block a user