mirror of
https://github.com/samba-team/samba.git
synced 2025-02-14 01:57:53 +03:00
vfs_gpfs: Prevent mangling of GPFS timestamps after 2106
gpfs_set_times as of August 2020 stores 32-bit unsigned tv_sec. We should not silently garble time stamps but reject the attempt to set an out-of-range timestamp. Bug: https://bugzilla.samba.org/show_bug.cgi?id=15151 Signed-off-by: Volker Lendecke <vl@samba.org> Reviewed-by: Christof Schmitt <cs@samba.org> (cherry picked from commit b954d181cd25d9029d3c222e8d97fe7a3b0b2400)
This commit is contained in:
parent
bb86d2f3a1
commit
1b4f782caf
@ -1672,15 +1672,27 @@ static int vfs_gpfs_lstat(struct vfs_handle_struct *handle,
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void timespec_to_gpfs_time(struct timespec ts, gpfs_timestruc_t *gt,
|
||||
int idx, int *flags)
|
||||
static int timespec_to_gpfs_time(
|
||||
struct timespec ts, gpfs_timestruc_t *gt, int idx, int *flags)
|
||||
{
|
||||
if (!is_omit_timespec(&ts)) {
|
||||
*flags |= 1 << idx;
|
||||
gt[idx].tv_sec = ts.tv_sec;
|
||||
gt[idx].tv_nsec = ts.tv_nsec;
|
||||
DEBUG(10, ("Setting GPFS time %d, flags 0x%x\n", idx, *flags));
|
||||
if (is_omit_timespec(&ts)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ts.tv_sec > UINT32_MAX) {
|
||||
DBG_WARNING("GPFS uses 32-bit unsigned timestamps, "
|
||||
"%ju is too large\n",
|
||||
(uintmax_t)ts.tv_sec);
|
||||
errno = ERANGE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
*flags |= 1 << idx;
|
||||
gt[idx].tv_sec = ts.tv_sec;
|
||||
gt[idx].tv_nsec = ts.tv_nsec;
|
||||
DBG_DEBUG("Setting GPFS time %d, flags 0x%x\n", idx, *flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int smbd_gpfs_set_times(struct files_struct *fsp,
|
||||
@ -1691,10 +1703,21 @@ static int smbd_gpfs_set_times(struct files_struct *fsp,
|
||||
int rc;
|
||||
|
||||
ZERO_ARRAY(gpfs_times);
|
||||
timespec_to_gpfs_time(ft->atime, gpfs_times, 0, &flags);
|
||||
timespec_to_gpfs_time(ft->mtime, gpfs_times, 1, &flags);
|
||||
rc = timespec_to_gpfs_time(ft->atime, gpfs_times, 0, &flags);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = timespec_to_gpfs_time(ft->mtime, gpfs_times, 1, &flags);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* No good mapping from LastChangeTime to ctime, not storing */
|
||||
timespec_to_gpfs_time(ft->create_time, gpfs_times, 3, &flags);
|
||||
rc = timespec_to_gpfs_time(ft->create_time, gpfs_times, 3, &flags);
|
||||
if (rc != 0) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
if (!flags) {
|
||||
DBG_DEBUG("nothing to do, return to avoid EINVAL\n");
|
||||
|
Loading…
x
Reference in New Issue
Block a user