diff --git a/src/ioslaves/file/fdreceiver.h b/src/ioslaves/file/fdreceiver.h --- a/src/ioslaves/file/fdreceiver.h +++ b/src/ioslaves/file/fdreceiver.h @@ -40,6 +40,7 @@ Q_SLOT void receiveFileDescriptor(); QSocketNotifier *m_readNotifier; + QString m_path; int m_socketDes; int m_fileDes; }; diff --git a/src/ioslaves/file/fdreceiver.cpp b/src/ioslaves/file/fdreceiver.cpp --- a/src/ioslaves/file/fdreceiver.cpp +++ b/src/ioslaves/file/fdreceiver.cpp @@ -19,23 +19,30 @@ ***/ #include +#include #include "sharefd_p.h" #include "fdreceiver.h" FdReceiver::FdReceiver(const QString &path, QObject *parent) : QObject(parent) , m_readNotifier(nullptr) + , m_path(path) , m_socketDes(-1) , m_fileDes(-1) { + SocketAddress addr(QFile::encodeName(m_path)); + if (!addr.address()) { + std::cerr << "Invalid socket address" << std::endl; + return; + } + m_socketDes = ::socket(AF_LOCAL, SOCK_STREAM|SOCK_NONBLOCK, 0); if (m_socketDes == -1) { std::cerr << "socket error:" << strerror(errno) << std::endl; return; } - const SocketAddress addr(path.toStdString()); if (bind(m_socketDes, addr.address(), addr.length()) != 0 || listen(m_socketDes, 5) != 0) { std::cerr << "bind/listen error:" << strerror(errno) << std::endl; ::close(m_socketDes); diff --git a/src/ioslaves/file/kauth/fdsender.cpp b/src/ioslaves/file/kauth/fdsender.cpp --- a/src/ioslaves/file/kauth/fdsender.cpp +++ b/src/ioslaves/file/kauth/fdsender.cpp @@ -24,13 +24,18 @@ FdSender::FdSender(const std::string &path) : m_socketDes(-1) { + SocketAddress addr(path.c_str()); + if (!addr.address()) { + std::cerr << "Invalid socket address" << std::endl; + return; + } + m_socketDes = ::socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); if (m_socketDes == -1) { std::cerr << "socket error:" << strerror(errno) << std::endl; return; } - SocketAddress addr(path); if (::connect(m_socketDes, addr.address(), addr.length()) != 0) { std::cerr << "connection error:" << strerror(errno) << std::endl; ::close(m_socketDes); diff --git a/src/ioslaves/file/sharefd_p.h b/src/ioslaves/file/sharefd_p.h --- a/src/ioslaves/file/sharefd_p.h +++ b/src/ioslaves/file/sharefd_p.h @@ -29,36 +29,46 @@ #define SOCK_NONBLOCK O_NONBLOCK #endif +#include + class SocketAddress { const sockaddr_un addr; public: - SocketAddress(const std::string &path) + SocketAddress(const QByteArray &path) : addr(make_address(path)) { } int length() const { - return sizeof addr; + return offsetof(struct sockaddr_un, sun_path) + strlen(addr.sun_path) + 1; } const sockaddr *address() const { - return reinterpret_cast(&addr); + return (addr.sun_path[0] || addr.sun_path[1]) ? reinterpret_cast(&addr) : nullptr; } private: - static sockaddr_un make_address(const std::string& path) + static sockaddr_un make_address(const QByteArray &path) { - sockaddr_un a{ AF_UNIX, {0}}; - std::string finalPath = "/tmp/" + path; + sockaddr_un a; + memset(&a, 0, sizeof(a)); + a.sun_family = AF_UNIX; + const QByteArray finalPath = "/tmp/" + path; + const size_t pathSize = finalPath.size(); + if (pathSize > 5) { #ifdef __linux__ - ::strcpy(&a.sun_path[1], finalPath.c_str()); + if (pathSize < sizeof(a.sun_path) - 2) { + memcpy(&a.sun_path[1], finalPath.constData(), pathSize + 1); #else - ::strcpy(a.sun_path, finalPath.c_str()); - ::unlink(finalPath.c_str()); + if (pathSize < sizeof(a.sun_path) - 1) { + memcpy(a.sun_path, finalPath.constData(), pathSize + 1); + ::unlink(finalPath.constData()); #endif + } + } return a; } };