All of lore.kernel.org
 help / color / mirror / Atom feed
From: Adrian Reber <areber@redhat.com>
To: Christian Brauner <christian.brauner@ubuntu.com>,
	Eric Biederman <ebiederm@xmission.com>,
	Pavel Emelyanov <ovzxemul@gmail.com>,
	Oleg Nesterov <oleg@redhat.com>,
	Dmitry Safonov <0x7f454c46@gmail.com>,
	Andrei Vagin <avagin@gmail.com>
Cc: linux-kernel@vger.kernel.org, Mike Rapoport <rppt@linux.ibm.com>,
	Radostin Stoyanov <rstoyanov1@gmail.com>,
	Adrian Reber <areber@redhat.com>,
	Michael Kerrisk <mtk.manpages@gmail.com>,
	Arnd Bergmann <arnd@arndb.de>,
	Cyrill Gorcunov <gorcunov@openvz.org>,
	Thomas Gleixner <tglx@linutronix.de>
Subject: [PATCH 1/4] ns: prepare time namespace for clone3()
Date: Tue, 17 Mar 2020 09:30:41 +0100	[thread overview]
Message-ID: <20200317083043.226593-2-areber@redhat.com> (raw)
In-Reply-To: <20200317083043.226593-1-areber@redhat.com>

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


  reply	other threads:[~2020-03-17  8:34 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-03-17  8:30 clone3: allow creation of time namespace with offset Adrian Reber
2020-03-17  8:30 ` Adrian Reber [this message]
2020-03-18 10:57   ` [PATCH 1/4] ns: prepare time namespace for clone3() Cyrill Gorcunov
2020-03-18 11:17     ` Christian Brauner
2020-03-18 11:28       ` Cyrill Gorcunov
2020-03-18 11:57         ` Christian Brauner
2020-03-18 11:58           ` Christian Brauner
2020-03-18 12:07             ` Cyrill Gorcunov
2020-03-17  8:30 ` [PATCH 2/4] clone3: allow creation of time namespace with offset Adrian Reber
2020-03-18 12:13   ` Christian Brauner
2020-03-17  8:30 ` [PATCH 3/4] clone3: align structs and comments Adrian Reber
2020-03-17  8:30 ` [PATCH 4/4] selftests: add clone3() in time namespace test Adrian Reber
2020-03-17  8:41 ` clone3: allow creation of time namespace with offset Christian Brauner
2020-03-17  8:43   ` Christian Brauner
2020-03-17  9:40 ` Michael Kerrisk (man-pages)
2020-03-17 14:23   ` Aleksa Sarai
2020-03-17 16:09     ` Christian Brauner
2020-03-18 10:18 ` Arnd Bergmann
2020-03-19  8:11   ` Adrian Reber
2020-03-19  8:16     ` Arnd Bergmann
2020-03-19 10:29       ` Christian Brauner
2020-03-20 18:33         ` Andrei Vagin
2020-03-24 16:09           ` Christian Brauner
2020-03-24 16:25             ` Adrian Reber
2020-03-24 17:56               ` Christian Brauner
2020-03-25  7:58                 ` Adrian Reber
2020-03-25 11:26                   ` Christian Brauner
2020-04-01 11:40                     ` Michael Kerrisk (man-pages)
2020-04-01 11:46                       ` Christian Brauner
2020-04-01 12:15                         ` Michael Kerrisk (man-pages)
2020-05-29 12:26 ` Michael Kerrisk (man-pages)
2020-05-29 15:10   ` Adrian Reber
2020-05-29 15:13     ` Christian Brauner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200317083043.226593-2-areber@redhat.com \
    --to=areber@redhat.com \
    --cc=0x7f454c46@gmail.com \
    --cc=arnd@arndb.de \
    --cc=avagin@gmail.com \
    --cc=christian.brauner@ubuntu.com \
    --cc=ebiederm@xmission.com \
    --cc=gorcunov@openvz.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mtk.manpages@gmail.com \
    --cc=oleg@redhat.com \
    --cc=ovzxemul@gmail.com \
    --cc=rppt@linux.ibm.com \
    --cc=rstoyanov1@gmail.com \
    --cc=tglx@linutronix.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.