generic compat_sys_ustat
Due to a different size of ino_t ustat needs a compat handler, but currently only x86 and mips provide one. Add a generic compat_sys_ustat and switch all architectures over to it. Instead of doing various user copy hacks compat_sys_ustat just reimplements sys_ustat as it's trivial. This was suggested by Arnd Bergmann. Found by Eric Sandeen when running xfstests/017 on ppc64, which causes stack smashing warnings on RHEL/Fedora due to the too large amount of data writen by the syscall. Signed-off-by: Christoph Hellwig <hch@lst.de> Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
This commit is contained in:
committed by
Al Viro
parent
ec1ab0abde
commit
2b1c6bd77d
28
fs/compat.c
28
fs/compat.c
@@ -378,6 +378,34 @@ out:
|
||||
return error;
|
||||
}
|
||||
|
||||
/*
|
||||
* This is a copy of sys_ustat, just dealing with a structure layout.
|
||||
* Given how simple this syscall is that apporach is more maintainable
|
||||
* than the various conversion hacks.
|
||||
*/
|
||||
asmlinkage long compat_sys_ustat(unsigned dev, struct compat_ustat __user *u)
|
||||
{
|
||||
struct super_block *sb;
|
||||
struct compat_ustat tmp;
|
||||
struct kstatfs sbuf;
|
||||
int err;
|
||||
|
||||
sb = user_get_super(new_decode_dev(dev));
|
||||
if (!sb)
|
||||
return -EINVAL;
|
||||
err = vfs_statfs(sb->s_root, &sbuf);
|
||||
drop_super(sb);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memset(&tmp, 0, sizeof(struct compat_ustat));
|
||||
tmp.f_tfree = sbuf.f_bfree;
|
||||
tmp.f_tinode = sbuf.f_ffree;
|
||||
if (copy_to_user(u, &tmp, sizeof(struct compat_ustat)))
|
||||
return -EFAULT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_compat_flock(struct flock *kfl, struct compat_flock __user *ufl)
|
||||
{
|
||||
if (!access_ok(VERIFY_READ, ufl, sizeof(*ufl)) ||
|
||||
|
Reference in New Issue
Block a user