svn commit: r335035 - in head/sys: compat/freebsd32 compat/linux kern

Bruce Evans bde at FreeBSD.org
Wed Jun 13 08:50:44 UTC 2018


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;


More information about the svn-src-all mailing list