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)
This commit is contained in:
Bruce Evans 2018-06-13 08:50:43 +00:00
parent 2b6fe1b2da
commit 372639f944
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=335035
3 changed files with 5 additions and 9 deletions

View File

@ -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);

View File

@ -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;

View File

@ -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;