kernel: pipe: runtime error checking
Add runtime error checking to k_pipe_cleanup and k_pipe_get and remove asserts. Adapted test which was expecting a fault to handle errors instead. Signed-off-by: Anas Nashif <anas.nashif@intel.com>
This commit is contained in:
parent
5076a83ef5
commit
361a84d07f
3 changed files with 22 additions and 23 deletions
|
@ -4155,9 +4155,11 @@ void k_pipe_init(struct k_pipe *pipe, unsigned char *buffer, size_t size);
|
|||
* if the buffer wasn't dynamically allocated.
|
||||
*
|
||||
* @param pipe Address of the pipe.
|
||||
* @retval 0 on success
|
||||
* @retval -EAGAIN nothing to cleanup
|
||||
* @req K-PIPE-002
|
||||
*/
|
||||
void k_pipe_cleanup(struct k_pipe *pipe);
|
||||
int k_pipe_cleanup(struct k_pipe *pipe);
|
||||
|
||||
/**
|
||||
* @brief Initialize a pipe and allocate a buffer for it
|
||||
|
@ -4216,6 +4218,7 @@ __syscall int k_pipe_put(struct k_pipe *pipe, void *data,
|
|||
* and K_FOREVER.
|
||||
*
|
||||
* @retval 0 At least @a min_xfer bytes of data were read.
|
||||
* @retval -EINVAL invalid parameters supplied
|
||||
* @retval -EIO Returned without waiting; zero data bytes were read.
|
||||
* @retval -EAGAIN Waiting period timed out; between zero and @a min_xfer
|
||||
* minus one data bytes were read.
|
||||
|
|
|
@ -20,8 +20,8 @@
|
|||
#include <sys/dlist.h>
|
||||
#include <init.h>
|
||||
#include <syscall_handler.h>
|
||||
#include <sys/__assert.h>
|
||||
#include <kernel_internal.h>
|
||||
#include <sys/check.h>
|
||||
|
||||
struct k_pipe_desc {
|
||||
unsigned char *buffer; /* Position in src/dest buffer */
|
||||
|
@ -174,16 +174,19 @@ static inline int z_vrfy_k_pipe_alloc_init(struct k_pipe *pipe, size_t size)
|
|||
#include <syscalls/k_pipe_alloc_init_mrsh.c>
|
||||
#endif
|
||||
|
||||
void k_pipe_cleanup(struct k_pipe *pipe)
|
||||
int k_pipe_cleanup(struct k_pipe *pipe)
|
||||
{
|
||||
__ASSERT_NO_MSG(!z_waitq_head(&pipe->wait_q.readers));
|
||||
__ASSERT_NO_MSG(!z_waitq_head(&pipe->wait_q.writers));
|
||||
CHECKIF(z_waitq_head(&pipe->wait_q.readers) != NULL ||
|
||||
z_waitq_head(&pipe->wait_q.writers) != NULL) {
|
||||
return -EAGAIN;
|
||||
}
|
||||
|
||||
if ((pipe->flags & K_PIPE_FLAG_ALLOC) != 0) {
|
||||
k_free(pipe->buffer);
|
||||
pipe->buffer = NULL;
|
||||
pipe->flags &= ~K_PIPE_FLAG_ALLOC;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -438,6 +441,10 @@ int z_pipe_put_internal(struct k_pipe *pipe, struct k_pipe_async *async_desc,
|
|||
ARG_UNUSED(async_desc);
|
||||
#endif
|
||||
|
||||
CHECKIF((min_xfer > bytes_to_write) || bytes_written == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&pipe->lock);
|
||||
|
||||
/*
|
||||
|
@ -577,8 +584,9 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
|||
size_t num_bytes_read = 0;
|
||||
size_t bytes_copied;
|
||||
|
||||
__ASSERT(min_xfer <= bytes_to_read, "");
|
||||
__ASSERT(bytes_read != NULL, "");
|
||||
CHECKIF((min_xfer > bytes_to_read) || bytes_read == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
k_spinlock_key_t key = k_spin_lock(&pipe->lock);
|
||||
|
||||
|
@ -586,7 +594,6 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
|||
* Create a list of "working readers" into which the data will be
|
||||
* directly copied.
|
||||
*/
|
||||
|
||||
if (!pipe_xfer_prepare(&xfer_list, &writer, &pipe->wait_q.writers,
|
||||
pipe->bytes_used, bytes_to_read,
|
||||
min_xfer, timeout)) {
|
||||
|
@ -718,7 +725,6 @@ int z_vrfy_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
|||
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_read, sizeof(*bytes_read)));
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE((void *)data, bytes_to_read));
|
||||
Z_OOPS(Z_SYSCALL_VERIFY(min_xfer <= bytes_to_read));
|
||||
|
||||
return z_impl_k_pipe_get((struct k_pipe *)pipe, (void *)data,
|
||||
bytes_to_read, bytes_read, min_xfer,
|
||||
|
@ -730,9 +736,6 @@ int z_vrfy_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
|||
int z_impl_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
|
||||
size_t *bytes_written, size_t min_xfer, s32_t timeout)
|
||||
{
|
||||
__ASSERT(min_xfer <= bytes_to_write, "");
|
||||
__ASSERT(bytes_written != NULL, "");
|
||||
|
||||
return z_pipe_put_internal(pipe, NULL, data,
|
||||
bytes_to_write, bytes_written,
|
||||
min_xfer, timeout);
|
||||
|
@ -745,7 +748,6 @@ int z_vrfy_k_pipe_put(struct k_pipe *pipe, void *data, size_t bytes_to_write,
|
|||
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_WRITE(bytes_written, sizeof(*bytes_written)));
|
||||
Z_OOPS(Z_SYSCALL_MEMORY_READ((void *)data, bytes_to_write));
|
||||
Z_OOPS(Z_SYSCALL_VERIFY(min_xfer <= bytes_to_write));
|
||||
|
||||
return z_impl_k_pipe_put((struct k_pipe *)pipe, (void *)data,
|
||||
bytes_to_write, bytes_written, min_xfer,
|
||||
|
|
|
@ -813,22 +813,16 @@ void test_pipe_get_timeout(void)
|
|||
* @ingroup kernel_pipe_tests
|
||||
* @see k_pipe_get()
|
||||
*/
|
||||
#ifdef CONFIG_USERSPACE
|
||||
/* userspace invalid size */
|
||||
void test_pipe_get_invalid_size(void)
|
||||
{
|
||||
size_t read;
|
||||
int ret;
|
||||
|
||||
valid_fault = true;
|
||||
k_pipe_get(&test_pipe, &rx_buffer,
|
||||
ret = k_pipe_get(&test_pipe, &rx_buffer,
|
||||
0, &read,
|
||||
1, TIMEOUT_200MSEC);
|
||||
|
||||
zassert_unreachable("fault didn't occur for min_xfer <= bytes_to_read");
|
||||
zassert_equal(ret, -EINVAL,
|
||||
"fault didn't occur for min_xfer <= bytes_to_read");
|
||||
}
|
||||
#else
|
||||
void test_pipe_get_invalid_size(void)
|
||||
{
|
||||
ztest_test_skip();
|
||||
}
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue