Commit aefad959 authored by Eric W. Biederman's avatar Eric W. Biederman
Browse files

sem/security: Pass kern_ipc_perm not sem_array into the sem security hooks



All of the implementations of security hooks that take sem_array only
access sem_perm the struct kern_ipc_perm member.  This means the
dependencies of the sem security hooks can be simplified by passing
the kern_ipc_perm member of sem_array.

Making this change will allow struct sem and struct sem_array
to become private to ipc/sem.c.

Signed-off-by: default avatar"Eric W. Biederman" <ebiederm@xmission.com>
parent dd206bec
Loading
Loading
Loading
Loading
+5 −5
Original line number Diff line number Diff line
@@ -1592,11 +1592,11 @@ union security_list_options {
	int (*shm_shmat)(struct shmid_kernel *shp, char __user *shmaddr,
				int shmflg);

	int (*sem_alloc_security)(struct sem_array *sma);
	void (*sem_free_security)(struct sem_array *sma);
	int (*sem_associate)(struct sem_array *sma, int semflg);
	int (*sem_semctl)(struct sem_array *sma, int cmd);
	int (*sem_semop)(struct sem_array *sma, struct sembuf *sops,
	int (*sem_alloc_security)(struct kern_ipc_perm *sma);
	void (*sem_free_security)(struct kern_ipc_perm *sma);
	int (*sem_associate)(struct kern_ipc_perm *sma, int semflg);
	int (*sem_semctl)(struct kern_ipc_perm *sma, int cmd);
	int (*sem_semop)(struct kern_ipc_perm *sma, struct sembuf *sops,
				unsigned nsops, int alter);

	int (*netlink_send)(struct sock *sk, struct sk_buff *skb);
+10 −11
Original line number Diff line number Diff line
@@ -36,7 +36,6 @@ struct linux_binprm;
struct cred;
struct rlimit;
struct siginfo;
struct sem_array;
struct sembuf;
struct kern_ipc_perm;
struct audit_context;
@@ -368,11 +367,11 @@ void security_shm_free(struct shmid_kernel *shp);
int security_shm_associate(struct shmid_kernel *shp, int shmflg);
int security_shm_shmctl(struct shmid_kernel *shp, int cmd);
int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmflg);
int security_sem_alloc(struct sem_array *sma);
void security_sem_free(struct sem_array *sma);
int security_sem_associate(struct sem_array *sma, int semflg);
int security_sem_semctl(struct sem_array *sma, int cmd);
int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
int security_sem_alloc(struct kern_ipc_perm *sma);
void security_sem_free(struct kern_ipc_perm *sma);
int security_sem_associate(struct kern_ipc_perm *sma, int semflg);
int security_sem_semctl(struct kern_ipc_perm *sma, int cmd);
int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
			unsigned nsops, int alter);
void security_d_instantiate(struct dentry *dentry, struct inode *inode);
int security_getprocattr(struct task_struct *p, char *name, char **value);
@@ -1103,25 +1102,25 @@ static inline int security_shm_shmat(struct shmid_kernel *shp,
	return 0;
}

static inline int security_sem_alloc(struct sem_array *sma)
static inline int security_sem_alloc(struct kern_ipc_perm *sma)
{
	return 0;
}

static inline void security_sem_free(struct sem_array *sma)
static inline void security_sem_free(struct kern_ipc_perm *sma)
{ }

static inline int security_sem_associate(struct sem_array *sma, int semflg)
static inline int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
{
	return 0;
}

static inline int security_sem_semctl(struct sem_array *sma, int cmd)
static inline int security_sem_semctl(struct kern_ipc_perm *sma, int cmd)
{
	return 0;
}

