FreeBSD/sys/security/audit/audit_pipe.c
/*
 * Audit pipe ioctl() routine.  Handle file descriptor and audit pipe layer
 * commands.
 */
Audit pipe ioctl() routine.  Handle file descriptor and audit pipe layer
commands.
Audit pipe ioctl () routine . Handle file descriptor and audit pipe layer commands .
static int
audit_pipe_ioctl(struct cdev *dev, u_long cmd, caddr_t data, int flag,
    struct thread *td)
{
	struct auditpipe_ioctl_preselect *aip;
	struct audit_pipe *ap;
	au_mask_t *maskp;
	int error, mode;
	au_id_t auid;
	error = devfs_get_cdevpriv((void **)&ap);
	if (error != 0)
		return (error);
	switch (cmd) {
	case FIONBIO:
		AUDIT_PIPE_LOCK(ap);
		if (*(int *)data)
			ap->ap_flags |= AUDIT_PIPE_NBIO;
		else
			ap->ap_flags &= ~AUDIT_PIPE_NBIO;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case FIONREAD:
		AUDIT_PIPE_LOCK(ap);
		*(int *)data = ap->ap_qbyteslen - ap->ap_qoffset;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case FIOASYNC:
		AUDIT_PIPE_LOCK(ap);
		if (*(int *)data)
			ap->ap_flags |= AUDIT_PIPE_ASYNC;
		else
			ap->ap_flags &= ~AUDIT_PIPE_ASYNC;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case FIOSETOWN:
		error = fsetown(*(int *)data, &ap->ap_sigio);
		break;
	case FIOGETOWN:
		*(int *)data = fgetown(&ap->ap_sigio);
		error = 0;
		break;
	case AUDITPIPE_GET_QLEN:
		*(u_int *)data = ap->ap_qlen;
		error = 0;
		break;
	case AUDITPIPE_GET_QLIMIT:
		*(u_int *)data = ap->ap_qlimit;
		error = 0;
		break;
	case AUDITPIPE_SET_QLIMIT:
		if (*(u_int *)data >= AUDIT_PIPE_QLIMIT_MIN ||
		    *(u_int *)data <= AUDIT_PIPE_QLIMIT_MAX) {
			ap->ap_qlimit = *(u_int *)data;
			error = 0;
		} else
			error = EINVAL;
		break;
	case AUDITPIPE_GET_QLIMIT_MIN:
		*(u_int *)data = AUDIT_PIPE_QLIMIT_MIN;
		error = 0;
		break;
	case AUDITPIPE_GET_QLIMIT_MAX:
		*(u_int *)data = AUDIT_PIPE_QLIMIT_MAX;
		error = 0;
		break;
	case AUDITPIPE_GET_PRESELECT_FLAGS:
		AUDIT_PIPE_LOCK(ap);
		maskp = (au_mask_t *)data;
		*maskp = ap->ap_preselect_flags;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case AUDITPIPE_SET_PRESELECT_FLAGS:
		AUDIT_PIPE_LOCK(ap);
		maskp = (au_mask_t *)data;
		ap->ap_preselect_flags = *maskp;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case AUDITPIPE_GET_PRESELECT_NAFLAGS:
		AUDIT_PIPE_LOCK(ap);
		maskp = (au_mask_t *)data;
		*maskp = ap->ap_preselect_naflags;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case AUDITPIPE_SET_PRESELECT_NAFLAGS:
		AUDIT_PIPE_LOCK(ap);
		maskp = (au_mask_t *)data;
		ap->ap_preselect_naflags = *maskp;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case AUDITPIPE_GET_PRESELECT_AUID:
		aip = (struct auditpipe_ioctl_preselect *)data;
		error = audit_pipe_preselect_get(ap, aip->aip_auid,
		    &aip->aip_mask);
		break;
	case AUDITPIPE_SET_PRESELECT_AUID:
		aip = (struct auditpipe_ioctl_preselect *)data;
		audit_pipe_preselect_set(ap, aip->aip_auid, aip->aip_mask);
		error = 0;
		break;
	case AUDITPIPE_DELETE_PRESELECT_AUID:
		auid = *(au_id_t *)data;
		error = audit_pipe_preselect_delete(ap, auid);
		break;
	case AUDITPIPE_FLUSH_PRESELECT_AUID:
		audit_pipe_preselect_flush(ap);
		error = 0;
		break;
	case AUDITPIPE_GET_PRESELECT_MODE:
		AUDIT_PIPE_LOCK(ap);
		*(int *)data = ap->ap_preselect_mode;
		AUDIT_PIPE_UNLOCK(ap);
		error = 0;
		break;
	case AUDITPIPE_SET_PRESELECT_MODE:
		mode = *(int *)data;
		switch (mode) {
		case AUDITPIPE_PRESELECT_MODE_TRAIL:
		case AUDITPIPE_PRESELECT_MODE_LOCAL:
			AUDIT_PIPE_LOCK(ap);
			ap->ap_preselect_mode = mode;
			AUDIT_PIPE_UNLOCK(ap);
			error = 0;
			break;
		default:
			error = EINVAL;
		}
		break;
	case AUDITPIPE_FLUSH:
		if (AUDIT_PIPE_SX_XLOCK_SIG(ap) != 0)
			return (EINTR);
		AUDIT_PIPE_LOCK(ap);
		audit_pipe_flush(ap);
		AUDIT_PIPE_UNLOCK(ap);
		AUDIT_PIPE_SX_XUNLOCK(ap);
		error = 0;
		break;
	case AUDITPIPE_GET_MAXAUDITDATA:
		*(u_int *)data = MAXAUDITDATA;
		error = 0;
		break;
	case AUDITPIPE_GET_INSERTS:
		*(u_int *)data = ap->ap_inserts;
		error = 0;
		break;
	case AUDITPIPE_GET_READS:
		*(u_int *)data = ap->ap_reads;
		error = 0;
		break;
	case AUDITPIPE_GET_DROPS:
		*(u_int *)data = ap->ap_drops;
		error = 0;
		break;
	case AUDITPIPE_GET_TRUNCATES:
		*(u_int *)data = 0;
		error = 0;
		break;
	default:
		error = ENOTTY;
	}
	return (error);
}
static int audit_pipe_ioctl ( struct cdev * dev , u_long cmd , caddr_t data , int flag , struct thread * td ) { struct auditpipe_ioctl_preselect * aip ; struct audit_pipe * ap ; au_mask_t * maskp ; int error , mode ; au_id_t auid ; error = devfs_get_cdevpriv ( ( void * * ) & ap ) ; if ( error != 0 ) return ( error ) ; switch ( cmd ) { case FIONBIO : AUDIT_PIPE_LOCK ( ap ) ; if ( * ( int * ) data ) ap -> ap_flags |= AUDIT_PIPE_NBIO ; else ap -> ap_flags &= ~ AUDIT_PIPE_NBIO ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case FIONREAD : AUDIT_PIPE_LOCK ( ap ) ; * ( int * ) data = ap -> ap_qbyteslen - ap -> ap_qoffset ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case FIOASYNC : AUDIT_PIPE_LOCK ( ap ) ; if ( * ( int * ) data ) ap -> ap_flags |= AUDIT_PIPE_ASYNC ; else ap -> ap_flags &= ~ AUDIT_PIPE_ASYNC ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case FIOSETOWN : error = fsetown ( * ( int * ) data , & ap -> ap_sigio ) ; break ; case FIOGETOWN : * ( int * ) data = fgetown ( & ap -> ap_sigio ) ; error = 0 ; break ; case AUDITPIPE_GET_QLEN : * ( u_int * ) data = ap -> ap_qlen ; error = 0 ; break ; case AUDITPIPE_GET_QLIMIT : * ( u_int * ) data = ap -> ap_qlimit ; error = 0 ; break ; case AUDITPIPE_SET_QLIMIT : if ( * ( u_int * ) data >= AUDIT_PIPE_QLIMIT_MIN || * ( u_int * ) data <= AUDIT_PIPE_QLIMIT_MAX ) { ap -> ap_qlimit = * ( u_int * ) data ; error = 0 ; } else error = EINVAL ; break ; case AUDITPIPE_GET_QLIMIT_MIN : * ( u_int * ) data = AUDIT_PIPE_QLIMIT_MIN ; error = 0 ; break ; case AUDITPIPE_GET_QLIMIT_MAX : * ( u_int * ) data = AUDIT_PIPE_QLIMIT_MAX ; error = 0 ; break ; case AUDITPIPE_GET_PRESELECT_FLAGS : AUDIT_PIPE_LOCK ( ap ) ; maskp = ( au_mask_t * ) data ; * maskp = ap -> ap_preselect_flags ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case AUDITPIPE_SET_PRESELECT_FLAGS : AUDIT_PIPE_LOCK ( ap ) ; maskp = ( au_mask_t * ) data ; ap -> ap_preselect_flags = * maskp ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case AUDITPIPE_GET_PRESELECT_NAFLAGS : AUDIT_PIPE_LOCK ( ap ) ; maskp = ( au_mask_t * ) data ; * maskp = ap -> ap_preselect_naflags ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case AUDITPIPE_SET_PRESELECT_NAFLAGS : AUDIT_PIPE_LOCK ( ap ) ; maskp = ( au_mask_t * ) data ; ap -> ap_preselect_naflags = * maskp ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case AUDITPIPE_GET_PRESELECT_AUID : aip = ( struct auditpipe_ioctl_preselect * ) data ; error = audit_pipe_preselect_get ( ap , aip -> aip_auid , & aip -> aip_mask ) ; break ; case AUDITPIPE_SET_PRESELECT_AUID : aip = ( struct auditpipe_ioctl_preselect * ) data ; audit_pipe_preselect_set ( ap , aip -> aip_auid , aip -> aip_mask ) ; error = 0 ; break ; case AUDITPIPE_DELETE_PRESELECT_AUID : auid = * ( au_id_t * ) data ; error = audit_pipe_preselect_delete ( ap , auid ) ; break ; case AUDITPIPE_FLUSH_PRESELECT_AUID : audit_pipe_preselect_flush ( ap ) ; error = 0 ; break ; case AUDITPIPE_GET_PRESELECT_MODE : AUDIT_PIPE_LOCK ( ap ) ; * ( int * ) data = ap -> ap_preselect_mode ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; case AUDITPIPE_SET_PRESELECT_MODE : mode = * ( int * ) data ; switch ( mode ) { case AUDITPIPE_PRESELECT_MODE_TRAIL : case AUDITPIPE_PRESELECT_MODE_LOCAL : AUDIT_PIPE_LOCK ( ap ) ; ap -> ap_preselect_mode = mode ; AUDIT_PIPE_UNLOCK ( ap ) ; error = 0 ; break ; default : error = EINVAL ; } break ; case AUDITPIPE_FLUSH : if ( AUDIT_PIPE_SX_XLOCK_SIG ( ap ) != 0 ) return ( EINTR ) ; AUDIT_PIPE_LOCK ( ap ) ; audit_pipe_flush ( ap ) ; AUDIT_PIPE_UNLOCK ( ap ) ; AUDIT_PIPE_SX_XUNLOCK ( ap ) ; error = 0 ; break ; case AUDITPIPE_GET_MAXAUDITDATA : * ( u_int * ) data = MAXAUDITDATA ; error = 0 ; break ; case AUDITPIPE_GET_INSERTS : * ( u_int * ) data = ap -> ap_inserts ; error = 0 ; break ; case AUDITPIPE_GET_READS : * ( u_int * ) data = ap -> ap_reads ; error = 0 ; break ; case AUDITPIPE_GET_DROPS : * ( u_int * ) data = ap -> ap_drops ; error = 0 ; break ; case AUDITPIPE_GET_TRUNCATES : * ( u_int * ) data = 0 ; error = 0 ; break ; default : error = ENOTTY ; } return ( error ) ; }
Audit pipe ioctl() routine.
Audit pipe ioctl () routine .
/*
	 * Audit pipe ioctls: first come standard device node ioctls, then
	 * manipulation of pipe settings, and finally, statistics query
	 * ioctls.
	 */ /* Lockless integer write. */