1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <netinet/in.h> 2255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 3255e72915d4cbddceb435e13d81601755714e9fSE Android 4255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context.h" 6255e72915d4cbddceb435e13d81601755714e9fSE Android#include "handle.h" 7255e72915d4cbddceb435e13d81601755714e9fSE Android 8255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 9255e72915d4cbddceb435e13d81601755714e9fSE Android#include "port_internal.h" 10255e72915d4cbddceb435e13d81601755714e9fSE Android 11255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int sepol2ipproto(sepol_handle_t * handle, int proto) 12255e72915d4cbddceb435e13d81601755714e9fSE Android{ 13255e72915d4cbddceb435e13d81601755714e9fSE Android 14255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 15255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_TCP: 16255e72915d4cbddceb435e13d81601755714e9fSE Android return IPPROTO_TCP; 17255e72915d4cbddceb435e13d81601755714e9fSE Android case SEPOL_PROTO_UDP: 18255e72915d4cbddceb435e13d81601755714e9fSE Android return IPPROTO_UDP; 19255e72915d4cbddceb435e13d81601755714e9fSE Android default: 20255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "unsupported protocol %u", proto); 21255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 22255e72915d4cbddceb435e13d81601755714e9fSE Android } 23255e72915d4cbddceb435e13d81601755714e9fSE Android} 24255e72915d4cbddceb435e13d81601755714e9fSE Android 25255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic inline int ipproto2sepol(sepol_handle_t * handle, int proto) 26255e72915d4cbddceb435e13d81601755714e9fSE Android{ 27255e72915d4cbddceb435e13d81601755714e9fSE Android 28255e72915d4cbddceb435e13d81601755714e9fSE Android switch (proto) { 29255e72915d4cbddceb435e13d81601755714e9fSE Android case IPPROTO_TCP: 30255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_PROTO_TCP; 31255e72915d4cbddceb435e13d81601755714e9fSE Android case IPPROTO_UDP: 32255e72915d4cbddceb435e13d81601755714e9fSE Android return SEPOL_PROTO_UDP; 33255e72915d4cbddceb435e13d81601755714e9fSE Android default: 34255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "invalid protocol %u " "found in policy", proto); 35255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 36255e72915d4cbddceb435e13d81601755714e9fSE Android } 37255e72915d4cbddceb435e13d81601755714e9fSE Android} 38255e72915d4cbddceb435e13d81601755714e9fSE Android 39255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create a low level port structure from 40255e72915d4cbddceb435e13d81601755714e9fSE Android * a high level representation */ 41255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int port_from_record(sepol_handle_t * handle, 42255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 43255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t ** port, const sepol_port_t * data) 44255e72915d4cbddceb435e13d81601755714e9fSE Android{ 45255e72915d4cbddceb435e13d81601755714e9fSE Android 46255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *tmp_port = NULL; 47255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *tmp_con = NULL; 48255e72915d4cbddceb435e13d81601755714e9fSE Android int tmp_proto; 49255e72915d4cbddceb435e13d81601755714e9fSE Android 50255e72915d4cbddceb435e13d81601755714e9fSE Android int low = sepol_port_get_low(data); 51255e72915d4cbddceb435e13d81601755714e9fSE Android int high = sepol_port_get_high(data); 52255e72915d4cbddceb435e13d81601755714e9fSE Android int proto = sepol_port_get_proto(data); 53255e72915d4cbddceb435e13d81601755714e9fSE Android 54255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port = (ocontext_t *) calloc(1, sizeof(ocontext_t)); 55255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_port) 56255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 57255e72915d4cbddceb435e13d81601755714e9fSE Android 58255e72915d4cbddceb435e13d81601755714e9fSE Android /* Process protocol */ 59255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_proto = sepol2ipproto(handle, proto); 60255e72915d4cbddceb435e13d81601755714e9fSE Android if (tmp_proto < 0) 61255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 62255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->u.port.protocol = tmp_proto; 63255e72915d4cbddceb435e13d81601755714e9fSE Android 64255e72915d4cbddceb435e13d81601755714e9fSE Android /* Port range */ 65255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->u.port.low_port = low; 66255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->u.port.high_port = high; 67255e72915d4cbddceb435e13d81601755714e9fSE Android if (tmp_port->u.port.low_port > tmp_port->u.port.high_port) { 68255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "low port %d exceeds high port %d", 69255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_port->u.port.low_port, tmp_port->u.port.high_port); 70255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 71255e72915d4cbddceb435e13d81601755714e9fSE Android } 72255e72915d4cbddceb435e13d81601755714e9fSE Android 73255e72915d4cbddceb435e13d81601755714e9fSE Android /* Context */ 74255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_from_record(handle, policydb, &tmp_con, 75255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_get_con(data)) < 0) 76255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 77255e72915d4cbddceb435e13d81601755714e9fSE Android context_cpy(&tmp_port->context[0], tmp_con); 78255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 79255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 80255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_con = NULL; 81255e72915d4cbddceb435e13d81601755714e9fSE Android 82255e72915d4cbddceb435e13d81601755714e9fSE Android *port = tmp_port; 83255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 84255e72915d4cbddceb435e13d81601755714e9fSE Android 85255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 86255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 87255e72915d4cbddceb435e13d81601755714e9fSE Android 88255e72915d4cbddceb435e13d81601755714e9fSE Android err: 89255e72915d4cbddceb435e13d81601755714e9fSE Android if (tmp_port != NULL) { 90255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&tmp_port->context[0]); 91255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_port); 92255e72915d4cbddceb435e13d81601755714e9fSE Android } 93255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 94255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 95255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not create port structure for range %u:%u (%s)", 96255e72915d4cbddceb435e13d81601755714e9fSE Android low, high, sepol_port_get_proto_str(proto)); 97255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 98255e72915d4cbddceb435e13d81601755714e9fSE Android} 99255e72915d4cbddceb435e13d81601755714e9fSE Android 100255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int port_to_record(sepol_handle_t * handle, 101255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 102255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t * port, sepol_port_t ** record) 103255e72915d4cbddceb435e13d81601755714e9fSE Android{ 104255e72915d4cbddceb435e13d81601755714e9fSE Android 105255e72915d4cbddceb435e13d81601755714e9fSE Android int proto = port->u.port.protocol; 106255e72915d4cbddceb435e13d81601755714e9fSE Android int low = port->u.port.low_port; 107255e72915d4cbddceb435e13d81601755714e9fSE Android int high = port->u.port.high_port; 108255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *con = &port->context[0]; 109255e72915d4cbddceb435e13d81601755714e9fSE Android int rec_proto = -1; 110255e72915d4cbddceb435e13d81601755714e9fSE Android 111255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_t *tmp_con = NULL; 112255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_t *tmp_record = NULL; 113255e72915d4cbddceb435e13d81601755714e9fSE Android 114255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_port_create(handle, &tmp_record) < 0) 115255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 116255e72915d4cbddceb435e13d81601755714e9fSE Android 117255e72915d4cbddceb435e13d81601755714e9fSE Android rec_proto = ipproto2sepol(handle, proto); 118255e72915d4cbddceb435e13d81601755714e9fSE Android if (rec_proto < 0) 119255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 120255e72915d4cbddceb435e13d81601755714e9fSE Android 121255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_set_proto(tmp_record, rec_proto); 122255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_set_range(tmp_record, low, high); 123255e72915d4cbddceb435e13d81601755714e9fSE Android 124255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_to_record(handle, policydb, con, &tmp_con) < 0) 125255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 126255e72915d4cbddceb435e13d81601755714e9fSE Android 127255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_port_set_con(handle, tmp_record, tmp_con) < 0) 128255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 129255e72915d4cbddceb435e13d81601755714e9fSE Android 130255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 131255e72915d4cbddceb435e13d81601755714e9fSE Android *record = tmp_record; 132255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 133255e72915d4cbddceb435e13d81601755714e9fSE Android 134255e72915d4cbddceb435e13d81601755714e9fSE Android err: 135255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not convert port range %u - %u (%s) " 136255e72915d4cbddceb435e13d81601755714e9fSE Android "to record", low, high, sepol_port_get_proto_str(rec_proto)); 137255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 138255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_free(tmp_record); 139255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 140255e72915d4cbddceb435e13d81601755714e9fSE Android} 141255e72915d4cbddceb435e13d81601755714e9fSE Android 142255e72915d4cbddceb435e13d81601755714e9fSE Android/* Return the number of ports */ 143255e72915d4cbddceb435e13d81601755714e9fSE Androidextern int sepol_port_count(sepol_handle_t * handle __attribute__ ((unused)), 144255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, unsigned int *response) 145255e72915d4cbddceb435e13d81601755714e9fSE Android{ 146255e72915d4cbddceb435e13d81601755714e9fSE Android 147255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int count = 0; 148255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 149255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 150255e72915d4cbddceb435e13d81601755714e9fSE Android 151255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_PORT]; 152255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c != NULL; c = c->next) 153255e72915d4cbddceb435e13d81601755714e9fSE Android count++; 154255e72915d4cbddceb435e13d81601755714e9fSE Android 155255e72915d4cbddceb435e13d81601755714e9fSE Android *response = count; 156255e72915d4cbddceb435e13d81601755714e9fSE Android 157255e72915d4cbddceb435e13d81601755714e9fSE Android handle = NULL; 158255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 159255e72915d4cbddceb435e13d81601755714e9fSE Android} 160255e72915d4cbddceb435e13d81601755714e9fSE Android 161255e72915d4cbddceb435e13d81601755714e9fSE Android/* Check if a port exists */ 162255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_exists(sepol_handle_t * handle, 163255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 164255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_port_key_t * key, int *response) 165255e72915d4cbddceb435e13d81601755714e9fSE Android{ 166255e72915d4cbddceb435e13d81601755714e9fSE Android 167255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 168255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 169255e72915d4cbddceb435e13d81601755714e9fSE Android 170255e72915d4cbddceb435e13d81601755714e9fSE Android int low, high, proto; 171255e72915d4cbddceb435e13d81601755714e9fSE Android const char *proto_str; 172255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_key_unpack(key, &low, &high, &proto); 173255e72915d4cbddceb435e13d81601755714e9fSE Android proto_str = sepol_port_get_proto_str(proto); 174255e72915d4cbddceb435e13d81601755714e9fSE Android proto = sepol2ipproto(handle, proto); 175255e72915d4cbddceb435e13d81601755714e9fSE Android if (proto < 0) 176255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 177255e72915d4cbddceb435e13d81601755714e9fSE Android 178255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_PORT]; 179255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 180255e72915d4cbddceb435e13d81601755714e9fSE Android int proto2 = c->u.port.protocol; 181255e72915d4cbddceb435e13d81601755714e9fSE Android int low2 = c->u.port.low_port; 182255e72915d4cbddceb435e13d81601755714e9fSE Android int high2 = c->u.port.high_port; 183255e72915d4cbddceb435e13d81601755714e9fSE Android 184255e72915d4cbddceb435e13d81601755714e9fSE Android if (proto == proto2 && low2 == low && high2 == high) { 185255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 1; 186255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 187255e72915d4cbddceb435e13d81601755714e9fSE Android } 188255e72915d4cbddceb435e13d81601755714e9fSE Android } 189255e72915d4cbddceb435e13d81601755714e9fSE Android 190255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 0; 191255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 192255e72915d4cbddceb435e13d81601755714e9fSE Android 193255e72915d4cbddceb435e13d81601755714e9fSE Android err: 194255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not check if port range %u - %u (%s) exists", 195255e72915d4cbddceb435e13d81601755714e9fSE Android low, high, proto_str); 196255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 197255e72915d4cbddceb435e13d81601755714e9fSE Android} 198255e72915d4cbddceb435e13d81601755714e9fSE Android 199255e72915d4cbddceb435e13d81601755714e9fSE Android/* Query a port */ 200255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_query(sepol_handle_t * handle, 201255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 202255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_port_key_t * key, sepol_port_t ** response) 203255e72915d4cbddceb435e13d81601755714e9fSE Android{ 204255e72915d4cbddceb435e13d81601755714e9fSE Android 205255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 206255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 207255e72915d4cbddceb435e13d81601755714e9fSE Android 208255e72915d4cbddceb435e13d81601755714e9fSE Android int low, high, proto; 209255e72915d4cbddceb435e13d81601755714e9fSE Android const char *proto_str; 210255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_key_unpack(key, &low, &high, &proto); 211255e72915d4cbddceb435e13d81601755714e9fSE Android proto_str = sepol_port_get_proto_str(proto); 212255e72915d4cbddceb435e13d81601755714e9fSE Android proto = sepol2ipproto(handle, proto); 213255e72915d4cbddceb435e13d81601755714e9fSE Android if (proto < 0) 214255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 215255e72915d4cbddceb435e13d81601755714e9fSE Android 216255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_PORT]; 217255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 218255e72915d4cbddceb435e13d81601755714e9fSE Android int proto2 = c->u.port.protocol; 219255e72915d4cbddceb435e13d81601755714e9fSE Android int low2 = c->u.port.low_port; 220255e72915d4cbddceb435e13d81601755714e9fSE Android int high2 = c->u.port.high_port; 221255e72915d4cbddceb435e13d81601755714e9fSE Android 222255e72915d4cbddceb435e13d81601755714e9fSE Android if (proto == proto2 && low2 == low && high2 == high) { 223255e72915d4cbddceb435e13d81601755714e9fSE Android if (port_to_record(handle, policydb, c, response) < 0) 224255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 225255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 226255e72915d4cbddceb435e13d81601755714e9fSE Android } 227255e72915d4cbddceb435e13d81601755714e9fSE Android } 228255e72915d4cbddceb435e13d81601755714e9fSE Android 229255e72915d4cbddceb435e13d81601755714e9fSE Android *response = NULL; 230255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 231255e72915d4cbddceb435e13d81601755714e9fSE Android 232255e72915d4cbddceb435e13d81601755714e9fSE Android err: 233255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not query port range %u - %u (%s)", 234255e72915d4cbddceb435e13d81601755714e9fSE Android low, high, proto_str); 235255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 236255e72915d4cbddceb435e13d81601755714e9fSE Android 237255e72915d4cbddceb435e13d81601755714e9fSE Android} 238255e72915d4cbddceb435e13d81601755714e9fSE Android 239255e72915d4cbddceb435e13d81601755714e9fSE Android/* Load a port into policy */ 240255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_modify(sepol_handle_t * handle, 241255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * p, 242255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_port_key_t * key, const sepol_port_t * data) 243255e72915d4cbddceb435e13d81601755714e9fSE Android{ 244255e72915d4cbddceb435e13d81601755714e9fSE Android 245255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *policydb = &p->p; 246255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *port = NULL; 247255e72915d4cbddceb435e13d81601755714e9fSE Android 248255e72915d4cbddceb435e13d81601755714e9fSE Android int low, high, proto; 249255e72915d4cbddceb435e13d81601755714e9fSE Android const char *proto_str; 250255e72915d4cbddceb435e13d81601755714e9fSE Android 251255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_key_unpack(key, &low, &high, &proto); 252255e72915d4cbddceb435e13d81601755714e9fSE Android proto_str = sepol_port_get_proto_str(proto); 253255e72915d4cbddceb435e13d81601755714e9fSE Android proto = sepol2ipproto(handle, proto); 254255e72915d4cbddceb435e13d81601755714e9fSE Android if (proto < 0) 255255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 256255e72915d4cbddceb435e13d81601755714e9fSE Android 257255e72915d4cbddceb435e13d81601755714e9fSE Android if (port_from_record(handle, policydb, &port, data) < 0) 258255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 259255e72915d4cbddceb435e13d81601755714e9fSE Android 260255e72915d4cbddceb435e13d81601755714e9fSE Android /* Attach to context list */ 261255e72915d4cbddceb435e13d81601755714e9fSE Android port->next = policydb->ocontexts[OCON_PORT]; 262255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->ocontexts[OCON_PORT] = port; 263255e72915d4cbddceb435e13d81601755714e9fSE Android 264255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 265255e72915d4cbddceb435e13d81601755714e9fSE Android 266255e72915d4cbddceb435e13d81601755714e9fSE Android err: 267255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not load port range %u - %u (%s)", 268255e72915d4cbddceb435e13d81601755714e9fSE Android low, high, proto_str); 269255e72915d4cbddceb435e13d81601755714e9fSE Android if (port != NULL) { 270255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&port->context[0]); 271255e72915d4cbddceb435e13d81601755714e9fSE Android free(port); 272255e72915d4cbddceb435e13d81601755714e9fSE Android } 273255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 274255e72915d4cbddceb435e13d81601755714e9fSE Android} 275255e72915d4cbddceb435e13d81601755714e9fSE Android 276255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_port_iterate(sepol_handle_t * handle, 277255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 278255e72915d4cbddceb435e13d81601755714e9fSE Android int (*fn) (const sepol_port_t * port, 279255e72915d4cbddceb435e13d81601755714e9fSE Android void *fn_arg), void *arg) 280255e72915d4cbddceb435e13d81601755714e9fSE Android{ 281255e72915d4cbddceb435e13d81601755714e9fSE Android 282255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 283255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 284255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_t *port = NULL; 285255e72915d4cbddceb435e13d81601755714e9fSE Android 286255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_PORT]; 287255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 288255e72915d4cbddceb435e13d81601755714e9fSE Android int status; 289255e72915d4cbddceb435e13d81601755714e9fSE Android 290255e72915d4cbddceb435e13d81601755714e9fSE Android if (port_to_record(handle, policydb, c, &port) < 0) 291255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 292255e72915d4cbddceb435e13d81601755714e9fSE Android 293255e72915d4cbddceb435e13d81601755714e9fSE Android /* Invoke handler */ 294255e72915d4cbddceb435e13d81601755714e9fSE Android status = fn(port, arg); 295255e72915d4cbddceb435e13d81601755714e9fSE Android if (status < 0) 296255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 297255e72915d4cbddceb435e13d81601755714e9fSE Android 298255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_free(port); 299255e72915d4cbddceb435e13d81601755714e9fSE Android port = NULL; 300255e72915d4cbddceb435e13d81601755714e9fSE Android 301255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handler requested exit */ 302255e72915d4cbddceb435e13d81601755714e9fSE Android if (status > 0) 303255e72915d4cbddceb435e13d81601755714e9fSE Android break; 304255e72915d4cbddceb435e13d81601755714e9fSE Android } 305255e72915d4cbddceb435e13d81601755714e9fSE Android 306255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 307255e72915d4cbddceb435e13d81601755714e9fSE Android 308255e72915d4cbddceb435e13d81601755714e9fSE Android err: 309255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not iterate over ports"); 310255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_port_free(port); 311255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 312255e72915d4cbddceb435e13d81601755714e9fSE Android} 313