|
@@ -249,8 +249,8 @@ int ipc_get_maxid(struct ipc_ids *ids)
|
|
|
|
|
|
int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
|
|
|
{
|
|
|
- uid_t euid;
|
|
|
- gid_t egid;
|
|
|
+ kuid_t euid;
|
|
|
+ kgid_t egid;
|
|
|
int id, err;
|
|
|
|
|
|
if (size > IPCMNI)
|
|
@@ -606,14 +606,14 @@ void ipc_rcu_putref(void *ptr)
|
|
|
|
|
|
int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
|
|
|
{
|
|
|
- uid_t euid = current_euid();
|
|
|
+ kuid_t euid = current_euid();
|
|
|
int requested_mode, granted_mode;
|
|
|
|
|
|
audit_ipc_obj(ipcp);
|
|
|
requested_mode = (flag >> 6) | (flag >> 3) | flag;
|
|
|
granted_mode = ipcp->mode;
|
|
|
- if (euid == ipcp->cuid ||
|
|
|
- euid == ipcp->uid)
|
|
|
+ if (uid_eq(euid, ipcp->cuid) ||
|
|
|
+ uid_eq(euid, ipcp->uid))
|
|
|
granted_mode >>= 6;
|
|
|
else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
|
|
|
granted_mode >>= 3;
|
|
@@ -643,10 +643,10 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
|
|
|
void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
|
|
|
{
|
|
|
out->key = in->key;
|
|
|
- out->uid = in->uid;
|
|
|
- out->gid = in->gid;
|
|
|
- out->cuid = in->cuid;
|
|
|
- out->cgid = in->cgid;
|
|
|
+ out->uid = from_kuid_munged(current_user_ns(), in->uid);
|
|
|
+ out->gid = from_kgid_munged(current_user_ns(), in->gid);
|
|
|
+ out->cuid = from_kuid_munged(current_user_ns(), in->cuid);
|
|
|
+ out->cgid = from_kgid_munged(current_user_ns(), in->cgid);
|
|
|
out->mode = in->mode;
|
|
|
out->seq = in->seq;
|
|
|
}
|
|
@@ -747,12 +747,19 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
|
|
|
* @in: the permission given as input.
|
|
|
* @out: the permission of the ipc to set.
|
|
|
*/
|
|
|
-void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
|
|
|
+int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
|
|
|
{
|
|
|
- out->uid = in->uid;
|
|
|
- out->gid = in->gid;
|
|
|
+ kuid_t uid = make_kuid(current_user_ns(), in->uid);
|
|
|
+ kgid_t gid = make_kgid(current_user_ns(), in->gid);
|
|
|
+ if (!uid_valid(uid) || !gid_valid(gid))
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ out->uid = uid;
|
|
|
+ out->gid = gid;
|
|
|
out->mode = (out->mode & ~S_IRWXUGO)
|
|
|
| (in->mode & S_IRWXUGO);
|
|
|
+
|
|
|
+ return 0;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -777,7 +784,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
|
|
|
struct ipc64_perm *perm, int extra_perm)
|
|
|
{
|
|
|
struct kern_ipc_perm *ipcp;
|
|
|
- uid_t euid;
|
|
|
+ kuid_t euid;
|
|
|
int err;
|
|
|
|
|
|
down_write(&ids->rw_mutex);
|
|
@@ -793,7 +800,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
|
|
|
perm->gid, perm->mode);
|
|
|
|
|
|
euid = current_euid();
|
|
|
- if (euid == ipcp->cuid || euid == ipcp->uid ||
|
|
|
+ if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) ||
|
|
|
ns_capable(ns->user_ns, CAP_SYS_ADMIN))
|
|
|
return ipcp;
|
|
|
|