/* * Read uncompressed id lookup table indexes from disk into memory */ __le64 *squashfs_read_id_index_table(struct super_block *sb, u64 id_table_start, u64 next_table, unsigned short no_ids) { unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids); __le64 *table; TRACE("In read_id_index_table, length %d\n", length); /* Sanity check values */ /* there should always be at least one id */ if (no_ids == 0) return ERR_PTR(-EINVAL); /* * length bytes should not extend into the next table - this check * also traps instances where id_table_start is incorrectly larger * than the next table start */ if (id_table_start + length > next_table) return ERR_PTR(-EINVAL); table = squashfs_read_table(sb, id_table_start, length); /* * table[0] points to the first id lookup table metadata block, this * should be less than id_table_start */ if (!IS_ERR(table) && le64_to_cpu(table[0]) >= id_table_start) { kfree(table); return ERR_PTR(-EINVAL); } return table; }
int read_uids_guids_4() { int res, i, indexes = SQUASHFS_ID_BLOCKS(sBlk.no_ids); long long id_index_table[indexes]; TRACE("read_uids_guids: no_ids %d\n", sBlk.no_ids); id_table = malloc(SQUASHFS_ID_BYTES(sBlk.no_ids)); if(id_table == NULL) { ERROR("read_uids_guids: failed to allocate id table\n"); return FALSE; } res = read_bytes(sBlk.id_table_start, SQUASHFS_ID_BLOCK_BYTES(sBlk.no_ids), (char *) id_index_table); if(res == FALSE) { ERROR("read_uids_guids: failed to read id index table\n"); return FALSE; } SQUASHFS_INSWAP_ID_BLOCKS(id_index_table, indexes); for(i = 0; i < indexes; i++) { res = read_block(id_index_table[i], NULL, ((char *) id_table) + i * SQUASHFS_METADATA_SIZE); if(res == FALSE) { ERROR("read_uids_guids: failed to read id table block" "\n"); return FALSE; } } SQUASHFS_INSWAP_INTS(id_table, sBlk.no_ids); return TRUE; }
/* * Read uncompressed id lookup table indexes from disk into memory */ __le64 *squashfs_read_id_index_table(struct super_block *sb, u64 id_table_start, unsigned short no_ids) { unsigned int length = SQUASHFS_ID_BLOCK_BYTES(no_ids); __le64 *id_table; int err; TRACE("In read_id_index_table, length %d\n", length); /* Allocate id lookup table indexes */ id_table = kmalloc(length, GFP_KERNEL); if (id_table == NULL) { ERROR("Failed to allocate id index table\n"); return ERR_PTR(-ENOMEM); } err = squashfs_read_table(sb, id_table, id_table_start, length); if (err < 0) { ERROR("unable to read id index table\n"); kfree(id_table); return ERR_PTR(err); } return id_table; }
unsigned int *read_id_table(int fd, struct squashfs_super_block *sBlk) { int indexes = SQUASHFS_ID_BLOCKS(sBlk->no_ids); long long index[indexes]; int bytes = SQUASHFS_ID_BYTES(sBlk->no_ids); unsigned int *id_table; int res, i; id_table = malloc(bytes); if(id_table == NULL) MEM_ERROR(); res = read_fs_bytes(fd, sBlk->id_table_start, SQUASHFS_ID_BLOCK_BYTES(sBlk->no_ids), index); if(res == 0) { ERROR("Failed to read id table index\n"); ERROR("Filesystem corrupted?\n"); free(id_table); return NULL; } SQUASHFS_INSWAP_ID_BLOCKS(index, indexes); for(i = 0; i < indexes; i++) { int expected = (i + 1) != indexes ? SQUASHFS_METADATA_SIZE : bytes & (SQUASHFS_METADATA_SIZE - 1); int length = read_block(fd, index[i], NULL, expected, ((unsigned char *) id_table) + (i * SQUASHFS_METADATA_SIZE)); TRACE("Read id table block %d, from 0x%llx, length %d\n", i, index[i], length); if(length == 0) { ERROR("Failed to read id table block %d, from 0x%llx, " "length %d\n", i, index[i], length); ERROR("Filesystem corrupted?\n"); free(id_table); return NULL; } } SQUASHFS_INSWAP_INTS(id_table, sBlk->no_ids); for(i = 0; i < sBlk->no_ids; i++) { TRACE("Adding id %d to id tables\n", id_table[i]); create_id(id_table[i]); } return id_table; }