Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 13 Jun 2018 08:50:43 +0000 (UTC)
From:      Bruce Evans <bde@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r335035 - in head/sys: compat/freebsd32 compat/linux kern
Message-ID:  <201806130850.w5D8ohl2090103@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: bde
Date: Wed Jun 13 08:50:43 2018
New Revision: 335035
URL: https://svnweb.freebsd.org/changeset/base/335035

Log:
  Fix some bugs found while fixing the representation and translation
  of 64-bit dev_t's (but not ones involving dev_t's).
  
  st_size was supposed to be clamped in cvtstat() and linux's copy_stat(),
  but the clamping code wasn't aware that st_size is signed, and also had
  an obfuscated off-by-1 value for the unsigned limit, so its effect was
  to produce a bizarre negative size instead of clamping.
  
  Change freebsd32's copy_ostat() to be no worse than cvtstat().  It was
  missing clamping and bzero()ing of padding.
  
  Reviewed by:	kib (except a final fix of the clamp to the signed maximum)

Modified:
  head/sys/compat/freebsd32/freebsd32_misc.c
  head/sys/compat/linux/linux_stats.c
  head/sys/kern/vfs_syscalls.c

Modified: head/sys/compat/freebsd32/freebsd32_misc.c
==============================================================================
--- head/sys/compat/freebsd32/freebsd32_misc.c	Wed Jun 13 07:55:57 2018	(r335034)
+++ head/sys/compat/freebsd32/freebsd32_misc.c	Wed Jun 13 08:50:43 2018	(r335035)
@@ -1972,6 +1972,7 @@ static void
 copy_ostat(struct stat *in, struct ostat32 *out)
 {
 
+	bzero(out, sizeof(*out));
 	CP(*in, *out, st_dev);
 	CP(*in, *out, st_ino);
 	CP(*in, *out, st_mode);
@@ -1979,7 +1980,7 @@ copy_ostat(struct stat *in, struct ostat32 *out)
 	CP(*in, *out, st_uid);
 	CP(*in, *out, st_gid);
 	CP(*in, *out, st_rdev);
-	CP(*in, *out, st_size);
+	out->st_size = MIN(in->st_size, INT32_MAX);
 	TS_CP(*in, *out, st_atim);
 	TS_CP(*in, *out, st_mtim);
 	TS_CP(*in, *out, st_ctim);

Modified: head/sys/compat/linux/linux_stats.c
==============================================================================
--- head/sys/compat/linux/linux_stats.c	Wed Jun 13 07:55:57 2018	(r335034)
+++ head/sys/compat/linux/linux_stats.c	Wed Jun 13 08:50:43 2018	(r335035)
@@ -229,10 +229,7 @@ stat_copyout(struct stat *buf, void *ubuf)
 	lbuf.st_uid = buf->st_uid;
 	lbuf.st_gid = buf->st_gid;
 	lbuf.st_rdev = buf->st_rdev;
-	if (buf->st_size < (quad_t)1 << 32)
-		lbuf.st_size = buf->st_size;
-	else
-		lbuf.st_size = -2;
+	lbuf.st_size = MIN(buf->st_size, INT32_MAX);
 	lbuf.st_atim.tv_sec = buf->st_atim.tv_sec;
 	lbuf.st_atim.tv_nsec = buf->st_atim.tv_nsec;
 	lbuf.st_mtim.tv_sec = buf->st_mtim.tv_sec;

Modified: head/sys/kern/vfs_syscalls.c
==============================================================================
--- head/sys/kern/vfs_syscalls.c	Wed Jun 13 07:55:57 2018	(r335034)
+++ head/sys/kern/vfs_syscalls.c	Wed Jun 13 08:50:43 2018	(r335035)
@@ -2065,6 +2065,7 @@ olstat(struct thread *td, struct olstat_args *uap)
 
 /*
  * Convert from an old to a new stat structure.
+ * XXX: many values are blindly truncated.
  */
 void
 cvtstat(struct stat *st, struct ostat *ost)
@@ -2078,10 +2079,7 @@ cvtstat(struct stat *st, struct ostat *ost)
 	ost->st_uid = st->st_uid;
 	ost->st_gid = st->st_gid;
 	ost->st_rdev = st->st_rdev;
-	if (st->st_size < (quad_t)1 << 32)
-		ost->st_size = st->st_size;
-	else
-		ost->st_size = -2;
+	ost->st_size = MIN(st->st_size, INT32_MAX);
 	ost->st_atim = st->st_atim;
 	ost->st_mtim = st->st_mtim;
 	ost->st_ctim = st->st_ctim;



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