[Libreoffice-commits] core.git: sd/source
sd/source/ui/inc/RemoteServer.hxx |1 - 1 file changed, 1 deletion(-) New commits: commit 4e511cc7dfbf14b6176ce352db8125c16eefeebf Author: Andrzej Hunt AuthorDate: Sat Jul 24 14:23:10 2021 +0200 Commit: Andrzej Hunt CommitDate: Sat Jul 24 16:05:19 2021 +0200 sdremote: remove useless comment It's been there since the beginning, but doesn't help us much: e4239e041468 (Initial checkin of remote control., 2012-07-09) Change-Id: I57425001cd0b9d0d035916405bd6d94329964b4e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119466 Tested-by: Jenkins Reviewed-by: Andrzej Hunt diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx index d5dba8c092f0..e676087899d9 100644 --- a/sd/source/ui/inc/RemoteServer.hxx +++ b/sd/source/ui/inc/RemoteServer.hxx @@ -8,7 +8,6 @@ */ #pragma once -// SERVER #include #include ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: sd/source
sd/source/ui/remotecontrol/BufferedStreamSocket.cxx |4 sd/source/ui/remotecontrol/BufferedStreamSocket.hxx |5 - 2 files changed, 8 insertions(+), 1 deletion(-) New commits: commit 2855f12072023930a15ea852e40d05de4a6be164 Author: Andrzej Hunt AuthorDate: Sat Jul 17 09:42:47 2021 +0200 Commit: Andrzej Hunt CommitDate: Sat Jul 24 09:51:36 2021 +0200 sdremote: close BufferedStreamSocket on destruction This follows the pattern in osl::Socket which also cleans up on destruction if necessary. By closing on destruction we can avoid leaking the underlying socket or filedescriptor in the numerous scenarios where we throw away the socket without bothering to call close(). This isn't a big deal in normal usage - we don't use many sockets in the first place - but you can quickly run out of filedescriptors when running sufficiently complex tests. We also need to make BufferedStreamSocket final to avoid triggering loplugin:fragiledestructor - BufferedStreamSocket probably should have been final anyway, so there's no reason not to do so. Change-Id: I90c271df4b598a6c2b326fde13543e6b27d7a110 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119093 Tested-by: Jenkins Reviewed-by: Andrzej Hunt diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx index b3a9cc154e37..58adb13ca7bf 100644 --- a/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx +++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.cxx @@ -47,6 +47,10 @@ BufferedStreamSocket::BufferedStreamSocket( int aSocket ): { } +BufferedStreamSocket::~BufferedStreamSocket() { +close(); +} + void BufferedStreamSocket::getPeerAddr(osl::SocketAddr& rAddr) { assert ( !usingCSocket ); diff --git a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx index 08a81cf002f6..6abf7ec1bf8d 100644 --- a/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx +++ b/sd/source/ui/remotecontrol/BufferedStreamSocket.hxx @@ -25,7 +25,7 @@ namespace sd * returned to being a StreamSocket wrapper if/when Bluetooth is * integrated into osl Sockets. */ -class BufferedStreamSocket : +class BufferedStreamSocket final : public IBluetoothSocket, private ::osl::StreamSocket { @@ -40,6 +40,9 @@ namespace sd */ explicit BufferedStreamSocket( int aSocket ); BufferedStreamSocket( const BufferedStreamSocket ); + +~BufferedStreamSocket(); + /** * Blocks until a line is read. * Returns whatever the last call of recv returned, i.e. 0 or less ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - sd/source
sd/source/ui/inc/RemoteServer.hxx |2 sd/source/ui/remotecontrol/Server.cxx | 116 ++ 2 files changed, 64 insertions(+), 54 deletions(-) New commits: commit 7d93272c6ad0a7209c1e5212484ee44970de850f Author: Andrzej Hunt AuthorDate: Fri Jul 16 18:52:57 2021 +0200 Commit: Noel Grandin CommitDate: Wed Jul 21 08:42:33 2021 +0200 sdremote: avoid infinite loop if client disconnects during handshake The following loop can turn into an infinite loop if the client disconnects at the wrong point in time, because pSocket->readLine() returns 0 (indicating disconnection), aLine remains empty (no data was read), and we just keep looping because we never bothered to check the return value: do { pSocket->readLine( aLine ); } while ( aLine.getLength() > 0 ); Aside from spinning unnecessarily, this infinite loop also stops the server from being able to accept any new incoming connections - in effect this causes a DOS of the server. Hence we need to start checking readLine's return value, and break out of this loop - and in fact break of the surrounding outer loop too (because we discard this connection and want to wait for another connection to arrive). Because of the nested looping it's hard to come up with a clean solution that only involves changing this loop - we'd probably need to introduce a temporary to remember that the client has disconnected, and check that temporary after the do...while - letting us 'continue' the outer loop. Therefore we first extract the code that handles newly accepted clients into a separate method, which then lets us simplify the implementation by returning at those points that we know a client has disappeared. That unfortunately makes this bug-fix patch a little more noisy than expected, but it is a refactoring that we'd want to make anyway. (There are further improvement we can make here, but I'll put those in a separate commit to simplify cherry-picking of just this fix. Examples include moving to smart pointers instead of new/delete, introducing an early return instead of the really long if statement, etc.) Change-Id: I13c6efa622a1b1de10b72757ea07e5f4660749fb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119083 Tested-by: Jenkins Reviewed-by: Noel Grandin (cherry picked from commit fcc4d8e01360baa9ba0bf20eb5e7a1c9af793a02) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119184 diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx index 65bc523ad274..d5dba8c092f0 100644 --- a/sd/source/ui/inc/RemoteServer.hxx +++ b/sd/source/ui/inc/RemoteServer.hxx @@ -28,6 +28,7 @@ namespace com::sun::star::uno { template class Reference; namespace sd { +class BufferedStreamSocket; class Communicator; struct ClientInfo @@ -81,6 +82,7 @@ namespace sd ::std::vector< std::shared_ptr< ClientInfoInternal > > mAvailableClients; void execute() override; +void handleAcceptedConnection( BufferedStreamSocket *pSocket ) ; }; } diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index d3f1ac67f904..b1be49b45dce 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -110,73 +110,81 @@ void RemoteServer::execute() return; // Closed, or other issue. } BufferedStreamSocket *pSocket = new BufferedStreamSocket( aSocket); -OString aLine; -if ( pSocket->readLine( aLine) -&& aLine == "LO_SERVER_CLIENT_PAIR" -&& pSocket->readLine( aLine ) ) -{ -OString aName( aLine ); +handleAcceptedConnection( pSocket ); +} +SAL_INFO( "sdremote", "shutting down RemoteServer" ); +spServer = nullptr; // Object is destroyed when Thread::execute() ends. +} -if ( ! pSocket->readLine( aLine ) ) -{ -delete pSocket; -continue; -} -OString aPin( aLine ); +void RemoteServer::handleAcceptedConnection( BufferedStreamSocket *pSocket ) +{ +OString aLine; +if ( pSocket->readLine( aLine) +&& aLine == "LO_SERVER_CLIENT_PAIR" +&& pSocket->readLine( aLine ) ) +{ +OString aName( aLine ); -SocketAddr aClientAddr; -pSocket->getPeerAddr( aClientAddr ); +if ( ! pSocket->readLine( aLine ) ) +{ +delete pSocket; +return; +} +OString aPin( aLine ); -MutexGuard aGuard( sDataMutex ); -std::shared_ptr< ClientInfoInternal > pClient = -std::make_shared( -OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ), -pSocket, OStringToOUString( aPin,
[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - sd/source
sd/source/ui/remotecontrol/Transmitter.cxx | 16 +--- sd/source/ui/remotecontrol/Transmitter.hxx | 11 --- 2 files changed, 17 insertions(+), 10 deletions(-) New commits: commit a4360b155bef02cf3da41e3f05c56d42feef7926 Author: Andrzej Hunt AuthorDate: Sun Jul 11 17:17:27 2021 +0200 Commit: Michael Stahl CommitDate: Tue Jul 20 11:22:42 2021 +0200 sdremote: fix race condition in Transmitter shutdown to plug leak We need to acquire the mutex in notifyFinished() to avoid a race between notifyFinished() and the loop in run(). And we also need to check mFinishRequested) while holding the mutex to avoid the same race condition. While we're here, rename the mutex to make it more obvious that it's not only protecting the queues. The race can happen because the loop in run() blocks until mQueuesNotEmpty is set. It also resets mQueuesNotEmpty at the end of each iteration if the queues are empty. So if someone sets mQueuesNotEmpty in the middle of an iteration, and the loop later resets it, the loop won't continue iterating. But we're actually using mQueuesNotEmpty to indicate either that the queues have data OR that we might want to finish transmission. And the problem is that notifyFinished() sets mFinishRequested, followed by setting mQueuesNotEmpty in an attempt to get the loop to process mFinishRequested (at which point the loop should finish and return). But as described above, we can easily get into a situation where the loop resets mQueuesNotEmpty again (at least if there's no more pending data in the queues). In this scenario, the loop blocks forever (we won't receive any new messages after notifyFinished()), causing a leak of both Transmitter and any resources it's using - e.g. the StreamSocket. The easiest way to fix this is to make it clear that the mutex protects all internal state, followed by using it to protect all internal state. This issue is not a big deal in normal usage - it's a tiny leak, and users won't connect enough clients for accumulated leaks to pose any issues. But it's ugly, and potentially problematic for long-running tests which could run out of filedescriptors because of the socket leak. I will rename mQueuesNotEmpty to something more obvious (possibly mProcessingRequired) in a separate commit. Change-Id: I2e22087054f3f6a02e05c568b1832ccc5a8b47a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118751 Reviewed-by: Andrzej Hunt Tested-by: Jenkins (cherry picked from commit 8e6cdb02450a876b5c684eb621e1c9383fb1c428) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118917 Reviewed-by: Michael Stahl diff --git a/sd/source/ui/remotecontrol/Transmitter.cxx b/sd/source/ui/remotecontrol/Transmitter.cxx index 8f3b7d24c184..76cda8feae55 100644 --- a/sd/source/ui/remotecontrol/Transmitter.cxx +++ b/sd/source/ui/remotecontrol/Transmitter.cxx @@ -17,8 +17,8 @@ using namespace sd; Transmitter::Transmitter( IBluetoothSocket* aSocket ) : pStreamSocket( aSocket ), mQueuesNotEmpty(), -mFinishRequested(), -mQueueMutex(), +mMutex(), +mFinishRequested( false ), mLowPriority(), mHighPriority() { @@ -32,10 +32,11 @@ void SAL_CALL Transmitter::run() { mQueuesNotEmpty.wait(); -if ( mFinishRequested.check() ) -return; +::osl::MutexGuard aGuard( mMutex ); -::osl::MutexGuard aQueueGuard( mQueueMutex ); +if ( mFinishRequested ) { +return; +} if ( !mHighPriority.empty() ) { OString aMessage( mHighPriority.front() ); @@ -60,7 +61,8 @@ void SAL_CALL Transmitter::run() void Transmitter::notifyFinished() { -mFinishRequested.set(); +::osl::MutexGuard aGuard( mMutex ); +mFinishRequested = true; mQueuesNotEmpty.set(); } @@ -70,7 +72,7 @@ Transmitter::~Transmitter() void Transmitter::addMessage( const OString& aMessage, const Priority aPriority ) { -::osl::MutexGuard aQueueGuard( mQueueMutex ); +::osl::MutexGuard aGuard( mMutex ); switch ( aPriority ) { case PRIORITY_LOW: diff --git a/sd/source/ui/remotecontrol/Transmitter.hxx b/sd/source/ui/remotecontrol/Transmitter.hxx index 8acebfeff7e8..1cd94ea26712 100644 --- a/sd/source/ui/remotecontrol/Transmitter.hxx +++ b/sd/source/ui/remotecontrol/Transmitter.hxx @@ -37,11 +37,16 @@ private: ::sd::IBluetoothSocket* pStreamSocket; ::osl::Condition mQueuesNotEmpty; -::osl::Condition mFinishRequested; - -::osl::Mutex mQueueMutex; +::osl::Mutex mMutex; +/** + * Used to indicate that we're done and the transmitter loop should exit. + * All access must be guarded my `mMutex`. + */ +bool mFinishRequested; +/// Queue for low priority messages. All access must be guarded my `mMutex`. std::queue
[Libreoffice-commits] core.git: sd/source
sd/source/ui/remotecontrol/Server.cxx | 100 +- 1 file changed, 51 insertions(+), 49 deletions(-) New commits: commit 137744a25b26d86b9be16a107b3bd011f6ab4b07 Author: Andrzej Hunt AuthorDate: Fri Jul 16 18:58:10 2021 +0200 Commit: Noel Grandin CommitDate: Sat Jul 17 11:50:08 2021 +0200 sdremote: introduce early return to improve handleAcceptedConnection This should make it easier to understand the handshake sequence. Change-Id: If06e98cdfe7295ed00efae61815a8696a90e9533 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119085 Tested-by: Jenkins Reviewed-by: Noel Grandin diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index e3576bacd52e..83a80e9916df 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -112,67 +112,69 @@ void RemoteServer::execute() void RemoteServer::handleAcceptedConnection( BufferedStreamSocket *pSocket ) { OString aLine; -if ( pSocket->readLine( aLine) -&& aLine == "LO_SERVER_CLIENT_PAIR" -&& pSocket->readLine( aLine ) ) +if ( ! ( pSocket->readLine( aLine) + && aLine == "LO_SERVER_CLIENT_PAIR" + && pSocket->readLine( aLine ) ) ) { -OString aName( aLine ); +SAL_INFO( "sdremote", "client failed to send LO_SERVER_CLIENT_PAIR, ignoring" ); +delete pSocket; +return; +} -if ( ! pSocket->readLine( aLine ) ) -{ +OString aName( aLine ); + +if ( ! pSocket->readLine( aLine ) ) +{ +delete pSocket; +return; +} +OString aPin( aLine ); + +SocketAddr aClientAddr; +pSocket->getPeerAddr( aClientAddr ); + +do +{ +// Read off any additional non-empty lines +// We know that we at least have the empty termination line to read. +if ( ! pSocket->readLine( aLine ) ) { delete pSocket; return; } -OString aPin( aLine ); +} +while ( aLine.getLength() > 0 ); -SocketAddr aClientAddr; -pSocket->getPeerAddr( aClientAddr ); +MutexGuard aGuard( sDataMutex ); +std::shared_ptr< ClientInfoInternal > pClient = +std::make_shared( +OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ), +pSocket, OStringToOUString( aPin, RTL_TEXTENCODING_UTF8 ) ); +mAvailableClients.push_back( pClient ); -do +// Check if we already have this server. +Reference< XNameAccess > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get(); +const Sequence< OUString > aNames = xConfig->getElementNames(); +for ( const auto& rName : aNames ) +{ +if ( rName == pClient->mName ) { -// Read off any additional non-empty lines -// We know that we at least have the empty termination line to read. -if ( ! pSocket->readLine( aLine ) ) { -delete pSocket; +Reference xSetItem( xConfig->getByName(rName), UNO_QUERY ); +Any axPin(xSetItem->getByName("PIN")); +OUString sPin; +axPin >>= sPin; + +if ( sPin == pClient->mPin ) { +SAL_INFO( "sdremote", "client found on validated list -- connecting" ); +connectClient( pClient, sPin ); return; } } -while ( aLine.getLength() > 0 ); - -MutexGuard aGuard( sDataMutex ); -std::shared_ptr< ClientInfoInternal > pClient = -std::make_shared( -OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ), -pSocket, OStringToOUString( aPin, RTL_TEXTENCODING_UTF8 ) ); -mAvailableClients.push_back( pClient ); - -// Check if we already have this server. -Reference< XNameAccess > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get(); -const Sequence< OUString > aNames = xConfig->getElementNames(); -for ( const auto& rName : aNames ) -{ -if ( rName == pClient->mName ) -{ -Reference xSetItem( xConfig->getByName(rName), UNO_QUERY ); -Any axPin(xSetItem->getByName("PIN")); -OUString sPin; -axPin >>= sPin; - -if ( sPin == pClient->mPin ) { -SAL_INFO( "sdremote", "client found on validated list -- connecting" ); -connectClient( pClient, sPin ); -return; -} -} -} -// Pin not found so inform the client. -SAL_INFO( "sdremote", "client not found on validated list" ); -pSocket->write( "LO_SERVER_VALIDATING_PIN\n\n", -strlen( "LO_SERVER_VALIDATING_PIN\n\n" ) ); -} else { -SAL_INFO( "sdremote", "client failed to send LO_SERVER_CLIENT_PAIR, ignoring" ); -
[Libreoffice-commits] core.git: sd/source
sd/source/ui/remotecontrol/Server.cxx | 11 +++ 1 file changed, 3 insertions(+), 8 deletions(-) New commits: commit d6078e02832d13054e6552c6e20277fd1f3e83f6 Author: Andrzej Hunt AuthorDate: Fri Jul 16 18:55:19 2021 +0200 Commit: Noel Grandin CommitDate: Sat Jul 17 11:49:20 2021 +0200 sdremote: clean up now-unneeded "found" flag Since ???, this code now lives in a standalone method, allowing us to return as soon as know that the handshake is complete. This lets us remove aFound and simplify the code a little. Change-Id: I51d5281492d2e4280a101e67d606073f4d064c29 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119084 Tested-by: Jenkins Reviewed-by: Noel Grandin diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index 6a1716b22e86..e3576bacd52e 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -149,7 +149,6 @@ void RemoteServer::handleAcceptedConnection( BufferedStreamSocket *pSocket ) // Check if we already have this server. Reference< XNameAccess > const xConfig = officecfg::Office::Impress::Misc::AuthorisedRemotes::get(); const Sequence< OUString > aNames = xConfig->getElementNames(); -bool aFound = false; for ( const auto& rName : aNames ) { if ( rName == pClient->mName ) @@ -162,18 +161,14 @@ void RemoteServer::handleAcceptedConnection( BufferedStreamSocket *pSocket ) if ( sPin == pClient->mPin ) { SAL_INFO( "sdremote", "client found on validated list -- connecting" ); connectClient( pClient, sPin ); -aFound = true; -break; +return; } } } // Pin not found so inform the client. -if ( !aFound ) -{ -SAL_INFO( "sdremote", "client not found on validated list" ); -pSocket->write( "LO_SERVER_VALIDATING_PIN\n\n", +SAL_INFO( "sdremote", "client not found on validated list" ); +pSocket->write( "LO_SERVER_VALIDATING_PIN\n\n", strlen( "LO_SERVER_VALIDATING_PIN\n\n" ) ); -} } else { SAL_INFO( "sdremote", "client failed to send LO_SERVER_CLIENT_PAIR, ignoring" ); delete pSocket; ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: sd/source
sd/source/ui/inc/RemoteServer.hxx |2 sd/source/ui/remotecontrol/Server.cxx | 116 ++ 2 files changed, 64 insertions(+), 54 deletions(-) New commits: commit fcc4d8e01360baa9ba0bf20eb5e7a1c9af793a02 Author: Andrzej Hunt AuthorDate: Fri Jul 16 18:52:57 2021 +0200 Commit: Noel Grandin CommitDate: Sat Jul 17 11:48:37 2021 +0200 sdremote: avoid infinite loop if client disconnects during handshake The following loop can turn into an infinite loop if the client disconnects at the wrong point in time, because pSocket->readLine() returns 0 (indicating disconnection), aLine remains empty (no data was read), and we just keep looping because we never bothered to check the return value: do { pSocket->readLine( aLine ); } while ( aLine.getLength() > 0 ); Aside from spinning unnecessarily, this infinite loop also stops the server from being able to accept any new incoming connections - in effect this causes a DOS of the server. Hence we need to start checking readLine's return value, and break out of this loop - and in fact break of the surrounding outer loop too (because we discard this connection and want to wait for another connection to arrive). Because of the nested looping it's hard to come up with a clean solution that only involves changing this loop - we'd probably need to introduce a temporary to remember that the client has disconnected, and check that temporary after the do...while - letting us 'continue' the outer loop. Therefore we first extract the code that handles newly accepted clients into a separate method, which then lets us simplify the implementation by returning at those points that we know a client has disappeared. That unfortunately makes this bug-fix patch a little more noisy than expected, but it is a refactoring that we'd want to make anyway. (There are further improvement we can make here, but I'll put those in a separate commit to simplify cherry-picking of just this fix. Examples include moving to smart pointers instead of new/delete, introducing an early return instead of the really long if statement, etc.) Change-Id: I13c6efa622a1b1de10b72757ea07e5f4660749fb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119083 Tested-by: Jenkins Reviewed-by: Noel Grandin diff --git a/sd/source/ui/inc/RemoteServer.hxx b/sd/source/ui/inc/RemoteServer.hxx index 65bc523ad274..d5dba8c092f0 100644 --- a/sd/source/ui/inc/RemoteServer.hxx +++ b/sd/source/ui/inc/RemoteServer.hxx @@ -28,6 +28,7 @@ namespace com::sun::star::uno { template class Reference; namespace sd { +class BufferedStreamSocket; class Communicator; struct ClientInfo @@ -81,6 +82,7 @@ namespace sd ::std::vector< std::shared_ptr< ClientInfoInternal > > mAvailableClients; void execute() override; +void handleAcceptedConnection( BufferedStreamSocket *pSocket ) ; }; } diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index 36e052dd006f..6a1716b22e86 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -103,73 +103,81 @@ void RemoteServer::execute() return; // Closed, or other issue. } BufferedStreamSocket *pSocket = new BufferedStreamSocket( aSocket); -OString aLine; -if ( pSocket->readLine( aLine) -&& aLine == "LO_SERVER_CLIENT_PAIR" -&& pSocket->readLine( aLine ) ) -{ -OString aName( aLine ); +handleAcceptedConnection( pSocket ); +} +SAL_INFO( "sdremote", "shutting down RemoteServer" ); +spServer = nullptr; // Object is destroyed when Thread::execute() ends. +} -if ( ! pSocket->readLine( aLine ) ) -{ -delete pSocket; -continue; -} -OString aPin( aLine ); +void RemoteServer::handleAcceptedConnection( BufferedStreamSocket *pSocket ) +{ +OString aLine; +if ( pSocket->readLine( aLine) +&& aLine == "LO_SERVER_CLIENT_PAIR" +&& pSocket->readLine( aLine ) ) +{ +OString aName( aLine ); -SocketAddr aClientAddr; -pSocket->getPeerAddr( aClientAddr ); +if ( ! pSocket->readLine( aLine ) ) +{ +delete pSocket; +return; +} +OString aPin( aLine ); -MutexGuard aGuard( sDataMutex ); -std::shared_ptr< ClientInfoInternal > pClient = -std::make_shared( -OStringToOUString( aName, RTL_TEXTENCODING_UTF8 ), -pSocket, OStringToOUString( aPin, RTL_TEXTENCODING_UTF8 ) ); -mAvailableClients.push_back( pClient ); +SocketAddr aClientAddr; +
[Libreoffice-commits] core.git: sd/source
sd/source/ui/remotecontrol/Server.cxx |7 --- 1 file changed, 7 deletions(-) New commits: commit 34309e232c13017c9d178627c652e5ffdeb3 Author: Andrzej Hunt AuthorDate: Sat Jul 17 08:44:22 2021 +0200 Commit: Andrzej Hunt CommitDate: Sat Jul 17 11:31:03 2021 +0200 sdremote: remove commented out experimental check The entire if statement was introduced only to check for experimental mode in the following commit - the xContext check is seemingly only needed for null safety: 79c1b16a96a6 (sdremote: make it possible to have only bluetooth enabled, 2012-11-27) Later, the epxerimental mode check was disabled in: b9d2671ae11d (merge WiFi support into remote control feature toggle, 2013-08-01) Given that the remote is clearly no longer experimental, it's time to remove the commented code entirely - and I think it's also safe to remove the xContext check too. (Note: the remote IS still controlled by the EnableSdRemote option, and IS disabled by default.) Change-Id: Id118924021d5029b4f15df9cbb3eba28f3b902c0 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/119091 Tested-by: Jenkins Reviewed-by: Andrzej Hunt diff --git a/sd/source/ui/remotecontrol/Server.cxx b/sd/source/ui/remotecontrol/Server.cxx index d3f1ac67f904..36e052dd006f 100644 --- a/sd/source/ui/remotecontrol/Server.cxx +++ b/sd/source/ui/remotecontrol/Server.cxx @@ -78,13 +78,6 @@ RemoteServer::~RemoteServer() void RemoteServer::execute() { SAL_INFO( "sdremote", "RemoteServer::execute called" ); -uno::Reference< uno::XComponentContext > xContext = comphelper::getProcessComponentContext(); -if (!xContext.is()/* || !officecfg::Office::Common::Misc::ExperimentalMode::get(xContext)*/) -{ -// SAL_INFO("sdremote", "not in experimental mode, disabling TCP server"); -spServer = nullptr; -return; -} osl::SocketAddr aAddr( "0.0.0.0", PORT ); if ( !mSocket.bind( aAddr ) ) { ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: sd/source
sd/source/ui/remotecontrol/Transmitter.cxx | 14 +++--- sd/source/ui/remotecontrol/Transmitter.hxx |2 +- 2 files changed, 8 insertions(+), 8 deletions(-) New commits: commit f4ea1e6095ff751cbecf10061c4eff9934ffd520 Author: Andrzej Hunt AuthorDate: Sun Jul 11 17:22:54 2021 +0200 Commit: Andrzej Hunt CommitDate: Fri Jul 16 07:20:36 2021 +0200 sdremote: Transmitter: s/mQueuesNotEmpty/mProcessingRequired/ Make mProcessingRequired's name a bit more self-explanatory to make it clear what we're actually using it for. See also a 8e6cdb0 which fixed a race condition caused by incorrect use of this Condition. Change-Id: I6ad63dbd5ae8ed767f42ea22e568ac47a4d08642 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118752 Tested-by: Jenkins Reviewed-by: Andrzej Hunt diff --git a/sd/source/ui/remotecontrol/Transmitter.cxx b/sd/source/ui/remotecontrol/Transmitter.cxx index 76cda8feae55..f00f15502a45 100644 --- a/sd/source/ui/remotecontrol/Transmitter.cxx +++ b/sd/source/ui/remotecontrol/Transmitter.cxx @@ -16,7 +16,7 @@ using namespace sd; Transmitter::Transmitter( IBluetoothSocket* aSocket ) : pStreamSocket( aSocket ), -mQueuesNotEmpty(), +mProcessingRequired(), mMutex(), mFinishRequested( false ), mLowPriority(), @@ -30,7 +30,7 @@ void SAL_CALL Transmitter::run() while ( true ) { -mQueuesNotEmpty.wait(); +mProcessingRequired.wait(); ::osl::MutexGuard aGuard( mMutex ); @@ -52,9 +52,9 @@ void SAL_CALL Transmitter::run() pStreamSocket->write( aMessage.getStr(), aMessage.getLength() ); } -if ( mLowPriority.empty() && mHighPriority.empty() ) +if ( mLowPriority.empty() && mHighPriority.empty()) { -mQueuesNotEmpty.reset(); +mProcessingRequired.reset(); } } } @@ -63,7 +63,7 @@ void Transmitter::notifyFinished() { ::osl::MutexGuard aGuard( mMutex ); mFinishRequested = true; -mQueuesNotEmpty.set(); +mProcessingRequired.set(); } Transmitter::~Transmitter() @@ -82,9 +82,9 @@ void Transmitter::addMessage( const OString& aMessage, const Priority aPriority mHighPriority.push( aMessage ); break; } -if ( !mQueuesNotEmpty.check() ) +if ( !mProcessingRequired.check() ) { -mQueuesNotEmpty.set(); +mProcessingRequired.set(); } } diff --git a/sd/source/ui/remotecontrol/Transmitter.hxx b/sd/source/ui/remotecontrol/Transmitter.hxx index 1cd94ea26712..c24f5a5a46fe 100644 --- a/sd/source/ui/remotecontrol/Transmitter.hxx +++ b/sd/source/ui/remotecontrol/Transmitter.hxx @@ -36,7 +36,7 @@ private: ::sd::IBluetoothSocket* pStreamSocket; -::osl::Condition mQueuesNotEmpty; +::osl::Condition mProcessingRequired; ::osl::Mutex mMutex; /** ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: sd/source
sd/source/ui/remotecontrol/Transmitter.cxx | 16 +--- sd/source/ui/remotecontrol/Transmitter.hxx | 11 --- 2 files changed, 17 insertions(+), 10 deletions(-) New commits: commit 8e6cdb02450a876b5c684eb621e1c9383fb1c428 Author: Andrzej Hunt AuthorDate: Sun Jul 11 17:17:27 2021 +0200 Commit: Andrzej Hunt CommitDate: Wed Jul 14 21:02:03 2021 +0200 sdremote: fix race condition in Transmitter shutdown to plug leak We need to acquire the mutex in notifyFinished() to avoid a race between notifyFinished() and the loop in run(). And we also need to check mFinishRequested) while holding the mutex to avoid the same race condition. While we're here, rename the mutex to make it more obvious that it's not only protecting the queues. The race can happen because the loop in run() blocks until mQueuesNotEmpty is set. It also resets mQueuesNotEmpty at the end of each iteration if the queues are empty. So if someone sets mQueuesNotEmpty in the middle of an iteration, and the loop later resets it, the loop won't continue iterating. But we're actually using mQueuesNotEmpty to indicate either that the queues have data OR that we might want to finish transmission. And the problem is that notifyFinished() sets mFinishRequested, followed by setting mQueuesNotEmpty in an attempt to get the loop to process mFinishRequested (at which point the loop should finish and return). But as described above, we can easily get into a situation where the loop resets mQueuesNotEmpty again (at least if there's no more pending data in the queues). In this scenario, the loop blocks forever (we won't receive any new messages after notifyFinished()), causing a leak of both Transmitter and any resources it's using - e.g. the StreamSocket. The easiest way to fix this is to make it clear that the mutex protects all internal state, followed by using it to protect all internal state. This issue is not a big deal in normal usage - it's a tiny leak, and users won't connect enough clients for accumulated leaks to pose any issues. But it's ugly, and potentially problematic for long-running tests which could run out of filedescriptors because of the socket leak. I will rename mQueuesNotEmpty to something more obvious (possibly mProcessingRequired) in a separate commit. Change-Id: I2e22087054f3f6a02e05c568b1832ccc5a8b47a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118751 Reviewed-by: Andrzej Hunt Tested-by: Jenkins diff --git a/sd/source/ui/remotecontrol/Transmitter.cxx b/sd/source/ui/remotecontrol/Transmitter.cxx index 8f3b7d24c184..76cda8feae55 100644 --- a/sd/source/ui/remotecontrol/Transmitter.cxx +++ b/sd/source/ui/remotecontrol/Transmitter.cxx @@ -17,8 +17,8 @@ using namespace sd; Transmitter::Transmitter( IBluetoothSocket* aSocket ) : pStreamSocket( aSocket ), mQueuesNotEmpty(), -mFinishRequested(), -mQueueMutex(), +mMutex(), +mFinishRequested( false ), mLowPriority(), mHighPriority() { @@ -32,10 +32,11 @@ void SAL_CALL Transmitter::run() { mQueuesNotEmpty.wait(); -if ( mFinishRequested.check() ) -return; +::osl::MutexGuard aGuard( mMutex ); -::osl::MutexGuard aQueueGuard( mQueueMutex ); +if ( mFinishRequested ) { +return; +} if ( !mHighPriority.empty() ) { OString aMessage( mHighPriority.front() ); @@ -60,7 +61,8 @@ void SAL_CALL Transmitter::run() void Transmitter::notifyFinished() { -mFinishRequested.set(); +::osl::MutexGuard aGuard( mMutex ); +mFinishRequested = true; mQueuesNotEmpty.set(); } @@ -70,7 +72,7 @@ Transmitter::~Transmitter() void Transmitter::addMessage( const OString& aMessage, const Priority aPriority ) { -::osl::MutexGuard aQueueGuard( mQueueMutex ); +::osl::MutexGuard aGuard( mMutex ); switch ( aPriority ) { case PRIORITY_LOW: diff --git a/sd/source/ui/remotecontrol/Transmitter.hxx b/sd/source/ui/remotecontrol/Transmitter.hxx index 8acebfeff7e8..1cd94ea26712 100644 --- a/sd/source/ui/remotecontrol/Transmitter.hxx +++ b/sd/source/ui/remotecontrol/Transmitter.hxx @@ -37,11 +37,16 @@ private: ::sd::IBluetoothSocket* pStreamSocket; ::osl::Condition mQueuesNotEmpty; -::osl::Condition mFinishRequested; - -::osl::Mutex mQueueMutex; +::osl::Mutex mMutex; +/** + * Used to indicate that we're done and the transmitter loop should exit. + * All access must be guarded my `mMutex`. + */ +bool mFinishRequested; +/// Queue for low priority messages. All access must be guarded my `mMutex`. std::queue mLowPriority; +/// Queue for high priority messages. All access must be guarded my `mMutex`. std::queue mHighPriority; };
[Libreoffice-commits] core.git: configure.ac
configure.ac |2 +- 1 file changed, 1 insertion(+), 1 deletion(-) New commits: commit e1d3c8438ade045aab4452dd59000d27f810ca91 Author: Andrzej Hunt AuthorDate: Sun Jul 4 14:54:43 2021 +0200 Commit: Caolán McNamara CommitDate: Sun Jul 4 20:35:03 2021 +0200 Fix LIB_FUZZING_ENGINE not-empty check Switch to '-z $LIB_FUZZING_ENGINE' to check if LIB_FUZZING_ENGINE is set. The previous version evaluates to false when LIB_FUZZING_ENGINE is not set, meaning you would not be warned at configure time when using -enable_fuzzers without setting LIB_FUZZING_ENGINE. Original broken version landed in: 44b36a0602b04342566362bce3f6bed7d2b096e4 ( https://gerrit.libreoffice.org/c/core/+/111691 ) Change-Id: Ic2174777ebf724e471cd605ba54b245e4e804705 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118372 Tested-by: Jenkins Reviewed-by: Caolán McNamara diff --git a/configure.ac b/configure.ac index 7a9eaf39b24b..b2ca6f8d4edd 100644 --- a/configure.ac +++ b/configure.ac @@ -10637,7 +10637,7 @@ AC_MSG_CHECKING([whether to enable fuzzers]) if test "$enable_fuzzers" != yes; then AC_MSG_RESULT([no]) else -if test $LIB_FUZZING_ENGINE == ""; then +if test -z $LIB_FUZZING_ENGINE; then AC_MSG_ERROR(['LIB_FUZZING_ENGINE' must be set when using --enable-fuzzers. Examples include '-fsanitize=fuzzer'.]) fi AC_MSG_RESULT([yes]) ___ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
[Libreoffice-commits] core.git: config_host.mk.in configure.ac vcl/Executable_602fuzzer.mk vcl/Executable_bmpfuzzer.mk vcl/Executable_cgmfuzzer.mk vcl/Executable_diffuzzer.mk vcl/Executable_docxfuzzer
config_host.mk.in |1 + configure.ac |4 vcl/Executable_602fuzzer.mk |2 +- vcl/Executable_bmpfuzzer.mk |2 +- vcl/Executable_cgmfuzzer.mk |2 +- vcl/Executable_diffuzzer.mk |2 +- vcl/Executable_docxfuzzer.mk |2 +- vcl/Executable_dxffuzzer.mk |2 +- vcl/Executable_epsfuzzer.mk |2 +- vcl/Executable_fodpfuzzer.mk |2 +- vcl/Executable_fodsfuzzer.mk |2 +- vcl/Executable_fodtfuzzer.mk |2 +- vcl/Executable_giffuzzer.mk |2 +- vcl/Executable_htmlfuzzer.mk |2 +- vcl/Executable_hwpfuzzer.mk |2 +- vcl/Executable_jpgfuzzer.mk |2 +- vcl/Executable_lwpfuzzer.mk |2 +- vcl/Executable_metfuzzer.mk |2 +- vcl/Executable_mmlfuzzer.mk |2 +- vcl/Executable_mtpfuzzer.mk |2 +- vcl/Executable_olefuzzer.mk |2 +- vcl/Executable_pcdfuzzer.mk |2 +- vcl/Executable_pctfuzzer.mk |2 +- vcl/Executable_pcxfuzzer.mk |2 +- vcl/Executable_pngfuzzer.mk |2 +- vcl/Executable_ppmfuzzer.mk |2 +- vcl/Executable_pptfuzzer.mk |2 +- vcl/Executable_pptxfuzzer.mk |2 +- vcl/Executable_psdfuzzer.mk |2 +- vcl/Executable_qpwfuzzer.mk |2 +- vcl/Executable_rasfuzzer.mk |2 +- vcl/Executable_rtffuzzer.mk |2 +- vcl/Executable_scrtffuzzer.mk |2 +- vcl/Executable_sftfuzzer.mk |2 +- vcl/Executable_slkfuzzer.mk |2 +- vcl/Executable_svmfuzzer.mk |2 +- vcl/Executable_tgafuzzer.mk |2 +- vcl/Executable_tiffuzzer.mk |2 +- vcl/Executable_wksfuzzer.mk |2 +- vcl/Executable_wmffuzzer.mk |2 +- vcl/Executable_ww2fuzzer.mk |2 +- vcl/Executable_ww6fuzzer.mk |2 +- vcl/Executable_ww8fuzzer.mk |2 +- vcl/Executable_xbmfuzzer.mk |2 +- vcl/Executable_xlsfuzzer.mk |2 +- vcl/Executable_xlsxfuzzer.mk |2 +- vcl/Executable_xpmfuzzer.mk |2 +- 47 files changed, 50 insertions(+), 45 deletions(-) New commits: commit 44b36a0602b04342566362bce3f6bed7d2b096e4 Author: Andrzej Hunt AuthorDate: Sat Feb 27 14:21:56 2021 +0100 Commit: Caolán McNamara CommitDate: Sun Feb 28 19:46:58 2021 +0100 Upgrade fuzzers to LIB_FUZZING_ENGINE And check that LIB_FUZZING_ENGINE is set during configure. Because: 1. It's easier to build locally this way (you don't need to build or hack a libFuzzingEngine.a - instead you can just specify LIB_FUZZING_ENGINE=-fsanitize=fuzzer to produce a valid build). 2. Using -lFuzzingEngine is deprecated [1] for various reasons [2]. The old behaviour can be emulated if desired by setting LIB_FUZZING_ENGINE=-lFuzzingEngine . This patch was tested as follows: - Building LO within oss-fuzz via: python infra/helper.py build_fuzzers --sanitizer address libreoffice python infra/helper.py check_build libreoffice - Building LO fuzzers standalone via: export CC="clang-11" export CXX="clang++-11 -stdlib=libc++" export CFLAGS="-fsanitize=address -fsanitize-address-use-after-scope -fsanitize=fuzzer-no-link -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION" export CXXFLAGS="$CFLAGS -stdlib=libc++" export LDFLAGS="$CFLAGS -Wl,--compress-debug-sections,zlib -lpthread" export LIB_FUZZING_ENGINE=-fsanitize=fuzzer ./autogen.sh --with-distro=LibreOfficeOssFuzz --with-system-libxml make fuzzers (--with-system-libxml only appears to be needed because of issues specific to my build environment/Suse 15.2. I'm invoking clang-11 simply because that's the most modern clang I have installed, plain clang should also work on most sufficiently modern systems). [1] https://github.com/google/oss-fuzz/blob/481280c65048fd12fb2141b9225af511a9ef7ed2/infra/presubmit.py#L46 [2] https://github.com/google/oss-fuzz/issues/2164 Change-Id: Iddb577c30a39620e72372ef6c2d3fda67f8aabdf Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111691 Tested-by: Jenkins Tested-by: Caolán McNamara Reviewed-by: Caolán McNamara diff --git a/config_host.mk.in b/config_host.mk.in index c6c9b7eae351..2f52785b840a 100644 --- a/config_host.mk.in +++ b/config_host.mk.in @@ -353,6 +353,7 @@ export LIBLAYOUT_JAR=@LIBLAYOUT_JAR@ export LIBLOADER_JAR=@LIBLOADER_JAR@ export LIBNUMBERTEXT_CFLAGS=$(gb_SPACE)@LIBNUMBERTEXT_CFLAGS@ export LIBNUMBERTEXT_LIBS=$(gb_SPACE)@LIBNUMBERTEXT_LIBS@ +export LIB_FUZZING_ENGINE=@LIB_FUZZING_ENGINE@ export LIBO_BIN_FOLDER=@LIBO_BIN_FOLDER@ export LIBO_BIN_FOLDER_FOR_BUILD=@LIBO_BIN_FOLDER_FOR_BUILD@ export LIBO_ETC_FOLDER=@LIBO_ETC_FOLDER@ diff --git a/configure.ac b/configure.ac index 9e0085370d2b..90b0cf01633b 100644 --- a/configure.ac +++ b/configure.ac @@ -10396,11 +10396,15 @@ AC_MSG_CHECKING([whether to enable fuzzers]) if test "$enable_fuzzers" != yes; then AC_MSG_RESULT([no]) else +if test $LIB_FUZZING_ENGINE == ""; then +