Mailing-List: contact cygwin-help AT sourceware DOT cygnus DOT com; run by ezmlm List-Subscribe: List-Archive: List-Post: List-Help: , Sender: cygwin-owner AT sources DOT redhat DOT com Delivered-To: mailing list cygwin AT sources DOT redhat DOT com Message-ID: <008601c0d1a0$4ddbd900$0101a8c0@luckynet.adm> From: "Thunder from the hill" To: "Cygwin Mailing List" Subject: cygwin programs again: realloc() segfaults with library v1.3.1 Date: Mon, 30 Apr 2001 11:05:20 -0700 Organization: LuckyNet Administration MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_NextPart_000_0075_01C0D165.726C34D0" X-Priority: 3 X-MSMail-Priority: Normal X-Mailer: Microsoft Outlook Express 5.50.4522.1200 X-MimeOLE: Produced By Microsoft MimeOLE V5.50.4522.1200 ------=_NextPart_000_0075_01C0D165.726C34D0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit I hate this mailer! I think I should better use another one. Again, this is the failing source code. Whenever realloc() is used in sendfile(), the MicroHTTPD segfaults. Thunder System: AMD K6-II 400 Windows NT 4.0 with latest cygwin --> uhttpd problem Self-compiled Linux with self-compiled programs --> uhttpd seems to work when running as root, else chroot() fails with ENOPERM. (sure, since only root may chroot().) VIIB graphic card SB Live! ------=_NextPart_000_0075_01C0D165.726C34D0 Content-Type: application/octet-stream; name="uhttpd-segfault.c" Content-Transfer-Encoding: quoted-printable Content-Disposition: attachment; filename="uhttpd-segfault.c" /* * MicroHTTPD - A minimalistic HTTP daemon. * * Written 2001 by Thunder from the hill */ /* * Include files */ #include #include #include #include #include #include #include #include #include #include /* * Functions */ int sendfile(int Socket, char *filename); /* Send file */ int http_request(int Socket, char *req); /* Respond to HTTP request */ void clear(char *set, size_t len); /* Emtpy array of size len */ /* * Variables */ int MySock; /* Socket */ int NewSock; /* Socket for accept. */ int peer_size =3D 0; /* Name stack size for the peer */ struct sockaddr_in addr; /* Our address */ struct sockaddr_in peer; /* The peer's address */ struct hostent *hostentry; /* Hostentry - for anything we need */ char *request; /* Our HTTP request */ char *BufIn, *BufOut; /* Input/Output-Buffer */ int BufInLen =3D 2048, BufOutLen =3D 2048; struct arx { short port; char *basedir; } args; void clear(char *set, size_t len) { char *sptr; realloc(set, len + 1); sptr =3D set; for (sptr =3D set; sptr < set + len; sptr++) { *sptr =3D '\0'; } return; } int http_request(int Socket, char *req) { char *req_substr; req_substr =3D strtok(req, " "); printf("HTTP Request: %s", req_substr); if (strlen(req_substr) > 0 && strcmp(req_substr, "GET") =3D=3D 0) { req_substr =3D strtok(NULL, " "); printf(" %s\n", req_substr); if (strstr(req_substr, "/internal/") !=3D NULL) { if (strcmp(req_substr, "/internal/uhttpd-logo") =3D=3D 0) { char uhttpd_logo[] =3D {71, 73, 70, 56, 57, 97, 100, 0, 25, 0, -9, 0, = 0, 0, 0, -128, 124, 124, -67, -102, -102, -51, -31, -31, -16, -23, -23, -12, -16, -16, -9, -8, -8, -5, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, 0, 0, 0, 100, 0, 25, 0, 71, 8, -4, 0, 1, 8, 28, 72, -80, -96, -63, -125, 8, 19, 42, 92, -56, -80, -95, -61, -127, 5, 34, 70, 76, 56, 96, 34, -128, -118, 22, 21, 22, 104, -72, -15, 96, 71, -126, 31, 25, -122, 124, 88, 48, 35, -56, -111, 26, 81, -110, 116, -88, 114, -91, -53, -105, 48, 99, -54, 76, 104, 114, 102, -53, -103, 56, 89, 74, -108, 88, 50, 100, 77, -113, 39, 81, 126, -12, 105, -112, -88, -64, -114, 67, 115, -98, 124, -8, 83, -87, 83, -105, 60, 87, -18, 124, 74, -107, 41, -43, -90, 85, -77, 70, 45, -22, -13, 38, -60, -98, 38, 45, 26, 5, 73, -10, -88, -39, -77, 76, -57, 114, -35, -71, -43, -93, -41, -81, 104, -113, -114, 20, -37, 118, 106, -50, -102, 88, -117, 102, -35, -5, -78, 109, 79, -66, -128, 117, -78, 29, 60, 56, -80, 97, -82, 56, -13, 30, -66, 123, 117, -79, 86, -118, 22, 49, -66, 5, 48, -103, 50, 66, -95, 86, 97, 42, 14, -5, -106, -16, 101, -54, 93, 51, -38, -75, 43, 87, 113, 80, -62, 126, 65, 47, 93, -117, -70, -80, -27, -72, -104, -31, -66, 78, 42, -107, -76, -37, 0, 0, 4, 96, 92, -24, 26, 40, 108, -67, -78, -111, -54, -42, -36, -110, 109, -128, -120, 3, 104, 86, -106, -71, -100, -71, -48, -26, -51, 29, 59, -1, 88, 81, 100, 116, -23, 119, 77, -85, -58, -50, 29, 98, -21, -21, 4, -35, 11, 6, 4, 0, 33, -2, -45, 84, 104, 105, 115, 32, 102, 105, 108, 101, 32, 119, 97, 115, 32, 99, 114, 101, 97, 116, 101, 100, 32, 98, 121, 13, 13, 71, 114, 97, 112, 104, 105, 99, 32, 87, 111, 114, 107, 115, 104, 111, 112, -103, 32, 80, 114, 111, 102, 101, 115, 115, 105, 111, 110, 97, 108, 32, 50, 46, 48, 97, 13, 13, 102, 114, 111, 109, 32, 65, 108, 99, 104, 101, 109, 121, 32, 77, 105, 110, 100, 119, 111, 114, 107, 115, 32, 73, 110, 99, 46, 13, 104, 116, 116, 112, 58, 47, 47, 119, 119, 119, 46, 109, 105, 110, 100, 119, 111, 114, 107, 115, 104, 111, 112, 46, 99, 111, 109, 13, 13, 84, 104, 105, 115, 32, 105, 109, 97, 103, 101, 32, 109, 97, 121, 32, 104, 97, 118, 101, 32, 98, 101, 101, 110, 32, 99, 114, 101, 97, 116, 101, 100, 32, 98, 121, 13, 97, 32, 112, 97, 114, 116, 121, 32, 111, 116, 104, 101, 114, 32, 116, 104, 97, 110, 32, 65, 108, 99, 104, 101, 109, 121, 32, 77, 105, 110, 100, 119, 111, 114, 107, 115, 32, 73, 110, 99, 46, 13, 13, 85, 115, 101, 32, 110, 111, 32, 104, 111, 111, 107, 115, 0, 59, -1, '\0'}; clear(BufOut, BufOutLen); if (BufOutLen < 1536 || BufOutLen > 2560) { realloc(BufOut, 1536); BufOutLen =3D 1536; } strcpy(BufOut, uhttpd_logo); } else if (strcmp(req_substr, "/internal/uhttpd-version") =3D=3D = 0) { clear(BufOut, BufOutLen); if (BufOutLen < 2304 || BufOutLen > 2560) { realloc(BufOut, 2304); BufOutLen =3D 2304; } strcpy(BufOut, "\n\n \n The MicroHTTPD\n = \n \n \n = \n
3D\"uhttpdWant something tiny at home instead of huge HTTP = servers? We have it: MicroHTTPD
\n

