Changeset 118


Ignore:
Timestamp:
Sep 4, 2007, 8:46:32 PM (17 years ago)
Author:
rainer
Message:

Fix for ticket #74 (local DoS attack on yule on BSD systems lacking the getpeereid() call).

Location:
trunk
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/configure.ac

    r106 r118  
    1313dnl start
    1414dnl
    15 AM_INIT_AUTOMAKE(samhain, 2.3.5)
     15AM_INIT_AUTOMAKE(samhain, 2.3.6)
    1616AC_CANONICAL_HOST
    1717
  • trunk/docs/Changelog

    r117 r118  
    112.3.6:
     2        * fix local DoS attack on BSD systems lacking getpeereid() (reported
     3          by Rob Holland).
    24        * fix yulectl password reading from $HOME/.yulectl_cred, erroneously
    35          rejected passwords with exactly 14 chars (reported by Jerry Brown)
  • trunk/src/sh_socket.c

    r50 r118  
    678678                      _("Message from recvmsg() was not SCM_CREDS"),
    679679                      _("sh_socket_read"));
     680
     681      /* Check for file descriptors sent using SCM_RIGHTS, and
     682       * close them. If MSG_CTRUNC is set, the buffer was too small,
     683       * and no fds are duped.
     684       */
     685      if (msg.msg_controllen >= sizeof(struct cmsghdr) &&
     686          (msg.msg_flags & MSG_CTRUNC) == 0)
     687        {
     688          unsigned int     data_size;
     689          unsigned int     data_i;
     690          int              fdcount, fdmax;
     691          struct cmsghdr * cmptr;
     692          int              fdsbuf[1 + (sizeof(cmsgmem)/sizeof(int))];
     693
     694          for (cmptr = CMSG_FIRSTHDR(&msg); cmptr != NULL;
     695               cmptr = CMSG_NXTHDR(&msg, cmptr))
     696            {
     697              if (cmptr->cmsg_len > sizeof (cmsgmem) ||
     698                  cmptr->cmsg_level != SOL_SOCKET ||
     699                  cmptr->cmsg_type  != SCM_RIGHTS)
     700                continue;
     701
     702              /* Crappy way of finding the data length.
     703               * cmptr->cmsg_len includes both header and padding,
     704               * how are you supposed to find the data length?
     705               * cmptr->cmsg_len - ALIGN(sizeof(struct cmsghdr)) ?
     706               */
     707              data_size = 0;
     708
     709              for (data_i = 0; data_i < cmptr->cmsg_len; ++data_i)
     710                {
     711                  if (CMSG_LEN(data_i) == cmptr->cmsg_len)
     712                    {
     713                      data_size = data_i;
     714                      break;
     715                    }
     716                }
     717              memcpy(fdsbuf, CMSG_DATA(cmptr), data_size);
     718              fdmax = data_size / sizeof(int);
     719              for (fdcount = 0; fdcount < fdmax; ++fdcount)
     720                (void) close(fdsbuf[fdcount]);
     721            }
     722        }
     723     
    680724      close(talkfd);
    681725      return -1;
Note: See TracChangeset for help on using the changeset viewer.