Skip to content

Commit

Permalink
time: Add do_timens_ktime_to_host() helper
Browse files Browse the repository at this point in the history
The helper subtracts namespace's clock offset from the given time
and ensures that the result is within [0, KTIME_MAX].

Co-developed-by: Dmitry Safonov <[email protected]>
Signed-off-by: Andrei Vagin <[email protected]>
Signed-off-by: Dmitry Safonov <[email protected]>
Signed-off-by: Thomas Gleixner <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
  • Loading branch information
avagin authored and KAGA-KOKO committed Jan 14, 2020
1 parent 5a590f3 commit 89dd8ee
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 0 deletions.
17 changes: 17 additions & 0 deletions include/linux/time_namespace.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,19 @@ static inline void timens_add_boottime(struct timespec64 *ts)
*ts = timespec64_add(*ts, ns_offsets->boottime);
}

ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
struct timens_offsets *offsets);

static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
{
struct time_namespace *ns = current->nsproxy->time_ns;

if (likely(ns == &init_time_ns))
return tim;

return do_timens_ktime_to_host(clockid, tim, &ns->offsets);
}

#else
static inline struct time_namespace *get_time_ns(struct time_namespace *ns)
{
Expand Down Expand Up @@ -88,6 +101,10 @@ static inline int timens_on_fork(struct nsproxy *nsproxy,

static inline void timens_add_monotonic(struct timespec64 *ts) { }
static inline void timens_add_boottime(struct timespec64 *ts) { }
static inline ktime_t timens_ktime_to_host(clockid_t clockid, ktime_t tim)
{
return tim;
}
#endif

#endif /* _LINUX_TIMENS_H */
36 changes: 36 additions & 0 deletions kernel/time/namespace.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,42 @@
#include <linux/err.h>
#include <linux/mm.h>

ktime_t do_timens_ktime_to_host(clockid_t clockid, ktime_t tim,
struct timens_offsets *ns_offsets)
{
ktime_t offset;

switch (clockid) {
case CLOCK_MONOTONIC:
offset = timespec64_to_ktime(ns_offsets->monotonic);
break;
case CLOCK_BOOTTIME:
case CLOCK_BOOTTIME_ALARM:
offset = timespec64_to_ktime(ns_offsets->boottime);
break;
default:
return tim;
}

/*
* Check that @tim value is in [offset, KTIME_MAX + offset]
* and subtract offset.
*/
if (tim < offset) {
/*
* User can specify @tim *absolute* value - if it's lesser than
* the time namespace's offset - it's already expired.
*/
tim = 0;
} else {
tim = ktime_sub(tim, offset);
if (unlikely(tim > KTIME_MAX))
tim = KTIME_MAX;
}

return tim;
}

static struct ucounts *inc_time_namespaces(struct user_namespace *ns)
{
return inc_ucount(ns, current_euid(), UCOUNT_TIME_NAMESPACES);
Expand Down

0 comments on commit 89dd8ee

Please sign in to comment.