aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c35
1 files changed, 21 insertions, 14 deletions
diff --git a/ipc/util.c b/ipc/util.c
index eb07fd356f27..72fd0785ac94 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -249,8 +249,8 @@ int ipc_get_maxid(struct ipc_ids *ids)
249 249
250int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size) 250int ipc_addid(struct ipc_ids* ids, struct kern_ipc_perm* new, int size)
251{ 251{
252 uid_t euid; 252 kuid_t euid;
253 gid_t egid; 253 kgid_t egid;
254 int id, err; 254 int id, err;
255 255
256 if (size > IPCMNI) 256 if (size > IPCMNI)
@@ -606,14 +606,14 @@ void ipc_rcu_putref(void *ptr)
606 606
607int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag) 607int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
608{ 608{
609 uid_t euid = current_euid(); 609 kuid_t euid = current_euid();
610 int requested_mode, granted_mode; 610 int requested_mode, granted_mode;
611 611
612 audit_ipc_obj(ipcp); 612 audit_ipc_obj(ipcp);
613 requested_mode = (flag >> 6) | (flag >> 3) | flag; 613 requested_mode = (flag >> 6) | (flag >> 3) | flag;
614 granted_mode = ipcp->mode; 614 granted_mode = ipcp->mode;
615 if (euid == ipcp->cuid || 615 if (uid_eq(euid, ipcp->cuid) ||
616 euid == ipcp->uid) 616 uid_eq(euid, ipcp->uid))
617 granted_mode >>= 6; 617 granted_mode >>= 6;
618 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid)) 618 else if (in_group_p(ipcp->cgid) || in_group_p(ipcp->gid))
619 granted_mode >>= 3; 619 granted_mode >>= 3;
@@ -643,10 +643,10 @@ int ipcperms(struct ipc_namespace *ns, struct kern_ipc_perm *ipcp, short flag)
643void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out) 643void kernel_to_ipc64_perm (struct kern_ipc_perm *in, struct ipc64_perm *out)
644{ 644{
645 out->key = in->key; 645 out->key = in->key;
646 out->uid = in->uid; 646 out->uid = from_kuid_munged(current_user_ns(), in->uid);
647 out->gid = in->gid; 647 out->gid = from_kgid_munged(current_user_ns(), in->gid);
648 out->cuid = in->cuid; 648 out->cuid = from_kuid_munged(current_user_ns(), in->cuid);
649 out->cgid = in->cgid; 649 out->cgid = from_kgid_munged(current_user_ns(), in->cgid);
650 out->mode = in->mode; 650 out->mode = in->mode;
651 out->seq = in->seq; 651 out->seq = in->seq;
652} 652}
@@ -747,12 +747,19 @@ int ipcget(struct ipc_namespace *ns, struct ipc_ids *ids,
747 * @in: the permission given as input. 747 * @in: the permission given as input.
748 * @out: the permission of the ipc to set. 748 * @out: the permission of the ipc to set.
749 */ 749 */
750void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out) 750int ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
751{ 751{
752 out->uid = in->uid; 752 kuid_t uid = make_kuid(current_user_ns(), in->uid);
753 out->gid = in->gid; 753 kgid_t gid = make_kgid(current_user_ns(), in->gid);
754 if (!uid_valid(uid) || !gid_valid(gid))
755 return -EINVAL;
756
757 out->uid = uid;
758 out->gid = gid;
754 out->mode = (out->mode & ~S_IRWXUGO) 759 out->mode = (out->mode & ~S_IRWXUGO)
755 | (in->mode & S_IRWXUGO); 760 | (in->mode & S_IRWXUGO);
761
762 return 0;
756} 763}
757 764
758/** 765/**
@@ -777,7 +784,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
777 struct ipc64_perm *perm, int extra_perm) 784 struct ipc64_perm *perm, int extra_perm)
778{ 785{
779 struct kern_ipc_perm *ipcp; 786 struct kern_ipc_perm *ipcp;
780 uid_t euid; 787 kuid_t euid;
781 int err; 788 int err;
782 789
783 down_write(&ids->rw_mutex); 790 down_write(&ids->rw_mutex);
@@ -793,7 +800,7 @@ struct kern_ipc_perm *ipcctl_pre_down(struct ipc_namespace *ns,
793 perm->gid, perm->mode); 800 perm->gid, perm->mode);
794 801
795 euid = current_euid(); 802 euid = current_euid();
796 if (euid == ipcp->cuid || euid == ipcp->uid || 803 if (uid_eq(euid, ipcp->cuid) || uid_eq(euid, ipcp->uid) ||
797 ns_capable(ns->user_ns, CAP_SYS_ADMIN)) 804 ns_capable(ns->user_ns, CAP_SYS_ADMIN))
798 return ipcp; 805 return ipcp;
799 806