mirror of
https://git.openafs.org/openafs.git
synced 2025-01-18 06:50:12 +00:00
Linux: stop trying to use getname/putname
The current code has afs_putname defined as kmem_cache_free (names_cachep, (void *) name); This is wrong and will cause a double -free when syscall auditing is enabled. Fix it to call putname properly. Instead of that, just create a new afs_getname function that doesn't bother with struct filename at all, and use that unconditionally. Signed-off-by:Jeff Layton <jlayton@redhat.com> Reviewed-on: http://gerrit.openafs.org/10547 Tested-by: BuildBot <buildbot@rampaginggeek.com> Reviewed-by: Jeff Layton <jlayton@poochiereds.net> Reviewed-by: Derrick Brashear <shadow@your-file-system.com> (cherry picked from commitd40ed73916
) Reviewed-on: http://gerrit.openafs.org/10578 Reviewed-by: Derrick Brashear <shadow@your-file-system.com> Reviewed-by: Andrew Deason <adeason@sinenomine.net> Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de> Tested-by: BuildBot <buildbot@rampaginggeek.com> (cherry picked from commitd68e6c24f5
) Change-Id: Ic8055a6ed7aa955266c0f3112817924ef8ba591b Reviewed-on: http://gerrit.openafs.org/10604 Tested-by: Stephan Wiesand <stephan.wiesand@desy.de> Reviewed-by: Stephan Wiesand <stephan.wiesand@desy.de>
This commit is contained in:
parent
6e97ac37ca
commit
512ef081c1
@ -837,7 +837,6 @@ case $AFS_SYSNAME in *_linux* | *_umlinux*)
|
||||
AC_CHECK_LINUX_STRUCT([file_operations], [iterate], [fs.h])
|
||||
AC_CHECK_LINUX_STRUCT([file_operations], [sendfile], [fs.h])
|
||||
AC_CHECK_LINUX_STRUCT([file_system_type], [mount], [fs.h])
|
||||
AC_CHECK_LINUX_STRUCT([filename], [name], [fs.h])
|
||||
AC_CHECK_LINUX_STRUCT([inode_operations], [truncate], [fs.h])
|
||||
AC_CHECK_LINUX_STRUCT([key_type], [preparse], [key-type.h])
|
||||
AC_CHECK_LINUX_STRUCT([key_type], [instantiate_prep], [key-type.h])
|
||||
|
@ -502,42 +502,6 @@ afs_dentry_open(struct dentry *dp, struct vfsmount *mnt, int flags, const struct
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !defined(STRUCT_FILENAME_HAS_NAME)
|
||||
typedef char *afs_name_t;
|
||||
|
||||
static inline char *
|
||||
afs_name_to_string(afs_name_t s) {
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
static inline void
|
||||
afs_putname(afs_name_t name) {
|
||||
putname((char *)name);
|
||||
}
|
||||
|
||||
static inline void
|
||||
afs_set_name(afs_name_t name, char *string) {
|
||||
name = string;
|
||||
}
|
||||
#else
|
||||
typedef struct filename *afs_name_t;
|
||||
|
||||
static inline char *
|
||||
afs_name_to_string(afs_name_t s) {
|
||||
return (char *)s->name;
|
||||
}
|
||||
|
||||
static inline void
|
||||
afs_putname(afs_name_t name) {
|
||||
kmem_cache_free(names_cachep, (void *)name);
|
||||
}
|
||||
|
||||
static inline void
|
||||
afs_set_name(afs_name_t aname, char *string) {
|
||||
aname->name = string;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int
|
||||
afs_truncate(struct inode *inode, int len)
|
||||
{
|
||||
|
@ -77,26 +77,53 @@ osi_lookupname_internal(char *aname, int followlink, struct vfsmount **mnt,
|
||||
return code;
|
||||
}
|
||||
|
||||
static char *
|
||||
afs_getname(char *aname)
|
||||
{
|
||||
int len;
|
||||
char *name = kmem_cache_alloc(names_cachep, GFP_KERNEL);
|
||||
|
||||
if (!name)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
len = strncpy_from_user(name, aname, PATH_MAX);
|
||||
if (len < 0)
|
||||
goto error;
|
||||
if (len >= PATH_MAX) {
|
||||
len = -ENAMETOOLONG;
|
||||
goto error;
|
||||
}
|
||||
return name;
|
||||
|
||||
error:
|
||||
kmem_cache_free(names_cachep, name);
|
||||
return ERR_PTR(len);
|
||||
}
|
||||
|
||||
static void
|
||||
afs_putname(char *name)
|
||||
{
|
||||
kmem_cache_free(names_cachep, name);
|
||||
}
|
||||
|
||||
int
|
||||
osi_lookupname(char *aname, uio_seg_t seg, int followlink,
|
||||
struct dentry **dpp)
|
||||
{
|
||||
int code;
|
||||
afs_name_t tname = NULL;
|
||||
char *name;
|
||||
|
||||
code = ENOENT;
|
||||
if (seg == AFS_UIOUSER) {
|
||||
tname = getname(aname);
|
||||
if (IS_ERR(tname))
|
||||
return PTR_ERR(tname);
|
||||
name = afs_name_to_string(tname);
|
||||
name = afs_getname(aname);
|
||||
if (IS_ERR(name))
|
||||
return -PTR_ERR(name);
|
||||
} else {
|
||||
name = aname;
|
||||
}
|
||||
code = osi_lookupname_internal(name, followlink, NULL, dpp);
|
||||
if (seg == AFS_UIOUSER) {
|
||||
afs_putname(tname);
|
||||
afs_putname(name);
|
||||
}
|
||||
return code;
|
||||
}
|
||||
@ -106,15 +133,14 @@ int osi_abspath(char *aname, char *buf, int buflen,
|
||||
{
|
||||
struct dentry *dp = NULL;
|
||||
struct vfsmount *mnt = NULL;
|
||||
afs_name_t tname;
|
||||
char *path;
|
||||
char *name, *path;
|
||||
int code;
|
||||
|
||||
code = ENOENT;
|
||||
tname = getname(aname);
|
||||
if (IS_ERR(tname))
|
||||
return -PTR_ERR(tname);
|
||||
code = osi_lookupname_internal(afs_name_to_string(tname), followlink, &mnt, &dp);
|
||||
name = afs_getname(aname);
|
||||
if (IS_ERR(name))
|
||||
return -PTR_ERR(name);
|
||||
code = osi_lookupname_internal(name, followlink, &mnt, &dp);
|
||||
if (!code) {
|
||||
#if defined(D_PATH_TAKES_STRUCT_PATH)
|
||||
afs_linux_path_t p = { mnt, dp };
|
||||
@ -133,7 +159,7 @@ int osi_abspath(char *aname, char *buf, int buflen,
|
||||
mntput(mnt);
|
||||
}
|
||||
|
||||
afs_putname(tname);
|
||||
afs_putname(name);
|
||||
return code;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user