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