Don't let userspace write to an active swap file because the kernel effectively has a long term lease on the storage and things could get seriously corrupted if we let this happen.
Unified · Split
| @@ -1978,6 +1978,9 @@ ssize_t blkdev_write_iter(struct kiocb *iocb, struct iov_iter *from) · 1977 unmodified lines | |||
| 1978 | if (bdev_read_only(I_BDEV(bd_inode))) | 1978 | if (bdev_read_only(I_BDEV(bd_inode))) |
| 1979 | return -EPERM; | 1979 | return -EPERM; |
| 1980 | 1980 | ||
| 1981 | if (IS_SWAPFILE(bd_inode)) | ||
| 1982 | return -ETXTBSY; | ||
| 1983 | |||
| 1981 | if (!iov_iter_count(from)) | 1984 | if (!iov_iter_count(from)) |
| 1982 | return 0; | 1985 | return 0; |
| 1983 | 1986 | ||
| @@ -3547,4 +3547,15 @@ static inline void simple_fill_fsxattr(struct fsxattr *fa, __u32 xflags) · 3546 unmodified lines | |||
| 3547 | fa->fsx_xflags = xflags; | 3547 | fa->fsx_xflags = xflags; |
| 3548 | } | 3548 | } |
| 3549 | 3549 | ||
| 3550 | /* | ||
| 3551 | * Flush file data before changing attributes. Caller must hold any locks | ||
| 3552 | * required to prevent further writes to this file until we're done setting | ||
| 3553 | * flags. | ||
| 3554 | */ | ||
| 3555 | static inline int inode_drain_writes(struct inode *inode) | ||
| 3556 | { | ||
| 3557 | inode_dio_wait(inode); | ||
| 3558 | return filemap_write_and_wait(inode->i_mapping); | ||
| 3559 | } | ||
| 3560 | |||
| 3550 | #endif /* _LINUX_FS_H */ | 3561 | #endif /* _LINUX_FS_H */ |
| @@ -2988,6 +2988,9 @@ inline ssize_t generic_write_checks(struct kiocb *iocb, struct iov_iter *from) · 2987 unmodified lines | |||
| 2988 | loff_t count; | 2988 | loff_t count; |
| 2989 | int ret; | 2989 | int ret; |
| 2990 | 2990 | ||
| 2991 | if (IS_SWAPFILE(inode)) | ||
| 2992 | return -ETXTBSY; | ||
| 2993 | |||
| 2991 | if (!iov_iter_count(from)) | 2994 | if (!iov_iter_count(from)) |
| 2992 | return 0; | 2995 | return 0; |
| 2993 | 2996 | ||
| @@ -2196,6 +2196,10 @@ static vm_fault_t do_page_mkwrite(struct vm_fault *vmf) · 2195 unmodified lines | |||
| 2196 | 2196 | ||
| 2197 | vmf->flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; | 2197 | vmf->flags = FAULT_FLAG_WRITE|FAULT_FLAG_MKWRITE; |
| 2198 | 2198 | ||
| 2199 | if (vmf->vma->vm_file && | ||
| 2200 | IS_SWAPFILE(vmf->vma->vm_file->f_mapping->host)) | ||
| 2201 | return VM_FAULT_SIGBUS; | ||
| 2202 | |||
| 2199 | ret = vmf->vma->vm_ops->page_mkwrite(vmf); | 2203 | ret = vmf->vma->vm_ops->page_mkwrite(vmf); |
| 2200 | /* Restore original flags so that caller is not surprised */ | 2204 | /* Restore original flags so that caller is not surprised */ |
| 2201 | vmf->flags = old_flags; | 2205 | vmf->flags = old_flags; |
| @@ -1483,8 +1483,12 @@ unsigned long do_mmap(struct file *file, unsigned long addr, · 1482 unmodified lines | |||
| 1483 | case MAP_SHARED_VALIDATE: | 1483 | case MAP_SHARED_VALIDATE: |
| 1484 | if (flags & ~flags_mask) | 1484 | if (flags & ~flags_mask) |
| 1485 | return -EOPNOTSUPP; | 1485 | return -EOPNOTSUPP; |
| 1486 | if ((prot&PROT_WRITE) && !(file->f_mode&FMODE_WRITE)) | 1486 | if (prot & PROT_WRITE) { |
| 1487 | return -EACCES; | 1487 | if (!(file->f_mode & FMODE_WRITE)) |
| 1488 | return -EACCES; | ||
| 1489 | if (IS_SWAPFILE(file->f_mapping->host)) | ||
| 1490 | return -ETXTBSY; | ||
| 1491 | } | ||
| 1488 | 1492 | ||
| 1489 | /* | 1493 | /* |
| 1490 | * Make sure we don't allow writing to an append-only | 1494 | * Make sure we don't allow writing to an append-only |
| @@ -3275,6 +3275,17 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) · 3274 unmodified lines | |||
| 3275 | if (error) | 3275 | if (error) |
| 3276 | goto bad_swap; | 3276 | goto bad_swap; |
| 3277 | 3277 | ||
| 3278 | /* | ||
| 3279 | * Flush any pending IO and dirty mappings before we start using this | ||
| 3280 | * swap device. | ||
| 3281 | */ | ||
| 3282 | inode->i_flags |= S_SWAPFILE; | ||
| 3283 | error = inode_drain_writes(inode); | ||
| 3284 | if (error) { | ||
| 3285 | inode->i_flags &= ~S_SWAPFILE; | ||
| 3286 | goto bad_swap; | ||
| 3287 | } | ||
| 3288 | |||
| 3278 | mutex_lock(&swapon_mutex); | 3289 | mutex_lock(&swapon_mutex); |
| 3279 | prio = -1; | 3290 | prio = -1; |
| 3280 | if (swap_flags & SWAP_FLAG_PREFER) | 3291 | if (swap_flags & SWAP_FLAG_PREFER) |
| @@ -3295,7 +3306,6 @@ SYSCALL_DEFINE2(swapon, const char __user *, specialfile, int, swap_flags) · 14 unmodified lines | |||
| 3295 | atomic_inc(&proc_poll_event); | 3306 | atomic_inc(&proc_poll_event); |
| 3296 | wake_up_interruptible(&proc_poll_wait); | 3307 | wake_up_interruptible(&proc_poll_wait); |
| 3297 | 3308 | ||
| 3298 | inode->i_flags |= S_SWAPFILE; | ||
| 3299 | error = 0; | 3309 | error = 0; |
| 3300 | goto out; | 3310 | goto out; |
| 3301 | bad_swap: | 3311 | bad_swap: |