static ssize_t dec_table(amqp_value_t *v, mnbytestream_t *bs, int fd) { init_table(&v->value.t); return unpack_table(bs, fd, &v->value.t); }
/** * aa_dfa_unpack - unpack the binary tables of a serialized dfa * @blob: aligned serialized stream of data to unpack (NOT NULL) * @size: size of data to unpack * @flags: flags controlling what type of accept tables are acceptable * * Unpack a dfa that has been serialized. To find information on the dfa * format look in Documentation/admin-guide/LSM/apparmor.rst * Assumes the dfa @blob stream has been aligned on a 8 byte boundary * * Returns: an unpacked dfa ready for matching or ERR_PTR on failure */ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags) { int hsize; int error = -ENOMEM; char *data = blob; struct table_header *table = NULL; struct aa_dfa *dfa = kzalloc(sizeof(struct aa_dfa), GFP_KERNEL); if (!dfa) goto fail; kref_init(&dfa->count); error = -EPROTO; /* get dfa table set header */ if (size < sizeof(struct table_set_header)) goto fail; if (ntohl(*(__be32 *) data) != YYTH_MAGIC) goto fail; hsize = ntohl(*(__be32 *) (data + 4)); if (size < hsize) goto fail; dfa->flags = ntohs(*(__be16 *) (data + 12)); if (dfa->flags != 0 && dfa->flags != YYTH_FLAG_DIFF_ENCODE) goto fail; data += hsize; size -= hsize; while (size > 0) { table = unpack_table(data, size); if (!table) goto fail; switch (table->td_id) { case YYTD_ID_ACCEPT: if (!(table->td_flags & ACCEPT1_FLAGS(flags))) goto fail; break; case YYTD_ID_ACCEPT2: if (!(table->td_flags & ACCEPT2_FLAGS(flags))) goto fail; break; case YYTD_ID_BASE: if (table->td_flags != YYTD_DATA32) goto fail; break; case YYTD_ID_DEF: case YYTD_ID_NXT: case YYTD_ID_CHK: if (table->td_flags != YYTD_DATA16) goto fail; break; case YYTD_ID_EC: if (table->td_flags != YYTD_DATA8) goto fail; break; default: goto fail; } /* check for duplicate table entry */ if (dfa->tables[table->td_id]) goto fail; dfa->tables[table->td_id] = table; data += table_size(table->td_lolen, table->td_flags); size -= table_size(table->td_lolen, table->td_flags); table = NULL; } error = verify_table_headers(dfa->tables, flags); if (error) goto fail; if (flags & DFA_FLAG_VERIFY_STATES) { error = verify_dfa(dfa); if (error) goto fail; } return dfa; fail: kvfree(table); dfa_free(dfa); return ERR_PTR(error); }
int unpack_dfa(struct aa_dfa *dfa, void *blob, size_t size) { int hsize, i; int error = -ENOMEM; /* get dfa table set header */ if (size < sizeof(struct table_set_header)) goto fail; if (ntohl(*(u32 *)blob) != YYTH_MAGIC) goto fail; hsize = ntohl(*(u32 *)(blob + 4)); if (size < hsize) goto fail; blob += hsize; size -= hsize; error = -EPROTO; while (size > 0) { struct table_header *table; table = unpack_table(blob, size); if (!table) goto fail; switch(table->td_id) { case YYTD_ID_ACCEPT: case YYTD_ID_BASE: dfa->tables[table->td_id - 1] = table; if (table->td_flags != YYTD_DATA32) goto fail; break; case YYTD_ID_DEF: case YYTD_ID_NXT: case YYTD_ID_CHK: dfa->tables[table->td_id - 1] = table; if (table->td_flags != YYTD_DATA16) goto fail; break; case YYTD_ID_EC: dfa->tables[table->td_id - 1] = table; if (table->td_flags != YYTD_DATA8) goto fail; break; default: kfree(table); goto fail; } blob += table_size(table->td_lolen, table->td_flags); size -= table_size(table->td_lolen, table->td_flags); } return 0; fail: for (i = 0; i < ARRAY_SIZE(dfa->tables); i++) { if (dfa->tables[i]) { kfree(dfa->tables[i]); dfa->tables[i] = NULL; } } return error; }