summaryrefslogtreecommitdiff
path: root/ipc
diff options
context:
space:
mode:
authorAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-10-20 00:10:27 -0300
committerAndré Fabian Silva Delgado <emulatorman@parabola.nu>2016-10-20 00:10:27 -0300
commitd0b2f91bede3bd5e3d24dd6803e56eee959c1797 (patch)
tree7fee4ab0509879c373c4f2cbd5b8a5be5b4041ee /ipc
parente914f8eb445e8f74b00303c19c2ffceaedd16a05 (diff)
Linux-libre 4.8.2-gnupck-4.8.2-gnu
Diffstat (limited to 'ipc')
-rw-r--r--ipc/mqueue.c20
-rw-r--r--ipc/msgutil.c2
-rw-r--r--ipc/namespace.c7
-rw-r--r--ipc/sem.c13
-rw-r--r--ipc/shm.c12
5 files changed, 20 insertions, 34 deletions
diff --git a/ipc/mqueue.c b/ipc/mqueue.c
index ade739f67..0b13ace26 100644
--- a/ipc/mqueue.c
+++ b/ipc/mqueue.c
@@ -305,8 +305,9 @@ err:
static int mqueue_fill_super(struct super_block *sb, void *data, int silent)
{
struct inode *inode;
- struct ipc_namespace *ns = data;
+ struct ipc_namespace *ns = sb->s_fs_info;
+ sb->s_iflags |= SB_I_NOEXEC | SB_I_NODEV;
sb->s_blocksize = PAGE_SIZE;
sb->s_blocksize_bits = PAGE_SHIFT;
sb->s_magic = MQUEUE_MAGIC;
@@ -326,17 +327,14 @@ static struct dentry *mqueue_mount(struct file_system_type *fs_type,
int flags, const char *dev_name,
void *data)
{
- if (!(flags & MS_KERNMOUNT)) {
- struct ipc_namespace *ns = current->nsproxy->ipc_ns;
- /* Don't allow mounting unless the caller has CAP_SYS_ADMIN
- * over the ipc namespace.
- */
- if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN))
- return ERR_PTR(-EPERM);
-
- data = ns;
+ struct ipc_namespace *ns;
+ if (flags & MS_KERNMOUNT) {
+ ns = data;
+ data = NULL;
+ } else {
+ ns = current->nsproxy->ipc_ns;
}
- return mount_ns(fs_type, flags, data, mqueue_fill_super);
+ return mount_ns(fs_type, flags, data, ns, ns->user_ns, mqueue_fill_super);
}
static void init_once(void *foo)
diff --git a/ipc/msgutil.c b/ipc/msgutil.c
index ed81aafd2..a521999de 100644
--- a/ipc/msgutil.c
+++ b/ipc/msgutil.c
@@ -37,8 +37,6 @@ struct ipc_namespace init_ipc_ns = {
#endif
};
-atomic_t nr_ipc_ns = ATOMIC_INIT(1);
-
struct msg_msgseg {
struct msg_msgseg *next;
/* the next part of the message follows immediately */
diff --git a/ipc/namespace.c b/ipc/namespace.c
index 068caf18d..d87e6baa1 100644
--- a/ipc/namespace.c
+++ b/ipc/namespace.c
@@ -34,20 +34,20 @@ static struct ipc_namespace *create_ipc_ns(struct user_namespace *user_ns,
ns->ns.ops = &ipcns_operations;
atomic_set(&ns->count, 1);
+ ns->user_ns = get_user_ns(user_ns);
+
err = mq_init_ns(ns);
if (err) {
+ put_user_ns(ns->user_ns);
ns_free_inum(&ns->ns);
kfree(ns);
return ERR_PTR(err);
}
- atomic_inc(&nr_ipc_ns);
sem_init_ns(ns);
msg_init_ns(ns);
shm_init_ns(ns);
- ns->user_ns = get_user_ns(user_ns);
-
return ns;
}
@@ -95,7 +95,6 @@ static void free_ipc_ns(struct ipc_namespace *ns)
sem_exit_ns(ns);
msg_exit_ns(ns);
shm_exit_ns(ns);
- atomic_dec(&nr_ipc_ns);
put_user_ns(ns->user_ns);
ns_free_inum(&ns->ns);
diff --git a/ipc/sem.c b/ipc/sem.c
index 5d2f875e8..7c9d4f768 100644
--- a/ipc/sem.c
+++ b/ipc/sem.c
@@ -260,16 +260,6 @@ static void sem_rcu_free(struct rcu_head *head)
}
/*
- * spin_unlock_wait() and !spin_is_locked() are not memory barriers, they
- * are only control barriers.
- * The code must pair with spin_unlock(&sem->lock) or
- * spin_unlock(&sem_perm.lock), thus just the control barrier is insufficient.
- *
- * smp_rmb() is sufficient, as writes cannot pass the control barrier.
- */
-#define ipc_smp_acquire__after_spin_is_unlocked() smp_rmb()
-
-/*
* Wait until all currently ongoing simple ops have completed.
* Caller must own sem_perm.lock.
* New simple ops cannot start, because simple ops first check
@@ -292,7 +282,6 @@ static void sem_wait_array(struct sem_array *sma)
sem = sma->sem_base + i;
spin_unlock_wait(&sem->lock);
}
- ipc_smp_acquire__after_spin_is_unlocked();
}
/*
@@ -350,7 +339,7 @@ static inline int sem_lock(struct sem_array *sma, struct sembuf *sops,
* complex_count++;
* spin_unlock(sem_perm.lock);
*/
- ipc_smp_acquire__after_spin_is_unlocked();
+ smp_acquire__after_ctrl_dep();
/*
* Now repeat the test of complex_count:
diff --git a/ipc/shm.c b/ipc/shm.c
index 41d8b7206..dbac8860c 100644
--- a/ipc/shm.c
+++ b/ipc/shm.c
@@ -476,13 +476,15 @@ static const struct file_operations shm_file_operations = {
.mmap = shm_mmap,
.fsync = shm_fsync,
.release = shm_release,
-#ifndef CONFIG_MMU
.get_unmapped_area = shm_get_unmapped_area,
-#endif
.llseek = noop_llseek,
.fallocate = shm_fallocate,
};
+/*
+ * shm_file_operations_huge is now identical to shm_file_operations,
+ * but we keep it distinct for the sake of is_file_shm_hugepages().
+ */
static const struct file_operations shm_file_operations_huge = {
.mmap = shm_mmap,
.fsync = shm_fsync,
@@ -578,7 +580,7 @@ static int newseg(struct ipc_namespace *ns, struct ipc_params *params)
if ((shmflg & SHM_NORESERVE) &&
sysctl_overcommit_memory != OVERCOMMIT_NEVER)
acctflag = VM_NORESERVE;
- file = shmem_kernel_file_setup(name, size, acctflag, 0);
+ file = shmem_kernel_file_setup(name, size, acctflag);
}
error = PTR_ERR(file);
if (IS_ERR(file))
@@ -764,10 +766,10 @@ static void shm_add_rss_swap(struct shmid_kernel *shp,
} else {
#ifdef CONFIG_SHMEM
struct shmem_inode_info *info = SHMEM_I(inode);
- spin_lock(&info->lock);
+ spin_lock_irq(&info->lock);
*rss_add += inode->i_mapping->nrpages;
*swp_add += info->swapped;
- spin_unlock(&info->lock);
+ spin_unlock_irq(&info->lock);
#else
*rss_add += inode->i_mapping->nrpages;
#endif