FreeBSD/sys/kern/sysv_ipc.c
/*
 * Check for IPC permission.
 *
 * Note: The MAC Framework does not require any modifications to the
 * ipcperm() function, as access control checks are performed throughout the
 * implementation of each primitive.  Those entry point calls complement the
 * ipcperm() discertionary checks.  Unlike file system discretionary access
 * control, the original create of an object is given the same rights as the
 * current owner.
 */
Check for IPC permission.
Note: The MAC Framework does not require any modifications to the
ipcperm() function, as access control checks are performed throughout the
implementation of each primitive.  Those entry point calls complement the
ipcperm() discertionary checks.  Unlike file system discretionary access
control, the original create of an object is given the same rights as the
current owner.
Check for IPC permission . Note : The MAC Framework does not require any modifications to the ipcperm () function as access control checks are performed throughout the implementation of each primitive . Those entry point calls complement the ipcperm () discertionary checks . Unlike file system discretionary access control the original create of an object is given the same rights as the current owner .
int
ipcperm(struct thread *td, struct ipc_perm *perm, int acc_mode)
{
	struct ucred *cred = td->td_ucred;
	int error, obj_mode, dac_granted, priv_granted;
	dac_granted = 0;
	if (cred->cr_uid == perm->cuid || cred->cr_uid == perm->uid) {
		obj_mode = perm->mode;
		dac_granted |= IPC_M;
	} else if (groupmember(perm->gid, cred) ||
	    groupmember(perm->cgid, cred)) {
		obj_mode = perm->mode;
		obj_mode <<= 3;
	} else {
		obj_mode = perm->mode;
		obj_mode <<= 6;
	}
#if 0
	if (obj_mode & IPC_M)
		dac_granted |= IPC_M;
#endif
	if (obj_mode & IPC_R)
		dac_granted |= IPC_R;
	if (obj_mode & IPC_W)
		dac_granted |= IPC_W;
	if ((dac_granted & acc_mode) == acc_mode)
		return (0);
	priv_granted = 0;
	if ((acc_mode & IPC_M) && !(dac_granted & IPC_M)) {
		error = priv_check(td, PRIV_IPC_ADMIN);
		if (error == 0)
			priv_granted |= IPC_M;
	}
	if ((acc_mode & IPC_R) && !(dac_granted & IPC_R)) {
		error = priv_check(td, PRIV_IPC_READ);
		if (error == 0)
			priv_granted |= IPC_R;
	}
	if ((acc_mode & IPC_W) && !(dac_granted & IPC_W)) {
		error = priv_check(td, PRIV_IPC_WRITE);
		if (error == 0)
			priv_granted |= IPC_W;
	}
	if (((dac_granted | priv_granted) & acc_mode) == acc_mode)
		return (0);
	else
		return (EACCES);
}
int ipcperm ( struct thread * td , struct ipc_perm * perm , int acc_mode ) { struct ucred * cred = td -> td_ucred ; int error , obj_mode , dac_granted , priv_granted ; dac_granted = 0 ; if ( cred -> cr_uid == perm -> cuid || cred -> cr_uid == perm -> uid ) { obj_mode = perm -> mode ; dac_granted |= IPC_M ; } else if ( groupmember ( perm -> gid , cred ) || groupmember ( perm -> cgid , cred ) ) { obj_mode = perm -> mode ; obj_mode <<= 3 ; } else { obj_mode = perm -> mode ; obj_mode <<= 6 ; } #if 0 if ( obj_mode & IPC_M ) dac_granted |= IPC_M ; #endif if ( obj_mode & IPC_R ) dac_granted |= IPC_R ; if ( obj_mode & IPC_W ) dac_granted |= IPC_W ; if ( ( dac_granted & acc_mode ) == acc_mode ) return ( 0 ) ; priv_granted = 0 ; if ( ( acc_mode & IPC_M ) && ! ( dac_granted & IPC_M ) ) { error = priv_check ( td , PRIV_IPC_ADMIN ) ; if ( error == 0 ) priv_granted |= IPC_M ; } if ( ( acc_mode & IPC_R ) && ! ( dac_granted & IPC_R ) ) { error = priv_check ( td , PRIV_IPC_READ ) ; if ( error == 0 ) priv_granted |= IPC_R ; } if ( ( acc_mode & IPC_W ) && ! ( dac_granted & IPC_W ) ) { error = priv_check ( td , PRIV_IPC_WRITE ) ; if ( error == 0 ) priv_granted |= IPC_W ; } if ( ( ( dac_granted | priv_granted ) & acc_mode ) == acc_mode ) return ( 0 ) ; else return ( EACCES ) ; }
Check for IPC permission.
Check for IPC permission .
/*
	 * While the System V IPC permission model allows IPC_M to be
	 * granted, as part of the mode, our implementation requires
	 * privilege to adminster the object if not the owner or creator.
	 */ /*
	 * Simple case: all required rights are granted by DAC.
	 */ /*
	 * Privilege is required to satisfy the request.
	 */