From: JINMEI Tatuya Date: Tue, 14 May 2013 22:14:49 +0000 (-0700) Subject: [2916] catch invalid FD X-Git-Tag: bind10-1.2.0beta1-release~453^2~8 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=e43764fda36554cd8c8f7a8f6aaec51ddc48014a;p=thirdparty%2Fkea.git [2916] catch invalid FD --- diff --git a/src/lib/asiolink/local_socket.cc b/src/lib/asiolink/local_socket.cc index fc605da2bf..05de56d500 100644 --- a/src/lib/asiolink/local_socket.cc +++ b/src/lib/asiolink/local_socket.cc @@ -14,6 +14,7 @@ #include #include +#include #include @@ -24,13 +25,21 @@ namespace isc { namespace asiolink { - class LocalSocket::Impl { public: Impl(IOService& io_service, int fd) : - asio_sock_(io_service.get_io_service()) + asio_sock_(io_service.get_io_service(), + asio::local::stream_protocol(), fd) { - asio_sock_.assign(asio::local::stream_protocol(), fd, ec_); + // Depending on the underlying demultiplex API, the constructor may or + // may not throw in case fd is invalid. To catch such cases sooner, + // we try to get the local endpoint (we don't need it in the rest of + // this implementation). + asio_sock_.local_endpoint(ec_); + if (ec_) { + isc_throw(IOError, "failed to open local socket with FD " << fd + << " (local endpoint unknown): " << ec_.message()); + } } void readCompleted(const asio::error_code& ec, ReadCallback user_callback); @@ -51,8 +60,16 @@ LocalSocket::Impl::readCompleted(const asio::error_code& ec, } LocalSocket::LocalSocket(IOService& io_service, int fd) : - impl_(new Impl(io_service, fd)) -{} + impl_(NULL) +{ + try { + impl_ = new Impl(io_service, fd); + } catch (const asio::error_code& error) { + // Catch and convert any exception from asio's constructor + isc_throw(IOError, "failed to open local socket with FD " << fd + << ": " << error.message()); + } +} LocalSocket::~LocalSocket() { delete impl_; diff --git a/src/lib/asiolink/tests/local_socket_unittest.cc b/src/lib/asiolink/tests/local_socket_unittest.cc index e1c72ee337..2b90877730 100644 --- a/src/lib/asiolink/tests/local_socket_unittest.cc +++ b/src/lib/asiolink/tests/local_socket_unittest.cc @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include @@ -103,6 +104,14 @@ TEST_F(LocalSocketTest, construct) { EXPECT_EQ(AF_UNIX, sock.getProtocol()); } +TEST_F(LocalSocketTest, constructError) { + // try to construct a LocalSocket object with a closed socket. It should + // fail. + const int fd = sock_pair_[0].release(); + EXPECT_EQ(0, close(fd)); + EXPECT_THROW(LocalSocket(io_service_, fd), IOError); +} + TEST_F(LocalSocketTest, autoClose) { // Confirm that passed FD will be closed on destruction of LocalSocket const int fd = sock_pair_[0].release();