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