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