aboutsummaryrefslogtreecommitdiffstats
path: root/ipc/util.c
diff options
context:
space:
mode:
Diffstat (limited to 'ipc/util.c')
-rw-r--r--ipc/util.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/ipc/util.c b/ipc/util.c
index dc8943aa9719..c4f1d33b89e4 100644
--- a/ipc/util.c
+++ b/ipc/util.c
@@ -824,6 +824,57 @@ void ipc_update_perm(struct ipc64_perm *in, struct kern_ipc_perm *out)
824 | (in->mode & S_IRWXUGO); 824 | (in->mode & S_IRWXUGO);
825} 825}
826 826
827/**
828 * ipcctl_pre_down - retrieve an ipc and check permissions for some IPC_XXX cmd
829 * @ids: the table of ids where to look for the ipc
830 * @id: the id of the ipc to retrieve
831 * @cmd: the cmd to check
832 * @perm: the permission to set
833 * @extra_perm: one extra permission parameter used by msq
834 *
835 * This function does some common audit and permissions check for some IPC_XXX
836 * cmd and is called from semctl_down, shmctl_down and msgctl_down.
837 * It must be called without any lock held and
838 * - retrieves the ipc with the given id in the given table.
839 * - performs some audit and permission check, depending on the given cmd
840 * - returns the ipc with both ipc and rw_mutex locks held in case of success
841 * or an err-code without any lock held otherwise.
842 */
843struct kern_ipc_perm *ipcctl_pre_down(struct ipc_ids *ids, int id, int cmd,
844 struct ipc64_perm *perm, int extra_perm)
845{
846 struct kern_ipc_perm *ipcp;
847 int err;
848
849 down_write(&ids->rw_mutex);
850 ipcp = ipc_lock_check_down(ids, id);
851 if (IS_ERR(ipcp)) {
852 err = PTR_ERR(ipcp);
853 goto out_up;
854 }
855
856 err = audit_ipc_obj(ipcp);
857 if (err)
858 goto out_unlock;
859
860 if (cmd == IPC_SET) {
861 err = audit_ipc_set_perm(extra_perm, perm->uid,
862 perm->gid, perm->mode);
863 if (err)
864 goto out_unlock;
865 }
866 if (current->euid == ipcp->cuid ||
867 current->euid == ipcp->uid || capable(CAP_SYS_ADMIN))
868 return ipcp;
869
870 err = -EPERM;
871out_unlock:
872 ipc_unlock(ipcp);
873out_up:
874 up_write(&ids->rw_mutex);
875 return ERR_PTR(err);
876}
877
827#ifdef __ARCH_WANT_IPC_PARSE_VERSION 878#ifdef __ARCH_WANT_IPC_PARSE_VERSION
828 879
829 880