Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 3 Apr 2020 16:31:45 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-12@freebsd.org
Subject:   svn commit: r359605 - in stable/12/sys: amd64/linux32 compat/linux i386/linux
Message-ID:  <202004031631.033GVjJR093321@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Fri Apr  3 16:31:45 2020
New Revision: 359605
URL: https://svnweb.freebsd.org/changeset/base/359605

Log:
  MFC r356945, r356946:
  Fix 64-bit syscall argument fetching in 32-bit Linux syscall handlers.
  
  PR:	243155

Modified:
  stable/12/sys/amd64/linux32/linux32_machdep.c
  stable/12/sys/amd64/linux32/linux32_proto.h
  stable/12/sys/amd64/linux32/linux32_systrace_args.c
  stable/12/sys/amd64/linux32/syscalls.master
  stable/12/sys/compat/linux/linux_file.c
  stable/12/sys/i386/linux/linux_machdep.c
Directory Properties:
  stable/12/   (props changed)

Modified: stable/12/sys/amd64/linux32/linux32_machdep.c
==============================================================================
--- stable/12/sys/amd64/linux32/linux32_machdep.c	Fri Apr  3 16:28:39 2020	(r359604)
+++ stable/12/sys/amd64/linux32/linux32_machdep.c	Fri Apr  3 16:31:45 2020	(r359605)
@@ -654,19 +654,6 @@ linux_sigaltstack(struct thread *td, struct linux_siga
 }
 
 int
-linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args)
-{
-
-#ifdef DEBUG
-	if (ldebug(ftruncate64))
-		printf(ARGS(ftruncate64, "%u, %jd"), args->fd,
-		    (intmax_t)args->length);
-#endif
-
-	return (kern_ftruncate(td, args->fd, args->length));
-}
-
-int
 linux_gettimeofday(struct thread *td, struct linux_gettimeofday_args *uap)
 {
 	struct timeval atv;

Modified: stable/12/sys/amd64/linux32/linux32_proto.h
==============================================================================
--- stable/12/sys/amd64/linux32/linux32_proto.h	Fri Apr  3 16:28:39 2020	(r359604)
+++ stable/12/sys/amd64/linux32/linux32_proto.h	Fri Apr  3 16:31:45 2020	(r359605)
@@ -574,13 +574,15 @@ struct linux_pread_args {
 	char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
 	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
 	char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)];
-	char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+	char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+	char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
 };
 struct linux_pwrite_args {
 	char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
 	char buf_l_[PADL_(char *)]; char * buf; char buf_r_[PADR_(char *)];
 	char nbyte_l_[PADL_(l_size_t)]; l_size_t nbyte; char nbyte_r_[PADR_(l_size_t)];
-	char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+	char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+	char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
 };
 struct linux_chown16_args {
 	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
@@ -623,11 +625,13 @@ struct linux_mmap2_args {
 };
 struct linux_truncate64_args {
 	char path_l_[PADL_(char *)]; char * path; char path_r_[PADR_(char *)];
-	char length_l_[PADL_(l_loff_t)]; l_loff_t length; char length_r_[PADR_(l_loff_t)];
+	char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+	char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
 };
 struct linux_ftruncate64_args {
 	char fd_l_[PADL_(l_uint)]; l_uint fd; char fd_r_[PADR_(l_uint)];
-	char length_l_[PADL_(l_loff_t)]; l_loff_t length; char length_r_[PADR_(l_loff_t)];
+	char length1_l_[PADL_(uint32_t)]; uint32_t length1; char length1_r_[PADR_(uint32_t)];
+	char length2_l_[PADL_(uint32_t)]; uint32_t length2; char length2_r_[PADR_(uint32_t)];
 };
 struct linux_stat64_args {
 	char filename_l_[PADL_(const char *)]; const char * filename; char filename_r_[PADR_(const char *)];
@@ -756,7 +760,8 @@ struct linux_set_thread_area_args {
 };
 struct linux_fadvise64_args {
 	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
-	char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
+	char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+	char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
 	char len_l_[PADL_(l_size_t)]; l_size_t len; char len_r_[PADR_(l_size_t)];
 	char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)];
 };
