* [PATCH v2 3/5] nohz: cpu_isolated strict mode configurable signal
From: Chris Metcalf @ 2015-05-15 21:27 UTC (permalink / raw)
To: Gilad Ben Yossef, Steven Rostedt, Ingo Molnar, Peter Zijlstra,
Andrew Morton, Rik van Riel, Tejun Heo, Frederic Weisbecker,
Thomas Gleixner, Paul E. McKenney, Christoph Lameter,
Viresh Kumar, linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
Cc: Chris Metcalf
In-Reply-To: <1431725251-20943-1-git-send-email-cmetcalf-d5a29ZRxExrQT0dZR+AlfA@public.gmane.org>
Allow userspace to override the default SIGKILL delivered
when a cpu_isolated process in STRICT mode does a syscall
or otherwise synchronously enters the kernel.
In addition to being able to set the signal, we now also
pass whether or not the interruption was from a syscall in
the si_code field of the siginfo.
Signed-off-by: Chris Metcalf <cmetcalf-d5a29ZRxExrQT0dZR+AlfA@public.gmane.org>
---
include/uapi/linux/prctl.h | 2 ++
kernel/time/tick-sched.c | 15 +++++++++++----
2 files changed, 13 insertions(+), 4 deletions(-)
diff --git a/include/uapi/linux/prctl.h b/include/uapi/linux/prctl.h
index 0c11238a84fb..ab45bd3d5799 100644
--- a/include/uapi/linux/prctl.h
+++ b/include/uapi/linux/prctl.h
@@ -195,5 +195,7 @@ struct prctl_mm_map {
#define PR_GET_CPU_ISOLATED 48
# define PR_CPU_ISOLATED_ENABLE (1 << 0)
# define PR_CPU_ISOLATED_STRICT (1 << 1)
+# define PR_CPU_ISOLATED_SET_SIG(sig) (((sig) & 0x7f) << 8)
+# define PR_CPU_ISOLATED_GET_SIG(bits) (((bits) >> 8) & 0x7f)
#endif /* _LINUX_PRCTL_H */
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 273820cd484a..772be78f926c 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -441,11 +441,18 @@ void tick_nohz_cpu_isolated_enter(void)
}
}
-static void kill_cpu_isolated_strict_task(void)
+static void kill_cpu_isolated_strict_task(int is_syscall)
{
+ siginfo_t info = {};
+ int sig;
+
dump_stack();
current->cpu_isolated_flags &= ~PR_CPU_ISOLATED_ENABLE;
- send_sig(SIGKILL, current, 1);
+
+ sig = PR_CPU_ISOLATED_GET_SIG(current->cpu_isolated_flags) ?: SIGKILL;
+ info.si_signo = sig;
+ info.si_code = is_syscall;
+ send_sig_info(sig, &info, current);
}
/*
@@ -464,7 +471,7 @@ void tick_nohz_cpu_isolated_syscall(int syscall)
pr_warn("%s/%d: cpu_isolated strict mode violated by syscall %d\n",
current->comm, current->pid, syscall);
- kill_cpu_isolated_strict_task();
+ kill_cpu_isolated_strict_task(1);
}
/*
@@ -475,7 +482,7 @@ void tick_nohz_cpu_isolated_exception(void)
{
pr_warn("%s/%d: cpu_isolated strict mode violated by exception\n",
current->comm, current->pid);
- kill_cpu_isolated_strict_task();
+ kill_cpu_isolated_strict_task(0);
}
#endif
--
2.1.2
^ permalink raw reply related
* Re: [PATCH v2 1/5] nohz_full: add support for "cpu_isolated" mode
From: Thomas Gleixner @ 2015-05-15 22:17 UTC (permalink / raw)
To: Chris Metcalf
Cc: Gilad Ben Yossef, Steven Rostedt, Ingo Molnar, Peter Zijlstra,
Andrew Morton, Rik van Riel, Tejun Heo, Frederic Weisbecker,
Paul E. McKenney, Christoph Lameter, Viresh Kumar,
linux-doc-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1431725251-20943-1-git-send-email-cmetcalf-d5a29ZRxExrQT0dZR+AlfA@public.gmane.org>
On Fri, 15 May 2015, Chris Metcalf wrote:
> +/*
> + * We normally return immediately to userspace.
> + *
> + * In "cpu_isolated" mode we wait until no more interrupts are
> + * pending. Otherwise we nap with interrupts enabled and wait for the
> + * next interrupt to fire, then loop back and retry.
> + *
> + * Note that if you schedule two "cpu_isolated" processes on the same
> + * core, neither will ever leave the kernel, and one will have to be
> + * killed manually.
And why are we not preventing that situation in the first place? The
scheduler should be able to figure that out easily..
> + Otherwise in situations where another process is
> + * in the runqueue on this cpu, this task will just wait for that
> + * other task to go idle before returning to user space.
> + */
> +void tick_nohz_cpu_isolated_enter(void)
> +{
> + struct clock_event_device *dev =
> + __this_cpu_read(tick_cpu_device.evtdev);
> + struct task_struct *task = current;
> + unsigned long start = jiffies;
> + bool warned = false;
> +
> + /* Drain the pagevecs to avoid unnecessary IPI flushes later. */
> + lru_add_drain();
> +
> + while (ACCESS_ONCE(dev->next_event.tv64) != KTIME_MAX) {
What's the ACCESS_ONCE for?
> + if (!warned && (jiffies - start) >= (5 * HZ)) {
> + pr_warn("%s/%d: cpu %d: cpu_isolated task blocked for %ld jiffies\n",
> + task->comm, task->pid, smp_processor_id(),
> + (jiffies - start));
What additional value has the jiffies delta over a plain human
readable '5sec' ?
> + warned = true;
> + }
> + if (should_resched())
> + schedule();
> + if (test_thread_flag(TIF_SIGPENDING))
> + break;
> +
> + /* Idle with interrupts enabled and wait for the tick. */
> + set_current_state(TASK_INTERRUPTIBLE);
> + arch_cpu_idle();
Oh NO! Not another variant of fake idle task. The idle implementations
can call into code which rightfully expects that the CPU is actually
IDLE.
I wasted enough time already debugging the resulting wreckage. Feel
free to use it for experimental purposes, but this is not going
anywhere near to a mainline kernel.
I completely understand WHY you want to do that, but we need proper
mechanisms for that and not some duct tape engineering band aids which
will create hard to debug side effects.
Hint: It's a scheduler job to make sure that the machine has quiesced
_BEFORE_ letting the magic task off to user land.
> + set_current_state(TASK_RUNNING);
> + }
> + if (warned) {
> + pr_warn("%s/%d: cpu %d: cpu_isolated task unblocked after %ld jiffies\n",
> + task->comm, task->pid, smp_processor_id(),
> + (jiffies - start));
> + dump_stack();
And that dump_stack() tells us which important information?
tick_nohz_cpu_isolated_enter
context_tracking_enter
context_tracking_user_enter
arch_return_to_user_code
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH 13/19] y2038: add compat handling for sys_semtimedop
From: Thomas Gleixner @ 2015-05-15 22:46 UTC (permalink / raw)
To: Arnd Bergmann
Cc: y2038-cunTk1MwBs8s++Sfvej+rw, baolin.wang-QSEj5FYQhm4dnm+yROfE0A,
albert.aribaud-iEu9NFBzPZE, john.stultz-QSEj5FYQhm4dnm+yROfE0A,
bamvor.zhangjian-QSEj5FYQhm4dnm+yROfE0A,
ruchandani.tina-Re5JQEeQqe8AvxtiuMwx3w,
linux-api-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
libc-alpha-9JcytcrH/bA+uJoB2kUjGw
In-Reply-To: <1430929826-318934-14-git-send-email-arnd-r2nGTMty4D4@public.gmane.org>
On Wed, 6 May 2015, Arnd Bergmann wrote:
> +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
> + unsigned, nsops,
> + const struct __kernel_timespec __user *, timeout)
> +{
> + unsigned long jiffies_left = 0;
> +
> + if (timeout) {
> + struct timespec64 _timeout;
> + if (get_timespec64(&_timeout, timeout))
Moo. I had to look 3 times to get not confused by the extra
underscore. What's wrong with a proper variable name which is easy to
distinguish?
> + return -EFAULT;
> + if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
> + _timeout.tv_nsec >= 1000000000L)
> + return -EINVAL;
We have proper helper functions to validate time specs.
Thanks,
tglx
^ permalink raw reply
* Re: [PATCH 17/19] y2038: use __kernel_timespec in sys_futex
From: Thomas Gleixner @ 2015-05-15 22:53 UTC (permalink / raw)
To: Arnd Bergmann
Cc: y2038, baolin.wang, albert.aribaud, john.stultz, bamvor.zhangjian,
ruchandani.tina, linux-api, linux-kernel, libc-alpha
In-Reply-To: <1430929826-318934-18-git-send-email-arnd@arndb.de>
On Wed, 6 May 2015, Arnd Bergmann wrote:
> Conversion for sys_futex is particularly easy, we can use the unmodified
> compat_sys_futex on 32-bit systems to provide compatibility for 32-bit
> time_t, and change sys_futex to pass a __kernel_timespec, which matches
> what future libc implementations will use as their struct timespec.
Unless I'm missing something I doubt that you get away that easy. It
works on 32bit, but not on 64 bit with 32bit app support:
Native 64bit: sys_futex()
32bit timespec32: compat_sys_futex()
32bit timespec64: ?????
You cannot map that to sys_futex() because the pointer size differs.
Thanks,
tglx
^ permalink raw reply
* [CFT][PATCH 00/10] Making new mounts of proc and sysfs as safe as bind mounts (take 2)
From: Eric W. Biederman @ 2015-05-16 2:05 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel, Linux API, Serge E. Hallyn, Andy Lutomirski,
Richard Weinberger, Kenton Varda, Michael Kerrisk-manpages,
Stéphane Graber, Eric Windisch, Greg Kroah-Hartman,
Tejun Heo
In-Reply-To: <87pp63jcca.fsf@x220.int.ebiederm.org>
The code is currently available at:
git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace.git for-testing
HEAD: 513d98ba1adfa9e3178b6fc3b2fa57a622283d32 mnt: Update fs_fully_visible to test for permanently empty directories
The problem: Mounting a new instance of proc of sysfs can allow things
that a bind mount of those filesystems would not.
That is the cases I am dealing with are:
unshare --user --net --mount ; mount -t sysfs ...
unshare --user --pid --mount ; mount -t proc ...
This set of changes enforces the preservation of locked mount flags,
from the existing mount to the current mount. Which means that if proc
was mounted read-only the current current will allow a new instance of
proc to be mounted read-write, and this set of changes enforces that
proc remain read-only.
This set of changes also updates sysctl, proc and sysfs to explicitly
create the directories they expect to be mount points as mount points.
Making the code a little clearly and making it so when fs_fully_visible
disregards something mounted on a proc or sysfs it is guaranteed to
be safe, unlike the current code which can occassionally let things
fall through the cracks.
These changes to enforce the administrators policy can actually matter
in the real world as has been shown by the recent docker issue.
With this patchset I have two concerns:
- The enforcement of not being able to mount proc or sysfs with fewer
mount flags than the existing mount may break something.
- That there is a filesystem that that common mounts on proc or sysfs
and I missed annotating it's mount point. That would make mounting
a freshy copy of proc or sysfs impossible.
I don't want to break userspace if I can help it, and the code has been
this way for a while so I figure there is time to find any pitfalls and
address them before this code gets merged. Folks rom lxc, sandstorm,
libvirt-lxc (anyone who uses user namespaces in the least) a
confirmation that I have not broken your existing code would be
appreciated.
If this works for you please give me your Tested-By
Since the first version I have renamed the directory creation calls to
have sysfs_create_mount_point and proc_create_mount_point (as suggested
by Greg KH so that it is very clear what the code that creates those
mount points is doing. I have also fixed a stupid bug that slipped into
the proc code when I refactored it. I have also gone through and rested
everything so hopefully nothing has slipped past me.
The well known mountpoints for pseudo filesystems that I could find are:
/dev/ffs*/ functionfs
/dev/gadget/ gadgetfs
/dev/mqueue mqueue
/dev/oprofile/ oprofilefs
/dev/pts/ devpts
/dev/shm/ tmpfs
/dlm/ ocfs2_dlmfs
/ipath/ ipathfs
/proc/fs/nfsd/ nfsd
/proc/openprom/ openpromfs
/proc/sys/fs/binfmt_misc/ binfmt_misc
/spu/ spufs
/sys/firmware/efi/efivars/ efivarfs
/sys/fs/cgroup/ cgroup
/sys/fs/fuse/connections/ fusectl
/sys/fs/pstore/ pstore
/sys/fs/selinux/ selinuxfs
/sys/fs/smackfs/ smackfs
/sys/hypervisor/s390/ s390_hypfs
/sys/kernel/config/ configfs
/sys/kernel/debug/ debugfs
/sys/kernel/security/ securityfs
/sys/kernel/tracing/ tracefs
/var/lib/ibmasm/ ibmasmfs
/var/lib/nfs/rpc_pipefs/ rpc_pipefs
Eric W. Biederman (10):
mnt: Refactor the logic for mounting sysfs and proc in a user namespace
mnt: Modify fs_fully_visible to deal with mount attributes
vfs: Ignore unlocked mounts in fs_fully_visible
fs: Add helper functions for permanently empty directories.
sysctl: Allow creating permanently empty directories that serve as mountpoints.
proc: Allow creating permanently empty directories that serve as mount points
kernfs: Add support for always empty directories.
sysfs: Add support for permanently empty directories to serve as mount points.
sysfs: Create mountpoints with sysfs_create_mount_point
mnt: Update fs_fully_visible to test for permanently empty directories
arch/s390/hypfs/inode.c | 12 ++----
drivers/firmware/efi/efi.c | 6 +--
fs/configfs/mount.c | 10 ++---
fs/debugfs/inode.c | 11 ++---
fs/fuse/inode.c | 9 ++---
fs/kernfs/dir.c | 38 +++++++++++++++++-
fs/kernfs/inode.c | 2 +
fs/libfs.c | 96 ++++++++++++++++++++++++++++++++++++++++++++
fs/namespace.c | 47 +++++++++++++++++++---
fs/proc/generic.c | 23 +++++++++++
fs/proc/inode.c | 4 ++
fs/proc/internal.h | 6 +++
fs/proc/proc_sysctl.c | 37 +++++++++++++++++
fs/proc/root.c | 9 ++---
fs/pstore/inode.c | 12 ++----
fs/sysfs/dir.c | 34 ++++++++++++++++
fs/sysfs/mount.c | 5 +--
fs/tracefs/inode.c | 6 +--
include/linux/fs.h | 4 +-
include/linux/kernfs.h | 3 ++
include/linux/sysctl.h | 3 ++
include/linux/sysfs.h | 16 ++++++++
kernel/cgroup.c | 10 ++---
kernel/sysctl.c | 8 +---
security/inode.c | 10 ++---
security/selinux/selinuxfs.c | 11 +++--
security/smack/smackfs.c | 8 ++--
27 files changed, 350 insertions(+), 90 deletions(-)
Eric
^ permalink raw reply
* [CFT][PATCH 01/10] mnt: Refactor the logic for mounting sysfs and proc in a user namespace
From: Eric W. Biederman @ 2015-05-16 2:06 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Fresh mounts of proc and sysfs are a very special case that works very
much like a bind mount. Unfortunately the current structure can not
preserve the MNT_LOCK... mount flags. Therefore refactor the logic
into a form that can be modified to preserve those lock bits.
Add a new filesystem flag FS_USERNS_VISIBLE that requires some mount
of the filesystem be fully visible in the current mount namespace,
before the filesystem may be mounted.
Move the logic for calling fs_fully_visible from proc and sysfs into
fs/namespace.c where it has greater access to mount namespace state.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/namespace.c | 8 +++++++-
fs/proc/root.c | 5 +----
fs/sysfs/mount.c | 5 +----
include/linux/fs.h | 2 +-
4 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 1b9e11167bae..8e7edaf60fe1 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2332,6 +2332,8 @@ unlock:
return err;
}
+static bool fs_fully_visible(struct file_system_type *fs_type);
+
/*
* create a new mount for userspace and request it to be added into the
* namespace's tree
@@ -2363,6 +2365,10 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
flags |= MS_NODEV;
mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
}
+ if (type->fs_flags & FS_USERNS_VISIBLE) {
+ if (!fs_fully_visible(type))
+ return -EPERM;
+ }
}
mnt = vfs_kern_mount(type, flags, name, data);
@@ -3164,7 +3170,7 @@ bool current_chrooted(void)
return chrooted;
}
-bool fs_fully_visible(struct file_system_type *type)
+static bool fs_fully_visible(struct file_system_type *type)
{
struct mnt_namespace *ns = current->nsproxy->mnt_ns;
struct mount *mnt;
diff --git a/fs/proc/root.c b/fs/proc/root.c
index b7fa4bfe896a..64e1ab64bde6 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -112,9 +112,6 @@ static struct dentry *proc_mount(struct file_system_type *fs_type,
ns = task_active_pid_ns(current);
options = data;
- if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
- return ERR_PTR(-EPERM);
-
/* Does the mounter have privilege over the pid namespace? */
if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
return ERR_PTR(-EPERM);
@@ -159,7 +156,7 @@ static struct file_system_type proc_fs_type = {
.name = "proc",
.mount = proc_mount,
.kill_sb = proc_kill_sb,
- .fs_flags = FS_USERNS_MOUNT,
+ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
};
void __init proc_root_init(void)
diff --git a/fs/sysfs/mount.c b/fs/sysfs/mount.c
index 8a49486bf30c..1c6ac6fcee9f 100644
--- a/fs/sysfs/mount.c
+++ b/fs/sysfs/mount.c
@@ -31,9 +31,6 @@ static struct dentry *sysfs_mount(struct file_system_type *fs_type,
bool new_sb;
if (!(flags & MS_KERNMOUNT)) {
- if (!capable(CAP_SYS_ADMIN) && !fs_fully_visible(fs_type))
- return ERR_PTR(-EPERM);
-
if (!kobj_ns_current_may_mount(KOBJ_NS_TYPE_NET))
return ERR_PTR(-EPERM);
}
@@ -58,7 +55,7 @@ static struct file_system_type sysfs_fs_type = {
.name = "sysfs",
.mount = sysfs_mount,
.kill_sb = sysfs_kill_sb,
- .fs_flags = FS_USERNS_MOUNT,
+ .fs_flags = FS_USERNS_VISIBLE | FS_USERNS_MOUNT,
};
int __init sysfs_init(void)
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 35ec87e490b1..2d24eeb8e59c 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -1897,6 +1897,7 @@ struct file_system_type {
#define FS_HAS_SUBTYPE 4
#define FS_USERNS_MOUNT 8 /* Can be mounted by userns root */
#define FS_USERNS_DEV_MOUNT 16 /* A userns mount does not imply MNT_NODEV */
+#define FS_USERNS_VISIBLE 32 /* FS must already be visible */
#define FS_RENAME_DOES_D_MOVE 32768 /* FS will handle d_move() during rename() internally. */
struct dentry *(*mount) (struct file_system_type *, int,
const char *, void *);
@@ -1984,7 +1985,6 @@ extern int vfs_ustat(dev_t, struct kstatfs *);
extern int freeze_super(struct super_block *super);
extern int thaw_super(struct super_block *super);
extern bool our_mnt(struct vfsmount *mnt);
-extern bool fs_fully_visible(struct file_system_type *);
extern int current_umask(void);
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 02/10] mnt: Modify fs_fully_visible to deal with mount attributes
From: Eric W. Biederman @ 2015-05-16 2:06 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel, Linux API, Serge E. Hallyn, Andy Lutomirski,
Richard Weinberger, Kenton Varda, Michael Kerrisk,
Stéphane Graber, Eric Windisch, Greg Kroah-Hartman,
Tejun Heo
In-Reply-To: <87siaxuvik.fsf@x220.int.ebiederm.org>
Ignore an existing mount if it's locked attributes are less permissive
than the new mounts attributes.
On success ensure the new mount locks all of the same attributes as
the old mount.
Cc: stable@vger.kernel.org
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
fs/namespace.c | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 8e7edaf60fe1..fccee9924e8c 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -2332,7 +2332,7 @@ unlock:
return err;
}
-static bool fs_fully_visible(struct file_system_type *fs_type);
+static bool fs_fully_visible(struct file_system_type *fs_type, int *new_mnt_flags);
/*
* create a new mount for userspace and request it to be added into the
@@ -2366,7 +2366,7 @@ static int do_new_mount(struct path *path, const char *fstype, int flags,
mnt_flags |= MNT_NODEV | MNT_LOCK_NODEV;
}
if (type->fs_flags & FS_USERNS_VISIBLE) {
- if (!fs_fully_visible(type))
+ if (!fs_fully_visible(type, &mnt_flags))
return -EPERM;
}
}
@@ -3170,9 +3170,10 @@ bool current_chrooted(void)
return chrooted;
}
-static bool fs_fully_visible(struct file_system_type *type)
+static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
{
struct mnt_namespace *ns = current->nsproxy->mnt_ns;
+ int new_flags = *new_mnt_flags;
struct mount *mnt;
bool visible = false;
@@ -3191,6 +3192,25 @@ static bool fs_fully_visible(struct file_system_type *type)
if (mnt->mnt.mnt_root != mnt->mnt.mnt_sb->s_root)
continue;
+ /* Verify the mount flags are equal to or more permissive
+ * than the proposed new mount.
+ */
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_READONLY) &&
+ !(new_flags & MNT_READONLY))
+ continue;
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NODEV) &&
+ !(new_flags & MNT_NODEV))
+ continue;
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NOSUID) &&
+ !(new_flags & MNT_NOSUID))
+ continue;
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_NOEXEC) &&
+ !(new_flags & MNT_NOEXEC))
+ continue;
+ if ((mnt->mnt.mnt_flags & MNT_LOCK_ATIME) &&
+ ((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
+ continue;
+
/* This mount is not fully visible if there are any child mounts
* that cover anything except for empty directories.
*/
@@ -3201,6 +3221,12 @@ static bool fs_fully_visible(struct file_system_type *type)
if (inode->i_nlink > 2)
goto next;
}
+ /* Preserve the locked attributes */
+ *new_mnt_flags |= mnt->mnt.mnt_flags & (MNT_LOCK_READONLY | \
+ MNT_LOCK_NODEV | \
+ MNT_LOCK_NOSUID | \
+ MNT_LOCK_NOEXEC | \
+ MNT_LOCK_ATIME);
visible = true;
goto found;
next: ;
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 03/10] vfs: Ignore unlocked mounts in fs_fully_visible
From: Eric W. Biederman @ 2015-05-16 2:07 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Limit the mounts fs_fully_visible considers to locked mounts.
Unlocked can always be unmounted so considering them adds hassle
but no security benefit.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/namespace.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index fccee9924e8c..3ede0669b8d2 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3211,11 +3211,15 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
((mnt->mnt.mnt_flags & MNT_ATIME_MASK) != (new_flags & MNT_ATIME_MASK)))
continue;
- /* This mount is not fully visible if there are any child mounts
- * that cover anything except for empty directories.
+ /* This mount is not fully visible if there are any
+ * locked child mounts that cover anything except for
+ * empty directories.
*/
list_for_each_entry(child, &mnt->mnt_mounts, mnt_child) {
struct inode *inode = child->mnt_mountpoint->d_inode;
+ /* Only worry about locked mounts */
+ if (!(mnt->mnt.mnt_flags & MNT_LOCKED))
+ continue;
if (!S_ISDIR(inode->i_mode))
goto next;
if (inode->i_nlink > 2)
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 04/10] fs: Add helper functions for permanently empty directories.
From: Eric W. Biederman @ 2015-05-16 2:07 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
To ensure it is safe to mount proc and sysfs I need to check if
filesystems that are mounted on top of them are mounted on truly empty
directories. Given that some directories can gain entries over time,
knowing that a directory is empty right now is insufficient.
Therefore add supporting infrastructure for permantently empty
directories that proc and sysfs can use when they create mount points
for filesystems and fs_fully_visible can use to test for permanently
empty directories to ensure that nothing will be gained by mounting a
fresh copy of proc or sysfs.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/libfs.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
include/linux/fs.h | 2 ++
2 files changed, 98 insertions(+)
diff --git a/fs/libfs.c b/fs/libfs.c
index cb1fb4b9b637..02813592e121 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -1093,3 +1093,99 @@ simple_nosetlease(struct file *filp, long arg, struct file_lock **flp,
return -EINVAL;
}
EXPORT_SYMBOL(simple_nosetlease);
+
+
+/*
+ * Operations for a permanently empty directory.
+ */
+static struct dentry *empty_dir_lookup(struct inode *dir, struct dentry *dentry, unsigned int flags)
+{
+ return ERR_PTR(-ENOENT);
+}
+
+static int empty_dir_getattr(struct vfsmount *mnt, struct dentry *dentry,
+ struct kstat *stat)
+{
+ struct inode *inode = d_inode(dentry);
+ generic_fillattr(inode, stat);
+ return 0;
+}
+
+static int empty_dir_setattr(struct dentry *dentry, struct iattr *attr)
+{
+ return -EPERM;
+}
+
+static int empty_dir_setxattr(struct dentry *dentry, const char *name,
+ const void *value, size_t size, int flags)
+{
+ return -EOPNOTSUPP;
+}
+
+static ssize_t empty_dir_getxattr(struct dentry *dentry, const char *name,
+ void *value, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static int empty_dir_removexattr(struct dentry *dentry, const char *name)
+{
+ return -EOPNOTSUPP;
+}
+
+static ssize_t empty_dir_listxattr(struct dentry *dentry, char *list, size_t size)
+{
+ return -EOPNOTSUPP;
+}
+
+static const struct inode_operations empty_dir_inode_operations = {
+ .lookup = empty_dir_lookup,
+ .permission = generic_permission,
+ .setattr = empty_dir_setattr,
+ .getattr = empty_dir_getattr,
+ .setxattr = empty_dir_setxattr,
+ .getxattr = empty_dir_getxattr,
+ .removexattr = empty_dir_removexattr,
+ .listxattr = empty_dir_listxattr,
+};
+
+static loff_t empty_dir_llseek(struct file *file, loff_t offset, int whence)
+{
+ /* An empty directory has two entries . and .. at offsets 0 and 1 */
+ return generic_file_llseek_size(file, offset, whence, 2, 2);
+}
+
+static int empty_dir_readdir(struct file *file, struct dir_context *ctx)
+{
+ dir_emit_dots(file, ctx);
+ return 0;
+}
+
+static const struct file_operations empty_dir_operations = {
+ .llseek = empty_dir_llseek,
+ .read = generic_read_dir,
+ .iterate = empty_dir_readdir,
+ .fsync = noop_fsync,
+};
+
+
+void make_empty_dir_inode(struct inode *inode)
+{
+ set_nlink(inode, 2);
+ inode->i_mode = S_IFDIR | S_IRUGO | S_IXUGO;
+ inode->i_uid = GLOBAL_ROOT_UID;
+ inode->i_gid = GLOBAL_ROOT_GID;
+ inode->i_rdev = 0;
+ inode->i_size = 2;
+ inode->i_blkbits = PAGE_SHIFT;
+ inode->i_blocks = 0;
+
+ inode->i_op = &empty_dir_inode_operations;
+ inode->i_fop = &empty_dir_operations;
+}
+
+bool is_empty_dir_inode(struct inode *inode)
+{
+ return (inode->i_fop == &empty_dir_operations) &&
+ (inode->i_op == &empty_dir_inode_operations);
+}
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2d24eeb8e59c..571aab91bfc0 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -2780,6 +2780,8 @@ extern struct dentry *simple_lookup(struct inode *, struct dentry *, unsigned in
extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
extern const struct file_operations simple_dir_operations;
extern const struct inode_operations simple_dir_inode_operations;
+extern void make_empty_dir_inode(struct inode *inode);
+extern bool is_empty_dir_inode(struct inode *inode);
struct tree_descr { char *name; const struct file_operations *ops; int mode; };
struct dentry *d_alloc_name(struct dentry *, const char *);
extern int simple_fill_super(struct super_block *, unsigned long, struct tree_descr *);
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 05/10] sysctl: Allow creating permanently empty directories that serve as mountpoints.
From: Eric W. Biederman @ 2015-05-16 2:08 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Add a magic sysctl table sysctl_mount_point that when used to
create a directory forces that directory to be permanently empty.
Update the code to use make_empty_dir_inode when accessing permanently
empty directories.
Update the code to not allow adding to permanently empty directories.
Update /proc/sys/fs/binfmt_misc to be a permanently empty directory.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/proc/proc_sysctl.c | 37 +++++++++++++++++++++++++++++++++++++
include/linux/sysctl.h | 3 +++
kernel/sysctl.c | 8 +-------
3 files changed, 41 insertions(+), 7 deletions(-)
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c
index fea2561d773b..fdda62e6115e 100644
--- a/fs/proc/proc_sysctl.c
+++ b/fs/proc/proc_sysctl.c
@@ -19,6 +19,28 @@ static const struct inode_operations proc_sys_inode_operations;
static const struct file_operations proc_sys_dir_file_operations;
static const struct inode_operations proc_sys_dir_operations;
+/* Support for permanently empty directories */
+
+struct ctl_table sysctl_mount_point[] = {
+ { }
+};
+
+static bool is_empty_dir(struct ctl_table_header *head)
+{
+ return head->ctl_table[0].child == sysctl_mount_point;
+}
+
+static void set_empty_dir(struct ctl_dir *dir)
+{
+ dir->header.ctl_table[0].child = sysctl_mount_point;
+}
+
+static void clear_empty_dir(struct ctl_dir *dir)
+
+{
+ dir->header.ctl_table[0].child = NULL;
+}
+
void proc_sys_poll_notify(struct ctl_table_poll *poll)
{
if (!poll)
@@ -187,6 +209,17 @@ static int insert_header(struct ctl_dir *dir, struct ctl_table_header *header)
struct ctl_table *entry;
int err;
+ /* Is this a permanently empty directory? */
+ if (is_empty_dir(&dir->header))
+ return -EROFS;
+
+ /* Am I creating a permanently empty directory? */
+ if (header->ctl_table == sysctl_mount_point) {
+ if (!RB_EMPTY_ROOT(&dir->root))
+ return -EINVAL;
+ set_empty_dir(dir);
+ }
+
dir->header.nreg++;
header->parent = dir;
err = insert_links(header);
@@ -202,6 +235,8 @@ fail:
erase_header(header);
put_links(header);
fail_links:
+ if (header->ctl_table == sysctl_mount_point)
+ clear_empty_dir(dir);
header->parent = NULL;
drop_sysctl_table(&dir->header);
return err;
@@ -419,6 +454,8 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
inode->i_mode |= S_IFDIR;
inode->i_op = &proc_sys_dir_operations;
inode->i_fop = &proc_sys_dir_file_operations;
+ if (is_empty_dir(head))
+ make_empty_dir_inode(inode);
}
out:
return inode;
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
index 795d5fea5697..fa7bc29925c9 100644
--- a/include/linux/sysctl.h
+++ b/include/linux/sysctl.h
@@ -188,6 +188,9 @@ struct ctl_table_header *register_sysctl_paths(const struct ctl_path *path,
void unregister_sysctl_table(struct ctl_table_header * table);
extern int sysctl_init(void);
+
+extern struct ctl_table sysctl_mount_point[];
+
#else /* CONFIG_SYSCTL */
static inline struct ctl_table_header *register_sysctl_table(struct ctl_table * table)
{
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index 2082b1a88fb9..c3eee4c6d6c1 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -1531,12 +1531,6 @@ static struct ctl_table vm_table[] = {
{ }
};
-#if defined(CONFIG_BINFMT_MISC) || defined(CONFIG_BINFMT_MISC_MODULE)
-static struct ctl_table binfmt_misc_table[] = {
- { }
-};
-#endif
-
static struct ctl_table fs_table[] = {
{
.procname = "inode-nr",
@@ -1690,7 +1684,7 @@ static struct ctl_table fs_table[] = {
{
.procname = "binfmt_misc",
.mode = 0555,
- .child = binfmt_misc_table,
+ .child = sysctl_mount_point,
},
#endif
{
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 06/10] proc: Allow creating permanently empty directories that serve as mount points
From: Eric W. Biederman @ 2015-05-16 2:08 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Add a new function proc_create_mount_point that when used to creates a
directory that can not be added to.
Add a new function is_empty_pde to test if a function is a mount
point.
Update the code to use make_empty_dir_inode when reporting
a permanently empty directory to the vfs.
Update the code to not allow adding to permanently empty directories.
Update /proc/openprom and /proc/fs/nfsd to be permanently empty directories.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/proc/generic.c | 23 +++++++++++++++++++++++
fs/proc/inode.c | 4 ++++
fs/proc/internal.h | 6 ++++++
fs/proc/root.c | 4 ++--
4 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index df6327a2b865..e5dee5c3188e 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -373,6 +373,10 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
WARN(1, "create '/proc/%s' by hand\n", qstr.name);
return NULL;
}
+ if (is_empty_pde(*parent)) {
+ WARN(1, "attempt to add to permanently empty directory");
+ return NULL;
+ }
ent = kzalloc(sizeof(struct proc_dir_entry) + qstr.len + 1, GFP_KERNEL);
if (!ent)
@@ -455,6 +459,25 @@ struct proc_dir_entry *proc_mkdir(const char *name,
}
EXPORT_SYMBOL(proc_mkdir);
+struct proc_dir_entry *proc_create_mount_point(const char *name)
+{
+ umode_t mode = S_IFDIR | S_IRUGO | S_IXUGO;
+ struct proc_dir_entry *ent, *parent = NULL;
+
+ ent = __proc_create(&parent, name, mode, 2);
+ if (ent) {
+ ent->data = NULL;
+ ent->proc_fops = NULL;
+ ent->proc_iops = NULL;
+ if (proc_register(parent, ent) < 0) {
+ kfree(ent);
+ parent->nlink--;
+ ent = NULL;
+ }
+ }
+ return ent;
+}
+
struct proc_dir_entry *proc_create_data(const char *name, umode_t mode,
struct proc_dir_entry *parent,
const struct file_operations *proc_fops,
diff --git a/fs/proc/inode.c b/fs/proc/inode.c
index 8272aaba1bb0..e3eb5524639f 100644
--- a/fs/proc/inode.c
+++ b/fs/proc/inode.c
@@ -423,6 +423,10 @@ struct inode *proc_get_inode(struct super_block *sb, struct proc_dir_entry *de)
inode->i_mtime = inode->i_atime = inode->i_ctime = CURRENT_TIME;
PROC_I(inode)->pde = de;
+ if (is_empty_pde(de)) {
+ make_empty_dir_inode(inode);
+ return inode;
+ }
if (de->mode) {
inode->i_mode = de->mode;
inode->i_uid = de->uid;
diff --git a/fs/proc/internal.h b/fs/proc/internal.h
index c835b94c0cd3..aa2781095bd1 100644
--- a/fs/proc/internal.h
+++ b/fs/proc/internal.h
@@ -191,6 +191,12 @@ static inline struct proc_dir_entry *pde_get(struct proc_dir_entry *pde)
}
extern void pde_put(struct proc_dir_entry *);
+static inline bool is_empty_pde(const struct proc_dir_entry *pde)
+{
+ return S_ISDIR(pde->mode) && !pde->proc_iops;
+}
+struct proc_dir_entry *proc_create_mount_point(const char *name);
+
/*
* inode.c
*/
diff --git a/fs/proc/root.c b/fs/proc/root.c
index 64e1ab64bde6..68feb0f70e63 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -179,10 +179,10 @@ void __init proc_root_init(void)
#endif
proc_mkdir("fs", NULL);
proc_mkdir("driver", NULL);
- proc_mkdir("fs/nfsd", NULL); /* somewhere for the nfsd filesystem to be mounted */
+ proc_create_mount_point("fs/nfsd"); /* somewhere for the nfsd filesystem to be mounted */
#if defined(CONFIG_SUN_OPENPROMFS) || defined(CONFIG_SUN_OPENPROMFS_MODULE)
/* just give it a mountpoint */
- proc_mkdir("openprom", NULL);
+ proc_create_mount_point("openprom");
#endif
proc_tty_init();
proc_mkdir("bus", NULL);
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 07/10] kernfs: Add support for always empty directories.
From: Eric W. Biederman @ 2015-05-16 2:09 UTC (permalink / raw)
To: Linux Containers
Cc: Linux API, Greg Kroah-Hartman, Andy Lutomirski, Kenton Varda,
Michael Kerrisk-manpages, Richard Weinberger,
linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Add a new function kernfs_create_empty_dir that can be used to create
directory that can not be modified.
Update the code to use make_empty_dir_inode when reporting a
permanently empty directory to the vfs.
Update the code to not allow adding to permanently empty directories.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/kernfs/dir.c | 38 +++++++++++++++++++++++++++++++++++++-
fs/kernfs/inode.c | 2 ++
include/linux/kernfs.h | 3 +++
3 files changed, 42 insertions(+), 1 deletion(-)
diff --git a/fs/kernfs/dir.c b/fs/kernfs/dir.c
index f131fc23ffc4..47dc636d80ed 100644
--- a/fs/kernfs/dir.c
+++ b/fs/kernfs/dir.c
@@ -585,6 +585,9 @@ int kernfs_add_one(struct kernfs_node *kn)
goto out_unlock;
ret = -ENOENT;
+ if (parent->flags & KERNFS_EMPTY_DIR)
+ goto out_unlock;
+
if ((parent->flags & KERNFS_ACTIVATED) && !kernfs_active(parent))
goto out_unlock;
@@ -776,6 +779,38 @@ struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
return ERR_PTR(rc);
}
+/**
+ * kernfs_create_empty_dir - create an always empty directory
+ * @parent: parent in which to create a new directory
+ * @name: name of the new directory
+ *
+ * Returns the created node on success, ERR_PTR() value on failure.
+ */
+struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
+ const char *name)
+{
+ struct kernfs_node *kn;
+ int rc;
+
+ /* allocate */
+ kn = kernfs_new_node(parent, name, S_IRUGO|S_IXUGO|S_IFDIR, KERNFS_DIR);
+ if (!kn)
+ return ERR_PTR(-ENOMEM);
+
+ kn->flags |= KERNFS_EMPTY_DIR;
+ kn->dir.root = parent->dir.root;
+ kn->ns = NULL;
+ kn->priv = NULL;
+
+ /* link in */
+ rc = kernfs_add_one(kn);
+ if (!rc)
+ return kn;
+
+ kernfs_put(kn);
+ return ERR_PTR(rc);
+}
+
static struct dentry *kernfs_iop_lookup(struct inode *dir,
struct dentry *dentry,
unsigned int flags)
@@ -1247,7 +1282,8 @@ int kernfs_rename_ns(struct kernfs_node *kn, struct kernfs_node *new_parent,
mutex_lock(&kernfs_mutex);
error = -ENOENT;
- if (!kernfs_active(kn) || !kernfs_active(new_parent))
+ if (!kernfs_active(kn) || !kernfs_active(new_parent) ||
+ (new_parent->flags & KERNFS_EMPTY_DIR))
goto out;
error = 0;
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index 2da8493a380b..756dd56aaf60 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -296,6 +296,8 @@ static void kernfs_init_inode(struct kernfs_node *kn, struct inode *inode)
case KERNFS_DIR:
inode->i_op = &kernfs_dir_iops;
inode->i_fop = &kernfs_dir_fops;
+ if (kn->flags & KERNFS_EMPTY_DIR)
+ make_empty_dir_inode(inode);
break;
case KERNFS_FILE:
inode->i_size = kn->attr.size;
diff --git a/include/linux/kernfs.h b/include/linux/kernfs.h
index 71ecdab1671b..29d1896c3ba5 100644
--- a/include/linux/kernfs.h
+++ b/include/linux/kernfs.h
@@ -45,6 +45,7 @@ enum kernfs_node_flag {
KERNFS_LOCKDEP = 0x0100,
KERNFS_SUICIDAL = 0x0400,
KERNFS_SUICIDED = 0x0800,
+ KERNFS_EMPTY_DIR = 0x1000,
};
/* @flags for kernfs_create_root() */
@@ -285,6 +286,8 @@ void kernfs_destroy_root(struct kernfs_root *root);
struct kernfs_node *kernfs_create_dir_ns(struct kernfs_node *parent,
const char *name, umode_t mode,
void *priv, const void *ns);
+struct kernfs_node *kernfs_create_empty_dir(struct kernfs_node *parent,
+ const char *name);
struct kernfs_node *__kernfs_create_file(struct kernfs_node *parent,
const char *name,
umode_t mode, loff_t size,
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 08/10] sysfs: Add support for permanently empty directories to serve as mount points.
From: Eric W. Biederman @ 2015-05-16 2:09 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
Add two functions sysfs_create_mount_point and sysfs_remove_mount_point
that hang a permanently empty directory off of a kobject or remove a
permanently emptpy directory hanging from a kobject. Export these new
functions so modular filesystems can use them.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/sysfs/dir.c | 34 ++++++++++++++++++++++++++++++++++
include/linux/sysfs.h | 16 ++++++++++++++++
2 files changed, 50 insertions(+)
diff --git a/fs/sysfs/dir.c b/fs/sysfs/dir.c
index 0b45ff42f374..94374e435025 100644
--- a/fs/sysfs/dir.c
+++ b/fs/sysfs/dir.c
@@ -121,3 +121,37 @@ int sysfs_move_dir_ns(struct kobject *kobj, struct kobject *new_parent_kobj,
return kernfs_rename_ns(kn, new_parent, kn->name, new_ns);
}
+
+/**
+ * sysfs_create_mount_point - create an always empty directory
+ * @parent_kobj: kobject that will contain this always empty directory
+ * @name: The name of the always empty directory to add
+ */
+int sysfs_create_mount_point(struct kobject *parent_kobj, const char *name)
+{
+ struct kernfs_node *kn, *parent = parent_kobj->sd;
+
+ kn = kernfs_create_empty_dir(parent, name);
+ if (IS_ERR(kn)) {
+ if (PTR_ERR(kn) == -EEXIST)
+ sysfs_warn_dup(parent, name);
+ return PTR_ERR(kn);
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(sysfs_create_mount_point);
+
+/**
+ * sysfs_remove_mount_point - remove an always empty directory.
+ * @parent_kobj: kobject that will contain this always empty directory
+ * @name: The name of the always empty directory to remove
+ *
+ */
+void sysfs_remove_mount_point(struct kobject *parent_kobj, const char *name)
+{
+ struct kernfs_node *parent = parent_kobj->sd;
+
+ kernfs_remove_by_name_ns(parent, name, NULL);
+}
+EXPORT_SYMBOL_GPL(sysfs_remove_mount_point);
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 99382c0df17e..3e7e41acc451 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -210,6 +210,10 @@ int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
int __must_check sysfs_move_dir_ns(struct kobject *kobj,
struct kobject *new_parent_kobj,
const void *new_ns);
+int __must_check sysfs_create_mount_point(struct kobject *parent_kobj,
+ const char *name);
+void sysfs_remove_mount_point(struct kobject *parent_kobj,
+ const char *name);
int __must_check sysfs_create_file_ns(struct kobject *kobj,
const struct attribute *attr,
@@ -298,6 +302,18 @@ static inline int sysfs_move_dir_ns(struct kobject *kobj,
return 0;
}
+static inline int sysfs_create_mount_point(struct kobject *parent_kobj,
+ const char *name)
+{
+ return 0;
+}
+
+static inline void sysfs_remove_mount_point(struct kobject *parent_kobj,
+ const char *name)
+{
+ return 0;
+}
+
static inline int sysfs_create_file_ns(struct kobject *kobj,
const struct attribute *attr,
const void *ns)
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 09/10] sysfs: Create mountpoints with sysfs_create_mount_point
From: Eric W. Biederman @ 2015-05-16 2:10 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
This allows for better documentation in the code and
it allows for a simpler and fully correct version of
fs_fully_visible to be written.
The mount points converted and their filesystems are:
/sys/hypervisor/s390/ s390_hypfs
/sys/kernel/config/ configfs
/sys/kernel/debug/ debugfs
/sys/firmware/efi/efivars/ efivarfs
/sys/fs/fuse/connections/ fusectl
/sys/fs/pstore/ pstore
/sys/kernel/tracing/ tracefs
/sys/fs/cgroup/ cgroup
/sys/kernel/security/ securityfs
/sys/fs/selinux/ selinuxfs
/sys/fs/smackfs/ smackfs
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
arch/s390/hypfs/inode.c | 12 ++++--------
drivers/firmware/efi/efi.c | 6 ++----
fs/configfs/mount.c | 10 ++++------
fs/debugfs/inode.c | 11 ++++-------
fs/fuse/inode.c | 9 +++------
fs/pstore/inode.c | 12 ++++--------
fs/tracefs/inode.c | 6 ++----
kernel/cgroup.c | 10 ++++------
security/inode.c | 10 ++++------
security/selinux/selinuxfs.c | 11 +++++------
security/smack/smackfs.c | 8 ++++----
11 files changed, 40 insertions(+), 65 deletions(-)
diff --git a/arch/s390/hypfs/inode.c b/arch/s390/hypfs/inode.c
index d3f896a35b98..2eeb0a0f506d 100644
--- a/arch/s390/hypfs/inode.c
+++ b/arch/s390/hypfs/inode.c
@@ -456,8 +456,6 @@ static const struct super_operations hypfs_s_ops = {
.show_options = hypfs_show_options,
};
-static struct kobject *s390_kobj;
-
static int __init hypfs_init(void)
{
int rc;
@@ -481,18 +479,16 @@ static int __init hypfs_init(void)
rc = -ENODATA;
goto fail_hypfs_sprp_exit;
}
- s390_kobj = kobject_create_and_add("s390", hypervisor_kobj);
- if (!s390_kobj) {
- rc = -ENOMEM;
+ rc = sysfs_create_mount_point(hypervisor_kobj, "s390");
+ if (rc)
goto fail_hypfs_diag0c_exit;
- }
rc = register_filesystem(&hypfs_type);
if (rc)
goto fail_filesystem;
return 0;
fail_filesystem:
- kobject_put(s390_kobj);
+ sysfs_remove_mount_point(hypervisor_kobj, "s390");
fail_hypfs_diag0c_exit:
hypfs_diag0c_exit();
fail_hypfs_sprp_exit:
@@ -510,7 +506,7 @@ fail_dbfs_exit:
static void __exit hypfs_exit(void)
{
unregister_filesystem(&hypfs_type);
- kobject_put(s390_kobj);
+ sysfs_remove_mount_point(hypervisor_kobj, "s390");
hypfs_diag0c_exit();
hypfs_sprp_exit();
hypfs_vm_exit();
diff --git a/drivers/firmware/efi/efi.c b/drivers/firmware/efi/efi.c
index 3061bb8629dc..e14363d12690 100644
--- a/drivers/firmware/efi/efi.c
+++ b/drivers/firmware/efi/efi.c
@@ -65,7 +65,6 @@ static int __init parse_efi_cmdline(char *str)
early_param("efi", parse_efi_cmdline);
static struct kobject *efi_kobj;
-static struct kobject *efivars_kobj;
/*
* Let's not leave out systab information that snuck into
@@ -212,10 +211,9 @@ static int __init efisubsys_init(void)
goto err_remove_group;
/* and the standard mountpoint for efivarfs */
- efivars_kobj = kobject_create_and_add("efivars", efi_kobj);
- if (!efivars_kobj) {
+ error = sysfs_create_mount_point(efi_kobj, "efivars");
+ if (error) {
pr_err("efivars: Subsystem registration failed.\n");
- error = -ENOMEM;
goto err_remove_group;
}
diff --git a/fs/configfs/mount.c b/fs/configfs/mount.c
index da94e41bdbf6..bca58da65e2b 100644
--- a/fs/configfs/mount.c
+++ b/fs/configfs/mount.c
@@ -129,8 +129,6 @@ void configfs_release_fs(void)
}
-static struct kobject *config_kobj;
-
static int __init configfs_init(void)
{
int err = -ENOMEM;
@@ -141,8 +139,8 @@ static int __init configfs_init(void)
if (!configfs_dir_cachep)
goto out;
- config_kobj = kobject_create_and_add("config", kernel_kobj);
- if (!config_kobj)
+ err = sysfs_create_mount_point(kernel_kobj, "config");
+ if (err)
goto out2;
err = register_filesystem(&configfs_fs_type);
@@ -152,7 +150,7 @@ static int __init configfs_init(void)
return 0;
out3:
pr_err("Unable to register filesystem!\n");
- kobject_put(config_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "config");
out2:
kmem_cache_destroy(configfs_dir_cachep);
configfs_dir_cachep = NULL;
@@ -163,7 +161,7 @@ out:
static void __exit configfs_exit(void)
{
unregister_filesystem(&configfs_fs_type);
- kobject_put(config_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "config");
kmem_cache_destroy(configfs_dir_cachep);
configfs_dir_cachep = NULL;
}
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index c1e7ffb0dab6..12756040ca20 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -716,20 +716,17 @@ bool debugfs_initialized(void)
}
EXPORT_SYMBOL_GPL(debugfs_initialized);
-
-static struct kobject *debug_kobj;
-
static int __init debugfs_init(void)
{
int retval;
- debug_kobj = kobject_create_and_add("debug", kernel_kobj);
- if (!debug_kobj)
- return -EINVAL;
+ retval = sysfs_create_mount_point(kernel_kobj, "debug");
+ if (retval)
+ return retval;
retval = register_filesystem(&debug_fs_type);
if (retval)
- kobject_put(debug_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "debug");
else
debugfs_registered = true;
diff --git a/fs/fuse/inode.c b/fs/fuse/inode.c
index 082ac1c97f39..18dacf9ed8ff 100644
--- a/fs/fuse/inode.c
+++ b/fs/fuse/inode.c
@@ -1238,7 +1238,6 @@ static void fuse_fs_cleanup(void)
}
static struct kobject *fuse_kobj;
-static struct kobject *connections_kobj;
static int fuse_sysfs_init(void)
{
@@ -1250,11 +1249,9 @@ static int fuse_sysfs_init(void)
goto out_err;
}
- connections_kobj = kobject_create_and_add("connections", fuse_kobj);
- if (!connections_kobj) {
- err = -ENOMEM;
+ err = sysfs_create_mount_point(fuse_kobj, "connections");
+ if (err)
goto out_fuse_unregister;
- }
return 0;
@@ -1266,7 +1263,7 @@ static int fuse_sysfs_init(void)
static void fuse_sysfs_cleanup(void)
{
- kobject_put(connections_kobj);
+ sysfs_remove_mount_point(fuse_kobj, "connections");
kobject_put(fuse_kobj);
}
diff --git a/fs/pstore/inode.c b/fs/pstore/inode.c
index dc43b5f29305..3adcc4669fac 100644
--- a/fs/pstore/inode.c
+++ b/fs/pstore/inode.c
@@ -461,22 +461,18 @@ static struct file_system_type pstore_fs_type = {
.kill_sb = pstore_kill_sb,
};
-static struct kobject *pstore_kobj;
-
static int __init init_pstore_fs(void)
{
- int err = 0;
+ int err;
/* Create a convenient mount point for people to access pstore */
- pstore_kobj = kobject_create_and_add("pstore", fs_kobj);
- if (!pstore_kobj) {
- err = -ENOMEM;
+ err = sysfs_create_mount_point(fs_kobj, "pstore");
+ if (err)
goto out;
- }
err = register_filesystem(&pstore_fs_type);
if (err < 0)
- kobject_put(pstore_kobj);
+ sysfs_remove_mount_point(fs_kobj, "pstore");
out:
return err;
diff --git a/fs/tracefs/inode.c b/fs/tracefs/inode.c
index d92bdf3b079a..a43df11a163f 100644
--- a/fs/tracefs/inode.c
+++ b/fs/tracefs/inode.c
@@ -631,14 +631,12 @@ bool tracefs_initialized(void)
return tracefs_registered;
}
-static struct kobject *trace_kobj;
-
static int __init tracefs_init(void)
{
int retval;
- trace_kobj = kobject_create_and_add("tracing", kernel_kobj);
- if (!trace_kobj)
+ retval = sysfs_create_mount_point(kernel_kobj, "tracing");
+ if (retval)
return -EINVAL;
retval = register_filesystem(&trace_fs_type);
diff --git a/kernel/cgroup.c b/kernel/cgroup.c
index 469dd547770c..e8a5491be756 100644
--- a/kernel/cgroup.c
+++ b/kernel/cgroup.c
@@ -1924,8 +1924,6 @@ static struct file_system_type cgroup_fs_type = {
.kill_sb = cgroup_kill_sb,
};
-static struct kobject *cgroup_kobj;
-
/**
* task_cgroup_path - cgroup path of a task in the first cgroup hierarchy
* @task: target task
@@ -5044,13 +5042,13 @@ int __init cgroup_init(void)
ss->bind(init_css_set.subsys[ssid]);
}
- cgroup_kobj = kobject_create_and_add("cgroup", fs_kobj);
- if (!cgroup_kobj)
- return -ENOMEM;
+ err = sysfs_create_mount_point(fs_kobj, "cgroup");
+ if (err)
+ return err;
err = register_filesystem(&cgroup_fs_type);
if (err < 0) {
- kobject_put(cgroup_kobj);
+ sysfs_remove_mount_point(fs_kobj, "cgroup");
return err;
}
diff --git a/security/inode.c b/security/inode.c
index 91503b79c5f8..0e37e4fba8fa 100644
--- a/security/inode.c
+++ b/security/inode.c
@@ -215,19 +215,17 @@ void securityfs_remove(struct dentry *dentry)
}
EXPORT_SYMBOL_GPL(securityfs_remove);
-static struct kobject *security_kobj;
-
static int __init securityfs_init(void)
{
int retval;
- security_kobj = kobject_create_and_add("security", kernel_kobj);
- if (!security_kobj)
- return -EINVAL;
+ retval = sysfs_create_mount_point(kernel_kobj, "security");
+ if (retval)
+ return retval;
retval = register_filesystem(&fs_type);
if (retval)
- kobject_put(security_kobj);
+ sysfs_remove_mount_point(kernel_kobj, "security");
return retval;
}
diff --git a/security/selinux/selinuxfs.c b/security/selinux/selinuxfs.c
index d2787cca1fcb..3d2201413028 100644
--- a/security/selinux/selinuxfs.c
+++ b/security/selinux/selinuxfs.c
@@ -1853,7 +1853,6 @@ static struct file_system_type sel_fs_type = {
};
struct vfsmount *selinuxfs_mount;
-static struct kobject *selinuxfs_kobj;
static int __init init_sel_fs(void)
{
@@ -1862,13 +1861,13 @@ static int __init init_sel_fs(void)
if (!selinux_enabled)
return 0;
- selinuxfs_kobj = kobject_create_and_add("selinux", fs_kobj);
- if (!selinuxfs_kobj)
- return -ENOMEM;
+ err = sysfs_create_mount_point(fs_kobj, "selinux");
+ if (err)
+ return err;
err = register_filesystem(&sel_fs_type);
if (err) {
- kobject_put(selinuxfs_kobj);
+ sysfs_remove_mount_point(fs_kobj, "selinux");
return err;
}
@@ -1887,7 +1886,7 @@ __initcall(init_sel_fs);
#ifdef CONFIG_SECURITY_SELINUX_DISABLE
void exit_sel_fs(void)
{
- kobject_put(selinuxfs_kobj);
+ sysfs_remove_mount_point(fs_kobj, "selinux");
kern_unmount(selinuxfs_mount);
unregister_filesystem(&sel_fs_type);
}
diff --git a/security/smack/smackfs.c b/security/smack/smackfs.c
index d9682985349e..ac4cac7c661a 100644
--- a/security/smack/smackfs.c
+++ b/security/smack/smackfs.c
@@ -2241,16 +2241,16 @@ static const struct file_operations smk_revoke_subj_ops = {
.llseek = generic_file_llseek,
};
-static struct kset *smackfs_kset;
/**
* smk_init_sysfs - initialize /sys/fs/smackfs
*
*/
static int smk_init_sysfs(void)
{
- smackfs_kset = kset_create_and_add("smackfs", NULL, fs_kobj);
- if (!smackfs_kset)
- return -ENOMEM;
+ int err;
+ err = sysfs_create_mount_point(fs_kobj, "smackfs");
+ if (err)
+ return err;
return 0;
}
--
2.2.1
^ permalink raw reply related
* [CFT][PATCH 10/10] mnt: Update fs_fully_visible to test for permanently empty directories
From: Eric W. Biederman @ 2015-05-16 2:11 UTC (permalink / raw)
To: Linux Containers
Cc: linux-fsdevel-u79uwXL29TY76Z2rM5mHXA, Linux API, Serge E. Hallyn,
Andy Lutomirski, Richard Weinberger, Kenton Varda,
Michael Kerrisk-manpages, Stéphane Graber, Eric Windisch,
Greg Kroah-Hartman, Tejun Heo
In-Reply-To: <87siaxuvik.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
fs_fully_visible attempts to make fresh mounts of proc and sysfs give
the mounter no more access to proc and sysfs than if they could have
by creating a bind mount. One aspect of proc and sysfs that makes
this particularly tricky is that there are other filesystems that
typically mount on top of proc and sysfs. As those filesystems are
mounted on empty directories in practice it is safe to ignore them.
However testing to ensure filesystems are mounted on empty directories
has not been something the in kernel data structures have supported so
the current test for an empty directory which checks to see
if nlink <= 2 is a bit lacking.
proc and sysfs have recently been modified to use the new empty_dir
infrastructure to create all of their dedicated mount points. Instead
of testing for S_ISDIR(inode->i_mode) && i_nlink <= 2 to see if a
directory is empty, test for is_empty_dir_inode(inode). That small
change guaranteess mounts found on proc and sysfs really are safe to
ignore, because the directories are not only empty but nothing can
ever be added to them. This guarantees there is nothing to worry
about when mounting proc and sysfs.
Cc: stable-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Signed-off-by: "Eric W. Biederman" <ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org>
---
fs/namespace.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/fs/namespace.c b/fs/namespace.c
index 3ede0669b8d2..eccd925c6e82 100644
--- a/fs/namespace.c
+++ b/fs/namespace.c
@@ -3220,9 +3220,8 @@ static bool fs_fully_visible(struct file_system_type *type, int *new_mnt_flags)
/* Only worry about locked mounts */
if (!(mnt->mnt.mnt_flags & MNT_LOCKED))
continue;
- if (!S_ISDIR(inode->i_mode))
- goto next;
- if (inode->i_nlink > 2)
+ /* Is the directory permanetly empty? */
+ if (!is_empty_dir_inode(inode))
goto next;
}
/* Preserve the locked attributes */
--
2.2.1
^ permalink raw reply related
* Re: [PATCH 17/19] y2038: use __kernel_timespec in sys_futex
From: Thomas Gleixner @ 2015-05-16 7:21 UTC (permalink / raw)
To: Arnd Bergmann
Cc: libc-alpha, baolin.wang, y2038, linux-api, ruchandani.tina,
linux-kernel, albert.aribaud, john.stultz, bamvor.zhangjian
In-Reply-To: <alpine.DEB.2.11.1505160049210.4225@nanos>
On Sat, 16 May 2015, Thomas Gleixner wrote:
> On Wed, 6 May 2015, Arnd Bergmann wrote:
>
> > Conversion for sys_futex is particularly easy, we can use the unmodified
> > compat_sys_futex on 32-bit systems to provide compatibility for 32-bit
> > time_t, and change sys_futex to pass a __kernel_timespec, which matches
> > what future libc implementations will use as their struct timespec.
>
> Unless I'm missing something I doubt that you get away that easy. It
> works on 32bit, but not on 64 bit with 32bit app support:
>
> Native 64bit: sys_futex()
> 32bit timespec32: compat_sys_futex()
> 32bit timespec64: ?????
>
> You cannot map that to sys_futex() because the pointer size differs.
Ignore that. You are right. Review induced brainmelt....
tglx
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038
^ permalink raw reply
* Re: [PATCH 13/19] y2038: add compat handling for sys_semtimedop
From: Arnd Bergmann @ 2015-05-16 7:28 UTC (permalink / raw)
To: Thomas Gleixner
Cc: y2038, baolin.wang, albert.aribaud, john.stultz, bamvor.zhangjian,
ruchandani.tina, linux-api, linux-kernel, libc-alpha
In-Reply-To: <alpine.DEB.2.11.1505160041370.4225@nanos>
On Saturday 16 May 2015 00:46:44 Thomas Gleixner wrote:
> On Wed, 6 May 2015, Arnd Bergmann wrote:
> > +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
> > + unsigned, nsops,
> > + const struct __kernel_timespec __user *, timeout)
> > +{
> > + unsigned long jiffies_left = 0;
> > +
> > + if (timeout) {
> > + struct timespec64 _timeout;
> > + if (get_timespec64(&_timeout, timeout))
>
> Moo. I had to look 3 times to get not confused by the extra
> underscore. What's wrong with a proper variable name which is easy to
> distinguish?
>
> > + return -EFAULT;
>
> > + if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
> > + _timeout.tv_nsec >= 1000000000L)
> > + return -EINVAL;
>
> We have proper helper functions to validate time specs.
I tried to change the existing code as little as possible, but I agree
with your points here. I'll add a cleanup patch to fix the current code
before my own patches.
Arnd
^ permalink raw reply
* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Daniel J Walsh @ 2015-05-16 9:46 UTC (permalink / raw)
To: Paul Moore, Andy Lutomirski
Cc: Eric W. Biederman, Linux API, Linux Containers,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA, Al Viro, Network Development,
Linux FS Devel, Eric Paris
In-Reply-To: <9125391.7ZiCneo6Xn@sifl>
On 05/15/2015 05:05 PM, Paul Moore wrote:
> On Thursday, May 14, 2015 11:23:09 PM Andy Lutomirski wrote:
>> On Thu, May 14, 2015 at 7:32 PM, Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>> On 15/05/14, Paul Moore wrote:
>>>> * Look at our existing audit records to determine which records should
>>>> have
>>>> namespace and container ID tokens added. We may only want to add the
>>>> additional fields in the case where the namespace/container ID tokens are
>>>> not the init namespace.
>>> If we have a record that ties a set of namespace IDs with a container
>>> ID, then I expect we only need to list the containerID along with auid
>>> and sessionID.
>> The problem here is that the kernel has no concept of a "container", and I
>> don't think it makes any sense to add one just for audit. "Container" is a
>> marketing term used by some userspace tools.
>>
>> I can imagine that both audit could benefit from a concept of a
>> namespace *path* that understands nesting (e.g. root/2/5/1 or
>> something along those lines). Mapping these to "containers" belongs
>> in userspace, I think.
> It might be helpful to climb up a few levels in this thread ...
>
> I think we all agree that containers are not a kernel construct. I further
> believe that the kernel has no business generating container IDs, those should
> come from userspace and will likely be different depending on how you define
> "container". However, what is less clear to me at this point is how the
> kernel should handle the setting, reporting, and general management of this
> container ID token.
>
Wouldn't the easiest thing be to just treat add a containerid to the
process context like auid. Then
make it a privileged operation to set it. Then tools that care about
auditing like docker can set the ID
and remove the Capability from it sub processes if it cares. All
processes adopt parent processes containerid.
Now containers can be audited and as long as userspace is written
correctly nested containers can either override the containerid or not
depending on what the audit rules are.
No special handling inside of namespaces.
^ permalink raw reply
* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Paul Moore @ 2015-05-16 12:16 UTC (permalink / raw)
To: Daniel J Walsh
Cc: Paul Moore, Andy Lutomirski, Serge E. Hallyn, Richard Guy Briggs,
Linux API, Linux Containers, linux-kernel@vger.kernel.org,
Al Viro, linux-audit, Eric W. Biederman, Network Development,
Linux FS Devel, Eric Paris
In-Reply-To: <555711FA.50703@redhat.com>
On Sat, May 16, 2015 at 5:46 AM, Daniel J Walsh <dwalsh@redhat.com> wrote:
> On 05/15/2015 05:05 PM, Paul Moore wrote:
>> On Thursday, May 14, 2015 11:23:09 PM Andy Lutomirski wrote:
>>> On Thu, May 14, 2015 at 7:32 PM, Richard Guy Briggs <rgb@redhat.com> wrote:
>>>> On 15/05/14, Paul Moore wrote:
>>>>> * Look at our existing audit records to determine which records should
>>>>> have
>>>>> namespace and container ID tokens added. We may only want to add the
>>>>> additional fields in the case where the namespace/container ID tokens are
>>>>> not the init namespace.
>>>> If we have a record that ties a set of namespace IDs with a container
>>>> ID, then I expect we only need to list the containerID along with auid
>>>> and sessionID.
>>> The problem here is that the kernel has no concept of a "container", and I
>>> don't think it makes any sense to add one just for audit. "Container" is a
>>> marketing term used by some userspace tools.
>>>
>>> I can imagine that both audit could benefit from a concept of a
>>> namespace *path* that understands nesting (e.g. root/2/5/1 or
>>> something along those lines). Mapping these to "containers" belongs
>>> in userspace, I think.
>> It might be helpful to climb up a few levels in this thread ...
>>
>> I think we all agree that containers are not a kernel construct. I further
>> believe that the kernel has no business generating container IDs, those should
>> come from userspace and will likely be different depending on how you define
>> "container". However, what is less clear to me at this point is how the
>> kernel should handle the setting, reporting, and general management of this
>> container ID token.
>>
> Wouldn't the easiest thing be to just treat add a containerid to the
> process context like auid.
I believe so. At least that was the point I was trying to get across
when I first jumped into this thread.
> Then make it a privileged operation to set it. Then tools that care about
> auditing like docker can set the ID
> and remove the Capability from it sub processes if it cares. All
> processes adopt parent processes containerid.
> Now containers can be audited and as long as userspace is written
> correctly nested containers can either override the containerid or not
> depending on what the audit rules are.
This part I'm still less certain on. I agree that setting the
container ID should be privileged in some sense, but the kernel
shouldn't *require* privilege to create a new container (however the
user chooses to define it). Simply requiring privilege to set the
container ID and failing silently may be sufficient.
--
paul moore
www.paul-moore.com
^ permalink raw reply
* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Eric W. Biederman @ 2015-05-16 14:46 UTC (permalink / raw)
To: Paul Moore
Cc: Daniel J Walsh, Paul Moore, Andy Lutomirski, Serge E. Hallyn,
Richard Guy Briggs, Linux API, Linux Containers,
linux-kernel@vger.kernel.org, Al Viro,
linux-audit-H+wXaHxf7aLQT0dZR+AlfA, Network Development,
Linux FS Devel, Eric Paris
In-Reply-To: <CAHC9VhRKSK9=9qPF3dgALS=x1g3LinNeQvuhNV5TvQ=D7Szuag-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org> writes:
> On Sat, May 16, 2015 at 5:46 AM, Daniel J Walsh <dwalsh-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>> On 05/15/2015 05:05 PM, Paul Moore wrote:
>>> On Thursday, May 14, 2015 11:23:09 PM Andy Lutomirski wrote:
>>>> On Thu, May 14, 2015 at 7:32 PM, Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>>>> On 15/05/14, Paul Moore wrote:
>>>>>> * Look at our existing audit records to determine which records should
>>>>>> have
>>>>>> namespace and container ID tokens added. We may only want to add the
>>>>>> additional fields in the case where the namespace/container ID tokens are
>>>>>> not the init namespace.
>>>>> If we have a record that ties a set of namespace IDs with a container
>>>>> ID, then I expect we only need to list the containerID along with auid
>>>>> and sessionID.
>>>> The problem here is that the kernel has no concept of a "container", and I
>>>> don't think it makes any sense to add one just for audit. "Container" is a
>>>> marketing term used by some userspace tools.
>>>>
>>>> I can imagine that both audit could benefit from a concept of a
>>>> namespace *path* that understands nesting (e.g. root/2/5/1 or
>>>> something along those lines). Mapping these to "containers" belongs
>>>> in userspace, I think.
>>> It might be helpful to climb up a few levels in this thread ...
>>>
>>> I think we all agree that containers are not a kernel construct. I further
>>> believe that the kernel has no business generating container IDs, those should
>>> come from userspace and will likely be different depending on how you define
>>> "container". However, what is less clear to me at this point is how the
>>> kernel should handle the setting, reporting, and general management of this
>>> container ID token.
>>>
>> Wouldn't the easiest thing be to just treat add a containerid to the
>> process context like auid.
>
> I believe so. At least that was the point I was trying to get across
> when I first jumped into this thread.
It sounds nice but containers are not just a per process construct.
Sometimes you might know anamespace but not which process instigated
action to happen on that namespace.
>> Then make it a privileged operation to set it. Then tools that care about
>> auditing like docker can set the ID
>> and remove the Capability from it sub processes if it cares. All
>> processes adopt parent processes containerid.
>> Now containers can be audited and as long as userspace is written
>> correctly nested containers can either override the containerid or not
>> depending on what the audit rules are.
>
> This part I'm still less certain on. I agree that setting the
> container ID should be privileged in some sense, but the kernel
> shouldn't *require* privilege to create a new container (however the
> user chooses to define it). Simply requiring privilege to set the
> container ID and failing silently may be sufficient.
My hope is as things mature fewer and fewer container things will need
any special privilege to create.
I think it needs to start with a clear definition of what is wanted and
then working backwards through which messages in which contexts you want
to have your magic bits.
Eric
^ permalink raw reply
* [PATCH] media: uapi: vsp1: Use __u32 instead of u32
From: Joe Perches @ 2015-05-16 18:11 UTC (permalink / raw)
To: Laurent Pinchart; +Cc: linux-api, LKML
Don't use the kernel types in uapi headers.
Signed-off-by: Joe Perches <joe@perches.com>
---
include/uapi/linux/vsp1.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/linux/vsp1.h b/include/uapi/linux/vsp1.h
index e18858f..9a82369 100644
--- a/include/uapi/linux/vsp1.h
+++ b/include/uapi/linux/vsp1.h
@@ -28,7 +28,7 @@
_IOWR('V', BASE_VIDIOC_PRIVATE + 1, struct vsp1_lut_config)
struct vsp1_lut_config {
- u32 lut[256];
+ __u32 lut[256];
};
#endif /* __VSP1_USER_H__ */
^ permalink raw reply related
* Re: [PATCH 13/19] y2038: add compat handling for sys_semtimedop
From: Arnd Bergmann @ 2015-05-16 19:54 UTC (permalink / raw)
To: Thomas Gleixner
Cc: libc-alpha, baolin.wang, y2038, linux-api, ruchandani.tina,
linux-kernel, albert.aribaud, john.stultz, bamvor.zhangjian
In-Reply-To: <alpine.DEB.2.11.1505160041370.4225@nanos>
On Saturday 16 May 2015 00:46:44 Thomas Gleixner wrote:
> On Wed, 6 May 2015, Arnd Bergmann wrote:
> > +SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
> > + unsigned, nsops,
> > + const struct __kernel_timespec __user *, timeout)
> > +{
> > + unsigned long jiffies_left = 0;
> > +
> > + if (timeout) {
> > + struct timespec64 _timeout;
> > + if (get_timespec64(&_timeout, timeout))
>
> Moo. I had to look 3 times to get not confused by the extra
> underscore. What's wrong with a proper variable name which is easy to
> distinguish?
>
> > + return -EFAULT;
>
> > + if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
> > + _timeout.tv_nsec >= 1000000000L)
> > + return -EINVAL;
>
> We have proper helper functions to validate time specs.
I ended up fixing both issues you noticed in the same patch
after all, and also simplified it slightly more.
Finally, I also noticed that I had not done a timespec64_to_jiffies()
call at the time when I wrote this patch, but it actually exists now,
so I've reordered my series and am using it in the new version, as
I should have done to start with.
Arnd
8<----
From e04b14d49273c27d92f1799233b82bcdafb43d9a Mon Sep 17 00:00:00 2001
From: Arnd Bergmann <arnd@arndb.de>
Date: Mon, 27 Apr 2015 23:30:39 +0200
Subject: [UPDATED PATCH] y2038: add compat handling for sys_semtimedop
This moves the compat_sys_semtimedop function to ipc/sem.c so it
can be shared with 32-bit architectures efficiently. Instead of
copying the timespec back to user space, we take a shortcut and
pass the kernel timespec64 value to the low-level implementation
directly.
The native sys_semtimedop() function is modified to take a
__kernel_timespec structure, which will be based on a 64-bit
time_t in the future.
There is a small API change here: if multiple errors are present,
and the timespec argument is an invalid pointer, we now return
-EFAULT before checking any of the other error conditions.
This is what the compat version has always done, but if it is a
problem, we need a more sophisticated approach.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/include/linux/syscalls.h b/include/linux/syscalls.h
index f3fdc312627b..c2a70a8f907d 100644
--- a/include/linux/syscalls.h
+++ b/include/linux/syscalls.h
@@ -665,7 +665,7 @@ asmlinkage long sys_semop(int semid, struct sembuf __user *sops,
asmlinkage long sys_semctl(int semid, int semnum, int cmd, unsigned long arg);
asmlinkage long sys_semtimedop(int semid, struct sembuf __user *sops,
unsigned nsops,
- const struct timespec __user *timeout);
+ const struct __kernel_timespec __user *timeout);
asmlinkage long sys_shmat(int shmid, char __user *shmaddr, int shmflg);
asmlinkage long sys_shmget(key_t key, size_t size, int flag);
asmlinkage long sys_shmdt(char __user *shmaddr);
diff --git a/ipc/compat.c b/ipc/compat.c
index 9b3c85f8a538..2bbdb093d1be 100644
--- a/ipc/compat.c
+++ b/ipc/compat.c
@@ -745,13 +745,3 @@ COMPAT_SYSCALL_DEFINE3(shmctl, int, first, int, second, void __user *, uptr)
}
return err;
}
-
-COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsems,
- unsigned, nsops,
- const struct compat_timespec __user *, timeout)
-{
- struct timespec __user *ts64;
- if (compat_convert_timespec(&ts64, timeout))
- return -EFAULT;
- return sys_semtimedop(semid, tsems, nsops, ts64);
-}
diff --git a/ipc/sem.c b/ipc/sem.c
index d1a6edd17eba..84d354a34df3 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -72,6 +72,7 @@
* The worst-case behavior is nevertheless O(N^2) for N wakeups.
*/
+#include <linux/compat.h>
#include <linux/slab.h>
#include <linux/spinlock.h>
#include <linux/init.h>
@@ -1779,8 +1780,8 @@ static int get_queue_result(struct sem_queue *q)
return error;
}
-SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
- unsigned, nsops, const struct timespec __user *, timeout)
+static long semtimedop(int semid, struct sembuf __user * tsops,
+ unsigned nsops, struct timespec64 *timeout)
{
int error = -EINVAL;
struct sem_array *sma;
@@ -1809,17 +1810,11 @@ SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
goto out_free;
}
if (timeout) {
- struct timespec _timeout;
- if (copy_from_user(&_timeout, timeout, sizeof(*timeout))) {
- error = -EFAULT;
- goto out_free;
- }
- if (_timeout.tv_sec < 0 || _timeout.tv_nsec < 0 ||
- _timeout.tv_nsec >= 1000000000L) {
+ if (!timespec64_valid(timeout)) {
error = -EINVAL;
goto out_free;
}
- jiffies_left = timespec_to_jiffies(&_timeout);
+ jiffies_left = timespec64_to_jiffies(timeout);
}
max = 0;
for (sop = sops; sop < sops + nsops; sop++) {
@@ -2014,10 +2009,36 @@ out_free:
return error;
}
+SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
+ unsigned, nsops,
+ const struct __kernel_timespec __user *, p)
+{
+ struct timespec64 timeout;
+
+ if (p && get_timespec64(&timeout, p))
+ return -EFAULT;
+
+ return semtimedop(semid, tsops, nsops, p ? &timeout : NULL);
+}
+
+#ifdef CONFIG_COMPAT_TIME
+COMPAT_SYSCALL_DEFINE4(semtimedop, int, semid, struct sembuf __user *, tsops,
+ unsigned, nsops,
+ const struct compat_timespec __user *, p)
+{
+ struct timespec64 timeout;
+
+ if (p && compat_get_timespec64(&timeout, p))
+ return -EFAULT;
+
+ return semtimedop(semid, tsops, nsops, p ? &timeout : NULL);
+}
+#endif
+
SYSCALL_DEFINE3(semop, int, semid, struct sembuf __user *, tsops,
unsigned, nsops)
{
- return sys_semtimedop(semid, tsops, nsops, NULL);
+ return semtimedop(semid, tsops, nsops, NULL);
}
/* If CLONE_SYSVSEM is set, establish sharing of SEM_UNDO state between
diff --git a/ipc/syscall.c b/ipc/syscall.c
index 52429489cde0..d7b17355d870 100644
--- a/ipc/syscall.c
+++ b/ipc/syscall.c
@@ -7,6 +7,7 @@
#include <linux/unistd.h>
#ifdef __ARCH_WANT_SYS_IPC
+#include <linux/compat_time.h>
#include <linux/errno.h>
#include <linux/ipc.h>
#include <linux/shm.h>
@@ -26,9 +27,15 @@ SYSCALL_DEFINE6(ipc, unsigned int, call, int, first, unsigned long, second,
return sys_semtimedop(first, (struct sembuf __user *)ptr,
second, NULL);
case SEMTIMEDOP:
+#if defined(CONFIG_ARCH_HAS_COMPAT_TIME) && !defined(CONFIG_64BIT)
+ return compat_sys_semtimedop(first, (struct sembuf __user *)ptr,
+ second,
+ (const struct compat_timespec __user *)fifth);
+#else
return sys_semtimedop(first, (struct sembuf __user *)ptr,
second,
(const struct timespec __user *)fifth);
+#endif
case SEMGET:
return sys_semget(first, second, third);
_______________________________________________
Y2038 mailing list
Y2038@lists.linaro.org
https://lists.linaro.org/mailman/listinfo/y2038
^ permalink raw reply related
* Re: [PATCH RFC v2 2/2] vfs: add O_NOCMTIME
From: Azat Khuzhin @ 2015-05-16 21:50 UTC (permalink / raw)
To: Zach Brown
Cc: Sage Weil, linux-fsdevel-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1431725028-24071-3-git-send-email-zab-ugsP4Wv/S6ZeoWH0uzbU5w@public.gmane.org>
On Fri, May 15, 2015 at 02:23:48PM -0700, Zach Brown wrote:
> Add a O_NOCMTIME flag which prevents inode time updates on writes and
> can greatly reduce the IO overhead of writes to allocated and
> initialized regions of files.
> --- a/include/linux/fs.h
> +++ b/include/linux/fs.h
You may also want to resolve this:
/*
* Don't update ctime and mtime.
*
* Currently a special hack for the XFS open_by_handle ioctl, but we'll
* hopefully graduate it to a proper O_CMTIME flag supported by open(2) soon.
*/
#define FMODE_NOCMTIME ((__force fmode_t)0x800)
^ permalink raw reply
* Re: [PATCH V6 05/10] audit: log creation and deletion of namespace instances
From: Paul Moore @ 2015-05-16 22:49 UTC (permalink / raw)
To: Eric W. Biederman
Cc: Linux API, Linux Containers, Daniel J Walsh,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Andy Lutomirski, Paul Moore, linux-audit-H+wXaHxf7aLQT0dZR+AlfA,
Al Viro, Network Development, Linux FS Devel, Eric Paris
In-Reply-To: <87r3qgpol6.fsf-JOvCrm2gF+uungPnsOpG7nhyD016LWXt@public.gmane.org>
On Sat, May 16, 2015 at 10:46 AM, Eric W. Biederman
<ebiederm-aS9lmoZGLiVWk0Htik3J/w@public.gmane.org> wrote:
> Paul Moore <paul-r2n+y4ga6xFZroRs9YW3xA@public.gmane.org> writes:
>> On Sat, May 16, 2015 at 5:46 AM, Daniel J Walsh <dwalsh-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>> On 05/15/2015 05:05 PM, Paul Moore wrote:
>>>> On Thursday, May 14, 2015 11:23:09 PM Andy Lutomirski wrote:
>>>>> On Thu, May 14, 2015 at 7:32 PM, Richard Guy Briggs <rgb-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org> wrote:
>>>>>> On 15/05/14, Paul Moore wrote:
>>>>>>> * Look at our existing audit records to determine which records should
>>>>>>> have
>>>>>>> namespace and container ID tokens added. We may only want to add the
>>>>>>> additional fields in the case where the namespace/container ID tokens are
>>>>>>> not the init namespace.
>>>>>> If we have a record that ties a set of namespace IDs with a container
>>>>>> ID, then I expect we only need to list the containerID along with auid
>>>>>> and sessionID.
>>>>> The problem here is that the kernel has no concept of a "container", and I
>>>>> don't think it makes any sense to add one just for audit. "Container" is a
>>>>> marketing term used by some userspace tools.
>>>>>
>>>>> I can imagine that both audit could benefit from a concept of a
>>>>> namespace *path* that understands nesting (e.g. root/2/5/1 or
>>>>> something along those lines). Mapping these to "containers" belongs
>>>>> in userspace, I think.
>>>> It might be helpful to climb up a few levels in this thread ...
>>>>
>>>> I think we all agree that containers are not a kernel construct. I further
>>>> believe that the kernel has no business generating container IDs, those should
>>>> come from userspace and will likely be different depending on how you define
>>>> "container". However, what is less clear to me at this point is how the
>>>> kernel should handle the setting, reporting, and general management of this
>>>> container ID token.
>>>>
>>> Wouldn't the easiest thing be to just treat add a containerid to the
>>> process context like auid.
>>
>> I believe so. At least that was the point I was trying to get across
>> when I first jumped into this thread.
>
> It sounds nice but containers are not just a per process construct.
> Sometimes you might know anamespace but not which process instigated
> action to happen on that namespace.
>From an auditing perspective I'm not sure we will ever hit those
cases; did you have a particular example in mind?
--
paul moore
www.paul-moore.com
^ permalink raw reply
* [PATCH for v4.2 0/3] membarrier system call
From: Mathieu Desnoyers @ 2015-05-16 23:48 UTC (permalink / raw)
To: Andrew Morton, Paul E . McKenney
Cc: linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-api-u79uwXL29TY76Z2rM5mHXA, Mathieu Desnoyers
Hi,
At this point, all we're awaiting for is formal Acked-by by affected
maintainers.
Andrew, should you eventually pick it up into your tree ? Or perhaps it should
go through Paul McKenney's tree, given that it uses synchronize_sched() ?
The only change since last post is a layout change in the patch changelog, so
I'm not even bumping the patch version (kept at v18).
Thanks,
Mathieu
Mathieu Desnoyers (2):
sys_membarrier(): system-wide memory barrier (generic, x86) (v18)
selftests: enhance membarrier syscall test
Pranith Kumar (1):
selftests: add membarrier syscall test
MAINTAINERS | 8 ++
arch/x86/syscalls/syscall_32.tbl | 1 +
arch/x86/syscalls/syscall_64.tbl | 1 +
include/linux/syscalls.h | 2 +
include/uapi/asm-generic/unistd.h | 4 +-
include/uapi/linux/Kbuild | 1 +
include/uapi/linux/membarrier.h | 53 +++++++++
init/Kconfig | 12 ++
kernel/Makefile | 1 +
kernel/membarrier.c | 66 +++++++++++
kernel/sys_ni.c | 3 +
tools/testing/selftests/Makefile | 1 +
tools/testing/selftests/membarrier/.gitignore | 1 +
tools/testing/selftests/membarrier/Makefile | 11 ++
.../testing/selftests/membarrier/membarrier_test.c | 121 ++++++++++++++++++++
15 files changed, 285 insertions(+), 1 deletions(-)
create mode 100644 include/uapi/linux/membarrier.h
create mode 100644 kernel/membarrier.c
create mode 100644 tools/testing/selftests/membarrier/.gitignore
create mode 100644 tools/testing/selftests/membarrier/Makefile
create mode 100644 tools/testing/selftests/membarrier/membarrier_test.c
--
1.7.7.3
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox