summaryrefslogtreecommitdiff
path: root/fs/open.c
diff options
context:
space:
mode:
authorPaul Moore <pmoore@redhat.com>2015-01-22 00:00:03 -0500
committerAl Viro <viro@zeniv.linux.org.uk>2015-01-23 00:22:20 -0500
commit5168910413830435fa3f0a593933a83721ec8bad (patch)
tree72c23b2a0c98aad8d04670cb32903253e76c41ce /fs/open.c
parent08518549722f0c992a9e4be71a0777f37147e9d2 (diff)
fs: create proper filename objects using getname_kernel()
There are several areas in the kernel that create temporary filename objects using the following pattern: int func(const char *name) { struct filename *file = { .name = name }; ... return 0; } ... which for the most part works okay, but it causes havoc within the audit subsystem as the filename object does not persist beyond the lifetime of the function. This patch converts all of these temporary filename objects into proper filename objects using getname_kernel() and putname() which ensure that the filename object persists until the audit subsystem is finished with it. Also, a special thanks to Al Viro, Guenter Roeck, and Sabrina Dubroca for helping resolve a difficult kernel panic on boot related to a use-after-free problem in kern_path_create(); the thread can be seen at the link below: * https://lkml.org/lkml/2015/1/20/710 This patch includes code that was either based on, or directly written by Al in the above thread. CC: viro@zeniv.linux.org.uk CC: linux@roeck-us.net CC: sd@queasysnail.net CC: linux-fsdevel@vger.kernel.org Signed-off-by: Paul Moore <pmoore@redhat.com> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
Diffstat (limited to 'fs/open.c')
-rw-r--r--fs/open.c10
1 files changed, 8 insertions, 2 deletions
diff --git a/fs/open.c b/fs/open.c
index 813be037b412..d36c42ff019d 100644
--- a/fs/open.c
+++ b/fs/open.c
@@ -971,8 +971,14 @@ struct file *file_open_name(struct filename *name, int flags, umode_t mode)
*/
struct file *filp_open(const char *filename, int flags, umode_t mode)
{
- struct filename name = {.name = filename};
- return file_open_name(&name, flags, mode);
+ struct filename *name = getname_kernel(filename);
+ struct file *file = ERR_CAST(name);
+
+ if (!IS_ERR(name)) {
+ file = file_open_name(name, flags, mode);
+ putname(name);
+ }
+ return file;
}
EXPORT_SYMBOL(filp_open);