#include <linux/types.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/capability.h>
#include <linux/fs.h>
#include <linux/namei.h>
#include <linux/mm.h>
static inline int putstat(struct sol_stat __user *ubuf, struct kstat *kbuf)
{
+ u32 ino;
+
if (kbuf->size > MAX_NON_LFS ||
!sysv_valid_dev(kbuf->dev) ||
!sysv_valid_dev(kbuf->rdev))
return -EOVERFLOW;
+ ino = kbuf->ino;
+ if (sizeof(ino) < sizeof(kbuf->ino) && ino != kbuf->ino)
+ return -EOVERFLOW;
if (put_user (sysv_encode_dev(kbuf->dev), &ubuf->st_dev) ||
- __put_user (kbuf->ino, &ubuf->st_ino) ||
+ __put_user (ino, &ubuf->st_ino) ||
__put_user (kbuf->mode, &ubuf->st_mode) ||
__put_user (kbuf->nlink, &ubuf->st_nlink) ||
__put_user (kbuf->uid, &ubuf->st_uid) ||
int error;
struct sol_statvfs __user *ss = A(buf);
- error = vfs_statfs(mnt->mnt_sb, &s);
+ error = vfs_statfs(mnt->mnt_root, &s);
if (!error) {
const char *p = mnt->mnt_sb->s_type->name;
int i = 0;
int j = strlen (p);
if (j > 15) j = 15;
- if (IS_RDONLY(inode)) i = 1;
+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
if (!sysv_valid_dev(inode->i_sb->s_dev))
return -EOVERFLOW;
int error;
struct sol_statvfs64 __user *ss = A(buf);
- error = vfs_statfs(mnt->mnt_sb, &s);
+ error = vfs_statfs(mnt->mnt_root, &s);
if (!error) {
const char *p = mnt->mnt_sb->s_type->name;
int i = 0;
int j = strlen (p);
if (j > 15) j = 15;
- if (IS_RDONLY(inode)) i = 1;
+ if (IS_RDONLY(inode) || MNT_IS_RDONLY(mnt)) i = 1;
if (mnt->mnt_flags & MNT_NOSUID) i |= 2;
if (!sysv_valid_dev(inode->i_sb->s_dev))
return -EOVERFLOW;