1255e72915d4cbddceb435e13d81601755714e9fSE Android#include <stdlib.h> 2255e72915d4cbddceb435e13d81601755714e9fSE Android 3255e72915d4cbddceb435e13d81601755714e9fSE Android#include "debug.h" 4255e72915d4cbddceb435e13d81601755714e9fSE Android#include "context.h" 5255e72915d4cbddceb435e13d81601755714e9fSE Android#include "handle.h" 6255e72915d4cbddceb435e13d81601755714e9fSE Android 7255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/policydb/policydb.h> 8255e72915d4cbddceb435e13d81601755714e9fSE Android#include <sepol/interfaces.h> 9255e72915d4cbddceb435e13d81601755714e9fSE Android#include "iface_internal.h" 10255e72915d4cbddceb435e13d81601755714e9fSE Android 11255e72915d4cbddceb435e13d81601755714e9fSE Android/* Create a low level structure from record */ 12255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int iface_from_record(sepol_handle_t * handle, 13255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 14255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t ** iface, const sepol_iface_t * record) 15255e72915d4cbddceb435e13d81601755714e9fSE Android{ 16255e72915d4cbddceb435e13d81601755714e9fSE Android 17255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *tmp_iface = NULL; 18255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *tmp_con = NULL; 19255e72915d4cbddceb435e13d81601755714e9fSE Android 20255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_iface = (ocontext_t *) calloc(1, sizeof(ocontext_t)); 21255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_iface) 22255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 23255e72915d4cbddceb435e13d81601755714e9fSE Android 24255e72915d4cbddceb435e13d81601755714e9fSE Android /* Name */ 25255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_iface->u.name = strdup(sepol_iface_get_name(record)); 26255e72915d4cbddceb435e13d81601755714e9fSE Android if (!tmp_iface->u.name) 27255e72915d4cbddceb435e13d81601755714e9fSE Android goto omem; 28255e72915d4cbddceb435e13d81601755714e9fSE Android 29255e72915d4cbddceb435e13d81601755714e9fSE Android /* Interface Context */ 30255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_from_record(handle, policydb, 31255e72915d4cbddceb435e13d81601755714e9fSE Android &tmp_con, sepol_iface_get_ifcon(record)) < 0) 32255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 33255e72915d4cbddceb435e13d81601755714e9fSE Android context_cpy(&tmp_iface->context[0], tmp_con); 34255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 35255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 36255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_con = NULL; 37255e72915d4cbddceb435e13d81601755714e9fSE Android 38255e72915d4cbddceb435e13d81601755714e9fSE Android /* Message Context */ 39255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_from_record(handle, policydb, 40255e72915d4cbddceb435e13d81601755714e9fSE Android &tmp_con, sepol_iface_get_msgcon(record)) < 0) 41255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 42255e72915d4cbddceb435e13d81601755714e9fSE Android context_cpy(&tmp_iface->context[1], tmp_con); 43255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 44255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 45255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_con = NULL; 46255e72915d4cbddceb435e13d81601755714e9fSE Android 47255e72915d4cbddceb435e13d81601755714e9fSE Android *iface = tmp_iface; 48255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 49255e72915d4cbddceb435e13d81601755714e9fSE Android 50255e72915d4cbddceb435e13d81601755714e9fSE Android omem: 51255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "out of memory"); 52255e72915d4cbddceb435e13d81601755714e9fSE Android 53255e72915d4cbddceb435e13d81601755714e9fSE Android err: 54255e72915d4cbddceb435e13d81601755714e9fSE Android if (tmp_iface != NULL) { 55255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_iface->u.name); 56255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&tmp_iface->context[0]); 57255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&tmp_iface->context[1]); 58255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_iface); 59255e72915d4cbddceb435e13d81601755714e9fSE Android } 60255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(tmp_con); 61255e72915d4cbddceb435e13d81601755714e9fSE Android free(tmp_con); 62255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "error creating interface structure"); 63255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 64255e72915d4cbddceb435e13d81601755714e9fSE Android} 65255e72915d4cbddceb435e13d81601755714e9fSE Android 66255e72915d4cbddceb435e13d81601755714e9fSE Androidstatic int iface_to_record(sepol_handle_t * handle, 67255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t * policydb, 68255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t * iface, sepol_iface_t ** record) 69255e72915d4cbddceb435e13d81601755714e9fSE Android{ 70255e72915d4cbddceb435e13d81601755714e9fSE Android 71255e72915d4cbddceb435e13d81601755714e9fSE Android char *name = iface->u.name; 72255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *ifcon = &iface->context[0]; 73255e72915d4cbddceb435e13d81601755714e9fSE Android context_struct_t *msgcon = &iface->context[1]; 74255e72915d4cbddceb435e13d81601755714e9fSE Android 75255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_t *tmp_con = NULL; 76255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_t *tmp_record = NULL; 77255e72915d4cbddceb435e13d81601755714e9fSE Android 78255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_iface_create(handle, &tmp_record) < 0) 79255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 80255e72915d4cbddceb435e13d81601755714e9fSE Android 81255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_iface_set_name(handle, tmp_record, name) < 0) 82255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 83255e72915d4cbddceb435e13d81601755714e9fSE Android 84255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_to_record(handle, policydb, ifcon, &tmp_con) < 0) 85255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 86255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_iface_set_ifcon(handle, tmp_record, tmp_con) < 0) 87255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 88255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 89255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_con = NULL; 90255e72915d4cbddceb435e13d81601755714e9fSE Android 91255e72915d4cbddceb435e13d81601755714e9fSE Android if (context_to_record(handle, policydb, msgcon, &tmp_con) < 0) 92255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 93255e72915d4cbddceb435e13d81601755714e9fSE Android if (sepol_iface_set_msgcon(handle, tmp_record, tmp_con) < 0) 94255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 95255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 96255e72915d4cbddceb435e13d81601755714e9fSE Android tmp_con = NULL; 97255e72915d4cbddceb435e13d81601755714e9fSE Android 98255e72915d4cbddceb435e13d81601755714e9fSE Android *record = tmp_record; 99255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 100255e72915d4cbddceb435e13d81601755714e9fSE Android 101255e72915d4cbddceb435e13d81601755714e9fSE Android err: 102255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not convert interface %s to record", name); 103255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_context_free(tmp_con); 104255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_free(tmp_record); 105255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 106255e72915d4cbddceb435e13d81601755714e9fSE Android} 107255e72915d4cbddceb435e13d81601755714e9fSE Android 108255e72915d4cbddceb435e13d81601755714e9fSE Android/* Check if an interface exists */ 109255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_exists(sepol_handle_t * handle __attribute__ ((unused)), 110255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 111255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_iface_key_t * key, int *response) 112255e72915d4cbddceb435e13d81601755714e9fSE Android{ 113255e72915d4cbddceb435e13d81601755714e9fSE Android 114255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 115255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 116255e72915d4cbddceb435e13d81601755714e9fSE Android 117255e72915d4cbddceb435e13d81601755714e9fSE Android const char *name; 118255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_key_unpack(key, &name); 119255e72915d4cbddceb435e13d81601755714e9fSE Android 120255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NETIF]; 121255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 122255e72915d4cbddceb435e13d81601755714e9fSE Android if (!strcmp(name, c->u.name)) { 123255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 1; 124255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 125255e72915d4cbddceb435e13d81601755714e9fSE Android } 126255e72915d4cbddceb435e13d81601755714e9fSE Android } 127255e72915d4cbddceb435e13d81601755714e9fSE Android *response = 0; 128255e72915d4cbddceb435e13d81601755714e9fSE Android 129255e72915d4cbddceb435e13d81601755714e9fSE Android handle = NULL; 130255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 131255e72915d4cbddceb435e13d81601755714e9fSE Android} 132255e72915d4cbddceb435e13d81601755714e9fSE Android 133255e72915d4cbddceb435e13d81601755714e9fSE Android/* Query an interface */ 134255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_query(sepol_handle_t * handle, 135255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 136255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_iface_key_t * key, sepol_iface_t ** response) 137255e72915d4cbddceb435e13d81601755714e9fSE Android{ 138255e72915d4cbddceb435e13d81601755714e9fSE Android 139255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 140255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 141255e72915d4cbddceb435e13d81601755714e9fSE Android 142255e72915d4cbddceb435e13d81601755714e9fSE Android const char *name; 143255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_key_unpack(key, &name); 144255e72915d4cbddceb435e13d81601755714e9fSE Android 145255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NETIF]; 146255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 147255e72915d4cbddceb435e13d81601755714e9fSE Android if (!strcmp(name, c->u.name)) { 148255e72915d4cbddceb435e13d81601755714e9fSE Android 149255e72915d4cbddceb435e13d81601755714e9fSE Android if (iface_to_record(handle, policydb, c, response) < 0) 150255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 151255e72915d4cbddceb435e13d81601755714e9fSE Android 152255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 153255e72915d4cbddceb435e13d81601755714e9fSE Android } 154255e72915d4cbddceb435e13d81601755714e9fSE Android } 155255e72915d4cbddceb435e13d81601755714e9fSE Android 156255e72915d4cbddceb435e13d81601755714e9fSE Android *response = NULL; 157255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 158255e72915d4cbddceb435e13d81601755714e9fSE Android 159255e72915d4cbddceb435e13d81601755714e9fSE Android err: 160255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not query interface %s", name); 161255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 162255e72915d4cbddceb435e13d81601755714e9fSE Android} 163255e72915d4cbddceb435e13d81601755714e9fSE Android 164255e72915d4cbddceb435e13d81601755714e9fSE Android/* Load an interface into policy */ 165255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_modify(sepol_handle_t * handle, 166255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_policydb_t * p, 167255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_iface_key_t * key, 168255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_iface_t * data) 169255e72915d4cbddceb435e13d81601755714e9fSE Android{ 170255e72915d4cbddceb435e13d81601755714e9fSE Android 171255e72915d4cbddceb435e13d81601755714e9fSE Android policydb_t *policydb = &p->p; 172255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *head, *prev, *c, *iface = NULL; 173255e72915d4cbddceb435e13d81601755714e9fSE Android 174255e72915d4cbddceb435e13d81601755714e9fSE Android const char *name; 175255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_key_unpack(key, &name); 176255e72915d4cbddceb435e13d81601755714e9fSE Android 177255e72915d4cbddceb435e13d81601755714e9fSE Android if (iface_from_record(handle, policydb, &iface, data) < 0) 178255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 179255e72915d4cbddceb435e13d81601755714e9fSE Android 180255e72915d4cbddceb435e13d81601755714e9fSE Android prev = NULL; 181255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NETIF]; 182255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 183255e72915d4cbddceb435e13d81601755714e9fSE Android if (!strcmp(name, c->u.name)) { 184255e72915d4cbddceb435e13d81601755714e9fSE Android 185255e72915d4cbddceb435e13d81601755714e9fSE Android /* Replace */ 186255e72915d4cbddceb435e13d81601755714e9fSE Android iface->next = c->next; 187255e72915d4cbddceb435e13d81601755714e9fSE Android if (prev == NULL) 188255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->ocontexts[OCON_NETIF] = iface; 189255e72915d4cbddceb435e13d81601755714e9fSE Android else 190255e72915d4cbddceb435e13d81601755714e9fSE Android prev->next = iface; 191255e72915d4cbddceb435e13d81601755714e9fSE Android free(c->u.name); 192255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&c->context[0]); 193255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&c->context[1]); 194255e72915d4cbddceb435e13d81601755714e9fSE Android free(c); 195255e72915d4cbddceb435e13d81601755714e9fSE Android 196255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 197255e72915d4cbddceb435e13d81601755714e9fSE Android } 198255e72915d4cbddceb435e13d81601755714e9fSE Android prev = c; 199255e72915d4cbddceb435e13d81601755714e9fSE Android } 200255e72915d4cbddceb435e13d81601755714e9fSE Android 201255e72915d4cbddceb435e13d81601755714e9fSE Android /* Attach to context list */ 202255e72915d4cbddceb435e13d81601755714e9fSE Android iface->next = policydb->ocontexts[OCON_NETIF]; 203255e72915d4cbddceb435e13d81601755714e9fSE Android policydb->ocontexts[OCON_NETIF] = iface; 204255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 205255e72915d4cbddceb435e13d81601755714e9fSE Android 206255e72915d4cbddceb435e13d81601755714e9fSE Android err: 207255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "error while loading interface %s", name); 208255e72915d4cbddceb435e13d81601755714e9fSE Android 209255e72915d4cbddceb435e13d81601755714e9fSE Android if (iface != NULL) { 210255e72915d4cbddceb435e13d81601755714e9fSE Android free(iface->u.name); 211255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&iface->context[0]); 212255e72915d4cbddceb435e13d81601755714e9fSE Android context_destroy(&iface->context[1]); 213255e72915d4cbddceb435e13d81601755714e9fSE Android free(iface); 214255e72915d4cbddceb435e13d81601755714e9fSE Android } 215255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 216255e72915d4cbddceb435e13d81601755714e9fSE Android} 217255e72915d4cbddceb435e13d81601755714e9fSE Android 218255e72915d4cbddceb435e13d81601755714e9fSE Android/* Return the number of interfaces */ 219255e72915d4cbddceb435e13d81601755714e9fSE Androidextern int sepol_iface_count(sepol_handle_t * handle __attribute__ ((unused)), 220255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, unsigned int *response) 221255e72915d4cbddceb435e13d81601755714e9fSE Android{ 222255e72915d4cbddceb435e13d81601755714e9fSE Android 223255e72915d4cbddceb435e13d81601755714e9fSE Android unsigned int count = 0; 224255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 225255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 226255e72915d4cbddceb435e13d81601755714e9fSE Android 227255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NETIF]; 228255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c != NULL; c = c->next) 229255e72915d4cbddceb435e13d81601755714e9fSE Android count++; 230255e72915d4cbddceb435e13d81601755714e9fSE Android 231255e72915d4cbddceb435e13d81601755714e9fSE Android *response = count; 232255e72915d4cbddceb435e13d81601755714e9fSE Android 233255e72915d4cbddceb435e13d81601755714e9fSE Android handle = NULL; 234255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 235255e72915d4cbddceb435e13d81601755714e9fSE Android} 236255e72915d4cbddceb435e13d81601755714e9fSE Android 237255e72915d4cbddceb435e13d81601755714e9fSE Androidint sepol_iface_iterate(sepol_handle_t * handle, 238255e72915d4cbddceb435e13d81601755714e9fSE Android const sepol_policydb_t * p, 239255e72915d4cbddceb435e13d81601755714e9fSE Android int (*fn) (const sepol_iface_t * iface, 240255e72915d4cbddceb435e13d81601755714e9fSE Android void *fn_arg), void *arg) 241255e72915d4cbddceb435e13d81601755714e9fSE Android{ 242255e72915d4cbddceb435e13d81601755714e9fSE Android 243255e72915d4cbddceb435e13d81601755714e9fSE Android const policydb_t *policydb = &p->p; 244255e72915d4cbddceb435e13d81601755714e9fSE Android ocontext_t *c, *head; 245255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_t *iface = NULL; 246255e72915d4cbddceb435e13d81601755714e9fSE Android 247255e72915d4cbddceb435e13d81601755714e9fSE Android head = policydb->ocontexts[OCON_NETIF]; 248255e72915d4cbddceb435e13d81601755714e9fSE Android for (c = head; c; c = c->next) { 249255e72915d4cbddceb435e13d81601755714e9fSE Android int status; 250255e72915d4cbddceb435e13d81601755714e9fSE Android 251255e72915d4cbddceb435e13d81601755714e9fSE Android if (iface_to_record(handle, policydb, c, &iface) < 0) 252255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 253255e72915d4cbddceb435e13d81601755714e9fSE Android 254255e72915d4cbddceb435e13d81601755714e9fSE Android /* Invoke handler */ 255255e72915d4cbddceb435e13d81601755714e9fSE Android status = fn(iface, arg); 256255e72915d4cbddceb435e13d81601755714e9fSE Android if (status < 0) 257255e72915d4cbddceb435e13d81601755714e9fSE Android goto err; 258255e72915d4cbddceb435e13d81601755714e9fSE Android 259255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_free(iface); 260255e72915d4cbddceb435e13d81601755714e9fSE Android iface = NULL; 261255e72915d4cbddceb435e13d81601755714e9fSE Android 262255e72915d4cbddceb435e13d81601755714e9fSE Android /* Handler requested exit */ 263255e72915d4cbddceb435e13d81601755714e9fSE Android if (status > 0) 264255e72915d4cbddceb435e13d81601755714e9fSE Android break; 265255e72915d4cbddceb435e13d81601755714e9fSE Android } 266255e72915d4cbddceb435e13d81601755714e9fSE Android 267255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_SUCCESS; 268255e72915d4cbddceb435e13d81601755714e9fSE Android 269255e72915d4cbddceb435e13d81601755714e9fSE Android err: 270255e72915d4cbddceb435e13d81601755714e9fSE Android ERR(handle, "could not iterate over interfaces"); 271255e72915d4cbddceb435e13d81601755714e9fSE Android sepol_iface_free(iface); 272255e72915d4cbddceb435e13d81601755714e9fSE Android return STATUS_ERR; 273255e72915d4cbddceb435e13d81601755714e9fSE Android} 274