Parcourir la source

tighten validation more, add portable version of CMSG_LEN

git-svn-id: svn://bind10.isc.org/svn/bind10/trunk@1695 e5f2f494-b856-4b98-b285-d166d9295462
JINMEI Tatuya il y a 15 ans
Parent
commit
811eea07ce
1 fichiers modifiés avec 18 ajouts et 5 suppressions
  1. 18 5
      src/lib/xfr/fd_share.cc

+ 18 - 5
src/lib/xfr/fd_share.cc

@@ -32,7 +32,19 @@ namespace {
 // Note that cmsg_space() could run slow on OSes that do not have
 // CMSG_SPACE.
 inline socklen_t
-cmsg_space(socklen_t len) {
+cmsg_len(const socklen_t len) {
+#ifdef CMSG_LEN
+    return (CMSG_LEN(len));
+#else
+    // Cast NULL so that any pointer arithmetic performed by CMSG_DATA
+    // is correct.
+    const uintptr_t hdrlen = (uintptr_t)CMSG_DATA(((struct cmsghdr*)NULL));
+    return (hdrlen + len);
+#endif
+}
+
+inline socklen_t
+cmsg_space(const socklen_t len) {
 #ifdef CMSG_SPACE
     return (CMSG_SPACE(len));
 #else
@@ -84,8 +96,9 @@ recv_fd(const int sock) {
     }
     const struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
     int fd = -1;
-    if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
-        fd = *(const int *)CMSG_DATA(cmsg);
+    if (cmsg != NULL && cmsg->cmsg_len == cmsg_len(sizeof(int)) &&
+        cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
+        fd = *(const int*)CMSG_DATA(cmsg);
     }
     free(msghdr.msg_control);
     return (fd);
@@ -111,10 +124,10 @@ send_fd(const int sock, const int fd) {
     }
 
     struct cmsghdr* cmsg = CMSG_FIRSTHDR(&msghdr);
-    cmsg->cmsg_len = msghdr.msg_controllen;
+    cmsg->cmsg_len = cmsg_len(sizeof(int));
     cmsg->cmsg_level = SOL_SOCKET;
     cmsg->cmsg_type = SCM_RIGHTS;
-    *(int *)CMSG_DATA(cmsg) = fd;
+    *(int*)CMSG_DATA(cmsg) = fd;
 
     const int ret = sendmsg(sock, &msghdr, 0);
     free(msghdr.msg_control);