mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-05-16 03:11:11 -04:00
fs: fix archiecture-specific compat_ftruncate64
The "small" argument to do_sys_ftruncate indicates if > 32-bit size should be reject, but all the arch-specific compat ftruncate64 implementations get this wrong. Merge do_sys_ftruncate and ksys_ftruncate, replace the integer as boolean small flag with a descriptive one about LFS semantics, and use it correctly in the architecture-specific ftruncate64 implementations. Fixes:1da177e4c3("Linux-2.6.12-rc2") Fixes:3dd681d944("arm64: 32-bit (compat) applications support") Signed-off-by: Christoph Hellwig <hch@lst.de> Link: https://patch.msgid.link/20260323070205.2939118-2-hch@lst.de Reviewed-by: Jan Kara <jack@suse.cz> Signed-off-by: Christian Brauner <brauner@kernel.org>
This commit is contained in:
committed by
Christian Brauner
parent
3d6bb84f6b
commit
e43dce8a0b
@@ -89,7 +89,7 @@ COMPAT_SYSCALL_DEFINE4(aarch32_truncate64, const char __user *, pathname,
|
||||
COMPAT_SYSCALL_DEFINE4(aarch32_ftruncate64, unsigned int, fd, u32, __pad,
|
||||
arg_u32p(length))
|
||||
{
|
||||
return ksys_ftruncate(fd, arg_u64(length));
|
||||
return ksys_ftruncate(fd, arg_u64(length), FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
COMPAT_SYSCALL_DEFINE5(aarch32_readahead, int, fd, u32, __pad,
|
||||
|
||||
@@ -60,7 +60,7 @@ SYSCALL_DEFINE4(32_truncate64, const char __user *, path,
|
||||
SYSCALL_DEFINE4(32_ftruncate64, unsigned long, fd, unsigned long, __dummy,
|
||||
unsigned long, a2, unsigned long, a3)
|
||||
{
|
||||
return ksys_ftruncate(fd, merge_64(a2, a3));
|
||||
return ksys_ftruncate(fd, merge_64(a2, a3), FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE5(32_llseek, unsigned int, fd, unsigned int, offset_high,
|
||||
|
||||
@@ -216,7 +216,7 @@ asmlinkage long parisc_truncate64(const char __user * path,
|
||||
asmlinkage long parisc_ftruncate64(unsigned int fd,
|
||||
unsigned int high, unsigned int low)
|
||||
{
|
||||
return ksys_ftruncate(fd, (long)high << 32 | low);
|
||||
return ksys_ftruncate(fd, (long)high << 32 | low, FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
/* stubs for the benefit of the syscall_table since truncate64 and truncate
|
||||
@@ -227,7 +227,7 @@ asmlinkage long sys_truncate64(const char __user * path, unsigned long length)
|
||||
}
|
||||
asmlinkage long sys_ftruncate64(unsigned int fd, unsigned long length)
|
||||
{
|
||||
return ksys_ftruncate(fd, length);
|
||||
return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
|
||||
}
|
||||
asmlinkage long sys_fcntl64(unsigned int fd, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
|
||||
@@ -101,7 +101,7 @@ PPC32_SYSCALL_DEFINE4(ppc_ftruncate64,
|
||||
unsigned int, fd, u32, reg4,
|
||||
unsigned long, len1, unsigned long, len2)
|
||||
{
|
||||
return ksys_ftruncate(fd, merge_64(len1, len2));
|
||||
return ksys_ftruncate(fd, merge_64(len1, len2), FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
PPC32_SYSCALL_DEFINE6(ppc32_fadvise64,
|
||||
|
||||
@@ -58,7 +58,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, path, u32, high, u32, lo
|
||||
|
||||
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd, u32, high, u32, low)
|
||||
{
|
||||
return ksys_ftruncate(fd, ((u64)high << 32) | low);
|
||||
return ksys_ftruncate(fd, ((u64)high << 32) | low, FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
static int cp_compat_stat64(struct kstat *stat,
|
||||
|
||||
@@ -61,7 +61,8 @@ SYSCALL_DEFINE3(ia32_truncate64, const char __user *, filename,
|
||||
SYSCALL_DEFINE3(ia32_ftruncate64, unsigned int, fd,
|
||||
unsigned long, offset_low, unsigned long, offset_high)
|
||||
{
|
||||
return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low);
|
||||
return ksys_ftruncate(fd, ((loff_t) offset_high << 32) | offset_low,
|
||||
FTRUNCATE_LFS);
|
||||
}
|
||||
|
||||
/* warning: next two assume little endian */
|
||||
|
||||
@@ -199,7 +199,6 @@ extern int build_open_flags(const struct open_how *how, struct open_flags *op);
|
||||
struct file *file_close_fd_locked(struct files_struct *files, unsigned fd);
|
||||
|
||||
int do_ftruncate(struct file *file, loff_t length, int small);
|
||||
int do_sys_ftruncate(unsigned int fd, loff_t length, int small);
|
||||
int chmod_common(const struct path *path, umode_t mode);
|
||||
int do_fchownat(int dfd, const char __user *filename, uid_t user, gid_t group,
|
||||
int flag);
|
||||
|
||||
12
fs/open.c
12
fs/open.c
@@ -197,7 +197,7 @@ int do_ftruncate(struct file *file, loff_t length, int small)
|
||||
ATTR_MTIME | ATTR_CTIME, file);
|
||||
}
|
||||
|
||||
int do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||
int ksys_ftruncate(unsigned int fd, loff_t length, unsigned int flags)
|
||||
{
|
||||
if (length < 0)
|
||||
return -EINVAL;
|
||||
@@ -205,18 +205,18 @@ int do_sys_ftruncate(unsigned int fd, loff_t length, int small)
|
||||
if (fd_empty(f))
|
||||
return -EBADF;
|
||||
|
||||
return do_ftruncate(fd_file(f), length, small);
|
||||
return do_ftruncate(fd_file(f), length, !(flags & FTRUNCATE_LFS));
|
||||
}
|
||||
|
||||
SYSCALL_DEFINE2(ftruncate, unsigned int, fd, off_t, length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 1);
|
||||
return ksys_ftruncate(fd, length, 0);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_COMPAT
|
||||
COMPAT_SYSCALL_DEFINE2(ftruncate, unsigned int, fd, compat_off_t, length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 1);
|
||||
return ksys_ftruncate(fd, length, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -229,7 +229,7 @@ SYSCALL_DEFINE2(truncate64, const char __user *, path, loff_t, length)
|
||||
|
||||
SYSCALL_DEFINE2(ftruncate64, unsigned int, fd, loff_t, length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 0);
|
||||
return ksys_ftruncate(fd, length, FTRUNCATE_LFS);
|
||||
}
|
||||
#endif /* BITS_PER_LONG == 32 */
|
||||
|
||||
@@ -245,7 +245,7 @@ COMPAT_SYSCALL_DEFINE3(truncate64, const char __user *, pathname,
|
||||
COMPAT_SYSCALL_DEFINE3(ftruncate64, unsigned int, fd,
|
||||
compat_arg_u64_dual(length))
|
||||
{
|
||||
return ksys_ftruncate(fd, compat_arg_u64_glue(length));
|
||||
return ksys_ftruncate(fd, compat_arg_u64_glue(length), FTRUNCATE_LFS);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
@@ -1283,12 +1283,8 @@ static inline long ksys_lchown(const char __user *filename, uid_t user,
|
||||
AT_SYMLINK_NOFOLLOW);
|
||||
}
|
||||
|
||||
int do_sys_ftruncate(unsigned int fd, loff_t length, int small);
|
||||
|
||||
static inline long ksys_ftruncate(unsigned int fd, loff_t length)
|
||||
{
|
||||
return do_sys_ftruncate(fd, length, 1);
|
||||
}
|
||||
#define FTRUNCATE_LFS (1u << 0) /* allow truncating > 32-bit */
|
||||
int ksys_ftruncate(unsigned int fd, loff_t length, unsigned int flags);
|
||||
|
||||
int do_sys_truncate(const char __user *pathname, loff_t length);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user