Skip to content

Commit 7608b6a

Browse files
legionusebiederm
authored andcommitted
sysctl: Allow to change limits for posix messages queues
All parameters of posix messages queues (queues_max/msg_max/msgsize_max) end up being limited by RLIMIT_MSGQUEUE. The code in mqueue_get_inode is where that limiting happens. The RLIMIT_MSGQUEUE is bound to the user namespace and is counted hierarchically. We can allow root in the user namespace to modify the posix messages queues parameters. Signed-off-by: Alexey Gladkov <legion@kernel.org> Link: https://lkml.kernel.org/r/7eb21211c8622e91d226e63416b1b93c079f60ee.1663756794.git.legion@kernel.org Signed-off-by: Eric W. Biederman <ebiederm@xmission.com>
1 parent f9b90c2 commit 7608b6a

File tree

1 file changed

+36
-0
lines changed

1 file changed

+36
-0
lines changed

ipc/mq_sysctl.c

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
#include <linux/stat.h>
1313
#include <linux/capability.h>
1414
#include <linux/slab.h>
15+
#include <linux/cred.h>
1516

1617
static int msg_max_limit_min = MIN_MSGMAX;
1718
static int msg_max_limit_max = HARD_MSGMAX;
@@ -76,8 +77,43 @@ static int set_is_seen(struct ctl_table_set *set)
7677
return &current->nsproxy->ipc_ns->mq_set == set;
7778
}
7879

80+
static void mq_set_ownership(struct ctl_table_header *head,
81+
struct ctl_table *table,
82+
kuid_t *uid, kgid_t *gid)
83+
{
84+
struct ipc_namespace *ns =
85+
container_of(head->set, struct ipc_namespace, mq_set);
86+
87+
kuid_t ns_root_uid = make_kuid(ns->user_ns, 0);
88+
kgid_t ns_root_gid = make_kgid(ns->user_ns, 0);
89+
90+
*uid = uid_valid(ns_root_uid) ? ns_root_uid : GLOBAL_ROOT_UID;
91+
*gid = gid_valid(ns_root_gid) ? ns_root_gid : GLOBAL_ROOT_GID;
92+
}
93+
94+
static int mq_permissions(struct ctl_table_header *head, struct ctl_table *table)
95+
{
96+
int mode = table->mode;
97+
kuid_t ns_root_uid;
98+
kgid_t ns_root_gid;
99+
100+
mq_set_ownership(head, table, &ns_root_uid, &ns_root_gid);
101+
102+
if (uid_eq(current_euid(), ns_root_uid))
103+
mode >>= 6;
104+
105+
if (in_egroup_p(ns_root_gid))
106+
mode >>= 3;
107+
108+
mode &= 7;
109+
110+
return (mode << 6) | (mode << 3) | mode;
111+
}
112+
79113
static struct ctl_table_root set_root = {
80114
.lookup = set_lookup,
115+
.permissions = mq_permissions,
116+
.set_ownership = mq_set_ownership,
81117
};
82118

83119
bool setup_mq_sysctls(struct ipc_namespace *ns)

0 commit comments

Comments
 (0)