Messages in this thread Patch in this message | | | From | Adrian Reber <> | Subject | [PATCH 1/4] ns: prepare time namespace for clone3() | Date | Tue, 17 Mar 2020 09:30:41 +0100 |
| |
To enable clone3()ing a process directly into a new time namespace with a clock offset, this changes the time namespace code by renaming the variable proc_timens_offset (which was used to set a timens offset via /proc) to set_timens_offset to avoid confusion why it will be used in clone3() without being related to /proc.
This also moves out the code of actually setting the clock offsets to its own function to be later used via clone3().
Signed-off-by: Adrian Reber <areber@redhat.com> --- fs/proc/base.c | 4 +- include/linux/time_namespace.h | 16 +++-- kernel/time/namespace.c | 126 +++++++++++++++++---------------- 3 files changed, 78 insertions(+), 68 deletions(-)
diff --git a/fs/proc/base.c b/fs/proc/base.c index c7c64272b0fa..2ca68f11ff0e 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -1554,7 +1554,7 @@ static ssize_t timens_offsets_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) { struct inode *inode = file_inode(file); - struct proc_timens_offset offsets[2]; + struct set_timens_offset offsets[2]; char *kbuf = NULL, *pos, *next_line; struct task_struct *p; int ret, noffsets; @@ -1572,7 +1572,7 @@ static ssize_t timens_offsets_write(struct file *file, const char __user *buf, ret = -EINVAL; noffsets = 0; for (pos = kbuf; pos; pos = next_line) { - struct proc_timens_offset *off = &offsets[noffsets]; + struct set_timens_offset *off = &offsets[noffsets]; int err; /* Find the end of line and ensure we don't look past it */ diff --git a/include/linux/time_namespace.h b/include/linux/time_namespace.h index 824d54e057eb..fb4ca4402a2a 100644 --- a/include/linux/time_namespace.h +++ b/include/linux/time_namespace.h @@ -30,6 +30,15 @@ struct time_namespace { extern struct time_namespace init_time_ns; +/* + * This structure is used to set the time namespace offset + * via /proc as well as via clone3(). + */ +struct set_timens_offset { + int clockid; + struct timespec64 val; +}; + #ifdef CONFIG_TIME_NS extern int vdso_join_timens(struct task_struct *task, struct time_namespace *ns); @@ -54,13 +63,8 @@ static inline void put_time_ns(struct time_namespace *ns) void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m); -struct proc_timens_offset { - int clockid; - struct timespec64 val; -}; - int proc_timens_set_offset(struct file *file, struct task_struct *p, - struct proc_timens_offset *offsets, int n); + struct set_timens_offset *offsets, int n); static inline void timens_add_monotonic(struct timespec64 *ts) { diff --git a/kernel/time/namespace.c b/kernel/time/namespace.c index 12858507d75a..839efa7c6886 100644 --- a/kernel/time/namespace.c +++ b/kernel/time/namespace.c @@ -307,6 +307,69 @@ static int timens_install(struct nsproxy *nsproxy, struct ns_common *new) return 0; } +static int timens_set_offset(struct task_struct *p, struct time_namespace *ns, + struct set_timens_offset *offsets, int noffsets) +{ + struct timespec64 tp; + int i, err; + + for (i = 0; i < noffsets; i++) { + struct set_timens_offset *off = &offsets[i]; + + switch (off->clockid) { + case CLOCK_MONOTONIC: + ktime_get_ts64(&tp); + break; + case CLOCK_BOOTTIME: + ktime_get_boottime_ts64(&tp); + break; + default: + return -EINVAL; + } + + if (off->val.tv_sec > KTIME_SEC_MAX || + off->val.tv_sec < -KTIME_SEC_MAX) + return -ERANGE; + + tp = timespec64_add(tp, off->val); + /* + * KTIME_SEC_MAX is divided by 2 to be sure that KTIME_MAX is + * still unreachable. + */ + if (tp.tv_sec < 0 || tp.tv_sec > KTIME_SEC_MAX / 2) + return -ERANGE; + } + + mutex_lock(&offset_lock); + if (ns->frozen_offsets) { + err = -EACCES; + goto out_unlock; + } + + err = 0; + /* Don't report errors after this line */ + for (i = 0; i < noffsets; i++) { + struct set_timens_offset *off = &offsets[i]; + struct timespec64 *offset = NULL; + + switch (off->clockid) { + case CLOCK_MONOTONIC: + offset = &ns->offsets.monotonic; + break; + case CLOCK_BOOTTIME: + offset = &ns->offsets.boottime; + break; + } + + *offset = off->val; + } + +out_unlock: + mutex_unlock(&offset_lock); + + return err; +} + int timens_on_fork(struct nsproxy *nsproxy, struct task_struct *tsk) { struct ns_common *nsc = &nsproxy->time_ns_for_children->ns; @@ -356,12 +419,11 @@ void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m) } int proc_timens_set_offset(struct file *file, struct task_struct *p, - struct proc_timens_offset *offsets, int noffsets) + struct set_timens_offset *offsets, int noffsets) { struct ns_common *ns; struct time_namespace *time_ns; - struct timespec64 tp; - int i, err; + int err; ns = timens_for_children_get(p); if (!ns) @@ -373,63 +435,7 @@ int proc_timens_set_offset(struct file *file, struct task_struct *p, return -EPERM; } - for (i = 0; i < noffsets; i++) { - struct proc_timens_offset *off = &offsets[i]; - - switch (off->clockid) { - case CLOCK_MONOTONIC: - ktime_get_ts64(&tp); - break; - case CLOCK_BOOTTIME: - ktime_get_boottime_ts64(&tp); - break; - default: - err = -EINVAL; - goto out; - } - - err = -ERANGE; - - if (off->val.tv_sec > KTIME_SEC_MAX || - off->val.tv_sec < -KTIME_SEC_MAX) - goto out; - - tp = timespec64_add(tp, off->val); - /* - * KTIME_SEC_MAX is divided by 2 to be sure that KTIME_MAX is - * still unreachable. - */ - if (tp.tv_sec < 0 || tp.tv_sec > KTIME_SEC_MAX / 2) - goto out; - } - - mutex_lock(&offset_lock); - if (time_ns->frozen_offsets) { - err = -EACCES; - goto out_unlock; - } - - err = 0; - /* Don't report errors after this line */ - for (i = 0; i < noffsets; i++) { - struct proc_timens_offset *off = &offsets[i]; - struct timespec64 *offset = NULL; - - switch (off->clockid) { - case CLOCK_MONOTONIC: - offset = &time_ns->offsets.monotonic; - break; - case CLOCK_BOOTTIME: - offset = &time_ns->offsets.boottime; - break; - } - - *offset = off->val; - } - -out_unlock: - mutex_unlock(&offset_lock); -out: + err = timens_set_offset(p, time_ns, offsets, noffsets); put_time_ns(time_ns); return err; base-commit: 8b614cb8f1dcac8ca77cf4dd85f46ef3055f8238 -- 2.24.1
| |