@@ -847,8 +852,10 @@ struct linux_utimes_args {
 };
 struct linux_fadvise64_64_args {
 	char fd_l_[PADL_(int)]; int fd; char fd_r_[PADR_(int)];
-	char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
-	char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)];
+	char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+	char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+	char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
+	char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
 	char advice_l_[PADL_(int)]; int advice; char advice_r_[PADR_(int)];
 };
 struct linux_mbind_args {
@@ -1021,8 +1028,10 @@ struct linux_splice_args {
 };
 struct linux_sync_file_range_args {
 	char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
-	char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
-	char nbytes_l_[PADL_(l_loff_t)]; l_loff_t nbytes; char nbytes_r_[PADR_(l_loff_t)];
+	char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+	char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+	char nbytes1_l_[PADL_(uint32_t)]; uint32_t nbytes1; char nbytes1_r_[PADR_(uint32_t)];
+	char nbytes2_l_[PADL_(uint32_t)]; uint32_t nbytes2; char nbytes2_r_[PADR_(uint32_t)];
 	char flags_l_[PADL_(unsigned int)]; unsigned int flags; char flags_r_[PADR_(unsigned int)];
 };
 struct linux_tee_args {
@@ -1064,8 +1073,10 @@ struct linux_eventfd_args {
 struct linux_fallocate_args {
 	char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];
 	char mode_l_[PADL_(l_int)]; l_int mode; char mode_r_[PADR_(l_int)];
-	char offset_l_[PADL_(l_loff_t)]; l_loff_t offset; char offset_r_[PADR_(l_loff_t)];
-	char len_l_[PADL_(l_loff_t)]; l_loff_t len; char len_r_[PADR_(l_loff_t)];
+	char offset1_l_[PADL_(uint32_t)]; uint32_t offset1; char offset1_r_[PADR_(uint32_t)];
+	char offset2_l_[PADL_(uint32_t)]; uint32_t offset2; char offset2_r_[PADR_(uint32_t)];
+	char len1_l_[PADL_(uint32_t)]; uint32_t len1; char len1_r_[PADR_(uint32_t)];
+	char len2_l_[PADL_(uint32_t)]; uint32_t len2; char len2_r_[PADR_(uint32_t)];
 };
 struct linux_timerfd_settime_args {
 	char fd_l_[PADL_(l_int)]; l_int fd; char fd_r_[PADR_(l_int)];

Modified: stable/12/sys/amd64/linux32/linux32_systrace_args.c
==============================================================================
--- stable/12/sys/amd64/linux32/linux32_systrace_args.c	Fri Apr  3 16:28:39 2020	(r359604)
+++ stable/12/sys/amd64/linux32/linux32_systrace_args.c	Fri Apr  3 16:31:45 2020	(r359605)
@@ -1235,8 +1235,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 		iarg[0] = p->fd; /* l_uint */
 		uarg[1] = (intptr_t) p->buf; /* char * */
 		iarg[2] = p->nbyte; /* l_size_t */
-		iarg[3] = p->offset; /* l_loff_t */
-		*n_args = 4;
+		uarg[3] = p->offset1; /* uint32_t */
+		uarg[4] = p->offset2; /* uint32_t */
+		*n_args = 5;
 		break;
 	}
 	/* linux_pwrite */
@@ -1245,8 +1246,9 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 		iarg[0] = p->fd; /* l_uint */
 		uarg[1] = (intptr_t) p->buf; /* char * */
 		iarg[2] = p->nbyte; /* l_size_t */
-		iarg[3] = p->offset; /* l_loff_t */
-		*n_args = 4;
+		uarg[3] = p->offset1; /* uint32_t */
+		uarg[4] = p->offset2; /* uint32_t */
+		*n_args = 5;
 		break;
 	}
 	/* linux_chown16 */
@@ -1324,16 +1326,18 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 	case 193: {
 		struct linux_truncate64_args *p = params;
 		uarg[0] = (intptr_t) p->path; /* char * */
-		iarg[1] = p->length; /* l_loff_t */
-		*n_args = 2;
+		uarg[1] = p->length1; /* uint32_t */
+		uarg[2] = p->length2; /* uint32_t */
+		*n_args = 3;
 		break;
 	}
 	/* linux_ftruncate64 */
 	case 194: {
 		struct linux_ftruncate64_args *p = params;
 		iarg[0] = p->fd; /* l_uint */
-		iarg[1] = p->length; /* l_loff_t */
-		*n_args = 2;
+		uarg[1] = p->length1; /* uint32_t */
+		uarg[2] = p->length2; /* uint32_t */
+		*n_args = 3;
 		break;
 	}
 	/* linux_stat64 */
@@ -1657,10 +1661,11 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 	case 250: {
 		struct linux_fadvise64_args *p = params;
 		iarg[0] = p->fd; /* int */
-		iarg[1] = p->offset; /* l_loff_t */
-		iarg[2] = p->len; /* l_size_t */
-		iarg[3] = p->advice; /* int */
-		*n_args = 4;
+		uarg[1] = p->offset1; /* uint32_t */
+		uarg[2] = p->offset2; /* uint32_t */
+		iarg[3] = p->len; /* l_size_t */
+		iarg[4] = p->advice; /* int */
+		*n_args = 5;
 		break;
 	}
 	/* linux_exit_group */
@@ -1828,10 +1833,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 	case 272: {
 		struct linux_fadvise64_64_args *p = params;
 		iarg[0] = p->fd; /* int */
-		iarg[1] = p->offset; /* l_loff_t */
-		iarg[2] = p->len; /* l_loff_t */
-		iarg[3] = p->advice; /* int */
-		*n_args = 4;
+		uarg[1] = p->offset1; /* uint32_t */
+		uarg[2] = p->offset2; /* uint32_t */
+		uarg[3] = p->len1; /* uint32_t */
+		uarg[4] = p->len2; /* uint32_t */
+		iarg[5] = p->advice; /* int */
+		*n_args = 6;
 		break;
 	}
 	/* linux_mbind */
@@ -2120,10 +2127,12 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 	case 314: {
 		struct linux_sync_file_range_args *p = params;
 		iarg[0] = p->fd; /* l_int */
-		iarg[1] = p->offset; /* l_loff_t */
-		iarg[2] = p->nbytes; /* l_loff_t */
-		uarg[3] = p->flags; /* unsigned int */
-		*n_args = 4;
+		uarg[1] = p->offset1; /* uint32_t */
+		uarg[2] = p->offset2; /* uint32_t */
+		uarg[3] = p->nbytes1; /* uint32_t */
+		uarg[4] = p->nbytes2; /* uint32_t */
+		uarg[5] = p->flags; /* unsigned int */
+		*n_args = 6;
 		break;
 	}
 	/* linux_tee */
@@ -2193,9 +2202,11 @@ systrace_args(int sysnum, void *params, uint64_t *uarg
 		struct linux_fallocate_args *p = params;
 		iarg[0] = p->fd; /* l_int */
 		iarg[1] = p->mode; /* l_int */
-		iarg[2] = p->offset; /* l_loff_t */
-		iarg[3] = p->len; /* l_loff_t */
-		*n_args = 4;
+		uarg[2] = p->offset1; /* uint32_t */
+		uarg[3] = p->offset2; /* uint32_t */
+		uarg[4] = p->len1; /* uint32_t */
+		uarg[5] = p->len2; /* uint32_t */
+		*n_args = 6;
 		break;
 	}
 	/* linux_timerfd_settime */
@@ -4871,8 +4882,11 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "l_size_t";
 			break;
 		case 3:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
+		case 4:
+			p = "uint32_t";
+			break;
 		default:
 			break;
 		};