static inline int security_sem_semop(struct sem_array *sma,
static inline int security_sem_semop(struct kern_ipc_perm *sma,
				     struct sembuf *sops, unsigned nsops,
				     int alter)
{
+8 −11
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ static void sem_rcu_free(struct rcu_head *head)
	struct kern_ipc_perm *p = container_of(head, struct kern_ipc_perm, rcu);
	struct sem_array *sma = container_of(p, struct sem_array, sem_perm);

	security_sem_free(sma);
	security_sem_free(&sma->sem_perm);
	kvfree(sma);
}

@@ -495,7 +495,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
	sma->sem_perm.key = key;

	sma->sem_perm.security = NULL;
	retval = security_sem_alloc(sma);
	retval = security_sem_alloc(&sma->sem_perm);
	if (retval) {
		kvfree(sma);
		return retval;
@@ -535,10 +535,7 @@ static int newary(struct ipc_namespace *ns, struct ipc_params *params)
 */
static inline int sem_security(struct kern_ipc_perm *ipcp, int semflg)
{
	struct sem_array *sma;

	sma = container_of(ipcp, struct sem_array, sem_perm);
	return security_sem_associate(sma, semflg);
	return security_sem_associate(ipcp, semflg);
}

/*
@@ -1209,7 +1206,7 @@ static int semctl_stat(struct ipc_namespace *ns, int semid,
	if (ipcperms(ns, &sma->sem_perm, S_IRUGO))
		goto out_unlock;

	err = security_sem_semctl(sma, cmd);
	err = security_sem_semctl(&sma->sem_perm, cmd);
	if (err)
		goto out_unlock;

@@ -1300,7 +1297,7 @@ static int semctl_setval(struct ipc_namespace *ns, int semid, int semnum,
		return -EACCES;
	}

	err = security_sem_semctl(sma, SETVAL);
	err = security_sem_semctl(&sma->sem_perm, SETVAL);
	if (err) {
		rcu_read_unlock();
		return -EACCES;
@@ -1354,7 +1351,7 @@ static int semctl_main(struct ipc_namespace *ns, int semid, int semnum,
	if (ipcperms(ns, &sma->sem_perm, cmd == SETALL ? S_IWUGO : S_IRUGO))
		goto out_rcu_wakeup;

	err = security_sem_semctl(sma, cmd);
	err = security_sem_semctl(&sma->sem_perm, cmd);
	if (err)
		goto out_rcu_wakeup;

@@ -1545,7 +1542,7 @@ static int semctl_down(struct ipc_namespace *ns, int semid,

	sma = container_of(ipcp, struct sem_array, sem_perm);

	err = security_sem_semctl(sma, cmd);
	err = security_sem_semctl(&sma->sem_perm, cmd);
	if (err)
		goto out_unlock1;

@@ -1962,7 +1959,7 @@ static long do_semtimedop(int semid, struct sembuf __user *tsops,
		goto out_free;
	}

	error = security_sem_semop(sma, sops, nsops, alter);
	error = security_sem_semop(&sma->sem_perm, sops, nsops, alter);
	if (error) {
		rcu_read_unlock();
		goto out_free;
+5 −5
Original line number Diff line number Diff line
@@ -1220,27 +1220,27 @@ int security_shm_shmat(struct shmid_kernel *shp, char __user *shmaddr, int shmfl
	return call_int_hook(shm_shmat, 0, shp, shmaddr, shmflg);
}

int security_sem_alloc(struct sem_array *sma)
int security_sem_alloc(struct kern_ipc_perm *sma)
{
	return call_int_hook(sem_alloc_security, 0, sma);
}

void security_sem_free(struct sem_array *sma)
void security_sem_free(struct kern_ipc_perm *sma)
{
	call_void_hook(sem_free_security, sma);
}

int security_sem_associate(struct sem_array *sma, int semflg)
int security_sem_associate(struct kern_ipc_perm *sma, int semflg)
{
	return call_int_hook(sem_associate, 0, sma, semflg);
}

int security_sem_semctl(struct sem_array *sma, int cmd)
int security_sem_semctl(struct kern_ipc_perm *sma, int cmd)
{
	return call_int_hook(sem_semctl, 0, sma, cmd);
}

int security_sem_semop(struct sem_array *sma, struct sembuf *sops,
int security_sem_semop(struct kern_ipc_perm *sma, struct sembuf *sops,
			unsigned nsops, int alter)
{
	return call_int_hook(sem_semop, 0, sma, sops, nsops, alter);
+14 −14
Original line number Diff line number Diff line
@@ -5767,53 +5767,53 @@ static int selinux_shm_shmat(struct shmid_kernel *shp,
}

/* Semaphore security operations */
static int selinux_sem_alloc_security(struct sem_array *sma)
static int selinux_sem_alloc_security(struct kern_ipc_perm *sma)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	u32 sid = current_sid();
	int rc;

	rc = ipc_alloc_security(&sma->sem_perm, SECCLASS_SEM);
	rc = ipc_alloc_security(sma, SECCLASS_SEM);
	if (rc)
		return rc;

	isec = sma->sem_perm.security;
	isec = sma->security;

	ad.type = LSM_AUDIT_DATA_IPC;
	ad.u.ipc_id = sma->sem_perm.key;
	ad.u.ipc_id = sma->key;

	rc = avc_has_perm(sid, isec->sid, SECCLASS_SEM,
			  SEM__CREATE, &ad);
	if (rc) {
		ipc_free_security(&sma->sem_perm);
		ipc_free_security(sma);
		return rc;
	}
	return 0;
}

static void selinux_sem_free_security(struct sem_array *sma)
static void selinux_sem_free_security(struct kern_ipc_perm *sma)
{
	ipc_free_security(&sma->sem_perm);
	ipc_free_security(sma);
}

static int selinux_sem_associate(struct sem_array *sma, int semflg)
static int selinux_sem_associate(struct kern_ipc_perm *sma, int semflg)
{
	struct ipc_security_struct *isec;
	struct common_audit_data ad;
	u32 sid = current_sid();

	isec = sma->sem_perm.security;
	isec = sma->security;

	ad.type = LSM_AUDIT_DATA_IPC;
	ad.u.ipc_id = sma->sem_perm.key;
	ad.u.ipc_id = sma->key;

	return avc_has_perm(sid, isec->sid, SECCLASS_SEM,
			    SEM__ASSOCIATE, &ad);
}

/* Note, at this point, sma is locked down */
static int selinux_sem_semctl(struct sem_array *sma, int cmd)
static int selinux_sem_semctl(struct kern_ipc_perm *sma, int cmd)
{
	int err;
	u32 perms;
@@ -5851,11 +5851,11 @@ static int selinux_sem_semctl(struct sem_array *sma, int cmd)
		return 0;
	}

	err = ipc_has_perm(&sma->sem_perm, perms);
	err = ipc_has_perm(sma, perms);
	return err;
}

static int selinux_sem_semop(struct sem_array *sma,
static int selinux_sem_semop(struct kern_ipc_perm *sma,
			     struct sembuf *sops, unsigned nsops, int alter)
{
	u32 perms;
@@ -5865,7 +5865,7 @@ static int selinux_sem_semop(struct sem_array *sma,
	else
		perms = SEM__READ;

	return ipc_has_perm(&sma->sem_perm, perms);
	return ipc_has_perm(sma, perms);
}

static int selinux_ipc_permission(struct kern_ipc_perm *ipcp, short flag)
Loading