mirror of
https://gitlab.rtems.org/rtems/rtos/rtems.git
synced 2025-12-05 23:23:13 +00:00
cpukit/close.c: Fix reference counting under concurrent access.
Fixes issue with IOP being freed during close call.
This commit is contained in:
@@ -52,7 +52,7 @@ int close(
|
|||||||
rtems_set_errno_and_return_minus_one( EBADF );
|
rtems_set_errno_and_return_minus_one( EBADF );
|
||||||
}
|
}
|
||||||
|
|
||||||
iop = rtems_libio_iop( fd );
|
LIBIO_GET_IOP( fd, iop );
|
||||||
flags = rtems_libio_iop_flags( iop );
|
flags = rtems_libio_iop_flags( iop );
|
||||||
|
|
||||||
while ( true ) {
|
while ( true ) {
|
||||||
@@ -60,15 +60,10 @@ int close(
|
|||||||
bool success;
|
bool success;
|
||||||
|
|
||||||
if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) {
|
if ( ( flags & LIBIO_FLAGS_OPEN ) == 0 ) {
|
||||||
|
rtems_libio_iop_drop( iop );
|
||||||
rtems_set_errno_and_return_minus_one( EBADF );
|
rtems_set_errno_and_return_minus_one( EBADF );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The expected flags depends on close when busy flag. If set
|
|
||||||
* there can be references held when calling the close handler */
|
|
||||||
if ( ( flags & LIBIO_FLAGS_CLOSE_BUSY ) == 0 ) {
|
|
||||||
flags &= LIBIO_FLAGS_FLAGS_MASK;
|
|
||||||
}
|
|
||||||
|
|
||||||
desired = flags & ~LIBIO_FLAGS_OPEN;
|
desired = flags & ~LIBIO_FLAGS_OPEN;
|
||||||
success = _Atomic_Compare_exchange_uint(
|
success = _Atomic_Compare_exchange_uint(
|
||||||
&iop->flags,
|
&iop->flags,
|
||||||
@@ -82,14 +77,15 @@ int close(
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( ( flags & LIBIO_FLAGS_REFERENCE_MASK ) != 0 ) {
|
if ( ( flags & LIBIO_FLAGS_REFERENCE_MASK ) != LIBIO_FLAGS_REFERENCE_INC ) {
|
||||||
|
rtems_libio_iop_drop( iop );
|
||||||
rtems_set_errno_and_return_minus_one( EBUSY );
|
rtems_set_errno_and_return_minus_one( EBUSY );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = (*iop->pathinfo.handlers->close_h)( iop );
|
rc = (*iop->pathinfo.handlers->close_h)( iop );
|
||||||
|
|
||||||
rtems_libio_free( iop );
|
rtems_libio_iop_drop( iop );
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user