1 /* $OpenBSD: slowcgi.c,v 1.58 2021/01/08 22:05:34 millert Exp $ */ 2 /* 3 * Copyright (c) 2013 David Gwynne <dlg@openbsd.org> 4 * Copyright (c) 2013 Florian Obser <florian@openbsd.org> 5 * 6 * Permission to use, copy, modify, and distribute this software for any 7 * purpose with or without fee is hereby granted, provided that the above 8 * copyright notice and this permission notice appear in all copies. 9 * 10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 17 */ 18 19 #include <sys/types.h> 20 #include <sys/ioctl.h> 21 #include <sys/queue.h> 22 #include <sys/socket.h> 23 #include <sys/stat.h> 24 #include <sys/time.h> 25 #include <sys/un.h> 26 #include <sys/wait.h> 27 #include <arpa/inet.h> 28 #include <err.h> 29 #include <fcntl.h> 30 #include <errno.h> 31 #include <event.h> 32 #include <limits.h> 33 #include <pwd.h> 34 #include <signal.h> 35 #include <stdarg.h> 36 #include <stdio.h> 37 #include <stdlib.h> 38 #include <string.h> 39 #include <syslog.h> 40 #include <unistd.h> 41 42 #define TIMEOUT_DEFAULT 120 43 #define SLOWCGI_USER "www" 44 45 #define FCGI_CONTENT_SIZE 65535 46 #define FCGI_PADDING_SIZE 255 47 #define FCGI_RECORD_SIZE \ 48 (sizeof(struct fcgi_record_header) + FCGI_CONTENT_SIZE + FCGI_PADDING_SIZE) 49 50 #define FCGI_ALIGNMENT 8 51 #define FCGI_ALIGN(n) \ 52 (((n) + (FCGI_ALIGNMENT - 1)) & ~(FCGI_ALIGNMENT - 1)) 53 54 #define STDOUT_DONE 1 55 #define STDERR_DONE 2 56 #define SCRIPT_DONE 4 57 58 #define FCGI_BEGIN_REQUEST 1 59 #define FCGI_ABORT_REQUEST 2 60 #define FCGI_END_REQUEST 3 61 #define FCGI_PARAMS 4 62 #define FCGI_STDIN 5 63 #define FCGI_STDOUT 6 64 #define FCGI_STDERR 7 65 #define FCGI_DATA 8 66 #define FCGI_GET_VALUES 9 67 #define FCGI_GET_VALUES_RESULT 10 68 #define FCGI_UNKNOWN_TYPE 11 69 #define FCGI_MAXTYPE (FCGI_UNKNOWN_TYPE) 70 71 #define FCGI_REQUEST_COMPLETE 0 72 #define FCGI_CANT_MPX_CONN 1 73 #define FCGI_OVERLOADED 2 74 #define FCGI_UNKNOWN_ROLE 3 75 76 #define FD_RESERVE 5 77 #define FD_NEEDED 6 78 int cgi_inflight = 0; 79 80 struct listener { 81 struct event ev, pause; 82 }; 83 84 struct env_val { 85 SLIST_ENTRY(env_val) entry; 86 char *val; 87 }; 88 SLIST_HEAD(env_head, env_val); 89 90 struct fcgi_record_header { 91 uint8_t version; 92 uint8_t type; 93 uint16_t id; 94 uint16_t content_len; 95 uint8_t padding_len; 96 uint8_t reserved; 97 }__packed; 98 99 struct fcgi_response { 100 TAILQ_ENTRY(fcgi_response) entry; 101 uint8_t data[FCGI_RECORD_SIZE]; 102 size_t data_pos; 103 size_t data_len; 104 }; 105 TAILQ_HEAD(fcgi_response_head, fcgi_response); 106 107 struct fcgi_stdin { 108 TAILQ_ENTRY(fcgi_stdin) entry; 109 uint8_t data[FCGI_RECORD_SIZE]; 110 size_t data_pos; 111 size_t data_len; 112 }; 113 TAILQ_HEAD(fcgi_stdin_head, fcgi_stdin); 114 115 struct request { 116 struct event ev; 117 struct event resp_ev; 118 struct event tmo; 119 int fd; 120 uint8_t buf[FCGI_RECORD_SIZE]; 121 size_t buf_pos; 122 size_t buf_len; 123 struct fcgi_response_head response_head; 124 struct fcgi_stdin_head stdin_head; 125 uint16_t id; 126 char script_name[PATH_MAX]; 127 struct env_head env; 128 int env_count; 129 pid_t script_pid; 130 int script_status; 131 struct event script_ev; 132 struct event script_err_ev; 133 struct event script_stdin_ev; 134 int stdin_fd_closed; 135 int stdout_fd_closed; 136 int stderr_fd_closed; 137 uint8_t script_flags; 138 uint8_t request_started; 139 int inflight_fds_accounted; 140 }; 141 142 struct requests { 143 SLIST_ENTRY(requests) entry; 144 struct request *request; 145 }; 146 SLIST_HEAD(requests_head, requests); 147 148 struct slowcgi_proc { 149 struct requests_head requests; 150 struct event ev_sigchld; 151 struct event ev_sigpipe; 152 }; 153 154 struct fcgi_begin_request_body { 155 uint16_t role; 156 uint8_t flags; 157 uint8_t reserved[5]; 158 }__packed; 159 160 struct fcgi_end_request_body { 161 uint32_t app_status; 162 uint8_t protocol_status; 163 uint8_t reserved[3]; 164 }__packed; 165 166 __dead void usage(void); 167 int slowcgi_listen(char *, struct passwd *); 168 void slowcgi_paused(int, short, void *); 169 int accept_reserve(int, struct sockaddr *, socklen_t *, int, int *); 170 void slowcgi_accept(int, short, void *); 171 void slowcgi_request(int, short, void *); 172 void slowcgi_response(int, short, void *); 173 void slowcgi_add_response(struct request *, struct fcgi_response *); 174 void slowcgi_timeout(int, short, void *); 175 void slowcgi_sig_handler(int, short, void *); 176 size_t parse_record(uint8_t * , size_t, struct request *); 177 void parse_begin_request(uint8_t *, uint16_t, struct request *, 178 uint16_t); 179 void parse_params(uint8_t *, uint16_t, struct request *, uint16_t); 180 void parse_stdin(uint8_t *, uint16_t, struct request *, uint16_t); 181 void exec_cgi(struct request *); 182 void script_in(int, struct event *, struct request *, uint8_t); 183 void script_std_in(int, short, void *); 184 void script_err_in(int, short, void *); 185 void script_out(int, short, void *); 186 void create_end_record(struct request *); 187 void dump_fcgi_record(const char *, 188 struct fcgi_record_header *); 189 void dump_fcgi_record_header(const char *, 190 struct fcgi_record_header *); 191 void dump_fcgi_begin_request_body(const char *, 192 struct fcgi_begin_request_body *); 193 void dump_fcgi_end_request_body(const char *, 194 struct fcgi_end_request_body *); 195 void cleanup_request(struct request *); 196 197 struct loggers { 198 __dead void (*err)(int, const char *, ...) 199 __attribute__((__format__ (printf, 2, 3))); 200 __dead void (*errx)(int, const char *, ...) 201 __attribute__((__format__ (printf, 2, 3))); 202 void (*warn)(const char *, ...) 203 __attribute__((__format__ (printf, 1, 2))); 204 void (*warnx)(const char *, ...) 205 __attribute__((__format__ (printf, 1, 2))); 206 void (*info)(const char *, ...) 207 __attribute__((__format__ (printf, 1, 2))); 208 void (*debug)(const char *, ...) 209 __attribute__((__format__ (printf, 1, 2))); 210 }; 211 212 const struct loggers conslogger = { 213 err, 214 errx, 215 warn, 216 warnx, 217 warnx, /* info */ 218 warnx /* debug */ 219 }; 220 221 __dead void syslog_err(int, const char *, ...) 222 __attribute__((__format__ (printf, 2, 3))); 223 __dead void syslog_errx(int, const char *, ...) 224 __attribute__((__format__ (printf, 2, 3))); 225 void syslog_warn(const char *, ...) 226 __attribute__((__format__ (printf, 1, 2))); 227 void syslog_warnx(const char *, ...) 228 __attribute__((__format__ (printf, 1, 2))); 229 void syslog_info(const char *, ...) 230 __attribute__((__format__ (printf, 1, 2))); 231 void syslog_debug(const char *, ...) 232 __attribute__((__format__ (printf, 1, 2))); 233 void syslog_vstrerror(int, int, const char *, va_list) 234 __attribute__((__format__ (printf, 3, 0))); 235 236 const struct loggers syslogger = { 237 syslog_err, 238 syslog_errx, 239 syslog_warn, 240 syslog_warnx, 241 syslog_info, 242 syslog_debug 243 }; 244 245 const struct loggers *logger = &conslogger; 246 247 #define lerr(_e, _f...) logger->err((_e), _f) 248 #define lerrx(_e, _f...) logger->errx((_e), _f) 249 #define lwarn(_f...) logger->warn(_f) 250 #define lwarnx(_f...) logger->warnx(_f) 251 #define linfo(_f...) logger->info(_f) 252 #define ldebug(_f...) logger->debug(_f) 253 254 __dead void 255 usage(void) 256 { 257 extern char *__progname; 258 fprintf(stderr, 259 "usage: %s [-d] [-p path] [-s socket] [-U user] [-u user]\n", 260 __progname); 261 exit(1); 262 } 263 264 struct timeval timeout = { TIMEOUT_DEFAULT, 0 }; 265 struct slowcgi_proc slowcgi_proc; 266 int debug = 0; 267 int on = 1; 268 char *fcgi_socket = "/var/www/run/slowcgi.sock"; 269 270 int 271 main(int argc, char *argv[]) 272 { 273 extern char *__progname; 274 struct listener *l = NULL; 275 struct passwd *pw; 276 struct stat sb; 277 int c, fd; 278 const char *chrootpath = NULL; 279 const char *sock_user = SLOWCGI_USER; 280 const char *slowcgi_user = SLOWCGI_USER; 281 282 /* 283 * Ensure we have fds 0-2 open so that we have no fd overlaps 284 * in exec_cgi() later. Just exit on error, we don't have enough 285 * fds open to output an error message anywhere. 286 */ 287 for (c=0; c < 3; c++) { 288 if (fstat(c, &sb) == -1) { 289 if ((fd = open("/dev/null", O_RDWR)) != -1) { 290 if (dup2(fd, c) == -1) 291 exit(1); 292 if (fd > c) 293 close(fd); 294 } else 295 exit(1); 296 } 297 } 298 299 while ((c = getopt(argc, argv, "dp:s:U:u:")) != -1) { 300 switch (c) { 301 case 'd': 302 debug++; 303 break; 304 case 'p': 305 chrootpath = optarg; 306 break; 307 case 's': 308 fcgi_socket = optarg; 309 break; 310 case 'U': 311 sock_user = optarg; 312 break; 313 case 'u': 314 slowcgi_user = optarg; 315 break; 316 default: 317 usage(); 318 /* NOTREACHED */ 319 } 320 } 321 322 if (geteuid() != 0) 323 errx(1, "need root privileges"); 324 325 if (!debug && daemon(0, 0) == -1) 326 err(1, "daemon"); 327 328 if (!debug) { 329 openlog(__progname, LOG_PID|LOG_NDELAY, LOG_DAEMON); 330 logger = &syslogger; 331 } 332 333 ldebug("sock_user: %s", sock_user); 334 pw = getpwnam(sock_user); 335 if (pw == NULL) 336 lerrx(1, "no %s user", sock_user); 337 338 fd = slowcgi_listen(fcgi_socket, pw); 339 340 ldebug("slowcgi_user: %s", slowcgi_user); 341 pw = getpwnam(slowcgi_user); 342 if (pw == NULL) 343 lerrx(1, "no %s user", slowcgi_user); 344 345 if (chrootpath == NULL) 346 chrootpath = pw->pw_dir; 347 348 if (chroot(chrootpath) == -1) 349 lerr(1, "chroot(%s)", chrootpath); 350 351 ldebug("chroot: %s", chrootpath); 352 353 if (chdir("/") == -1) 354 lerr(1, "chdir(/)"); 355 356 if (setgroups(1, &pw->pw_gid) || 357 setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) || 358 setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)) 359 lerr(1, "unable to revoke privs"); 360 361 if (pledge("stdio rpath unix proc exec", NULL) == -1) 362 lerr(1, "pledge"); 363 364 SLIST_INIT(&slowcgi_proc.requests); 365 event_init(); 366 367 l = calloc(1, sizeof(*l)); 368 if (l == NULL) 369 lerr(1, "listener ev alloc"); 370 371 event_set(&l->ev, fd, EV_READ | EV_PERSIST, slowcgi_accept, l); 372 event_add(&l->ev, NULL); 373 evtimer_set(&l->pause, slowcgi_paused, l); 374 375 signal_set(&slowcgi_proc.ev_sigchld, SIGCHLD, slowcgi_sig_handler, 376 &slowcgi_proc); 377 signal_set(&slowcgi_proc.ev_sigpipe, SIGPIPE, slowcgi_sig_handler, 378 &slowcgi_proc); 379 380 signal_add(&slowcgi_proc.ev_sigchld, NULL); 381 signal_add(&slowcgi_proc.ev_sigpipe, NULL); 382 383 event_dispatch(); 384 return (0); 385 } 386 387 int 388 slowcgi_listen(char *path, struct passwd *pw) 389 { 390 struct sockaddr_un sun; 391 mode_t old_umask; 392 int fd; 393 394 if ((fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC, 395 0)) == -1) 396 lerr(1, "slowcgi_listen: socket"); 397 398 bzero(&sun, sizeof(sun)); 399 sun.sun_family = AF_UNIX; 400 if (strlcpy(sun.sun_path, path, sizeof(sun.sun_path)) >= 401 sizeof(sun.sun_path)) 402 lerrx(1, "socket path too long"); 403 404 if (unlink(path) == -1) 405 if (errno != ENOENT) 406 lerr(1, "slowcgi_listen: unlink %s", path); 407 408 old_umask = umask(S_IXUSR|S_IXGRP|S_IWOTH|S_IROTH|S_IXOTH); 409 410 if (bind(fd, (struct sockaddr *)&sun, sizeof(sun)) == -1) 411 lerr(1,"slowcgi_listen: bind: %s", path); 412 413 umask(old_umask); 414 415 if (chown(path, pw->pw_uid, pw->pw_gid) == -1) 416 lerr(1, "slowcgi_listen: chown: %s", path); 417 418 if (listen(fd, 5) == -1) 419 lerr(1, "listen"); 420 421 ldebug("socket: %s", path); 422 return fd; 423 } 424 425 void 426 slowcgi_paused(int fd, short events, void *arg) 427 { 428 struct listener *l = arg; 429 event_add(&l->ev, NULL); 430 } 431 432 int 433 accept_reserve(int sockfd, struct sockaddr *addr, socklen_t *addrlen, 434 int reserve, int *counter) 435 { 436 int ret; 437 if (getdtablecount() + reserve + 438 ((*counter + 1) * FD_NEEDED) >= getdtablesize()) { 439 ldebug("inflight fds exceeded"); 440 errno = EMFILE; 441 return -1; 442 } 443 444 if ((ret = accept4(sockfd, addr, addrlen, SOCK_NONBLOCK | SOCK_CLOEXEC)) 445 > -1) { 446 (*counter)++; 447 ldebug("inflight incremented, now %d", *counter); 448 } 449 return ret; 450 } 451 452 void 453 slowcgi_accept(int fd, short events, void *arg) 454 { 455 struct listener *l; 456 struct sockaddr_storage ss; 457 struct timeval backoff; 458 struct request *c; 459 struct requests *requests; 460 socklen_t len; 461 int s; 462 463 l = arg; 464 backoff.tv_sec = 1; 465 backoff.tv_usec = 0; 466 c = NULL; 467 468 len = sizeof(ss); 469 if ((s = accept_reserve(fd, (struct sockaddr *)&ss, 470 &len, FD_RESERVE, &cgi_inflight)) == -1) { 471 switch (errno) { 472 case EINTR: 473 case EWOULDBLOCK: 474 case ECONNABORTED: 475 return; 476 case EMFILE: 477 case ENFILE: 478 event_del(&l->ev); 479 evtimer_add(&l->pause, &backoff); 480 return; 481 default: 482 lerr(1, "accept"); 483 } 484 } 485 486 c = calloc(1, sizeof(*c)); 487 if (c == NULL) { 488 lwarn("cannot calloc request"); 489 close(s); 490 cgi_inflight--; 491 return; 492 } 493 requests = calloc(1, sizeof(*requests)); 494 if (requests == NULL) { 495 lwarn("cannot calloc requests"); 496 close(s); 497 cgi_inflight--; 498 free(c); 499 return; 500 } 501 c->fd = s; 502 c->buf_pos = 0; 503 c->buf_len = 0; 504 c->request_started = 0; 505 c->stdin_fd_closed = c->stdout_fd_closed = c->stderr_fd_closed = 0; 506 c->inflight_fds_accounted = 0; 507 TAILQ_INIT(&c->response_head); 508 TAILQ_INIT(&c->stdin_head); 509 510 event_set(&c->ev, s, EV_READ | EV_PERSIST, slowcgi_request, c); 511 event_add(&c->ev, NULL); 512 event_set(&c->resp_ev, s, EV_WRITE | EV_PERSIST, slowcgi_response, c); 513 evtimer_set(&c->tmo, slowcgi_timeout, c); 514 evtimer_add(&c->tmo, &timeout); 515 requests->request = c; 516 SLIST_INSERT_HEAD(&slowcgi_proc.requests, requests, entry); 517 } 518 519 void 520 slowcgi_timeout(int fd, short events, void *arg) 521 { 522 cleanup_request((struct request*) arg); 523 } 524 525 void 526 slowcgi_sig_handler(int sig, short event, void *arg) 527 { 528 struct request *c; 529 struct requests *ncs; 530 struct slowcgi_proc *p; 531 pid_t pid; 532 int status; 533 534 p = arg; 535 536 switch (sig) { 537 case SIGCHLD: 538 while ((pid = waitpid(WAIT_ANY, &status, WNOHANG)) > 0) { 539 c = NULL; 540 SLIST_FOREACH(ncs, &p->requests, entry) 541 if (ncs->request->script_pid == pid) { 542 c = ncs->request; 543 break; 544 } 545 if (c == NULL) { 546 lwarnx("caught exit of unknown child %i", pid); 547 continue; 548 } 549 550 if (WIFSIGNALED(status)) 551 c->script_status = WTERMSIG(status); 552 else 553 c->script_status = WEXITSTATUS(status); 554 555 if (c->script_flags == (STDOUT_DONE | STDERR_DONE)) 556 create_end_record(c); 557 c->script_flags |= SCRIPT_DONE; 558 559 ldebug("wait: %s", c->script_name); 560 } 561 if (pid == -1 && errno != ECHILD) 562 lwarn("waitpid"); 563 break; 564 case SIGPIPE: 565 /* ignore */ 566 break; 567 default: 568 lerr(1, "unexpected signal: %d", sig); 569 break; 570 } 571 } 572 573 void 574 slowcgi_add_response(struct request *c, struct fcgi_response *resp) 575 { 576 struct fcgi_record_header *header; 577 size_t padded_len; 578 579 header = (struct fcgi_record_header*)resp->data; 580 581 /* The FastCGI spec suggests to align the output buffer */ 582 padded_len = FCGI_ALIGN(resp->data_len); 583 if (padded_len > resp->data_len) { 584 /* There should always be FCGI_PADDING_SIZE bytes left */ 585 if (padded_len > FCGI_RECORD_SIZE) 586 lerr(1, "response too long"); 587 header->padding_len = padded_len - resp->data_len; 588 resp->data_len = padded_len; 589 } 590 591 TAILQ_INSERT_TAIL(&c->response_head, resp, entry); 592 event_add(&c->resp_ev, NULL); 593 } 594 595 void 596 slowcgi_response(int fd, short events, void *arg) 597 { 598 struct request *c; 599 struct fcgi_record_header *header; 600 struct fcgi_response *resp; 601 ssize_t n; 602 603 c = arg; 604 605 while ((resp = TAILQ_FIRST(&c->response_head))) { 606 header = (struct fcgi_record_header*) resp->data; 607 if (debug > 1) 608 dump_fcgi_record("resp ", header); 609 610 n = write(fd, resp->data + resp->data_pos, resp->data_len); 611 if (n == -1) { 612 if (errno == EAGAIN || errno == EINTR) 613 return; 614 cleanup_request(c); 615 return; 616 } 617 resp->data_pos += n; 618 resp->data_len -= n; 619 if (resp->data_len == 0) { 620 TAILQ_REMOVE(&c->response_head, resp, entry); 621 free(resp); 622 } 623 } 624 625 if (TAILQ_EMPTY(&c->response_head)) { 626 if (c->script_flags == (STDOUT_DONE | STDERR_DONE | 627 SCRIPT_DONE)) 628 cleanup_request(c); 629 else 630 event_del(&c->resp_ev); 631 } 632 } 633 634 void 635 slowcgi_request(int fd, short events, void *arg) 636 { 637 struct request *c; 638 ssize_t n; 639 size_t parsed; 640 641 c = arg; 642 643 n = read(fd, c->buf + c->buf_pos + c->buf_len, 644 FCGI_RECORD_SIZE - c->buf_pos-c->buf_len); 645 646 switch (n) { 647 case -1: 648 switch (errno) { 649 case EINTR: 650 case EAGAIN: 651 return; 652 default: 653 goto fail; 654 } 655 break; 656 657 case 0: 658 ldebug("closed connection"); 659 goto fail; 660 default: 661 break; 662 } 663 664 c->buf_len += n; 665 666 /* 667 * Parse the records as they are received. Per the FastCGI 668 * specification, the server need only receive the FastCGI 669 * parameter records in full; it is free to begin execution 670 * at that point, which is what happens here. 671 */ 672 do { 673 parsed = parse_record(c->buf + c->buf_pos, c->buf_len, c); 674 c->buf_pos += parsed; 675 c->buf_len -= parsed; 676 } while (parsed > 0 && c->buf_len > 0); 677 678 /* Make space for further reads */ 679 if (c->buf_len > 0) { 680 bcopy(c->buf + c->buf_pos, c->buf, c->buf_len); 681 c->buf_pos = 0; 682 } 683 return; 684 fail: 685 cleanup_request(c); 686 } 687 688 void 689 parse_begin_request(uint8_t *buf, uint16_t n, struct request *c, uint16_t id) 690 { 691 /* XXX -- FCGI_CANT_MPX_CONN */ 692 if (c->request_started) { 693 lwarnx("unexpected FCGI_BEGIN_REQUEST, ignoring"); 694 return; 695 } 696 697 if (n != sizeof(struct fcgi_begin_request_body)) { 698 lwarnx("wrong size %d != %lu", n, 699 sizeof(struct fcgi_begin_request_body)); 700 return; 701 } 702 703 c->request_started = 1; 704 705 c->id = id; 706 SLIST_INIT(&c->env); 707 c->env_count = 0; 708 } 709 710 void 711 parse_params(uint8_t *buf, uint16_t n, struct request *c, uint16_t id) 712 { 713 struct env_val *env_entry; 714 uint32_t name_len, val_len; 715 716 if (!c->request_started) { 717 lwarnx("FCGI_PARAMS without FCGI_BEGIN_REQUEST, ignoring"); 718 return; 719 } 720 721 if (c->id != id) { 722 lwarnx("unexpected id, ignoring"); 723 return; 724 } 725 726 /* 727 * If this is the last FastCGI parameter record, 728 * begin execution of the CGI script. 729 */ 730 if (n == 0) { 731 exec_cgi(c); 732 return; 733 } 734 735 while (n > 0) { 736 if (buf[0] >> 7 == 0) { 737 name_len = buf[0]; 738 n--; 739 buf++; 740 } else { 741 if (n > 3) { 742 name_len = ((buf[0] & 0x7f) << 24) + 743 (buf[1] << 16) + (buf[2] << 8) + buf[3]; 744 n -= 4; 745 buf += 4; 746 } else 747 return; 748 } 749 750 if (n > 0) { 751 if (buf[0] >> 7 == 0) { 752 val_len = buf[0]; 753 n--; 754 buf++; 755 } else { 756 if (n > 3) { 757 val_len = ((buf[0] & 0x7f) << 24) + 758 (buf[1] << 16) + (buf[2] << 8) + 759 buf[3]; 760 n -= 4; 761 buf += 4; 762 } else 763 return; 764 } 765 } else 766 return; 767 768 if (n < name_len + val_len) 769 return; 770 771 if ((env_entry = malloc(sizeof(struct env_val))) == NULL) { 772 lwarnx("cannot allocate env_entry"); 773 return; 774 } 775 776 if ((env_entry->val = calloc(sizeof(char), name_len + val_len + 777 2)) == NULL) { 778 lwarnx("cannot allocate env_entry->val"); 779 free(env_entry); 780 return; 781 } 782 783 bcopy(buf, env_entry->val, name_len); 784 buf += name_len; 785 n -= name_len; 786 787 env_entry->val[name_len] = '\0'; 788 if (val_len < PATH_MAX && strcmp(env_entry->val, 789 "SCRIPT_NAME") == 0 && c->script_name[0] == '\0') { 790 bcopy(buf, c->script_name, val_len); 791 c->script_name[val_len] = '\0'; 792 } else if (val_len < PATH_MAX && strcmp(env_entry->val, 793 "SCRIPT_FILENAME") == 0) { 794 bcopy(buf, c->script_name, val_len); 795 c->script_name[val_len] = '\0'; 796 } 797 env_entry->val[name_len] = '='; 798 799 bcopy(buf, (env_entry->val) + name_len + 1, val_len); 800 buf += val_len; 801 n -= val_len; 802 803 SLIST_INSERT_HEAD(&c->env, env_entry, entry); 804 ldebug("env[%d], %s", c->env_count, env_entry->val); 805 c->env_count++; 806 } 807 } 808 809 void 810 parse_stdin(uint8_t *buf, uint16_t n, struct request *c, uint16_t id) 811 { 812 struct fcgi_stdin *node; 813 814 if (c->id != id) { 815 lwarnx("unexpected id, ignoring"); 816 return; 817 } 818 819 if ((node = calloc(1, sizeof(struct fcgi_stdin))) == NULL) { 820 lwarnx("cannot calloc stdin node"); 821 return; 822 } 823 824 bcopy(buf, node->data, n); 825 node->data_pos = 0; 826 node->data_len = n; 827 828 TAILQ_INSERT_TAIL(&c->stdin_head, node, entry); 829 830 if (event_initialized(&c->script_stdin_ev)) 831 event_add(&c->script_stdin_ev, NULL); 832 } 833 834 size_t 835 parse_record(uint8_t *buf, size_t n, struct request *c) 836 { 837 struct fcgi_record_header *h; 838 839 if (n < sizeof(struct fcgi_record_header)) 840 return (0); 841 842 h = (struct fcgi_record_header*) buf; 843 844 if (debug > 1) 845 dump_fcgi_record("", h); 846 847 if (n < sizeof(struct fcgi_record_header) + ntohs(h->content_len) 848 + h->padding_len) 849 return (0); 850 851 if (h->version != 1) 852 lerrx(1, "wrong version"); 853 854 switch (h->type) { 855 case FCGI_BEGIN_REQUEST: 856 parse_begin_request(buf + sizeof(struct fcgi_record_header), 857 ntohs(h->content_len), c, ntohs(h->id)); 858 break; 859 case FCGI_PARAMS: 860 parse_params(buf + sizeof(struct fcgi_record_header), 861 ntohs(h->content_len), c, ntohs(h->id)); 862 break; 863 case FCGI_STDIN: 864 parse_stdin(buf + sizeof(struct fcgi_record_header), 865 ntohs(h->content_len), c, ntohs(h->id)); 866 break; 867 default: 868 lwarnx("unimplemented type %d", h->type); 869 break; 870 } 871 872 return (sizeof(struct fcgi_record_header) + ntohs(h->content_len) 873 + h->padding_len); 874 } 875 876 /* 877 * Fork a new CGI process to handle the request, translating 878 * between FastCGI parameter records and CGI's environment variables, 879 * as well as between the CGI process' stdin/stdout and the 880 * corresponding FastCGI records. 881 */ 882 void 883 exec_cgi(struct request *c) 884 { 885 struct env_val *env_entry; 886 int s_in[2], s_out[2], s_err[2], i; 887 pid_t pid; 888 char *argv[2]; 889 char **env; 890 char *path; 891 892 i = 0; 893 894 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, s_in) == -1) 895 lerr(1, "socketpair"); 896 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, s_out) == -1) 897 lerr(1, "socketpair"); 898 if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, s_err) == -1) 899 lerr(1, "socketpair"); 900 cgi_inflight--; 901 c->inflight_fds_accounted = 1; 902 ldebug("fork: %s", c->script_name); 903 904 switch (pid = fork()) { 905 case -1: 906 c->script_status = errno; 907 908 lwarn("fork"); 909 910 close(s_in[0]); 911 close(s_out[0]); 912 close(s_err[0]); 913 914 close(s_in[1]); 915 close(s_out[1]); 916 close(s_err[1]); 917 918 c->stdin_fd_closed = c->stdout_fd_closed = 919 c->stderr_fd_closed = 1; 920 c->script_flags = (STDOUT_DONE | STDERR_DONE | SCRIPT_DONE); 921 922 create_end_record(c); 923 return; 924 case 0: 925 /* Child process */ 926 if (pledge("stdio rpath exec", NULL) == -1) 927 lerr(1, "pledge"); 928 close(s_in[0]); 929 close(s_out[0]); 930 close(s_err[0]); 931 932 if (dup2(s_in[1], STDIN_FILENO) == -1) 933 _exit(1); 934 if (dup2(s_out[1], STDOUT_FILENO) == -1) 935 _exit(1); 936 if (dup2(s_err[1], STDERR_FILENO) == -1) 937 _exit(1); 938 939 close(s_in[1]); 940 close(s_out[1]); 941 close(s_err[1]); 942 943 path = strrchr(c->script_name, '/'); 944 if (path != NULL) { 945 if (path != c->script_name) { 946 *path = '\0'; 947 if (chdir(c->script_name) == -1) 948 lwarn("cannot chdir to %s", 949 c->script_name); 950 *path = '/'; 951 } else 952 if (chdir("/") == -1) 953 lwarn("cannot chdir to /"); 954 } 955 956 argv[0] = c->script_name; 957 argv[1] = NULL; 958 if ((env = calloc(c->env_count + 1, sizeof(char*))) == NULL) 959 _exit(1); 960 SLIST_FOREACH(env_entry, &c->env, entry) 961 env[i++] = env_entry->val; 962 env[i++] = NULL; 963 execve(c->script_name, argv, env); 964 lwarn("execve %s", c->script_name); 965 _exit(1); 966 967 } 968 969 /* Parent process*/ 970 close(s_in[1]); 971 close(s_out[1]); 972 close(s_err[1]); 973 974 fcntl(s_in[0], F_SETFD, FD_CLOEXEC); 975 fcntl(s_out[0], F_SETFD, FD_CLOEXEC); 976 fcntl(s_err[0], F_SETFD, FD_CLOEXEC); 977 978 if (ioctl(s_in[0], FIONBIO, &on) == -1) 979 lerr(1, "script ioctl(FIONBIO)"); 980 if (ioctl(s_out[0], FIONBIO, &on) == -1) 981 lerr(1, "script ioctl(FIONBIO)"); 982 if (ioctl(s_err[0], FIONBIO, &on) == -1) 983 lerr(1, "script ioctl(FIONBIO)"); 984 985 c->script_pid = pid; 986 event_set(&c->script_stdin_ev, s_in[0], EV_WRITE | EV_PERSIST, 987 script_out, c); 988 event_add(&c->script_stdin_ev, NULL); 989 event_set(&c->script_ev, s_out[0], EV_READ | EV_PERSIST, 990 script_std_in, c); 991 event_add(&c->script_ev, NULL); 992 event_set(&c->script_err_ev, s_err[0], EV_READ | EV_PERSIST, 993 script_err_in, c); 994 event_add(&c->script_err_ev, NULL); 995 } 996 997 void 998 create_end_record(struct request *c) 999 { 1000 struct fcgi_response *resp; 1001 struct fcgi_record_header *header; 1002 struct fcgi_end_request_body *end_request; 1003 1004 if ((resp = calloc(1, sizeof(struct fcgi_response))) == NULL) { 1005 lwarnx("cannot malloc fcgi_response"); 1006 return; 1007 } 1008 header = (struct fcgi_record_header*) resp->data; 1009 header->version = 1; 1010 header->type = FCGI_END_REQUEST; 1011 header->id = htons(c->id); 1012 header->content_len = htons(sizeof(struct 1013 fcgi_end_request_body)); 1014 header->padding_len = 0; 1015 header->reserved = 0; 1016 end_request = (struct fcgi_end_request_body *) (resp->data + 1017 sizeof(struct fcgi_record_header)); 1018 end_request->app_status = htonl(c->script_status); 1019 end_request->protocol_status = FCGI_REQUEST_COMPLETE; 1020 end_request->reserved[0] = 0; 1021 end_request->reserved[1] = 0; 1022 end_request->reserved[2] = 0; 1023 resp->data_pos = 0; 1024 resp->data_len = sizeof(struct fcgi_end_request_body) + 1025 sizeof(struct fcgi_record_header); 1026 slowcgi_add_response(c, resp); 1027 } 1028 1029 void 1030 script_in(int fd, struct event *ev, struct request *c, uint8_t type) 1031 { 1032 struct fcgi_response *resp; 1033 struct fcgi_record_header *header; 1034 ssize_t n; 1035 1036 if ((resp = calloc(1, sizeof(struct fcgi_response))) == NULL) { 1037 lwarnx("cannot malloc fcgi_response"); 1038 return; 1039 } 1040 header = (struct fcgi_record_header*) resp->data; 1041 header->version = 1; 1042 header->type = type; 1043 header->id = htons(c->id); 1044 header->padding_len = 0; 1045 header->reserved = 0; 1046 1047 n = read(fd, resp->data + sizeof(struct fcgi_record_header), 1048 FCGI_CONTENT_SIZE); 1049 1050 if (n == -1) { 1051 switch (errno) { 1052 case EINTR: 1053 case EAGAIN: 1054 free(resp); 1055 return; 1056 default: 1057 n = 0; /* fake empty FCGI_STD{OUT,ERR} response */ 1058 } 1059 } 1060 header->content_len = htons(n); 1061 resp->data_pos = 0; 1062 resp->data_len = n + sizeof(struct fcgi_record_header); 1063 slowcgi_add_response(c, resp); 1064 1065 if (n == 0) { 1066 if (type == FCGI_STDOUT) 1067 c->script_flags |= STDOUT_DONE; 1068 else 1069 c->script_flags |= STDERR_DONE; 1070 1071 if (c->script_flags == (STDOUT_DONE | STDERR_DONE | 1072 SCRIPT_DONE)) { 1073 create_end_record(c); 1074 } 1075 event_del(ev); 1076 close(fd); 1077 if (type == FCGI_STDOUT) 1078 c->stdout_fd_closed = 1; 1079 else 1080 c->stderr_fd_closed = 1; 1081 } 1082 } 1083 1084 void 1085 script_std_in(int fd, short events, void *arg) 1086 { 1087 struct request *c = arg; 1088 script_in(fd, &c->script_ev, c, FCGI_STDOUT); 1089 } 1090 1091 void 1092 script_err_in(int fd, short events, void *arg) 1093 { 1094 struct request *c = arg; 1095 script_in(fd, &c->script_err_ev, c, FCGI_STDERR); 1096 } 1097 1098 void 1099 script_out(int fd, short events, void *arg) 1100 { 1101 struct request *c; 1102 struct fcgi_stdin *node; 1103 ssize_t n; 1104 1105 c = arg; 1106 1107 while ((node = TAILQ_FIRST(&c->stdin_head))) { 1108 if (node->data_len == 0) { /* end of stdin marker */ 1109 close(fd); 1110 c->stdin_fd_closed = 1; 1111 break; 1112 } 1113 n = write(fd, node->data + node->data_pos, node->data_len); 1114 if (n == -1) { 1115 if (errno == EAGAIN || errno == EINTR) 1116 return; 1117 event_del(&c->script_stdin_ev); 1118 return; 1119 } 1120 node->data_pos += n; 1121 node->data_len -= n; 1122 if (node->data_len == 0) { 1123 TAILQ_REMOVE(&c->stdin_head, node, entry); 1124 free(node); 1125 } 1126 } 1127 event_del(&c->script_stdin_ev); 1128 } 1129 1130 void 1131 cleanup_request(struct request *c) 1132 { 1133 struct fcgi_response *resp; 1134 struct fcgi_stdin *stdin_node; 1135 struct env_val *env_entry; 1136 struct requests *ncs, *tcs; 1137 1138 evtimer_del(&c->tmo); 1139 if (event_initialized(&c->ev)) 1140 event_del(&c->ev); 1141 if (event_initialized(&c->resp_ev)) 1142 event_del(&c->resp_ev); 1143 if (event_initialized(&c->script_ev)) { 1144 if (!c->stdout_fd_closed) 1145 close(EVENT_FD(&c->script_ev)); 1146 event_del(&c->script_ev); 1147 } 1148 if (event_initialized(&c->script_err_ev)) { 1149 if (!c->stderr_fd_closed) 1150 close(EVENT_FD(&c->script_err_ev)); 1151 event_del(&c->script_err_ev); 1152 } 1153 if (event_initialized(&c->script_stdin_ev)) { 1154 if (!c->stdin_fd_closed) 1155 close(EVENT_FD(&c->script_stdin_ev)); 1156 event_del(&c->script_stdin_ev); 1157 } 1158 close(c->fd); 1159 while (!SLIST_EMPTY(&c->env)) { 1160 env_entry = SLIST_FIRST(&c->env); 1161 SLIST_REMOVE_HEAD(&c->env, entry); 1162 free(env_entry->val); 1163 free(env_entry); 1164 } 1165 1166 while ((resp = TAILQ_FIRST(&c->response_head))) { 1167 TAILQ_REMOVE(&c->response_head, resp, entry); 1168 free(resp); 1169 } 1170 while ((stdin_node = TAILQ_FIRST(&c->stdin_head))) { 1171 TAILQ_REMOVE(&c->stdin_head, stdin_node, entry); 1172 free(stdin_node); 1173 } 1174 SLIST_FOREACH_SAFE(ncs, &slowcgi_proc.requests, entry, tcs) { 1175 if (ncs->request == c) { 1176 SLIST_REMOVE(&slowcgi_proc.requests, ncs, requests, 1177 entry); 1178 free(ncs); 1179 break; 1180 } 1181 } 1182 if (! c->inflight_fds_accounted) 1183 cgi_inflight--; 1184 free(c); 1185 } 1186 1187 void 1188 dump_fcgi_record(const char *p, struct fcgi_record_header *h) 1189 { 1190 dump_fcgi_record_header(p, h); 1191 1192 if (h->type == FCGI_BEGIN_REQUEST) 1193 dump_fcgi_begin_request_body(p, 1194 (struct fcgi_begin_request_body *)(h + 1)); 1195 else if (h->type == FCGI_END_REQUEST) 1196 dump_fcgi_end_request_body(p, 1197 (struct fcgi_end_request_body *)(h + 1)); 1198 } 1199 1200 void 1201 dump_fcgi_record_header(const char* p, struct fcgi_record_header *h) 1202 { 1203 ldebug("%sversion: %d", p, h->version); 1204 ldebug("%stype: %d", p, h->type); 1205 ldebug("%srequestId: %d", p, ntohs(h->id)); 1206 ldebug("%scontentLength: %d", p, ntohs(h->content_len)); 1207 ldebug("%spaddingLength: %d", p, h->padding_len); 1208 ldebug("%sreserved: %d", p, h->reserved); 1209 } 1210 1211 void 1212 dump_fcgi_begin_request_body(const char *p, struct fcgi_begin_request_body *b) 1213 { 1214 ldebug("%srole %d", p, ntohs(b->role)); 1215 ldebug("%sflags %d", p, b->flags); 1216 } 1217 1218 void 1219 dump_fcgi_end_request_body(const char *p, struct fcgi_end_request_body *b) 1220 { 1221 ldebug("%sappStatus: %d", p, ntohl(b->app_status)); 1222 ldebug("%sprotocolStatus: %d", p, b->protocol_status); 1223 } 1224 1225 void 1226 syslog_vstrerror(int e, int priority, const char *fmt, va_list ap) 1227 { 1228 char *s; 1229 1230 if (vasprintf(&s, fmt, ap) == -1) { 1231 syslog(LOG_EMERG, "unable to alloc in syslog_vstrerror"); 1232 exit(1); 1233 } 1234 syslog(priority, "%s: %s", s, strerror(e)); 1235 free(s); 1236 } 1237 1238 __dead void 1239 syslog_err(int ecode, const char *fmt, ...) 1240 { 1241 va_list ap; 1242 1243 va_start(ap, fmt); 1244 syslog_vstrerror(errno, LOG_CRIT, fmt, ap); 1245 va_end(ap); 1246 exit(ecode); 1247 } 1248 1249 __dead void 1250 syslog_errx(int ecode, const char *fmt, ...) 1251 { 1252 va_list ap; 1253 1254 va_start(ap, fmt); 1255 vsyslog(LOG_CRIT, fmt, ap); 1256 va_end(ap); 1257 exit(ecode); 1258 } 1259 1260 void 1261 syslog_warn(const char *fmt, ...) 1262 { 1263 va_list ap; 1264 1265 va_start(ap, fmt); 1266 syslog_vstrerror(errno, LOG_ERR, fmt, ap); 1267 va_end(ap); 1268 } 1269 1270 void 1271 syslog_warnx(const char *fmt, ...) 1272 { 1273 va_list ap; 1274 1275 va_start(ap, fmt); 1276 vsyslog(LOG_ERR, fmt, ap); 1277 va_end(ap); 1278 } 1279 1280 void 1281 syslog_info(const char *fmt, ...) 1282 { 1283 va_list ap; 1284 1285 va_start(ap, fmt); 1286 vsyslog(LOG_INFO, fmt, ap); 1287 va_end(ap); 1288 } 1289 1290 void 1291 syslog_debug(const char *fmt, ...) 1292 { 1293 va_list ap; 1294 1295 va_start(ap, fmt); 1296 vsyslog(LOG_DEBUG, fmt, ap); 1297 va_end(ap); 1298 } 1299