1 #include <linux/syscalls.h> 2 #include <linux/export.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 #include <linux/compat.h> 11 #include "internal.h" 12 13 static int flags_by_mnt(int mnt_flags) 14 { 15 int flags = 0; 16 17 if (mnt_flags & MNT_READONLY) 18 flags |= ST_RDONLY; 19 if (mnt_flags & MNT_NOSUID) 20 flags |= ST_NOSUID; 21 if (mnt_flags & MNT_NODEV) 22 flags |= ST_NODEV; 23 if (mnt_flags & MNT_NOEXEC) 24 flags |= ST_NOEXEC; 25 if (mnt_flags & MNT_NOATIME) 26 flags |= ST_NOATIME; 27 if (mnt_flags & MNT_NODIRATIME) 28 flags |= ST_NODIRATIME; 29 if (mnt_flags & MNT_RELATIME) 30 flags |= ST_RELATIME; 31 return flags; 32 } 33 34 static int flags_by_sb(int s_flags) 35 { 36 int flags = 0; 37 if (s_flags & MS_SYNCHRONOUS) 38 flags |= ST_SYNCHRONOUS; 39 if (s_flags & MS_MANDLOCK) 40 flags |= ST_MANDLOCK; 41 return flags; 42 } 43 44 static int calculate_f_flags(struct vfsmount *mnt) 45 { 46 return ST_VALID | flags_by_mnt(mnt->mnt_flags) | 47 flags_by_sb(mnt->mnt_sb->s_flags); 48 } 49 50 static int statfs_by_dentry(struct dentry *dentry, struct kstatfs *buf) 51 { 52 int retval; 53 54 if (!dentry->d_sb->s_op->statfs) 55 return -ENOSYS; 56 57 memset(buf, 0, sizeof(*buf)); 58 retval = security_sb_statfs(dentry); 59 if (retval) 60 return retval; 61 retval = dentry->d_sb->s_op->statfs(dentry, buf); 62 if (retval == 0 && buf->f_frsize == 0) 63 buf->f_frsize = buf->f_bsize; 64 return retval; 65 } 66 67 int vfs_statfs(const struct path *path, struct kstatfs *buf) 68 { 69 int error; 70 71 error = statfs_by_dentry(path->dentry, buf); 72 if (!error) 73 buf->f_flags = calculate_f_flags(path->mnt); 74 return error; 75 } 76 EXPORT_SYMBOL(vfs_statfs); 77 78 int user_statfs(const char __user *pathname, struct kstatfs *st) 79 { 80 struct path path; 81 int error; 82 unsigned int lookup_flags = LOOKUP_FOLLOW|LOOKUP_AUTOMOUNT; 83 retry: 84 error = user_path_at(AT_FDCWD, pathname, lookup_flags, &path); 85 if (!error) { 86 error = vfs_statfs(&path, st); 87 path_put(&path); 88 if (retry_estale(error, lookup_flags)) { 89 lookup_flags |= LOOKUP_REVAL; 90 goto retry; 91 } 92 } 93 return error; 94 } 95 96 int fd_statfs(int fd, struct kstatfs *st) 97 { 98 struct fd f = fdget_raw(fd); 99 int error = -EBADF; 100 if (f.file) { 101 error = vfs_statfs(&f.file->f_path, st); 102 fdput(f); 103 } 104 return error; 105 } 106 107 static int do_statfs_native(struct kstatfs *st, struct statfs __user *p) 108 { 109 struct statfs buf; 110 111 if (sizeof(buf) == sizeof(*st)) 112 memcpy(&buf, st, sizeof(*st)); 113 else { 114 if (sizeof buf.f_blocks == 4) { 115 if ((st->f_blocks | st->f_bfree | st->f_bavail | 116 st->f_bsize | st->f_frsize) & 117 0xffffffff00000000ULL) 118 return -EOVERFLOW; 119 /* 120 * f_files and f_ffree may be -1; it's okay to stuff 121 * that into 32 bits 122 */ 123 if (st->f_files != -1 && 124 (st->f_files & 0xffffffff00000000ULL)) 125 return -EOVERFLOW; 126 if (st->f_ffree != -1 && 127 (st->f_ffree & 0xffffffff00000000ULL)) 128 return -EOVERFLOW; 129 } 130 131 buf.f_type = st->f_type; 132 buf.f_bsize = st->f_bsize; 133 buf.f_blocks = st->f_blocks; 134 buf.f_bfree = st->f_bfree; 135 buf.f_bavail = st->f_bavail; 136 buf.f_files = st->f_files; 137 buf.f_ffree = st->f_ffree; 138 buf.f_fsid = st->f_fsid; 139 buf.f_namelen = st->f_namelen; 140 buf.f_frsize = st->f_frsize; 141 buf.f_flags = st->f_flags; 142 memset(buf.f_spare, 0, sizeof(buf.f_spare)); 143 } 144 if (copy_to_user(p, &buf, sizeof(buf))) 145 return -EFAULT; 146 return 0; 147 } 148 149 static int do_statfs64(struct kstatfs *st, struct statfs64 __user *p) 150 { 151 struct statfs64 buf; 152 if (sizeof(buf) == sizeof(*st)) 153 memcpy(&buf, st, sizeof(*st)); 154 else { 155 buf.f_type = st->f_type; 156 buf.f_bsize = st->f_bsize; 157 buf.f_blocks = st->f_blocks; 158 buf.f_bfree = st->f_bfree; 159 buf.f_bavail = st->f_bavail; 160 buf.f_files = st->f_files; 161 buf.f_ffree = st->f_ffree; 162 buf.f_fsid = st->f_fsid; 163 buf.f_namelen = st->f_namelen; 164 buf.f_frsize = st->f_frsize; 165 buf.f_flags = st->f_flags; 166 memset(buf.f_spare, 0, sizeof(buf.f_spare)); 167 } 168 if (copy_to_user(p, &buf, sizeof(buf))) 169 return -EFAULT; 170 return 0; 171 } 172 173 SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct statfs __user *, buf) 174 { 175 struct kstatfs st; 176 int error = user_statfs(pathname, &st); 177 if (!error) 178 error = do_statfs_native(&st, buf); 179 return error; 180 } 181 182 SYSCALL_DEFINE3(statfs64, const char __user *, pathname, size_t, sz, struct statfs64 __user *, buf) 183 { 184 struct kstatfs st; 185 int error; 186 if (sz != sizeof(*buf)) 187 return -EINVAL; 188 error = user_statfs(pathname, &st); 189 if (!error) 190 error = do_statfs64(&st, buf); 191 return error; 192 } 193 194 SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct statfs __user *, buf) 195 { 196 struct kstatfs st; 197 int error = fd_statfs(fd, &st); 198 if (!error) 199 error = do_statfs_native(&st, buf); 200 return error; 201 } 202 203 SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, size_t, sz, struct statfs64 __user *, buf) 204 { 205 struct kstatfs st; 206 int error; 207 208 if (sz != sizeof(*buf)) 209 return -EINVAL; 210 211 error = fd_statfs(fd, &st); 212 if (!error) 213 error = do_statfs64(&st, buf); 214 return error; 215 } 216 217 int vfs_ustat(dev_t dev, struct kstatfs *sbuf) 218 { 219 struct super_block *s = user_get_super(dev); 220 int err; 221 if (!s) 222 return -EINVAL; 223 224 err = statfs_by_dentry(s->s_root, sbuf); 225 drop_super(s); 226 return err; 227 } 228 229 SYSCALL_DEFINE2(ustat, unsigned, dev, struct ustat __user *, ubuf) 230 { 231 struct ustat tmp; 232 struct kstatfs sbuf; 233 int err = vfs_ustat(new_decode_dev(dev), &sbuf); 234 if (err) 235 return err; 236 237 memset(&tmp,0,sizeof(struct ustat)); 238 tmp.f_tfree = sbuf.f_bfree; 239 tmp.f_tinode = sbuf.f_ffree; 240 241 return copy_to_user(ubuf, &tmp, sizeof(struct ustat)) ? -EFAULT : 0; 242 } 243 244 #ifdef CONFIG_COMPAT 245 static int put_compat_statfs(struct compat_statfs __user *ubuf, struct kstatfs *kbuf) 246 { 247 if (sizeof ubuf->f_blocks == 4) { 248 if ((kbuf->f_blocks | kbuf->f_bfree | kbuf->f_bavail | 249 kbuf->f_bsize | kbuf->f_frsize) & 0xffffffff00000000ULL) 250 return -EOVERFLOW; 251 /* f_files and f_ffree may be -1; it's okay 252 * to stuff that into 32 bits */ 253 if (kbuf->f_files != 0xffffffffffffffffULL 254 && (kbuf->f_files & 0xffffffff00000000ULL)) 255 return -EOVERFLOW; 256 if (kbuf->f_ffree != 0xffffffffffffffffULL 257 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 258 return -EOVERFLOW; 259 } 260 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 261 __put_user(kbuf->f_type, &ubuf->f_type) || 262 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 263 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 264 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 265 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 266 __put_user(kbuf->f_files, &ubuf->f_files) || 267 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 268 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 269 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 270 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 271 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 272 __put_user(kbuf->f_flags, &ubuf->f_flags) || 273 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 274 return -EFAULT; 275 return 0; 276 } 277 278 /* 279 * The following statfs calls are copies of code from fs/statfs.c and 280 * should be checked against those from time to time 281 */ 282 COMPAT_SYSCALL_DEFINE2(statfs, const char __user *, pathname, struct compat_statfs __user *, buf) 283 { 284 struct kstatfs tmp; 285 int error = user_statfs(pathname, &tmp); 286 if (!error) 287 error = put_compat_statfs(buf, &tmp); 288 return error; 289 } 290 291 COMPAT_SYSCALL_DEFINE2(fstatfs, unsigned int, fd, struct compat_statfs __user *, buf) 292 { 293 struct kstatfs tmp; 294 int error = fd_statfs(fd, &tmp); 295 if (!error) 296 error = put_compat_statfs(buf, &tmp); 297 return error; 298 } 299 300 static int put_compat_statfs64(struct compat_statfs64 __user *ubuf, struct kstatfs *kbuf) 301 { 302 if (sizeof(ubuf->f_bsize) == 4) { 303 if ((kbuf->f_type | kbuf->f_bsize | kbuf->f_namelen | 304 kbuf->f_frsize | kbuf->f_flags) & 0xffffffff00000000ULL) 305 return -EOVERFLOW; 306 /* f_files and f_ffree may be -1; it's okay 307 * to stuff that into 32 bits */ 308 if (kbuf->f_files != 0xffffffffffffffffULL 309 && (kbuf->f_files & 0xffffffff00000000ULL)) 310 return -EOVERFLOW; 311 if (kbuf->f_ffree != 0xffffffffffffffffULL 312 && (kbuf->f_ffree & 0xffffffff00000000ULL)) 313 return -EOVERFLOW; 314 } 315 if (!access_ok(VERIFY_WRITE, ubuf, sizeof(*ubuf)) || 316 __put_user(kbuf->f_type, &ubuf->f_type) || 317 __put_user(kbuf->f_bsize, &ubuf->f_bsize) || 318 __put_user(kbuf->f_blocks, &ubuf->f_blocks) || 319 __put_user(kbuf->f_bfree, &ubuf->f_bfree) || 320 __put_user(kbuf->f_bavail, &ubuf->f_bavail) || 321 __put_user(kbuf->f_files, &ubuf->f_files) || 322 __put_user(kbuf->f_ffree, &ubuf->f_ffree) || 323 __put_user(kbuf->f_namelen, &ubuf->f_namelen) || 324 __put_user(kbuf->f_fsid.val[0], &ubuf->f_fsid.val[0]) || 325 __put_user(kbuf->f_fsid.val[1], &ubuf->f_fsid.val[1]) || 326 __put_user(kbuf->f_frsize, &ubuf->f_frsize) || 327 __put_user(kbuf->f_flags, &ubuf->f_flags) || 328 __clear_user(ubuf->f_spare, sizeof(ubuf->f_spare))) 329 return -EFAULT; 330 return 0; 331 } 332 333 COMPAT_SYSCALL_DEFINE3(statfs64, const char __user *, pathname, compat_size_t, sz, struct compat_statfs64 __user *, buf) 334 { 335 struct kstatfs tmp; 336 int error; 337 338 if (sz != sizeof(*buf)) 339 return -EINVAL; 340 341 error = user_statfs(pathname, &tmp); 342 if (!error) 343 error = put_compat_statfs64(buf, &tmp); 344 return error; 345 } 346 347 COMPAT_SYSCALL_DEFINE3(fstatfs64, unsigned int, fd, compat_size_t, sz, struct compat_statfs64 __user *, buf) 348 { 349 struct kstatfs tmp; 350 int error; 351 352 if (sz != sizeof(*buf)) 353 return -EINVAL; 354 355 error = fd_statfs(fd, &tmp); 356 if (!error) 357 error = put_compat_statfs64(buf, &tmp); 358 return error; 359 } 360 361 /* 362 * This is a copy of sys_ustat, just dealing with a structure layout. 363 * Given how simple this syscall is that apporach is more maintainable 364 * than the various conversion hacks. 365 */ 366 COMPAT_SYSCALL_DEFINE2(ustat, unsigned, dev, struct compat_ustat __user *, u) 367 { 368 struct compat_ustat tmp; 369 struct kstatfs sbuf; 370 int err = vfs_ustat(new_decode_dev(dev), &sbuf); 371 if (err) 372 return err; 373 374 memset(&tmp, 0, sizeof(struct compat_ustat)); 375 tmp.f_tfree = sbuf.f_bfree; 376 tmp.f_tinode = sbuf.f_ffree; 377 if (copy_to_user(u, &tmp, sizeof(struct compat_ustat))) 378 return -EFAULT; 379 return 0; 380 } 381 #endif 382