Received: by 2002:a25:e7d8:0:0:0:0:0 with SMTP id e207csp3524551ybh; Tue, 17 Mar 2020 01:35:48 -0700 (PDT) X-Google-Smtp-Source: ADFU+vvdb6CpC/gqk/K1gA9ZNQoL3v03dsxewLsu3MYGLpE9YOWT1wcVNN3q8TZJhzesKJ2hNVTG X-Received: by 2002:a05:6830:23b6:: with SMTP id m22mr2726986ots.225.1584434148367; Tue, 17 Mar 2020 01:35:48 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1584434148; cv=none; d=google.com; s=arc-20160816; b=z7yTAXuPpy+cVaQVi2d2vNEwIAJozETOJjwC2/GHVlOEnTdaY6V9DnMv10SmfKwTGw JfuGhp/IyyJRuWuPVR3R6Hhu+LbvoFhhKVncHurikfekB0vp6G0Ulvi9EfrNyh/3TpyN 88GCDNa1g8V13iUQ9ohuT4a2W4cnho/F66brq1lRg117kcR6K8/5CfP3u+KmNz4HIAAQ VMX2yhY+7tBUOX0Gaetuz5I4pSAXE+P8zUNu/CyelyN1a+YeAEWXzbBTxDNkUMRhbA+k 9e6KVUWISegeIWC5mPdh1j5ufeZ8hrLF1ChtJRboRJHyphO9xGsmloYorJcm7dv4hvYQ PYfw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=7PSv8VeOYJuoOz6tIXCbXt0QkRfe/tTdz8LKpb1tyPY=; b=IOfmTP592zc2SCb8WJl/2oA0FYPsEF1Qkh91cVxeOF+oCO/oF3c1dhWHkRjeRo/ApJ 9l+CWtZ7CimWxfevdqeyTHUd99Qs15xHfVG/C+QZSclnh1ECENS0SutpAoCDPuno971c xO/HbBXLeLeChy+/QmjAIGWhai9TzDq8zguRjvQNdHHO+g+nR7PxtqPbua6JhAZsHphU rqCm0Ei/QeKmYcJ000V4TLEzCX5uG4HvTYOH6lnTIBwkh6aU2MpkE2Iq8t6X/Lwh+0N0 Ml3NBOzfBOQurWpQCqxYW8eV4TkixgODJzzR23EZeKttWtLwM/E/e0MvSb2zcSlFnAwM Dd1A== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NDfdJkOl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id k6si1406810otn.172.2020.03.17.01.35.36; Tue, 17 Mar 2020 01:35:48 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=NDfdJkOl; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726334AbgCQIeE (ORCPT + 99 others); Tue, 17 Mar 2020 04:34:04 -0400 Received: from us-smtp-delivery-74.mimecast.com ([216.205.24.74]:44932 "EHLO us-smtp-delivery-74.mimecast.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725995AbgCQIeE (ORCPT ); Tue, 17 Mar 2020 04:34:04 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1584434042; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7PSv8VeOYJuoOz6tIXCbXt0QkRfe/tTdz8LKpb1tyPY=; b=NDfdJkOlKHkVBYenoCUCehQHsqo/1kI25VPI17YGzA4KV0o/ch43WQI0eXBVJe2GGHjoFu ZgR5OGNiXnMlHHFd3IcK2IT7ny5XmunwkCBqER+X2AYhZzlzNviku9gy+pMDZ9g0gBsdTX 1xaZkbpxgh9PLhvBIH0cYu84F916WIc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-175-eMGhW-TZP5WTbc6WXXwR9A-1; Tue, 17 Mar 2020 04:32:38 -0400 X-MC-Unique: eMGhW-TZP5WTbc6WXXwR9A-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.phx2.redhat.com [10.5.11.12]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BABD48010C7; Tue, 17 Mar 2020 08:32:35 +0000 (UTC) Received: from dcbz.redhat.com (ovpn-112-179.ams2.redhat.com [10.36.112.179]) by smtp.corp.redhat.com (Postfix) with ESMTP id 2B49260BF3; Tue, 17 Mar 2020 08:32:33 +0000 (UTC) From: Adrian Reber To: Christian Brauner , Eric Biederman , Pavel Emelyanov , Oleg Nesterov , Dmitry Safonov <0x7f454c46@gmail.com>, Andrei Vagin Cc: linux-kernel@vger.kernel.org, Mike Rapoport , Radostin Stoyanov , Adrian Reber , Michael Kerrisk , Arnd Bergmann , Cyrill Gorcunov , Thomas Gleixner Subject: [PATCH 1/4] ns: prepare time namespace for clone3() Date: Tue, 17 Mar 2020 09:30:41 +0100 Message-Id: <20200317083043.226593-2-areber@redhat.com> In-Reply-To: <20200317083043.226593-1-areber@redhat.com> References: <20200317083043.226593-1-areber@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.12 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- 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 *fi= le, const char __user *buf, size_t count, loff_t *ppos) { struct inode *inode =3D file_inode(file); - struct proc_timens_offset offsets[2]; + struct set_timens_offset offsets[2]; char *kbuf =3D NULL, *pos, *next_line; struct task_struct *p; int ret, noffsets; @@ -1572,7 +1572,7 @@ static ssize_t timens_offsets_write(struct file *fi= le, const char __user *buf, ret =3D -EINVAL; noffsets =3D 0; for (pos =3D kbuf; pos; pos =3D next_line) { - struct proc_timens_offset *off =3D &offsets[noffsets]; + struct set_timens_offset *off =3D &offsets[noffsets]; int err; =20 /* 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_namespac= e.h index 824d54e057eb..fb4ca4402a2a 100644 --- a/include/linux/time_namespace.h +++ b/include/linux/time_namespace.h @@ -30,6 +30,15 @@ struct time_namespace { =20 extern struct time_namespace init_time_ns; =20 +/* + * 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) =20 void proc_timens_show_offsets(struct task_struct *p, struct seq_file *m)= ; =20 -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); =20 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, s= truct ns_common *new) return 0; } =20 +static int timens_set_offset(struct task_struct *p, struct time_namespac= e *ns, + struct set_timens_offset *offsets, int noffsets) +{ + struct timespec64 tp; + int i, err; + + for (i =3D 0; i < noffsets; i++) { + struct set_timens_offset *off =3D &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 =3D 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 =3D -EACCES; + goto out_unlock; + } + + err =3D 0; + /* Don't report errors after this line */ + for (i =3D 0; i < noffsets; i++) { + struct set_timens_offset *off =3D &offsets[i]; + struct timespec64 *offset =3D NULL; + + switch (off->clockid) { + case CLOCK_MONOTONIC: + offset =3D &ns->offsets.monotonic; + break; + case CLOCK_BOOTTIME: + offset =3D &ns->offsets.boottime; + break; + } + + *offset =3D 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 =3D &nsproxy->time_ns_for_children->ns; @@ -356,12 +419,11 @@ void proc_timens_show_offsets(struct task_struct *p= , struct seq_file *m) } =20 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; =20 ns =3D 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; } =20 - for (i =3D 0; i < noffsets; i++) { - struct proc_timens_offset *off =3D &offsets[i]; - - switch (off->clockid) { - case CLOCK_MONOTONIC: - ktime_get_ts64(&tp); - break; - case CLOCK_BOOTTIME: - ktime_get_boottime_ts64(&tp); - break; - default: - err =3D -EINVAL; - goto out; - } - - err =3D -ERANGE; - - if (off->val.tv_sec > KTIME_SEC_MAX || - off->val.tv_sec < -KTIME_SEC_MAX) - goto out; - - tp =3D 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 =3D -EACCES; - goto out_unlock; - } - - err =3D 0; - /* Don't report errors after this line */ - for (i =3D 0; i < noffsets; i++) { - struct proc_timens_offset *off =3D &offsets[i]; - struct timespec64 *offset =3D NULL; - - switch (off->clockid) { - case CLOCK_MONOTONIC: - offset =3D &time_ns->offsets.monotonic; - break; - case CLOCK_BOOTTIME: - offset =3D &time_ns->offsets.boottime; - break; - } - - *offset =3D off->val; - } - -out_unlock: - mutex_unlock(&offset_lock); -out: + err =3D timens_set_offset(p, time_ns, offsets, noffsets); put_time_ns(time_ns); =20 return err; base-commit: 8b614cb8f1dcac8ca77cf4dd85f46ef3055f8238 --=20 2.24.1