1 #include <linux/syscalls.h> 2 #include <linux/module.h> 3 #include <linux/fs.h> 4 #include <linux/file.h> 5 #include <linux/mount.h> 6 #include <linux/namei.h> 7 #include <linux/statfs.h> 8 #include <linux/security.h> 9 #include <linux/uaccess.h> 10 11 static int flags_by_mnt(int mnt_flags) 12 { 13 int flags = 0; 14 15 if (mnt_flags & MNT_READONLY) 16 flags |= ST_RDONLY; 17 if (mnt_flags & MNT_NOSUID) 18 flags |= ST_NOSUID; 19 if (mnt_flags & MNT_NODEV) 20 flags |= ST_NODEV; 21 if (mnt_flags & MNT_NOEXEC) 22 flags |= ST_NOEXEC; 23 if (mnt_flags & MNT_NOATIME) 24 flags |= ST_NOATIME; 25 if (mnt_flags & MNT_NODIRATIME) 26 flags |= ST_NODIRATIME; 27 if (mnt_flags & MNT_RELATIME) 28 flags |= ST_RELATIME; 29 return flags; 30 } 31 32 static int flags_by_sb(int s_flags) 33 { 34 int flags = 0; 35 if (s_flags & MS_SYNCHRONOUS) 36 flags |= ST_SYNCHRONOUS; 37 if (s_flags & MS_MANDLOCK) 38 flags |= ST_MANDLOCK; 39 return flags; 40 } 41 42 static int calculate_f_flags(struct vfsmount *mnt) 43 { 44 return ST_VALID | flags_by_mnt(mnt->mnt_flags) | 45 flags_by_sb(mnt->mnt_sb->s_flags); 46 } 47 48 int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) 49 { 50 int retval; 51 52 if (!dentry->d_sb->s_op->statfs) 53 return -ENOSYS; 54 55 memset(buf, 0, sizeof(*buf)); 56 retval = security_sb_statfs(dentry); 57 if (retval) 58 return retval; 59 retval = dentry->d_sb->s_op->statfs(dentry, buf); 60 if (retval == 0 && buf->f_frsize == 0) 61 buf->f_frsize = buf->f_bsize; 62 return retval; 63 } 64 65 int vfs_statfs(struct path *path, struct kstatfs *buf) 66 { 67 int error; 68 69 error = statfs_by_dentry(path->dentry, buf); 70 if (!error) 71 buf->f_flags = calculate_f_flags(path->mnt); 72 return error; 73 } 74 EXPORT_SYMBOL(vfs_statfs); 75 76 int user_statfs(const char __user *pathname, struct kstatfs *st) 77 { 78 struct path path; 79 int error = user_path(pathname, &path); 80 if (!error) { 81 error = vfs_statfs(&path, st); 82 path_put(&path); 83 } 84 return error; 85 } 86 87 int fd_statfs(int fd, struct kstatfs *st) 88 { 89 struct file *file = fget(fd); 90 int error = -EBADF; 91 if (file) { 92 error = vfs_statfs(&file->f_path, st); 93 fput(file); 94 } 95 return error; 96 } 97 98 static int do_statfs_native(struct kstatfs *st, struct statfs __user *p) 99 { 100 struct statfs buf; 101 102 if (sizeof(buf) == sizeof(*st)) 103 memcpy(&buf, st, sizeof(*st)); 104 else { 105 if (sizeof buf.f_blocks == 4) { 106 if ((st->f_blocks | st->f_bfree | st->f_bavail | 107 st->f_bsize | st->f_frsize) & 108 0xffffffff00000000ULL) 109 return -EOVERFLOW; 110 /* 111 * f_files and f_ffree may be -1; it's okay to stuff 112 * that into 32 bits 113 */ 114 if (st->f_files != -1 && 115 (st->f_files & 0xffffffff00000000ULL)) 116 return -EOVERFLOW; 117 if (st->f_ffree != -1 && 118 (st->f_ffree & 0xffffffff00000000ULL)) 119 return -EOVERFLOW; 120 } 121 122 buf.f_type = st->f_type; 123 buf.f_bsize = st->f_bsize; 124 buf.f_blocks = st->f_blocks; 125 buf.f_bfree = st->f_bfree; 126 buf.f_bavail = st->f_bavail; 127 buf.f_files = st->f_files; 128 buf.f_ffree = st->f_ffree; 129 buf.f_fsid = st->f_fsid; 130 buf.f_namelen = st->f_namelen; 131 buf.f_frsize = st->f_frsize; 132 buf.f_flags = st->f_flags; 133 memset(buf.f_spare, 0, sizeof(buf.f_spare)); 134 } 135 if (copy_to_user(p, &buf, sizeof(buf))) 136 return -EFAULT; 137 return 0; 138 } 139 140 static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p) 141 { 142 struct statfs64 buf; 143 if (sizeof(buf) == sizeof(*st)) 144 memcpy(&buf, st, sizeof(*st)); 145 else { 146 buf.f_type = st->f_type; 147 buf.f_bsize = st->f_bsize; 148 buf.f_blocks = st->f_blocks; 149 buf.f_bfree = st->f_bfree; 150 buf.f_bavail = st->f_bavail; 151 buf.f_files = st->f_files; 152 buf.f_ffree = st->f_ffree; 153 buf.f_fsid = st->f_fsid; 154 buf.f_namelen = st->f_namelen; 155 buf.f_frsize = st->f_frsize; 156 buf.f_flags = st->f_flags; 157 memset(buf.f_spare, 0, sizeof(buf.f_spare)); 158 } 159 if (copy_to_user(p, &buf, sizeof(buf))) 160 return -EFAULT; 161 return 0; 162 } 163 164 SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) 165 { 166 struct kstatfs st; 167 int error = user_statfs(pathname, &st); 168 if (!error) 169 error = do_statfs_native(&st, buf); 170 return error; 171 } 172 173 SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) 174 { 175 struct kstatfs st; 176 int error; 177 if (sz != sizeof(*buf)) 178 return -EINVAL; 179 error = user_statfs(pathname, &st); 180 if (!error) 181 error = do_statfs64(&st, buf); 182 return error; 183 } 184 185 SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) 186 { 187 struct kstatfs st; 188 int error = fd_statfs(fd, &st); 189 if (!error) 190 error = do_statfs_native(&st, buf); 191 return error; 192 } 193 194 SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) 195 { 196 struct kstatfs st; 197 int error; 198 199 if (sz != sizeof(*buf)) 200 return -EINVAL; 201 202 error = fd_statfs(fd, &st); 203 if (!error) 204 error = do_statfs64(&st, buf); 205 return error; 206 } 207 208 SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) 209 { 210 struct super_block *s; 211 struct ustat tmp; 212 struct kstatfs sbuf; 213 int err; 214 215 s = user_get_super(new_decode_dev(dev)); 216 if (!s) 217 return -EINVAL; 218 219 err = statfs_by_dentry(s->s_root, &sbuf); 220 drop_super(s); 221 if (err) 222 return err; 223 224 memset(&tmp,0,sizeof(struct ustat)); 225 tmp.f_tfree = sbuf.f_bfree; 226 tmp.f_tinode = sbuf.f_ffree; 227 228 return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0; 229 } 230