Skip to content

Commit

Permalink
linux-user: Allocate thunk size dynamically
Browse files Browse the repository at this point in the history
We store all struct types in an array of static size without ever
checking whether we overrun it. Of course some day someone (like me
in another, ancient ALSA enabling patch set) will run into the limit
without realizing it.

So let's make the allocation dynamic. We already know the number of
structs that we want to allocate, so we only need to pass the variable
into the respective piece of code.

Also, to ensure we don't accidently overwrite random memory, add some
asserts to sanity check whether a thunk is actually part of our array.

Signed-off-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Riku Voipio <riku.voipio@linaro.org>
  • Loading branch information
agraf authored and Riku Voipio committed Jun 15, 2015
1 parent 0a2df85 commit 8be656b
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 5 deletions.
4 changes: 3 additions & 1 deletion include/exec/user/thunk.h
Expand Up @@ -74,7 +74,7 @@ const argtype *thunk_convert(void *dst, const void *src,
const argtype *type_ptr, int to_host);
#ifndef NO_THUNK_TYPE_SIZE

extern StructEntry struct_entries[];
extern StructEntry *struct_entries;

int thunk_type_size_array(const argtype *type_ptr, int is_host);
int thunk_type_align_array(const argtype *type_ptr, int is_host);
Expand Down Expand Up @@ -186,4 +186,6 @@ unsigned int target_to_host_bitmask(unsigned int x86_mask,
unsigned int host_to_target_bitmask(unsigned int alpha_mask,
const bitmask_transtbl * trans_tbl);

void thunk_init(unsigned int max_structs);

#endif
3 changes: 3 additions & 0 deletions linux-user/syscall.c
Expand Up @@ -3277,6 +3277,7 @@ static abi_long do_ipc(unsigned int call, abi_long first,
#define STRUCT_SPECIAL(name) STRUCT_ ## name,
enum {
#include "syscall_types.h"
STRUCT_MAX
};
#undef STRUCT
#undef STRUCT_SPECIAL
Expand Down Expand Up @@ -4879,6 +4880,8 @@ void syscall_init(void)
int size;
int i;

thunk_init(STRUCT_MAX);

#define STRUCT(name, ...) thunk_register_struct(STRUCT_ ## name, #name, struct_ ## name ## _def);
#define STRUCT_SPECIAL(name) thunk_register_struct_direct(STRUCT_ ## name, #name, &struct_ ## name ## _def);
#include "syscall_types.h"
Expand Down
16 changes: 12 additions & 4 deletions thunk.c
Expand Up @@ -25,10 +25,8 @@

//#define DEBUG

#define MAX_STRUCTS 128

/* XXX: make it dynamic */
StructEntry struct_entries[MAX_STRUCTS];
static unsigned int max_struct_entries;
StructEntry *struct_entries;

static const argtype *thunk_type_next_ptr(const argtype *type_ptr);

Expand Down Expand Up @@ -70,6 +68,7 @@ void thunk_register_struct(int id, const char *name, const argtype *types)
StructEntry *se;
int nb_fields, offset, max_align, align, size, i, j;

assert(id < max_struct_entries);
se = struct_entries + id;

/* first we count the number of fields */
Expand Down Expand Up @@ -117,6 +116,8 @@ void thunk_register_struct_direct(int id, const char *name,
const StructEntry *se1)
{
StructEntry *se;

assert(id < max_struct_entries);
se = struct_entries + id;
*se = *se1;
se->name = name;
Expand Down Expand Up @@ -244,6 +245,7 @@ const argtype *thunk_convert(void *dst, const void *src,
const argtype *field_types;
const int *dst_offsets, *src_offsets;

assert(*type_ptr < max_struct_entries);
se = struct_entries + *type_ptr++;
if (se->convert[0] != NULL) {
/* specific conversion is needed */
Expand Down Expand Up @@ -314,3 +316,9 @@ int thunk_type_align_array(const argtype *type_ptr, int is_host)
return thunk_type_align(type_ptr, is_host);
}
#endif /* ndef NO_THUNK_TYPE_SIZE */

void thunk_init(unsigned int max_structs)
{
max_struct_entries = max_structs;
struct_entries = g_new0(StructEntry, max_structs);
}

0 comments on commit 8be656b

Please sign in to comment.