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 @@ -63,11 +63,30 @@ { int client = ::accept(m_socketDes, NULL, NULL); if (client > 0) { - FDMessageHeader msg; - if (::recvmsg(client, msg.message(), 0) == 2) { - ::memcpy(&m_fileDes, CMSG_DATA(msg.cmsgHeader()), sizeof m_fileDes); + // Receive fd only if socket owner is root + bool acceptConnection = false; +#if defined(__linux__) + ucred cred; + socklen_t len = sizeof(cred); + if (getsockopt(client, SOL_SOCKET, SO_PEERCRED, &cred, &len) == 0 && cred.uid == 0) { + acceptConnection = true; + } +#elif defined(__FreeBSD__) || defined(__APPLE__) + uid_t uid; + gid_t gid; + if (getpeereid(m_socketDes, &uid, &gid) == 0 && uid == 0) { + acceptConnection = true; + } +#else +#error Cannot get socket credentials! +#endif + if (acceptConnection) { + FDMessageHeader msg; + if (::recvmsg(client, msg.message(), 0) == 2) { + ::memcpy(&m_fileDes, CMSG_DATA(msg.cmsgHeader()), sizeof m_fileDes); + } + ::close(client); } - ::close(client); } } 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 @@ -22,6 +22,8 @@ #include #include #include +#include +#include // fix SOCK_NONBLOCK for e.g. macOS #ifndef SOCK_NONBLOCK @@ -54,9 +56,9 @@ sockaddr_un a{ AF_UNIX, {0}}; std::string finalPath = "/tmp/" + path; #ifdef __linux__ - ::strcpy(&a.sun_path[1], finalPath.c_str()); + ::strncpy(&a.sun_path[1], finalPath.c_str(), sizeof(a.sun_path)-2); #else - ::strcpy(a.sun_path, finalPath.c_str()); + ::strncpy(a.sun_path, finalPath.c_str(), sizeof(a.sun_path)-1); ::unlink(finalPath.c_str()); #endif return a;