summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2014-05-01 15:47:41 +0100
committerVincent Penquerc'h <vincent.penquerch@collabora.co.uk>2014-06-06 12:36:13 +0100
commit988914384acdf30eab22226d79de3541e7e6f02d (patch)
tree15e4aa1a7d235fc269951e537d8c7cf2ccec9bc5
parent909f41fb49ddb7d8745a3fd6565bf2eb6531e3e6 (diff)
Add some checks on the number of variables per type
We want to ensure no more than, say, 8 constants are added to a program. Adding more will violate pervasive assumptions in the code, and may lead to various buffer overflows. By trapping these add creation time, we prevent these issues without cluttering the code with range checks. The user is assumed non malicious here. Add a test to check we can add up to and including the limit for a type, but no more.
-rw-r--r--orc/orccompiler.c11
-rw-r--r--orc/orclimits.h7
-rw-r--r--orc/orcprogram.c84
-rw-r--r--orc/orcprogram.h1
-rw-r--r--testsuite/Makefile.am3
-rw-r--r--testsuite/test-limits.c72
6 files changed, 174 insertions, 4 deletions
diff --git a/orc/orccompiler.c b/orc/orccompiler.c
index c30226a..d338a54 100644
--- a/orc/orccompiler.c
+++ b/orc/orccompiler.c
@@ -189,8 +189,16 @@ orc_program_compile_full (OrcProgram *program, OrcTarget *target,
OrcCompiler *compiler;
int i;
OrcCompileResult result;
+ const char *error_msg;
ORC_INFO("initializing compiler for program \"%s\"", program->name);
+ error_msg = orc_program_get_error (program);
+ if (error_msg && strcmp (error_msg, "")) {
+ ORC_WARNING ("program %s failed to compile, reason: %s",
+ program->name, error_msg);
+ return ORC_COMPILE_RESULT_UNKNOWN_PARSE;
+ }
+
compiler = malloc (sizeof(OrcCompiler));
memset (compiler, 0, sizeof(OrcCompiler));
@@ -377,8 +385,7 @@ error:
program->name, compiler->result);
}
result = compiler->result;
- if (program->error_msg) free (program->error_msg);
- program->error_msg = compiler->error_msg;
+ orc_program_set_error (program, compiler->error_msg);
if (result == 0) {
result = ORC_COMPILE_RESULT_UNKNOWN_COMPILE;
}
diff --git a/orc/orclimits.h b/orc/orclimits.h
index ebb9828..928b00c 100644
--- a/orc/orclimits.h
+++ b/orc/orclimits.h
@@ -29,6 +29,13 @@ ORC_BEGIN_DECLS
#define ORC_MAX_VAR_SIZE 8
+#define ORC_MAX_DEST_VARS 4
+#define ORC_MAX_SRC_VARS 8
+#define ORC_MAX_TEMP_VARS 16
+#define ORC_MAX_CONST_VARS 8
+#define ORC_MAX_PARAM_VARS 8
+#define ORC_MAX_ACCUM_VARS 4
+
enum {
ORC_VAR_D1,
ORC_VAR_D2,
diff --git a/orc/orcprogram.c b/orc/orcprogram.c
index 384a68f..9251b97 100644
--- a/orc/orcprogram.c
+++ b/orc/orcprogram.c
@@ -307,6 +307,11 @@ orc_program_add_temporary (OrcProgram *program, int size, const char *name)
{
int i = ORC_VAR_T1 + program->n_temp_vars;
+ if (program->n_temp_vars >= ORC_MAX_TEMP_VARS) {
+ orc_program_set_error (program, "too many temporary variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_TEMP;
program->vars[i].size = size;
program->vars[i].name = strdup(name);
@@ -330,6 +335,11 @@ orc_program_dup_temporary (OrcProgram *program, int var, int j)
{
int i = ORC_VAR_T1 + program->n_temp_vars;
+ if (program->n_temp_vars >= ORC_MAX_TEMP_VARS) {
+ orc_program_set_error (program, "too many temporary variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_TEMP;
program->vars[i].size = program->vars[var].size;
program->vars[i].name = malloc (strlen(program->vars[var].name) + 10);
@@ -357,6 +367,11 @@ orc_program_add_source_full (OrcProgram *program, int size, const char *name,
{
int i = ORC_VAR_S1 + program->n_src_vars;
+ if (program->n_src_vars >= ORC_MAX_SRC_VARS) {
+ orc_program_set_error (program, "too many source variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_SRC;
program->vars[i].size = size;
if (alignment == 0) alignment = size;
@@ -402,6 +417,11 @@ orc_program_add_destination_full (OrcProgram *program, int size, const char *nam
{
int i = ORC_VAR_D1 + program->n_dest_vars;
+ if (program->n_dest_vars >= ORC_MAX_DEST_VARS) {
+ orc_program_set_error (program, "too many destination variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_DEST;
program->vars[i].size = size;
if (alignment == 0) alignment = size;
@@ -449,6 +469,11 @@ orc_program_add_constant (OrcProgram *program, int size, int value, const char *
i = ORC_VAR_C1 + program->n_const_vars;
+ if (program->n_const_vars >= ORC_MAX_CONST_VARS) {
+ orc_program_set_error (program, "too many constants allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_CONST;
program->vars[i].size = size;
program->vars[i].value.i = value;
@@ -466,6 +491,11 @@ orc_program_add_constant_int64 (OrcProgram *program, int size,
i = ORC_VAR_C1 + program->n_const_vars;
+ if (program->n_const_vars >= ORC_MAX_CONST_VARS) {
+ orc_program_set_error (program, "too many constants allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_CONST;
program->vars[i].size = size;
program->vars[i].value.i = value;
@@ -505,6 +535,11 @@ orc_program_add_constant_str (OrcProgram *program, int size,
i = ORC_VAR_C1 + program->n_const_vars;
+ if (program->n_const_vars >= ORC_MAX_CONST_VARS) {
+ orc_program_set_error (program, "too many constants allocated");
+ return 0;
+ }
+
val_i = _strtoll (value, &end, 0);
if (end[0] == 0) {
program->vars[i].value.i = val_i;
@@ -561,6 +596,11 @@ orc_program_add_parameter (OrcProgram *program, int size, const char *name)
{
int i = ORC_VAR_P1 + program->n_param_vars;
+ if (program->n_param_vars >= ORC_MAX_PARAM_VARS) {
+ orc_program_set_error (program, "too many parameter variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_PARAM;
program->vars[i].param_type = ORC_PARAM_TYPE_INT;
program->vars[i].size = size;
@@ -585,6 +625,11 @@ orc_program_add_parameter_float (OrcProgram *program, int size, const char *name
{
int i = ORC_VAR_P1 + program->n_param_vars;
+ if (program->n_param_vars >= ORC_MAX_PARAM_VARS) {
+ orc_program_set_error (program, "too many parameter variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_PARAM;
program->vars[i].param_type = ORC_PARAM_TYPE_FLOAT;
program->vars[i].size = size;
@@ -600,6 +645,11 @@ orc_program_add_parameter_double (OrcProgram *program, int size,
{
int i = ORC_VAR_P1 + program->n_param_vars;
+ if (program->n_param_vars >= ORC_MAX_PARAM_VARS) {
+ orc_program_set_error (program, "too many parameter variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_PARAM;
program->vars[i].param_type = ORC_PARAM_TYPE_DOUBLE;
program->vars[i].size = size;
@@ -615,6 +665,11 @@ orc_program_add_parameter_int64 (OrcProgram *program, int size,
{
int i = ORC_VAR_P1 + program->n_param_vars;
+ if (program->n_param_vars >= ORC_MAX_PARAM_VARS) {
+ orc_program_set_error (program, "too many parameter variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_PARAM;
program->vars[i].param_type = ORC_PARAM_TYPE_INT64;
program->vars[i].size = size;
@@ -639,6 +694,11 @@ orc_program_add_accumulator (OrcProgram *program, int size, const char *name)
{
int i = ORC_VAR_A1 + program->n_accum_vars;
+ if (program->n_accum_vars >= ORC_MAX_ACCUM_VARS) {
+ orc_program_set_error (program, "too many accumulator variables allocated");
+ return 0;
+ }
+
program->vars[i].vartype = ORC_VAR_TYPE_ACCUMULATOR;
program->vars[i].size = size;
program->vars[i].name = strdup(name);
@@ -962,7 +1022,8 @@ orc_program_get_asm_code (OrcProgram *program)
*
* Returns a character string containing the error message from
* compilation. This string is valid until the program
- * is compiled again or the program is freed.
+ * is compiled again, the program is freed, or another error
+ * is set.
*
* Returns: a character string
*/
@@ -974,6 +1035,23 @@ orc_program_get_error (OrcProgram *program)
}
/**
+ * orc_program_set_error:
+ * @program: a pointer to an OrcProgram structure
+ * @error: an error string
+ *
+ * Stores the error in the program. This string is duplicated.
+ * If an error has already been set, this new error is ignored.
+ * An error will stay till the next call to _reset, if any.
+ */
+void
+orc_program_set_error (OrcProgram *program, const char *error)
+{
+ if (!program->error_msg && error) {
+ program->error_msg = strdup (error);
+ }
+}
+
+/**
* orc_program_get_max_array_size:
* @program: a pointer to an OrcProgram structure
*
@@ -1080,6 +1158,10 @@ orc_program_reset (OrcProgram *program)
free(program->asm_code);
program->asm_code = NULL;
}
+ if (program->error_msg) {
+ free(program->error_msg);
+ program->error_msg = NULL;
+ }
}
OrcCode *
diff --git a/orc/orcprogram.h b/orc/orcprogram.h
index 6c442e1..4316ef4 100644
--- a/orc/orcprogram.h
+++ b/orc/orcprogram.h
@@ -176,6 +176,7 @@ OrcCode *orc_program_take_code (OrcProgram *program);
const char *orc_program_get_asm_code (OrcProgram *program);
const char * orc_program_get_error (OrcProgram *program);
+void orc_program_set_error (OrcProgram *program, const char *error);
int orc_program_get_max_array_size (OrcProgram *program);
int orc_program_get_max_accumulator_size (OrcProgram *program);
diff --git a/testsuite/Makefile.am b/testsuite/Makefile.am
index a2fc635..9fb62fa 100644
--- a/testsuite/Makefile.am
+++ b/testsuite/Makefile.am
@@ -12,7 +12,8 @@ TESTS = \
exec_parse \
perf_opcodes_sys perf_parse \
memcpy_speed \
- abi
+ abi \
+ test-limits
noinst_PROGRAMS = $(TESTS) generate_xml_table generate_xml_table2 \
generate_opcodes_sys compile_parse compile_parse_c memcpy_speed \
diff --git a/testsuite/test-limits.c b/testsuite/test-limits.c
new file mode 100644
index 0000000..ed19d8a
--- /dev/null
+++ b/testsuite/test-limits.c
@@ -0,0 +1,72 @@
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <orc/orc.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <orc-test/orctest.h>
+
+
+static int error = FALSE;
+static const char *names = "0123456789abcdefX";
+
+static void
+test_simple (int max, int (*adder) (OrcProgram *, int, const char *))
+{
+ OrcProgram *p;
+ int v;
+ OrcCompileResult result;
+
+ p = orc_program_new ();
+
+ /* dummy program so compile doesn't barf */
+ orc_program_add_destination (p, 2, "d1");
+ orc_program_add_source (p, 2, "s1");
+ orc_program_append_str (p, "addw", "d1", "d1", "s1");
+
+ /* we've alreay added one of those */
+ if (adder == orc_program_add_destination || adder == orc_program_add_source)
+ max--;
+
+ /* Check we can add up to the claimed max */
+ for (v = 0; v < max; v++)
+ (*adder) (p, 2, names + v);
+ result = orc_program_compile (p);
+ if (!ORC_COMPILE_RESULT_IS_SUCCESSFUL (result))
+ error = TRUE;
+
+ /* Check we can not add one more */
+ (*adder) (p, 2, names + v);
+ result = orc_program_compile (p);
+ if (ORC_COMPILE_RESULT_IS_SUCCESSFUL (result))
+ error = TRUE;
+
+ orc_program_free (p);
+}
+
+static int
+add_constant (OrcProgram *program, int size, const char *name)
+{
+ return orc_program_add_constant (program, size, 0, name);
+}
+
+int
+main (int argc, char *argv[])
+{
+ orc_init();
+ orc_test_init();
+
+ test_simple (ORC_MAX_DEST_VARS, orc_program_add_destination);
+ test_simple (ORC_MAX_SRC_VARS, orc_program_add_source);
+ test_simple (ORC_MAX_TEMP_VARS, orc_program_add_temporary);
+ test_simple (ORC_MAX_CONST_VARS, add_constant);
+ test_simple (ORC_MAX_PARAM_VARS, orc_program_add_parameter);
+ test_simple (ORC_MAX_ACCUM_VARS, orc_program_add_accumulator);
+
+ if (error) return 1;
+ return 0;
+}
+