MicroHTTPD

\n

The = MicroHTTPD (or evern more short, uhttpd) is a very small OpenSource HTTP = daemon. CGIs are not yet supported, but may come later. If you like it, = please tell the = author!\n

License

\n

MicroHTTPD v1.0 - a minimalistic HTTP daemon.
\n = Copyright (c) 2001, Thunder from the hill.

\n This server is = free software; you can redistribute and/or modify it under the terms of = the GNU General Public License as published by the Free Software = Foundation; either version 2 of the License or (at your option) any = later version.

\n This server is distributed in hope that it = will be useful, but WITHOUT ANY WARRANTY; without even the = implied warranty of MERCHANTABILITY or FITNESS FOR A = PARTICULAR PURPOSE. See the GNU General Public License for more = details.

\n For the license, visit the GNU website!


\n = Thunder from the hill hereby disclaims any copyright interest in the = server »MicroHTTPD« (a minimalistic web server), written by = Thunder from the hill.
thunder, April 28, 2001
Thunder from the = hill, OpenSource Author\n

Visit this = site for updates and news!

\n \n\n"); } else if (strcmp(req_substr, "/internal/getuhttpdversion") =3D=3D = 0) { clear(BufOut, BufOutLen); if (BufOutLen < 16 || BufOutLen > 128) { realloc(BufOut, 16); BufOutLen =3D 16; } strcpy(BufOut, "1.0\n"); } else { clear(BufOut, BufOutLen); if (BufOutLen < 16 || BufOutLen > 128) { realloc(BufOut, 16); BufOutLen =3D 16; } strcpy(BufOut, "HTTP/1.0 404\n"); printf("Answered 404\n"); } if (send(Socket, BufOut, BufOutLen, 0) < strlen(BufOut)) { printf("Error while sending %i bytes in line %i!\n", strlen(BufOut), = __LINE__ - 1); return -1; } } else { /* req_substr =3D strtok(NULL, " "); */ if (sendfile(Socket, req_substr) < 0) { printf("Error while sending %s in line %i!\n", req_substr, __LINE__ - = 1); return -1; } } } else { printf("Invalid request method %s.\n", req_substr); strcpy(BufOut, "\n\n \n Invalid request = method\n \n \n

