blob: 34a6fbf6ea2b7c304ba02f6c42967345a97557ef [file] [log] [blame]
/*
* Copyright (c) 2017 Intel Corporation
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <zephyr.h>
#include <syscall_handler.h>
#include <ztest.h>
#define SEM_ARRAY_SIZE 16
/* Show that extern declarations don't interfere with detecting kernel
* objects, this was at one point a problem.
*/
extern struct k_sem sem1;
static __kernel struct k_sem semarray[SEM_ARRAY_SIZE];
static struct k_sem *dyn_sem[SEM_ARRAY_SIZE];
K_SEM_DEFINE(sem1, 0, 1);
static __kernel struct k_sem sem2;
static __kernel char bad_sem[sizeof(struct k_sem)];
static struct k_sem sem3;
static int test_object(struct k_sem *sem, int retval)
{
int ret;
if (retval) {
/* Expected to fail; bypass _obj_validation_check() so we don't
* fill the logs with spam
*/
ret = _k_object_validate(_k_object_find(sem), K_OBJ_SEM, 0);
} else {
ret = _obj_validation_check(_k_object_find(sem), sem,
K_OBJ_SEM, 0);
}
if (ret != retval) {
TC_PRINT("FAIL check of %p is not %d, got %d instead\n", sem,
retval, ret);
return 1;
}
return 0;
}
void object_permission_checks(struct k_sem *sem, bool skip_init)
{
/* Should fail because we don't have perms on this object */
zassert_false(test_object(sem, -EPERM),
"object should not have had permission granted");
k_object_access_grant(sem, k_current_get());
if (!skip_init) {
/* Should fail, not initialized and we have no permissions */
zassert_false(test_object(sem, -EINVAL),
"object should not have been initialized");
k_sem_init(sem, 0, 1);
}
/* This should succeed now */
zassert_false(test_object(sem, 0),
"object should have had sufficient permissions");
}
extern const k_tid_t _main_thread;
void test_generic_object(void)
{
struct k_sem stack_sem;
/* None of these should be even in the table */
zassert_false(test_object(&stack_sem, -EBADF), NULL);
zassert_false(test_object((struct k_sem *)&bad_sem, -EBADF), NULL);
zassert_false(test_object((struct k_sem *)0xFFFFFFFF, -EBADF), NULL);
#ifdef CONFIG_APPLICATION_MEMORY
zassert_false(test_object(&sem3, -EBADF), NULL);
#else
object_permission_checks(&sem3, false);
#endif
object_permission_checks(&sem1, true);
object_permission_checks(&sem2, false);
for (int i = 0; i < SEM_ARRAY_SIZE; i++) {
object_permission_checks(&semarray[i], false);
dyn_sem[i] = k_object_alloc(K_OBJ_SEM);
zassert_not_null(dyn_sem[i], "couldn't allocate semaphore\n");
/* Give an extra reference to another thread so the object
* doesn't disappear if we revoke our own
*/
k_object_access_grant(dyn_sem[i], _main_thread);
}
/* dynamic object table well-populated with semaphores at this point */
for (int i = 0; i < SEM_ARRAY_SIZE; i++) {
/* Should have permission granted but be uninitialized */
zassert_false(test_object(dyn_sem[i], -EINVAL), NULL);
k_object_access_revoke(dyn_sem[i], k_current_get());
object_permission_checks(dyn_sem[i], false);
k_object_free(dyn_sem[i]);
zassert_false(test_object(dyn_sem[i], -EBADF), NULL);
}
}
void test_main(void)
{
k_thread_system_pool_assign(k_current_get());
ztest_test_suite(object_validation,
ztest_unit_test(test_generic_object));
ztest_run_test_suite(object_validation);
}