The code to check the adjtimex() or clock_adjtime() arguments is spread
out across multiple files for presumably only historic reasons. As a
preparatation for a rework to get rid of the use of 'struct timeval'
and 'struct timespec' in there, this moves all the portions into
kernel/time/timekeeping.c and marks them as 'static'.
The warp_clock() function here is not as closely related as the others,
but I feel it still makes sense to move it here in order to consolidate
all callers of timekeeping_inject_offset().
Signed-off-by: Arnd Bergmann <arnd(a)arndb.de>
---
include/linux/time.h | 26 ----------
kernel/time/ntp.c | 61 ----------------------
kernel/time/ntp_internal.h | 1 -
kernel/time/time.c | 36 +------------
kernel/time/timekeeping.c | 123 ++++++++++++++++++++++++++++++++++++++++++++-
kernel/time/timekeeping.h | 2 +-
6 files changed, 123 insertions(+), 126 deletions(-)
diff --git a/include/linux/time.h b/include/linux/time.h
index 9bc1f945777c..c0fbad08448f 100644
--- a/include/linux/time.h
+++ b/include/linux/time.h
@@ -134,32 +134,6 @@ static inline bool timeval_valid(const struct timeval *tv)
extern struct timespec timespec_trunc(struct timespec t, unsigned gran);
-/*
- * Validates if a timespec/timeval used to inject a time offset is valid.
- * Offsets can be postive or negative. The value of the timeval/timespec
- * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
- * always be non-negative.
- */
-static inline bool timeval_inject_offset_valid(const struct timeval *tv)
-{
- /* We don't check the tv_sec as it can be positive or negative */
-
- /* Can't have more microseconds then a second */
- if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
- return false;
- return true;
-}
-
-static inline bool timespec_inject_offset_valid(const struct timespec *ts)
-{
- /* We don't check the tv_sec as it can be positive or negative */
-
- /* Can't have more nanoseconds then a second */
- if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
- return false;
- return true;
-}
-
/* Some architectures do not supply their own clocksource.
* This is mainly the case in architectures that get their
* inter-tick times by reading the counter on their interval
diff --git a/kernel/time/ntp.c b/kernel/time/ntp.c
index edf19cc53140..a5e702669d84 100644
--- a/kernel/time/ntp.c
+++ b/kernel/time/ntp.c
@@ -653,67 +653,6 @@ static inline void process_adjtimex_modes(struct timex *txc,
}
-
-/**
- * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex
- */
-int ntp_validate_timex(struct timex *txc)
-{
- if (txc->modes & ADJ_ADJTIME) {
- /* singleshot must not be used with any other mode bits */
- if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
- return -EINVAL;
- if (!(txc->modes & ADJ_OFFSET_READONLY) &&
- !capable(CAP_SYS_TIME))
- return -EPERM;
- } else {
- /* In order to modify anything, you gotta be super-user! */
- if (txc->modes && !capable(CAP_SYS_TIME))
- return -EPERM;
- /*
- * if the quartz is off by more than 10% then
- * something is VERY wrong!
- */
- if (txc->modes & ADJ_TICK &&
- (txc->tick < 900000/USER_HZ ||
- txc->tick > 1100000/USER_HZ))
- return -EINVAL;
- }
-
- if (txc->modes & ADJ_SETOFFSET) {
- /* In order to inject time, you gotta be super-user! */
- if (!capable(CAP_SYS_TIME))
- return -EPERM;
-
- if (txc->modes & ADJ_NANO) {
- struct timespec ts;
-
- ts.tv_sec = txc->time.tv_sec;
- ts.tv_nsec = txc->time.tv_usec;
- if (!timespec_inject_offset_valid(&ts))
- return -EINVAL;
-
- } else {
- if (!timeval_inject_offset_valid(&txc->time))
- return -EINVAL;
- }
- }
-
- /*
- * Check for potential multiplication overflows that can
- * only happen on 64-bit systems:
- */
- if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
- if (LLONG_MIN / PPM_SCALE > txc->freq)
- return -EINVAL;
- if (LLONG_MAX / PPM_SCALE < txc->freq)
- return -EINVAL;
- }
-
- return 0;
-}
-
-
/*
* adjtimex mainly allows reading (and writing, if superuser) of
* kernel time-keeping variables. used by xntpd.
diff --git a/kernel/time/ntp_internal.h b/kernel/time/ntp_internal.h
index d8a7c11fa71a..74b52cd48209 100644
--- a/kernel/time/ntp_internal.h
+++ b/kernel/time/ntp_internal.h
@@ -7,7 +7,6 @@ extern void ntp_clear(void);
extern u64 ntp_tick_length(void);
extern ktime_t ntp_get_next_leap(void);
extern int second_overflow(time64_t secs);
-extern int ntp_validate_timex(struct timex *);
extern int __do_adjtimex(struct timex *, struct timespec64 *, s32 *);
extern void __hardpps(const struct timespec64 *, const struct timespec64 *);
#endif /* _LINUX_NTP_INTERNAL_H */
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 44a8c1402133..04684e294f00 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -158,40 +158,6 @@ SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
}
/*
- * Indicates if there is an offset between the system clock and the hardware
- * clock/persistent clock/rtc.
- */
-int persistent_clock_is_local;
-
-/*
- * Adjust the time obtained from the CMOS to be UTC time instead of
- * local time.
- *
- * This is ugly, but preferable to the alternatives. Otherwise we
- * would either need to write a program to do it in /etc/rc (and risk
- * confusion if the program gets run more than once; it would also be
- * hard to make the program warp the clock precisely n hours) or
- * compile in the timezone information into the kernel. Bad, bad....
- *
- * - TYT, 1992-01-01
- *
- * The best thing to do is to keep the CMOS clock in universal time (UTC)
- * as real UNIX machines always do it. This avoids all headaches about
- * daylight saving times and warping kernel clocks.
- */
-static inline void warp_clock(void)
-{
- if (sys_tz.tz_minuteswest != 0) {
- struct timespec adjust;
-
- persistent_clock_is_local = 1;
- adjust.tv_sec = sys_tz.tz_minuteswest * 60;
- adjust.tv_nsec = 0;
- timekeeping_inject_offset(&adjust);
- }
-}
-
-/*
* In case for some reason the CMOS clock has not already been running
* in UTC, but in some local time: The first time we set the timezone,
* we will warp the clock so that it is ticking UTC time instead of
@@ -224,7 +190,7 @@ int do_sys_settimeofday64(const struct timespec64 *tv, const struct timezone *tz
if (firsttime) {
firsttime = 0;
if (!tv)
- warp_clock();
+ timekeeping_warp_clock();
}
}
if (tv)
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 8af77006e937..679dbfbea419 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -1300,13 +1300,39 @@ int do_settimeofday64(const struct timespec64 *ts)
}
EXPORT_SYMBOL(do_settimeofday64);
+/*
+ * Validates if a timespec/timeval used to inject a time offset is valid.
+ * Offsets can be postive or negative. The value of the timeval/timespec
+ * is the sum of its fields, but *NOTE*: the field tv_usec/tv_nsec must
+ * always be non-negative.
+ */
+static inline bool timeval_inject_offset_valid(const struct timeval *tv)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more microseconds then a second */
+ if (tv->tv_usec < 0 || tv->tv_usec >= USEC_PER_SEC)
+ return false;
+ return true;
+}
+
+static inline bool timespec_inject_offset_valid(const struct timespec *ts)
+{
+ /* We don't check the tv_sec as it can be positive or negative */
+
+ /* Can't have more nanoseconds then a second */
+ if (ts->tv_nsec < 0 || ts->tv_nsec >= NSEC_PER_SEC)
+ return false;
+ return true;
+}
+
/**
* timekeeping_inject_offset - Adds or subtracts from the current time.
* @tv: pointer to the timespec variable containing the offset
*
* Adds or subtracts an offset value from the current time.
*/
-int timekeeping_inject_offset(struct timespec *ts)
+static int timekeeping_inject_offset(struct timespec *ts)
{
struct timekeeper *tk = &tk_core.timekeeper;
unsigned long flags;
@@ -1345,7 +1371,40 @@ int timekeeping_inject_offset(struct timespec *ts)
return ret;
}
-EXPORT_SYMBOL(timekeeping_inject_offset);
+
+/*
+ * Indicates if there is an offset between the system clock and the hardware
+ * clock/persistent clock/rtc.
+ */
+int persistent_clock_is_local;
+
+/*
+ * Adjust the time obtained from the CMOS to be UTC time instead of
+ * local time.
+ *
+ * This is ugly, but preferable to the alternatives. Otherwise we
+ * would either need to write a program to do it in /etc/rc (and risk
+ * confusion if the program gets run more than once; it would also be
+ * hard to make the program warp the clock precisely n hours) or
+ * compile in the timezone information into the kernel. Bad, bad....
+ *
+ * - TYT, 1992-01-01
+ *
+ * The best thing to do is to keep the CMOS clock in universal time (UTC)
+ * as real UNIX machines always do it. This avoids all headaches about
+ * daylight saving times and warping kernel clocks.
+ */
+void timekeeping_warp_clock(void)
+{
+ if (sys_tz.tz_minuteswest != 0) {
+ struct timespec adjust;
+
+ persistent_clock_is_local = 1;
+ adjust.tv_sec = sys_tz.tz_minuteswest * 60;
+ adjust.tv_nsec = 0;
+ timekeeping_inject_offset(&adjust);
+ }
+}
/**
* __timekeeping_set_tai_offset - Sets the TAI offset from UTC and monotonic
@@ -2290,6 +2349,66 @@ ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq, ktime_t *offs_real,
}
/**
+ * ntp_validate_timex - Ensures the timex is ok for use in do_adjtimex
+ */
+static int ntp_validate_timex(struct timex *txc)
+{
+ if (txc->modes & ADJ_ADJTIME) {
+ /* singleshot must not be used with any other mode bits */
+ if (!(txc->modes & ADJ_OFFSET_SINGLESHOT))
+ return -EINVAL;
+ if (!(txc->modes & ADJ_OFFSET_READONLY) &&
+ !capable(CAP_SYS_TIME))
+ return -EPERM;
+ } else {
+ /* In order to modify anything, you gotta be super-user! */
+ if (txc->modes && !capable(CAP_SYS_TIME))
+ return -EPERM;
+ /*
+ * if the quartz is off by more than 10% then
+ * something is VERY wrong!
+ */
+ if (txc->modes & ADJ_TICK &&
+ (txc->tick < 900000/USER_HZ ||
+ txc->tick > 1100000/USER_HZ))
+ return -EINVAL;
+ }
+
+ if (txc->modes & ADJ_SETOFFSET) {
+ /* In order to inject time, you gotta be super-user! */
+ if (!capable(CAP_SYS_TIME))
+ return -EPERM;
+
+ if (txc->modes & ADJ_NANO) {
+ struct timespec ts;
+
+ ts.tv_sec = txc->time.tv_sec;
+ ts.tv_nsec = txc->time.tv_usec;
+ if (!timespec_inject_offset_valid(&ts))
+ return -EINVAL;
+
+ } else {
+ if (!timeval_inject_offset_valid(&txc->time))
+ return -EINVAL;
+ }
+ }
+
+ /*
+ * Check for potential multiplication overflows that can
+ * only happen on 64-bit systems:
+ */
+ if ((txc->modes & ADJ_FREQUENCY) && (BITS_PER_LONG == 64)) {
+ if (LLONG_MIN / PPM_SCALE > txc->freq)
+ return -EINVAL;
+ if (LLONG_MAX / PPM_SCALE < txc->freq)
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+
+/**
* do_adjtimex() - Accessor function to NTP __do_adjtimex function
*/
int do_adjtimex(struct timex *txc)
diff --git a/kernel/time/timekeeping.h b/kernel/time/timekeeping.h
index d0914676d4c5..44aec7893cdd 100644
--- a/kernel/time/timekeeping.h
+++ b/kernel/time/timekeeping.h
@@ -10,7 +10,7 @@ extern ktime_t ktime_get_update_offsets_now(unsigned int *cwsseq,
extern int timekeeping_valid_for_hres(void);
extern u64 timekeeping_max_deferment(void);
-extern int timekeeping_inject_offset(struct timespec *ts);
+extern void timekeeping_warp_clock(void);
extern int timekeeping_suspend(void);
extern void timekeeping_resume(void);
--
2.9.0
I'm in the process of finishing up the last bits on y2038-unsafe
code in the kernel, this series is for v4l2, which has no problem
with overflow, but has multiple ioctls that break with user space
built against a new 32-bit libc.
I posted similar patches as part of a series back in 2015, the
new version was rewritten from scratch and I double-checked with
the old version to make sure I did not miss anything I had already
taken care of before.
Hans Verkuil worked on a different patch set in 2017, but this
also did not get to the point of being merged.
My new version contains compat-ioctl support, which the old one
did not and should be complete, but given its size likely contains
bugs. I did randconfig build tests, but no runtime test, so
careful review as well as testing would be much appreciated.
With this version, the newly added code takes care of the existing
ABI, while the existing code got moved to the 64-bit time_t
interface and is used internally. This means that testing with
existing binaries should exercise most of the modifications
and if that works and doesn't get shot down in review, we can
probably live without testing the new ABI explicitly.
I'm not entirely happy with the compat-ioctl implementation that
adds quite a bit of code duplication, but I hope this is
acceptable anyway, as a better implementation would likely
require a larger refactoring of the compat-ioctl file, while
my approach simply adds support for the additional data structure
variants.
I uploaded git branch on top of the v4l2/dvb branch to [2].
Arnd
Changes since v4:
- Move non-public contents out of uapi header
- split out __kernel_v4l2_timeval into separate struct
- use compound initializers for v4l2_event_time32 and
v4l2_buffer_time32 conversion
- add comment for v4l2_buffer_get_timestamp()
Changes since v3:
- This is a minor update compared to version 3 of this series,
with bugfixes for small mistakes that I found or that were
reported by automated build bots.
[1] https://lwn.net/Articles/657754/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=…
Arnd Bergmann (8):
media: documentation: fix video_event description
media: v4l2: abstract timeval handling in v4l2_buffer
media: v4l2-core: compat: ignore native command codes
media: v4l2-core: split out data copy from video_usercopy
media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI
media: v4l2-core: fix v4l2_buffer handling for time64 ABI
media: v4l2-core: fix compat VIDIOC_DQEVENT for time64 ABI
media: v4l2-core: fix compat v4l2_buffer handling for time64 ABI
.../media/uapi/dvb/video-get-event.rst | 2 +-
Documentation/media/uapi/dvb/video_types.rst | 2 +-
.../media/common/videobuf2/videobuf2-v4l2.c | 4 +-
drivers/media/pci/meye/meye.c | 4 +-
drivers/media/usb/cpia2/cpia2_v4l.c | 4 +-
drivers/media/usb/stkwebcam/stk-webcam.c | 2 +-
drivers/media/usb/usbvision/usbvision-video.c | 4 +-
drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 470 +++++++++++++++---
drivers/media/v4l2-core/v4l2-event.c | 5 +-
drivers/media/v4l2-core/v4l2-ioctl.c | 209 ++++++--
drivers/media/v4l2-core/v4l2-subdev.c | 26 +-
drivers/media/v4l2-core/videobuf-core.c | 5 +-
include/media/v4l2-common.h | 21 +
include/media/v4l2-ioctl.h | 55 ++
include/trace/events/v4l2.h | 2 +-
include/uapi/linux/videodev2.h | 29 ++
16 files changed, 709 insertions(+), 135 deletions(-)
--
2.20.0
Push clamping timestamps down the call stack into notify_change(), so
in-kernel callers like nfsd and overlayfs will get similar timestamp
set behavior as utimes.
Suggested-by: Miklos Szeredi <mszeredi(a)redhat.com>
Fixes: 42e729b9ddbb ("utimes: Clamp the timestamps before update")
Cc: stable(a)vger.kernel.org # v5.4
Cc: Deepa Dinamani <deepa.kernel(a)gmail.com>
Cc: Jeff Layton <jlayton(a)kernel.org>
Signed-off-by: Amir Goldstein <amir73il(a)gmail.com>
---
Arnd,
This fixes xfstest generic/402 when run with -overlay setup.
Note that running the test requires latest xfstests with:
acb2ba78 - overlay: support timestamp range check
I had previously posted a fix specific for overlayfs [1],
but Miklos suggested this more generic fix, which should also
serve nfsd and other in-kernel users.
I tested this change with test generic/402 on ext4/xfs/btrfs
and overlayfs, but not with nfsd.
Jeff, could you ack this change is good for nfsd as well?
Thanks,
Amir.
[1] https://lore.kernel.org/linux-fsdevel/20191111073000.2957-1-amir73il@gmail.…
fs/attr.c | 5 +++++
fs/utimes.c | 4 ++--
2 files changed, 7 insertions(+), 2 deletions(-)
diff --git a/fs/attr.c b/fs/attr.c
index df28035aa23e..e8de5e636e66 100644
--- a/fs/attr.c
+++ b/fs/attr.c
@@ -268,8 +268,13 @@ int notify_change(struct dentry * dentry, struct iattr * attr, struct inode **de
attr->ia_ctime = now;
if (!(ia_valid & ATTR_ATIME_SET))
attr->ia_atime = now;
+ else
+ attr->ia_atime = timestamp_truncate(attr->ia_atime, inode);
if (!(ia_valid & ATTR_MTIME_SET))
attr->ia_mtime = now;
+ else
+ attr->ia_mtime = timestamp_truncate(attr->ia_mtime, inode);
+
if (ia_valid & ATTR_KILL_PRIV) {
error = security_inode_need_killpriv(dentry);
if (error < 0)
diff --git a/fs/utimes.c b/fs/utimes.c
index 1ba3f7883870..090739322463 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -36,14 +36,14 @@ static int utimes_common(const struct path *path, struct timespec64 *times)
if (times[0].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_ATIME;
else if (times[0].tv_nsec != UTIME_NOW) {
- newattrs.ia_atime = timestamp_truncate(times[0], inode);
+ newattrs.ia_atime = times[0];
newattrs.ia_valid |= ATTR_ATIME_SET;
}
if (times[1].tv_nsec == UTIME_OMIT)
newattrs.ia_valid &= ~ATTR_MTIME;
else if (times[1].tv_nsec != UTIME_NOW) {
- newattrs.ia_mtime = timestamp_truncate(times[1], inode);
+ newattrs.ia_mtime = times[1];
newattrs.ia_valid |= ATTR_MTIME_SET;
}
/*
--
2.17.1
I'm in the process of finishing up the last bits on y2038-unsafe
code in the kernel, this series is for v4l2, which has no problem
with overflow, but has multiple ioctls that break with user space
built against a new 32-bit libc.
I posted similar patches as part of a series back in 2015, the
new version was rewritten from scratch and I double-checked with
the old version to make sure I did not miss anything I had already
taken care of before.
Hans Verkuil worked on a different patch set in 2017, but this
also did not get to the point of being merged.
My new version contains compat-ioctl support, which the old one
did not and should be complete, but given its size likely contains
bugs. I did randconfig build tests, but no runtime test, so
careful review as well as testing would be much appreciated.
With this version, the newly added code takes care of the existing
ABI, while the existing code got moved to the 64-bit time_t
interface and is used internally. This means that testing with
existing binaries should exercise most of the modifications
and if that works and doesn't get shot down in review, we can
probably live without testing the new ABI explicitly.
I'm not entirely happy with the compat-ioctl implementation that
adds quite a bit of code duplication, but I hope this is
acceptable anyway, as a better implementation would likely
require a larger refactoring of the compat-ioctl file, while
my approach simply adds support for the additional data structure
variants.
This is a minor update compared to version 3 of this series,
with bugfixes for small mistakes that I found or that were
reported by automated build bots. I updated the tree at [2]
to this version now.
Arnd
[1] https://lwn.net/Articles/657754/
[2] https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=…
Arnd Bergmann (8):
media: documentation: fix video_event description
media: v4l2: abstract timeval handling in v4l2_buffer
media: v4l2-core: compat: ignore native command codes
media: v4l2-core: split out data copy from video_usercopy
media: v4l2-core: fix VIDIOC_DQEVENT for time64 ABI
media: v4l2-core: fix v4l2_buffer handling for time64 ABI
media: v4l2-core: fix compat VIDIOC_DQEVENT for time64 ABI
media: v4l2-core: fix compat v4l2_buffer handling for time64 ABI
.../media/uapi/dvb/video-get-event.rst | 2 +-
Documentation/media/uapi/dvb/video_types.rst | 2 +-
.../media/common/videobuf2/videobuf2-v4l2.c | 4 +-
drivers/media/pci/meye/meye.c | 4 +-
drivers/media/usb/cpia2/cpia2_v4l.c | 4 +-
drivers/media/usb/stkwebcam/stk-webcam.c | 2 +-
drivers/media/usb/usbvision/usbvision-video.c | 4 +-
drivers/media/v4l2-core/v4l2-compat-ioctl32.c | 470 +++++++++++++++---
drivers/media/v4l2-core/v4l2-event.c | 5 +-
drivers/media/v4l2-core/v4l2-ioctl.c | 188 +++++--
drivers/media/v4l2-core/v4l2-subdev.c | 20 +-
drivers/media/v4l2-core/videobuf-core.c | 4 +-
include/linux/videodev2.h | 17 +-
include/trace/events/v4l2.h | 2 +-
include/uapi/linux/videodev2.h | 77 +++
15 files changed, 669 insertions(+), 136 deletions(-)
--
2.20.0
See below for the changes compared to v3:
|diff --git a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
|index a13e4849df0c..3bbf47d950e0 100644
|--- a/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
|+++ b/drivers/media/v4l2-core/v4l2-compat-ioctl32.c
|@@ -500,7 +500,7 @@ struct v4l2_buffer32_time32 {
| __u32 bytesused;
| __u32 flags;
| __u32 field; /* enum v4l2_field */
|- struct compat_timeval timestamp;
|+ struct old_timeval32 timestamp;
| struct v4l2_timecode timecode;
| __u32 sequence;
|
|@@ -1290,7 +1290,7 @@ struct v4l2_event32_time32 {
| } u;
| __u32 pending;
| __u32 sequence;
|- struct compat_timespec timestamp;
|+ struct old_timespec32 timestamp;
| __u32 id;
| __u32 reserved[8];
| };
|@@ -1482,8 +1482,8 @@ static long do_video_ioctl(struct file *file, unsigned int cmd, unsigned long ar
| case VIDIOC_S_EXT_CTRLS32: ncmd = VIDIOC_S_EXT_CTRLS; break;
| case VIDIOC_TRY_EXT_CTRLS32: ncmd = VIDIOC_TRY_EXT_CTRLS; break;
| #ifdef CONFIG_X86_64
|- case VIDIOC_DQEVENT32: cmd = VIDIOC_DQEVENT; break;
|- case VIDIOC_DQEVENT32_TIME32: cmd = VIDIOC_DQEVENT_TIME32; break;
|+ case VIDIOC_DQEVENT32: ncmd = VIDIOC_DQEVENT; break;
|+ case VIDIOC_DQEVENT32_TIME32: ncmd = VIDIOC_DQEVENT_TIME32; break;
| #endif
| case VIDIOC_OVERLAY32: ncmd = VIDIOC_OVERLAY; break;
| case VIDIOC_STREAMON32: ncmd = VIDIOC_STREAMON; break;
|diff --git a/drivers/media/v4l2-core/v4l2-ioctl.c b/drivers/media/v4l2-core/v4l2-ioctl.c
|index cd9a80960289..ad125cd4eb41 100644
|--- a/drivers/media/v4l2-core/v4l2-ioctl.c
|+++ b/drivers/media/v4l2-core/v4l2-ioctl.c
|@@ -474,7 +474,7 @@ static void v4l_print_buffer(const void *arg, bool write_only)
| const struct v4l2_plane *plane;
| int i;
|
|- pr_cont("%02ld:%02d:%02d.%09ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
|+ pr_cont("%02d:%02d:%02d.%09ld index=%d, type=%s, request_fd=%d, flags=0x%08x, field=%s, sequence=%d, memory=%s",
| (int)p->timestamp.tv_sec / 3600,
| ((int)p->timestamp.tv_sec / 60) % 60,
| ((int)p->timestamp.tv_sec % 60),
|@@ -821,7 +821,7 @@ static void v4l_print_event(const void *arg, bool write_only)
| const struct v4l2_event *p = arg;
| const struct v4l2_event_ctrl *c;
|
|- pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%lu.%9.9lu\n",
|+ pr_cont("type=0x%x, pending=%u, sequence=%u, id=%u, timestamp=%llu.%9.9llu\n",
| p->type, p->pending, p->sequence, p->id,
| p->timestamp.tv_sec, p->timestamp.tv_nsec);
| switch (p->type) {
|diff --git a/include/linux/videodev2.h b/include/linux/videodev2.h
|index 481ee3013b50..4086036e37d5 100644
|--- a/include/linux/videodev2.h
|+++ b/include/linux/videodev2.h
|@@ -62,7 +62,7 @@
| static inline u64 v4l2_buffer_get_timestamp(const struct v4l2_buffer *buf)
| {
| return buf->timestamp.tv_sec * NSEC_PER_SEC +
|- buf->timestamp.tv_usec * NSEC_PER_USEC;
|+ (u32)buf->timestamp.tv_usec * NSEC_PER_USEC;
| }
|
| static inline void v4l2_buffer_set_timestamp(struct v4l2_buffer *buf,
|diff --git a/include/uapi/linux/videodev2.h b/include/uapi/linux/videodev2.h
|index 4275d6e92dae..ca10828328a5 100644
|--- a/include/uapi/linux/videodev2.h
|+++ b/include/uapi/linux/videodev2.h
|@@ -1001,7 +1001,12 @@ struct v4l2_buffer {
| /* match glibc timeval64 format */
| struct {
| long long tv_sec;
|+# if defined(__sparc__) && defined(__arch64__)
|+ int tv_usec;
|+ int __pad;
|+# else
| long long tv_usec;
|+# endif
| } timestamp;
| #else
| struct timeval timestamp;
|
I've gone through the remaining uses of time_t etc and come up with a
set of 90 patches of varying complexity and importance, to the point
of being able to remove the old time_t/timeval/timespec from the kernel
headers completely.
This set includes the eight patches that I think should be merged
right away and backported into stable kernels if possible.
Please apply individual patches to the respective maintainer trees
for either v5.4 or v5.5 as appropriate.
For reference, the full series of 90 patches can be found at
https://git.kernel.org/pub/scm/linux/kernel/git/arnd/playground.git/log/?h=…
Arnd
Arnd Bergmann (8):
y2038: timex: remove incorrect time_t truncation
timekeeping: optimize ns_to_timespec64
powerpc: fix vdso32 for ppc64le
ipmi: kill off 'timespec' usage again
netfilter: xt_time: use time64_t
lp: fix sparc64 LPSETTIMEOUT ioctl
ppdev: fix PPGETTIME/PPSETTIME ioctls
Input: input_event: fix struct padding on sparc64
arch/powerpc/kernel/vdso32/gettimeofday.S | 2 +-
drivers/char/ipmi/ipmi_si_intf.c | 40 ++++++++---------------
drivers/char/lp.c | 4 +++
drivers/char/ppdev.c | 16 ++++++---
drivers/input/evdev.c | 3 ++
drivers/input/misc/uinput.c | 3 ++
include/uapi/linux/input.h | 1 +
kernel/time/ntp.c | 2 +-
kernel/time/time.c | 21 +++++++-----
net/netfilter/xt_time.c | 19 ++++++-----
10 files changed, 61 insertions(+), 50 deletions(-)
Cc: Benjamin Herrenschmidt <benh(a)kernel.crashing.org>
Cc: Paul Mackerras <paulus(a)samba.org>
Cc: Michael Ellerman <mpe(a)ellerman.id.au>
Cc: Corey Minyard <minyard(a)acm.org>
Cc: Greg Kroah-Hartman <gregkh(a)linuxfoundation.org>
Cc: Sudip Mukherjee <sudipm.mukherjee(a)gmail.com>
Cc: Dmitry Torokhov <dmitry.torokhov(a)gmail.com>
Cc: John Stultz <john.stultz(a)linaro.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: Stephen Boyd <sboyd(a)kernel.org>
Cc: Pablo Neira Ayuso <pablo(a)netfilter.org>
Cc: Jozsef Kadlecsik <kadlec(a)netfilter.org>
Cc: Florian Westphal <fw(a)strlen.de>
Cc: "David S. Miller" <davem(a)davemloft.net>
Cc: linuxppc-dev(a)lists.ozlabs.org
Cc: linux-kernel(a)vger.kernel.org
Cc: openipmi-developer(a)lists.sourceforge.net
Cc: linux-input(a)vger.kernel.org
Cc: netfilter-devel(a)vger.kernel.org
Cc: coreteam(a)netfilter.org
Cc: netdev(a)vger.kernel.org
Cc: sparclinux(a)vger.kernel.org
--
2.20.0
On compat interfaces, the high order bits of nanoseconds should
be zeroed out. This is because the application code or the libc
do not guarantee zeroing of these. If used without zeroing,
kernel might be at risk of using timespec values incorrectly.
Originally it was handled correctly, but lost during is_compat_syscall()
cleanup. Revert the condition back to check CONFIG_64BIT.
Reported-by: Ben Hutchings <ben.hutchings(a)codethink.co.uk>
Fixes: 98f76206b335 ("compat: Cleanup in_compat_syscall() callers")
Cc: Arnd Bergmann <arnd(a)arndb.de>
Cc: Ben Hutchings <ben.hutchings(a)codethink.co.uk>
Cc: John Stultz <john.stultz(a)linaro.org>
Cc: Stephen Boyd <sboyd(a)kernel.org>
Cc: Thomas Gleixner <tglx(a)linutronix.de>
Cc: y2038(a)lists.linaro.org
Cc: stable(a)vger.kernel.org # v4.20+
Signed-off-by: Dmitry Safonov <dima(a)arista.com>
---
kernel/time/time.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/time/time.c b/kernel/time/time.c
index 5c54ca632d08..1cb045c5c97e 100644
--- a/kernel/time/time.c
+++ b/kernel/time/time.c
@@ -881,7 +881,7 @@ int get_timespec64(struct timespec64 *ts,
ts->tv_sec = kts.tv_sec;
/* Zero out the padding for 32 bit systems or in compat mode */
- if (IS_ENABLED(CONFIG_64BIT_TIME) && in_compat_syscall())
+ if (IS_ENABLED(CONFIG_64BIT_TIME) && (!IS_ENABLED(CONFIG_64BIT) || in_compat_syscall()))
kts.tv_nsec &= 0xFFFFFFFFUL;
ts->tv_nsec = kts.tv_nsec;
--
2.24.0