FreeBSD/sys/security/mac_portacl/mac_portacl.c
/*
 * Note: due to races, there is not a single serializable order
 * between parallel calls to the sysctl.
 */
due to races, there is not a single serializable order
between parallel calls to the sysctl.
due to races there is not a single serializable order between parallel calls to the sysctl .
static int
sysctl_rules(SYSCTL_HANDLER_ARGS)
{
	char *string, *copy_string, *new_string;
	struct rulehead head, save_head;
	int error;
	new_string = NULL;
	if (req->newptr != NULL) {
		new_string = malloc(MAC_RULE_STRING_LEN, M_PORTACL,
		    M_WAITOK | M_ZERO);
		mtx_lock(&rule_mtx);
		strcpy(new_string, rule_string);
		mtx_unlock(&rule_mtx);
		string = new_string;
	} else
		string = rule_string;
	error = sysctl_handle_string(oidp, string, MAC_RULE_STRING_LEN, req);
	if (error)
		goto out;
	if (req->newptr != NULL) {
		copy_string = strdup(string, M_PORTACL);
		TAILQ_INIT(&head);
		error = parse_rules(copy_string, &head);
		free(copy_string, M_PORTACL);
		if (error)
			goto out;
		TAILQ_INIT(&save_head);
		mtx_lock(&rule_mtx);
		TAILQ_CONCAT(&save_head, &rule_head, r_entries);
		TAILQ_CONCAT(&rule_head, &head, r_entries);
		strcpy(rule_string, string);
		mtx_unlock(&rule_mtx);
		toast_rules(&save_head);
	}
out:
	if (new_string != NULL)
		free(new_string, M_PORTACL);
	return (error);
}
static int sysctl_rules ( SYSCTL_HANDLER_ARGS ) { char * string , * copy_string , * new_string ; struct rulehead head , save_head ; int error ; new_string = NULL ; if ( req -> newptr != NULL ) { new_string = malloc ( MAC_RULE_STRING_LEN , M_PORTACL , M_WAITOK | M_ZERO ) ; mtx_lock ( & rule_mtx ) ; strcpy ( new_string , rule_string ) ; mtx_unlock ( & rule_mtx ) ; string = new_string ; } else string = rule_string ; error = sysctl_handle_string ( oidp , string , MAC_RULE_STRING_LEN , req ) ; if ( error ) goto out ; if ( req -> newptr != NULL ) { copy_string = strdup ( string , M_PORTACL ) ; TAILQ_INIT ( & head ) ; error = parse_rules ( copy_string , & head ) ; free ( copy_string , M_PORTACL ) ; if ( error ) goto out ; TAILQ_INIT ( & save_head ) ; mtx_lock ( & rule_mtx ) ; TAILQ_CONCAT ( & save_head , & rule_head , r_entries ) ; TAILQ_CONCAT ( & rule_head , & head , r_entries ) ; strcpy ( rule_string , string ) ; mtx_unlock ( & rule_mtx ) ; toast_rules ( & save_head ) ; } out : if ( new_string != NULL ) free ( new_string , M_PORTACL ) ; return ( error ) ; }
Note: due to races, there is not a single serializable order
 between parallel calls to the sysctl.
Note : due to races there is not a single serializable order between parallel calls to the sysctl .