Invalid request method

\n =

The desired request method was not supported by = the server.

\n \n\n"); if (send(Socket, BufOut, 1024, 0) < 0) { printf("Error while sending 318 bytes in line %i.\n", __LINE__ - = 1); return -1; } } return 0; } int sendfile(int Socket, char *filename) { int fd; /* File descriptor */ char *NoQuestPtr; /* Question marks removed */ char *fn_afterall =3D malloc(strlen(filename)); /* What will be left from filename */ char *sbuf =3D malloc(1024); int i =3D 0; struct stat _thisfile; /* Stat structure */ struct stat *thisfile =3D &_thisfile; /* Stat structure pointer */ NoQuestPtr =3D strtok(filename, "?"); if (stat(NoQuestPtr, thisfile) < 0) { if (send(Socket, "HTTP/1.0 404\n", 14, 0) < 0) { return -1; } return 0; } strcpy(fn_afterall, NoQuestPtr); if (S_ISDIR(thisfile->st_mode) !=3D 0) { char *fn_last =3D NoQuestPtr + strlen(NoQuestPtr) - 1; printf("%s considered to be a directory (%i)\n", NoQuestPtr, = S_ISDIR(thisfile->st_mode)); printf("STUB: realloc() segfaults in sendfile(Socket, \"%s\");\n", = NoQuestPtr); realloc(fn_afterall, strlen(filename) + 20); printf("fn_afterall has address %p and contains string %s.\n", = fn_afterall, fn_afterall); if (*fn_last !=3D '/') strcat(fn_afterall, "/"); strcat(fn_afterall, "index.html"); } if ((fd =3D open(fn_afterall, O_RDONLY)) < 0) { printf("Access to %s seems denied, or such.\n", fn_afterall); if (send(Socket, "\n\n \n Access to file = denied.\n \n \n

File access error

\n

File access seems denied: chdir() worked, stat() = returned OK, but file access seems denied.

\n \n\n", = 347, 0) < 0) { return -1; } return 0; } printf("sbuf has address %p and contains %s. Clearing.\n", sbuf, = sbuf); clear(sbuf, 1024); printf("Survived clearing.\n"); while (read(fd, sbuf, 1024) > 0) { if (send(Socket, sbuf, strlen(sbuf), 0) < 0) { return -1; } } if (close(fd) < 0) { printf("Error while closing file descriptor!\n"); } if (chdir("/") < 0) { printf("Error when changing back to base dir (/).\n"); } return 0; } void usage(void) { printf("%s [-d directory] port\n\t-d directory\n\t\tThe web directory = (target for chroot).\n\tport\n\t\tThe port to bind the server to.\n", = __FILE__); return; } int main (int argc, char **argv) { int argp =3D 1; BufOut =3D malloc(2048); BufIn =3D malloc(2048); args.basedir =3D malloc(24); strcpy(args.basedir, "/usr/local/httpd"); if (argc < 2 || argc > 4) { usage(); exit (1); } while (argp < argc) { if (strcmp(argv[argp], "-d") =3D=3D 0) { if (argv[argp + 1] !=3D NULL) { clear(args.basedir, strlen(args.basedir)); realloc(args.basedir, strlen(argv[argp + 1]) + 1); strcpy(args.basedir, argv[argp + 1]); argp++; argp++; } else { printf("Parameter -d requires a directory to be set.\n"); usage(); exit(1); } } else { args.port =3D (short) atol(argv[argp]); argp++; } } printf("\033[2J\t\t\t --- MicroHTTPD ---\n"); printf("Creating socket: AF_INET, SOCK_STREAM, IPPROTO_TCP.\n"); MySock =3D socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (MySock =3D=3D (~0)) { printf("%s: Error creating server socket.\nErrno was: %i\n", = __FILE__, errno); exit(1); } printf("Setting up server socket: "); addr.sin_family =3D AF_INET; printf("AF_INET"); addr.sin_port =3D htons(args.port); printf(", Port=3D%i", args.port); addr.sin_addr.s_addr =3D htonl(INADDR_ANY); printf(", any IP.\n"); if (bind(MySock, (struct sockaddr *)&addr, sizeof(addr)) < 0) { printf("%s: Error when using bind.\n", __FILE__); if (errno =3D=3D EADDRNOTAVAIL) { printf("Address not available.\n"); } else if (errno =3D=3D EADDRINUSE) { printf("Some other socket is already using the address.\n"); } else if (errno =3D=3D EINVAL) { printf("The socket already has an address.\n"); } else if (errno =3D=3D EACCES) { printf("Access to socket denied. (Maybe choose a port > = 1024?)\n"); } else if (errno =3D=3D EBADF) { printf("Bad file descriptor. (???)\n"); } else { printf("Unknown error (errno =3D %i)\n", errno); } exit(1); } printf("\n\t =3D=3D=3D Server socket started up and bound to port %i = =3D=3D=3D\n\n", args.port); printf("Listening for connections.\n"); if (listen(MySock, 10) < 0) { printf("%s: Listening error. Errno is %i.\n", __FILE__, errno); exit(1); } peer_size =3D sizeof(peer); if (chroot(args.basedir) < 0) { printf("chroot() failed!\n"); exit(1); } BufIn =3D malloc(1025); while ((NewSock =3D accept(MySock, (struct sockaddr *)&peer, = &peer_size)) !=3D -1) { char host_addr[16]; clear(BufIn, BufInLen); clear(BufOut, BufOutLen); strcpy(host_addr, inet_ntoa(peer.sin_addr)); hostentry =3D gethostbyname(host_addr); if (hostentry =3D=3D NULL) { printf("Connection from %s, port %i.\n", host_addr, ntohs(peer.sin_port)); } else { printf("Connection from %s (%s), port %i.\n", hostentry->h_name, inet_ntoa(peer.sin_addr), ntohs(peer.sin_port)); } errno =3D 0; if (recv(NewSock, BufIn, 1024, 0) < 0) { printf("%s: recv() failed. ", __FILE__); if (errno =3D=3D EBADF) { printf("Bad file descriptor. (???)\n"); } else if (errno =3D=3D ENOTSOCK) { printf("Not a socket. (???)\n"); } else if (errno =3D=3D EWOULDBLOCK) { printf("Would block nonblocking mode socket.\n"); } else if (errno =3D=3D EINTR) { printf("Interrupted by a signal.\n"); } else if (errno =3D=3D ENOTCONN) { printf("Socket disconnected.\n"); } else { printf("Unknown error (errno =3D %i)\n", errno); } errno =3D 0; } if (BufIn =3D=3D NULL) { printf("Error: HTTP request was NULL!\n"); send(NewSock, "HTTP/1.0 505\n", 1024, 0); } else if (http_request(NewSock, BufIn) < 0) { printf("Socket error %i.\n", errno); errno =3D 0; } printf("Host disconnected.\n"); shutdown(NewSock, 2); close (NewSock); } if (NewSock =3D=3D -1) { printf("Exit from bad accept() run (whatever might have = happened).\n"); } printf("%s: Cleaning up. Closing socket: ", __FILE__); close (MySock); printf("OK.\n"); printf("Server: exit.\n"); exit(0); } ------=_NextPart_000_0075_01C0D165.726C34D0 Content-Type: text/plain; charset=us-ascii -- Want to unsubscribe from this list? Check out: http://cygwin.com/ml/#unsubscribe-simple ------=_NextPart_000_0075_01C0D165.726C34D0--