@@ -4890,8 +4904,11 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "l_size_t";
 			break;
 		case 3:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
+		case 4:
+			p = "uint32_t";
+			break;
 		default:
 			break;
 		};
@@ -5015,8 +5032,11 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "userland char *";
 			break;
 		case 1:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
+		case 2:
+			p = "uint32_t";
+			break;
 		default:
 			break;
 		};
@@ -5028,8 +5048,11 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "l_uint";
 			break;
 		case 1:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
+		case 2:
+			p = "uint32_t";
+			break;
 		default:
 			break;
 		};
@@ -5479,12 +5502,15 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "int";
 			break;
 		case 1:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
 		case 2:
-			p = "l_size_t";
+			p = "uint32_t";
 			break;
 		case 3:
+			p = "l_size_t";
+			break;
+		case 4:
 			p = "int";
 			break;
 		default:
@@ -5759,12 +5785,18 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "int";
 			break;
 		case 1:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
 		case 2:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
 		case 3:
+			p = "uint32_t";
+			break;
+		case 4:
+			p = "uint32_t";
+			break;
+		case 5:
 			p = "int";
 			break;
 		default:
@@ -6174,12 +6206,18 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "l_int";
 			break;
 		case 1:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
 		case 2:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
 		case 3:
+			p = "uint32_t";
+			break;
+		case 4:
+			p = "uint32_t";
+			break;
+		case 5:
 			p = "unsigned int";
 			break;
 		default:
