mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-11-16 12:34:45 +00:00
libfs/pipe: Fix panic caused by incomplete pipe dup
When dup fd, should also clone fctnl flags. Also should check NULL param in pipe_* funcs. Signed-off-by: yang.zhang <zhangyang01@kylinos.cn>
This commit is contained in:
@@ -58,6 +58,7 @@ static int duplicate_iop( rtems_libio_t *iop )
|
||||
rtems_filesystem_location_clone( &diop->pathinfo, &iop->pathinfo );
|
||||
rtems_filesystem_instance_unlock( &iop->pathinfo );
|
||||
|
||||
rtems_libio_iop_flags_set( diop, rtems_libio_fcntl_flags( oflag ) );
|
||||
/*
|
||||
* XXX: We call the open handler here to have a proper open and close pair.
|
||||
*
|
||||
@@ -65,10 +66,7 @@ static int duplicate_iop( rtems_libio_t *iop )
|
||||
*/
|
||||
rv = (*diop->pathinfo.handlers->open_h)( diop, NULL, oflag, 0 );
|
||||
if ( rv == 0 ) {
|
||||
rtems_libio_iop_flags_set(
|
||||
diop,
|
||||
LIBIO_FLAGS_OPEN | rtems_libio_fcntl_flags( oflag )
|
||||
);
|
||||
rtems_libio_iop_flags_set( diop, LIBIO_FLAGS_OPEN );
|
||||
rv = rtems_libio_iop_to_descriptor( diop );
|
||||
} else {
|
||||
rtems_libio_free( diop );
|
||||
|
||||
@@ -151,6 +151,9 @@ void pipe_release(
|
||||
pipe_control_t *pipe = *pipep;
|
||||
uint32_t mode;
|
||||
|
||||
if (!pipe)
|
||||
return;
|
||||
|
||||
pipe_lock();
|
||||
PIPE_LOCK(pipe);
|
||||
|
||||
@@ -275,6 +278,9 @@ ssize_t pipe_read(
|
||||
{
|
||||
int chunk, chunk1, read = 0, ret = 0;
|
||||
|
||||
if (!pipe)
|
||||
return -EPIPE;
|
||||
|
||||
PIPE_LOCK(pipe);
|
||||
|
||||
while (PIPE_EMPTY(pipe)) {
|
||||
@@ -331,6 +337,9 @@ ssize_t pipe_write(
|
||||
{
|
||||
int chunk, chunk1, written = 0, ret = 0;
|
||||
|
||||
if (!pipe)
|
||||
return -EPIPE;
|
||||
|
||||
/* Write nothing */
|
||||
if (count == 0)
|
||||
return 0;
|
||||
@@ -401,6 +410,10 @@ int pipe_ioctl(
|
||||
rtems_libio_t *iop
|
||||
)
|
||||
{
|
||||
|
||||
if (!pipe)
|
||||
return -EPIPE;
|
||||
|
||||
if (cmd == FIONREAD) {
|
||||
if (buffer == NULL)
|
||||
return -EFAULT;
|
||||
|
||||
@@ -45,14 +45,28 @@ const char rtems_test_name[] = "PSXPIPE 1";
|
||||
/* forward declarations to avoid warnings */
|
||||
rtems_task Init(rtems_task_argument ignored);
|
||||
|
||||
static int dup_fd_test(int *fd)
|
||||
{
|
||||
int r;
|
||||
|
||||
if ((r = fcntl(*fd, F_DUPFD, 0)) < 0 ||
|
||||
fcntl(r, F_SETFD, FD_CLOEXEC) < 0 ||
|
||||
fcntl(r, F_SETFL, O_NONBLOCK))
|
||||
return -1;
|
||||
(void)close(*fd);
|
||||
(*fd = r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
rtems_task Init(
|
||||
rtems_task_argument ignored
|
||||
)
|
||||
{
|
||||
int fd[2] = {0,0};
|
||||
int dummy_fd[2] = {0,0};
|
||||
int dummy_fd[4] = {0,0};
|
||||
int status = 0;
|
||||
void *opaque = NULL;
|
||||
char c;
|
||||
|
||||
TEST_BEGIN();
|
||||
|
||||
@@ -65,8 +79,16 @@ rtems_task Init(
|
||||
status = pipe( fd );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
status = close( fd[0] );
|
||||
status |= close( fd[1] );
|
||||
puts( "Init - dup pipe -- OK" );
|
||||
status = dup_fd_test(&fd[0]);
|
||||
status |= dup_fd_test(&fd[1]);
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
/* close pipe writer, so reader can return immediately */
|
||||
puts( "Init - read pipe -- OK" );
|
||||
status = close( fd[1] );
|
||||
status |= read(fd[0], &c, 1);
|
||||
status |= close( fd[0] );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
puts( "Init - create pipe -- OK" );
|
||||
@@ -91,6 +113,10 @@ rtems_task Init(
|
||||
rtems_test_assert( dummy_fd[0] != -1 );
|
||||
dummy_fd[1] = open( "/file02", O_RDONLY | O_CREAT, S_IRWXU );
|
||||
rtems_test_assert( dummy_fd[1] != -1 );
|
||||
dummy_fd[2] = open( "/file03", O_RDONLY | O_CREAT, S_IRWXU );
|
||||
rtems_test_assert( dummy_fd[2] != -1 );
|
||||
dummy_fd[3] = open( "/file04", O_RDONLY | O_CREAT, S_IRWXU );
|
||||
rtems_test_assert( dummy_fd[3] != -1 );
|
||||
|
||||
/* case where fifo_open for read => open fails */
|
||||
puts( "Init - create pipe -- expect ENFILE" );
|
||||
@@ -98,8 +124,8 @@ rtems_task Init(
|
||||
rtems_test_assert( status == -1 );
|
||||
rtems_test_assert( errno == ENFILE );
|
||||
|
||||
status = close( dummy_fd[1] );
|
||||
status |= unlink( "/file02" );
|
||||
status = close( dummy_fd[3] );
|
||||
status |= unlink( "/file04" );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
/* case where fifo_open for write => open fails */
|
||||
@@ -110,6 +136,10 @@ rtems_task Init(
|
||||
|
||||
status = close( dummy_fd[0] );
|
||||
status |= unlink( "/file01" );
|
||||
status |= close( dummy_fd[1] );
|
||||
status |= unlink( "/file02" );
|
||||
status |= close( dummy_fd[2] );
|
||||
status |= unlink( "/file03" );
|
||||
rtems_test_assert( status == 0 );
|
||||
|
||||
TEST_END();
|
||||
@@ -121,7 +151,7 @@ rtems_task Init(
|
||||
#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER
|
||||
#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
|
||||
|
||||
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 5
|
||||
#define CONFIGURE_MAXIMUM_FILE_DESCRIPTORS 7
|
||||
|
||||
#define CONFIGURE_MAXIMUM_TASKS 1
|
||||
#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
*** TEST POSIX PIPE CREATION - 01 ***
|
||||
Init - attempt to create pipe -- expect EFAULT
|
||||
Init - create pipe -- OK
|
||||
Init - dup pipe -- OK
|
||||
Init - read pipe -- OK
|
||||
Init - create pipe -- OK
|
||||
Init - attempt to create pipe -- expect ENOMEM
|
||||
Init - create pipe -- expect ENFILE
|
||||
|
||||
Reference in New Issue
Block a user