| Index: tests/minsfi/test_invoke_args.c
|
| diff --git a/tests/minsfi/test_invoke_args.c b/tests/minsfi/test_invoke_args.c
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..b88ca44625eeca28fcf64553aa02eb15e3256ef8
|
| --- /dev/null
|
| +++ b/tests/minsfi/test_invoke_args.c
|
| @@ -0,0 +1,106 @@
|
| +/*
|
| + * Copyright (c) 2014 The Native Client Authors. All rights reserved.
|
| + * Use of this source code is governed by a BSD-style license that can be
|
| + * found in the LICENSE file.
|
| + */
|
| +#include <string.h>
|
| +
|
| +#include "native_client/src/include/minsfi.h"
|
| +#include "native_client/src/include/minsfi_priv.h"
|
| +#include "native_client/src/include/nacl_assert.h"
|
| +
|
| +/*
|
| + * Helper function which creates a NULL-terminated string that occupies
|
| + * the given number of bytes.
|
| + */
|
| +static inline char *get_str(int bytes) {
|
| + char *str = (char*) malloc(bytes);
|
| + memset(str, 'A', bytes - 1);
|
| + str[bytes - 1] = 0;
|
| + return str;
|
| +}
|
| +
|
| +/*
|
| + * Test the CopyArguments function. We verify that it will not attempt to write
|
| + * beyond the bounds of the untrusted stack.
|
| + */
|
| +void test_copy_limits(void) {
|
| + const MinsfiSandbox *sb;
|
| + int stack_fit;
|
| + char *argv_fit[1];
|
| + char *argv_info_overflow[1];
|
| + char *argv_arg_overflow[2];
|
| +
|
| + /* Initialize the sandbox. */
|
| + MinsfiInitializeSandbox();
|
| + sb = MinsfiGetActiveSandbox();
|
| +
|
| + /* argc < 0 doesn't make sense */
|
| + ASSERT_EQ(0, MinsfiCopyArguments(-5, NULL, sb));
|
| +
|
| + /*
|
| + * Test that CopyArguments allows to fill the whole stack.
|
| + * The info structure will contain two integers. We cannot invoke the sandbox
|
| + * because it would immediately overflow the stack.
|
| + */
|
| + stack_fit = sb->mem_layout.stack.length - 2 * sizeof(sfiptr_t);
|
| + argv_fit[0] = get_str(stack_fit);
|
| + ASSERT_EQ(sb->mem_layout.stack.offset, MinsfiCopyArguments(1, argv_fit, sb));
|
| +
|
| + /*
|
| + * Test that CopyArguments fails if the arguments don't leave enough space
|
| + * for the info structure.
|
| + */
|
| + argv_info_overflow[0] = get_str(stack_fit + 1);
|
| + ASSERT_EQ(0, MinsfiCopyArguments(1, argv_info_overflow, sb));
|
| + ASSERT_EQ(EXIT_FAILURE, MinsfiInvokeSandbox(1, argv_info_overflow));
|
| +
|
| + /*
|
| + * Test that CopyArguments fails if the arguments do not fit onto the stack.
|
| + * The info structure will contain three integers.
|
| + */
|
| + stack_fit = sb->mem_layout.stack.length - 3 * sizeof(sfiptr_t);
|
| + argv_arg_overflow[0] = get_str(stack_fit - 15);
|
| + argv_arg_overflow[1] = get_str(16);
|
| + ASSERT_EQ(0, MinsfiCopyArguments(2, argv_arg_overflow, sb));
|
| + ASSERT_EQ(EXIT_FAILURE, MinsfiInvokeSandbox(2, argv_arg_overflow));
|
| +
|
| + /* Clean up. */
|
| + MinsfiDestroySandbox();
|
| + free(argv_fit[0]);
|
| + free(argv_info_overflow[0]);
|
| + free(argv_arg_overflow[0]);
|
| + free(argv_arg_overflow[1]);
|
| +}
|
| +
|
| +/*
|
| + * This tests whether arguments are correctly passed to the sandbox. We do
|
| + * this by passing it a series of strings containing integer numbers. The
|
| + * sandbox is expected to parse the arguments and return their sum.
|
| + */
|
| +void test_arguments_valid(void) {
|
| + char *argv_99[] = { "99" };
|
| + char *argv_1_22_333[] = { "1", "22", "333" };
|
| +
|
| + /* Prepare the sandbox. */
|
| + MinsfiInitializeSandbox();
|
| +
|
| + /* Empty arguments. The sandbox should always receive at least one argument
|
| + * (the name of the binary) but we test this anyway. */
|
| + ASSERT_EQ(0, MinsfiInvokeSandbox(0, NULL));
|
| +
|
| + /* Single argument. */
|
| + ASSERT_EQ(99, MinsfiInvokeSandbox(1, argv_99));
|
| +
|
| + /* Multiple arguments. */
|
| + ASSERT_EQ(356, MinsfiInvokeSandbox(3, argv_1_22_333));
|
| +
|
| + /* Clean up. */
|
| + MinsfiDestroySandbox();
|
| +}
|
| +
|
| +int main(void) {
|
| + test_copy_limits();
|
| + test_arguments_valid();
|
| + return 0;
|
| +}
|
|
|