@@ -6278,10 +6316,16 @@ systrace_entry_setargdesc(int sysnum, int ndx, char *d
 			p = "l_int";
 			break;
 		case 2:
-			p = "l_loff_t";
+			p = "uint32_t";
 			break;
 		case 3:
-			p = "l_loff_t";
+			p = "uint32_t";
+			break;
+		case 4:
+			p = "uint32_t";
+			break;
+		case 5:
+			p = "uint32_t";
 			break;
 		default:
 			break;

Modified: stable/12/sys/amd64/linux32/syscalls.master
==============================================================================
--- stable/12/sys/amd64/linux32/syscalls.master	Fri Apr  3 16:28:39 2020	(r359604)
+++ stable/12/sys/amd64/linux32/syscalls.master	Fri Apr  3 16:31:45 2020	(r359605)
@@ -325,9 +325,9 @@
 				    l_sigset_t *newset, \
 				    l_size_t sigsetsize); }
 180	AUE_PREAD	STD	{ int linux_pread(l_uint fd, char *buf, \
-				    l_size_t nbyte, l_loff_t offset); }
+				    l_size_t nbyte, uint32_t offset1, uint32_t offset2); }
 181	AUE_PWRITE	STD	{ int linux_pwrite(l_uint fd, char *buf, \
-				    l_size_t nbyte, l_loff_t offset); }
+				    l_size_t nbyte, uint32_t offset1, uint32_t offset2); }
 182	AUE_CHOWN	STD	{ int linux_chown16(char *path, \
 				    l_uid16_t uid, l_gid16_t gid); }
 183	AUE_GETCWD	STD	{ int linux_getcwd(char *buf, \
@@ -349,9 +349,9 @@
 				    l_ulong prot, l_ulong flags, l_ulong fd, \
 				    l_ulong pgoff); }
 193	AUE_TRUNCATE	STD	{ int linux_truncate64(char *path, \
-				    l_loff_t length); }
+				    uint32_t length1, uint32_t length2); }
 194	AUE_FTRUNCATE	STD	{ int linux_ftruncate64(l_uint fd, \
-				    l_loff_t length); }
+				    uint32_t length1, uint32_t length2); }
 195	AUE_STAT	STD	{ int linux_stat64(const char *filename, \
 				    struct l_stat64 *statbuf); }
 196	AUE_LSTAT	STD	{ int linux_lstat64(const char *filename, \
@@ -426,7 +426,7 @@
 247	AUE_NULL	UNIMPL	linux_io_getevents
 248	AUE_NULL	UNIMPL	linux_io_submit
 249	AUE_NULL	UNIMPL	linux_io_cancel
-250	AUE_NULL	STD	{ int linux_fadvise64(int fd, l_loff_t offset, \
+250	AUE_NULL	STD	{ int linux_fadvise64(int fd, uint32_t offset1, uint32_t offset2, \
 					l_size_t len, int advice); }
 251	AUE_NULL	UNIMPL
 252	AUE_EXIT	STD	{ int linux_exit_group(int error_code); }
@@ -456,7 +456,8 @@
 271	AUE_UTIMES	STD	{ int linux_utimes(char *fname, \
 					struct l_timeval *tptr); }
 272	AUE_NULL	STD	{ int linux_fadvise64_64(int fd, \
-					l_loff_t offset, l_loff_t len, \
+					uint32_t offset1, uint32_t offset2, \
+					uint32_t len1, uint32_t len2, \
 					int advice); }
 273	AUE_NULL	UNIMPL	vserver
 274	AUE_NULL	STD	{ int linux_mbind(void); }
@@ -524,8 +525,9 @@
 312	AUE_NULL	STD	{ int linux_get_robust_list(l_int pid, \
 				    struct linux_robust_list_head **head, l_size_t *len); }
 313	AUE_NULL	STD	{ int linux_splice(void); }
-314	AUE_NULL	STD	{ int linux_sync_file_range(l_int fd, l_loff_t offset,
-				    l_loff_t nbytes, unsigned int flags); }
+314	AUE_NULL	STD	{ int linux_sync_file_range(l_int fd, uint32_t offset1,
+				    uint32_t offset2, uint32_t nbytes1, uint32_t nbytes2,
+				    unsigned int flags); }
 315	AUE_NULL	STD	{ int linux_tee(void); }
 316	AUE_NULL	STD	{ int linux_vmsplice(void); }
 ; Linux 2.6.18:
@@ -543,7 +545,8 @@
 323	AUE_NULL	STD	{ int linux_eventfd(l_uint initval); }
 ; Linux 2.6.23:
 324	AUE_NULL	STD	{ int linux_fallocate(l_int fd, l_int mode, \
-				    l_loff_t offset, l_loff_t len); }
+				    uint32_t offset1, uint32_t offset2, uint32_t len1,
+				    uint32_t len2); }
 ; Linux 2.6.25:
 325	AUE_NULL	STD	{ int linux_timerfd_settime(l_int fd, l_int flags,	\
 				    const struct l_itimerspec *new_value,		\

Modified: stable/12/sys/compat/linux/linux_file.c
==============================================================================
--- stable/12/sys/compat/linux/linux_file.c	Fri Apr  3 16:28:39 2020	(r359604)
+++ stable/12/sys/compat/linux/linux_file.c	Fri Apr  3 16:31:45 2020	(r359605)
@@ -54,6 +54,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/vnode.h>
 
 #ifdef COMPAT_LINUX32
+#include <compat/freebsd32/freebsd32_misc.h>
 #include <machine/../linux32/linux.h>
 #include <machine/../linux32/linux32_proto.h>
 #else
@@ -67,7 +68,6 @@ __FBSDID("$FreeBSD$");
 static int	linux_common_open(struct thread *, int, char *, int, int);
 static int	linux_getdents_error(struct thread *, int, int);
 
-
 #ifdef LINUX_LEGACY_SYSCALLS
 int
 linux_creat(struct thread *td, struct linux_creat_args *args)
@@ -898,7 +898,6 @@ linux_truncate(struct thread *td, struct linux_truncat
 	int error;
 
 	LCONVPATHEXIST(td, args->path, &path);
-
 #ifdef DEBUG
 	if (ldebug(truncate))
 		printf(ARGS(truncate, "%s, %ld"), path, (long)args->length);
@@ -914,8 +913,15 @@ int
 linux_truncate64(struct thread *td, struct linux_truncate64_args *args)
 {
 	char *path;
+	off_t length;
 	int error;
 
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	length = PAIR32TO64(off_t, args->length);
+#else
+	length = args->length;
+#endif
+
 	LCONVPATHEXIST(td, args->path, &path);
 
 #ifdef DEBUG
@@ -923,7 +929,7 @@ linux_truncate64(struct thread *td, struct linux_trunc
 		printf(ARGS(truncate64, "%s, %jd"), path, args->length);
 #endif
 
-	error = kern_truncate(td, path, UIO_SYSSPACE, args->length);
+	error = kern_truncate(td, path, UIO_SYSSPACE, length);
 	LFREEPATH(path);
 	return (error);
 }
@@ -936,6 +942,22 @@ linux_ftruncate(struct thread *td, struct linux_ftrunc
 	return (kern_ftruncate(td, args->fd, args->length));
 }
 
+#if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
+int
+linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args)
+{
+	off_t length;
+
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	length = PAIR32TO64(off_t, args->length);
+#else
+	length = args->length;
+#endif
+
+	return (kern_ftruncate(td, args->fd, length));
+}
+#endif
+
 #ifdef LINUX_LEGACY_SYSCALLS
 int
 linux_link(struct thread *td, struct linux_link_args *args)
@@ -1006,8 +1028,17 @@ linux_fdatasync(struct thread *td, struct linux_fdatas
 int
 linux_sync_file_range(struct thread *td, struct linux_sync_file_range_args *uap)
 {
+	off_t nbytes, offset;
 
-	if (uap->offset < 0 || uap->nbytes < 0 ||
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	nbytes = PAIR32TO64(off_t, uap->nbytes);
+	offset = PAIR32TO64(off_t, uap->offset);
+#else
+	nbytes = uap->nbytes;
+	offset = uap->offset;
+#endif
+
+	if (offset < 0 || nbytes < 0 ||
 	    (uap->flags & ~(LINUX_SYNC_FILE_RANGE_WAIT_BEFORE |
 	    LINUX_SYNC_FILE_RANGE_WRITE |
 	    LINUX_SYNC_FILE_RANGE_WAIT_AFTER)) != 0) {
@@ -1021,18 +1052,23 @@ int
 linux_pread(struct thread *td, struct linux_pread_args *uap)
 {
 	struct vnode *vp;
+	off_t offset;
 	int error;
 
-	error = kern_pread(td, uap->fd, uap->buf, uap->nbyte, uap->offset);
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	offset = PAIR32TO64(off_t, uap->offset);
+#else
+	offset = uap->offset;
+#endif
+
+	error = kern_pread(td, uap->fd, uap->buf, uap->nbyte, offset);
 	if (error == 0) {
 		/* This seems to violate POSIX but Linux does it. */
 		error = fgetvp(td, uap->fd, &cap_pread_rights, &vp);
 		if (error != 0)
 			return (error);
-		if (vp->v_type == VDIR) {
-			vrele(vp);
-			return (EISDIR);
-		}
+		if (vp->v_type == VDIR)
+			error = EISDIR;
 		vrele(vp);
 	}
 	return (error);
@@ -1041,8 +1077,15 @@ linux_pread(struct thread *td, struct linux_pread_args
 int
 linux_pwrite(struct thread *td, struct linux_pwrite_args *uap)
 {
+	off_t offset;
 
-	return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, uap->offset));
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	offset = PAIR32TO64(off_t, uap->offset);
+#else
+	offset = uap->offset;
+#endif
+
+	return (kern_pwrite(td, uap->fd, uap->buf, uap->nbyte, offset));
 }
 
 int
@@ -1586,26 +1629,40 @@ convert_fadvice(int advice)
 int
 linux_fadvise64(struct thread *td, struct linux_fadvise64_args *args)
 {
+	off_t offset;
 	int advice;
 
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	offset = PAIR32TO64(off_t, args->offset);
+#else
+	offset = args->offset;
+#endif
+
 	advice = convert_fadvice(args->advice);
 	if (advice == -1)
 		return (EINVAL);
-	return (kern_posix_fadvise(td, args->fd, args->offset, args->len,
-	    advice));
+	return (kern_posix_fadvise(td, args->fd, offset, args->len, advice));
 }
 
 #if defined(__i386__) || (defined(__amd64__) && defined(COMPAT_LINUX32))
 int
 linux_fadvise64_64(struct thread *td, struct linux_fadvise64_64_args *args)
 {
+	off_t len, offset;
 	int advice;
 
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	len = PAIR32TO64(off_t, args->len);
+	offset = PAIR32TO64(off_t, args->offset);
+#else
+	len = args->len;
+	offset = args->offset;
+#endif
+
 	advice = convert_fadvice(args->advice);
 	if (advice == -1)
 		return (EINVAL);
-	return (kern_posix_fadvise(td, args->fd, args->offset, args->len,
-	    advice));
+	return (kern_posix_fadvise(td, args->fd, offset, len, advice));
 }
 #endif /* __i386__ || (__amd64__ && COMPAT_LINUX32) */
 
@@ -1689,6 +1746,7 @@ linux_dup3(struct thread *td, struct linux_dup3_args *
 int
 linux_fallocate(struct thread *td, struct linux_fallocate_args *args)
 {
+	off_t len, offset;
 
 	/*
 	 * We emulate only posix_fallocate system call for which
@@ -1697,6 +1755,13 @@ linux_fallocate(struct thread *td, struct linux_falloc
 	if (args->mode != 0)
 		return (ENOSYS);
 
-	return (kern_posix_fallocate(td, args->fd, args->offset,
-	    args->len));
+#if defined(__amd64__) && defined(COMPAT_LINUX32)
+	len = PAIR32TO64(off_t, args->len);
+	offset = PAIR32TO64(off_t, args->offset);
+#else
+	len = args->len;
+	offset = args->offset;
+#endif
+
+	return (kern_posix_fallocate(td, args->fd, offset, len));
 }

Modified: stable/12/sys/i386/linux/linux_machdep.c
==============================================================================
--- stable/12/sys/i386/linux/linux_machdep.c	Fri Apr  3 16:28:39 2020	(r359604)
+++ stable/12/sys/i386/linux/linux_machdep.c	Fri Apr  3 16:31:45 2020	(r359605)
@@ -616,19 +616,6 @@ linux_sigaltstack(struct thread *td, struct linux_siga
 }
 
 int
-linux_ftruncate64(struct thread *td, struct linux_ftruncate64_args *args)
-{
-
-#ifdef DEBUG
-	if (ldebug(ftruncate64))
-		printf(ARGS(ftruncate64, "%u, %jd"), args->fd,
-		    (intmax_t)args->length);
-#endif
-
-	return (kern_ftruncate(td, args->fd, args->length));
-}
-
-int
 linux_set_thread_area(struct thread *td, struct linux_set_thread_area_args *args)
 {
 	struct l_user_desc info;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004031631.033GVjJR093321>