mirror of
https://git.FreeBSD.org/src.git
synced 2024-12-20 11:11:24 +00:00
Normalize the tv_usec part of the utimes(2) arguments to ensure
that a file's atime and mtime are only set to correct fractional second values (0-999999000ns with the current interface). Prior to this change users could create files with values outside that range. Moreover, on 32-bit machines tv_usec offsets larger than 4.3s would result in an unnormalized AND wrong timestamp value, due to overflow. MFC after: 1 week
This commit is contained in:
parent
2f7a934c4f
commit
51339e8593
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=154003
@ -2712,6 +2712,25 @@ fchown(td, uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize the tv_usec value of t within the allowed range.
|
||||
*/
|
||||
static struct timeval
|
||||
normalize_timeval(const struct timeval *t)
|
||||
{
|
||||
struct timeval n;
|
||||
|
||||
if (t->tv_usec >= 0 && t->tv_usec < 1000000)
|
||||
return *t;
|
||||
n.tv_sec = t->tv_sec + t->tv_usec / 1000000;
|
||||
n.tv_usec = t->tv_usec % 1000000;
|
||||
if (n.tv_usec < 0) {
|
||||
n.tv_sec--;
|
||||
n.tv_usec += 1000000;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common implementation code for utimes(), lutimes(), and futimes().
|
||||
*/
|
||||
@ -2721,7 +2740,7 @@ getutimes(usrtvp, tvpseg, tsp)
|
||||
enum uio_seg tvpseg;
|
||||
struct timespec *tsp;
|
||||
{
|
||||
struct timeval tv[2];
|
||||
struct timeval tv[2], tvn;
|
||||
const struct timeval *tvp;
|
||||
int error;
|
||||
|
||||
@ -2738,8 +2757,10 @@ getutimes(usrtvp, tvpseg, tsp)
|
||||
tvp = tv;
|
||||
}
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
|
||||
TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
|
||||
tvn = normalize_timeval(&tvp[0]);
|
||||
TIMEVAL_TO_TIMESPEC(&tvn, &tsp[0]);
|
||||
tvn = normalize_timeval(&tvp[1]);
|
||||
TIMEVAL_TO_TIMESPEC(&tvn, &tsp[1]);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
@ -2712,6 +2712,25 @@ fchown(td, uap)
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Normalize the tv_usec value of t within the allowed range.
|
||||
*/
|
||||
static struct timeval
|
||||
normalize_timeval(const struct timeval *t)
|
||||
{
|
||||
struct timeval n;
|
||||
|
||||
if (t->tv_usec >= 0 && t->tv_usec < 1000000)
|
||||
return *t;
|
||||
n.tv_sec = t->tv_sec + t->tv_usec / 1000000;
|
||||
n.tv_usec = t->tv_usec % 1000000;
|
||||
if (n.tv_usec < 0) {
|
||||
n.tv_sec--;
|
||||
n.tv_usec += 1000000;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
/*
|
||||
* Common implementation code for utimes(), lutimes(), and futimes().
|
||||
*/
|
||||
@ -2721,7 +2740,7 @@ getutimes(usrtvp, tvpseg, tsp)
|
||||
enum uio_seg tvpseg;
|
||||
struct timespec *tsp;
|
||||
{
|
||||
struct timeval tv[2];
|
||||
struct timeval tv[2], tvn;
|
||||
const struct timeval *tvp;
|
||||
int error;
|
||||
|
||||
@ -2738,8 +2757,10 @@ getutimes(usrtvp, tvpseg, tsp)
|
||||
tvp = tv;
|
||||
}
|
||||
|
||||
TIMEVAL_TO_TIMESPEC(&tvp[0], &tsp[0]);
|
||||
TIMEVAL_TO_TIMESPEC(&tvp[1], &tsp[1]);
|
||||
tvn = normalize_timeval(&tvp[0]);
|
||||
TIMEVAL_TO_TIMESPEC(&tvn, &tsp[0]);
|
||||
tvn = normalize_timeval(&tvp[1]);
|
||||
TIMEVAL_TO_TIMESPEC(&tvn, &tsp[1]);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user