diff options
author | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-10-14 13:59:55 +0300 |
---|---|---|
committer | Evgeny Grin (Karlson2k) <k2k@narod.ru> | 2022-10-14 15:13:46 +0300 |
commit | cf6f91bd6ef6d1cd6e430e7ccaa898e67739d20d (patch) | |
tree | f0e84e5030dc22eb51bc50b0e8f7ad374a7d81fd | |
parent | 30beb61e117fdfe1f7b1bca602c5c4b1cce33fc5 (diff) | |
download | libmicrohttpd-cf6f91bd6ef6d1cd6e430e7ccaa898e67739d20d.tar.gz libmicrohttpd-cf6f91bd6ef6d1cd6e430e7ccaa898e67739d20d.zip |
Added check for hypothetical too large accepted sockets addresses
Also added warning (instead of rejection) for zero-length addresses.
-rw-r--r-- | src/microhttpd/daemon.c | 85 |
1 files changed, 61 insertions, 24 deletions
diff --git a/src/microhttpd/daemon.c b/src/microhttpd/daemon.c index c5aa3d9d..60aa2471 100644 --- a/src/microhttpd/daemon.c +++ b/src/microhttpd/daemon.c | |||
@@ -3656,6 +3656,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3656 | bool sk_nonbl; | 3656 | bool sk_nonbl; |
3657 | bool sk_spipe_supprs; | 3657 | bool sk_spipe_supprs; |
3658 | bool sk_cloexec; | 3658 | bool sk_cloexec; |
3659 | enum MHD_tristate sk_non_ip; | ||
3659 | 3660 | ||
3660 | #ifdef MHD_USE_THREADS | 3661 | #ifdef MHD_USE_THREADS |
3661 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ | 3662 | mhd_assert ( (0 == (daemon->options & MHD_USE_INTERNAL_POLLING_THREAD)) || \ |
@@ -3675,37 +3676,48 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3675 | addrstorage.ss_len = addrlen; | 3676 | addrstorage.ss_len = addrlen; |
3676 | #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */ | 3677 | #endif /* HAVE_STRUCT_SOCKADDR_STORAGE_SS_LEN */ |
3677 | 3678 | ||
3679 | /* Initialise with default values to avoid compiler warnings */ | ||
3680 | sk_nonbl = false; | ||
3681 | sk_spipe_supprs = false; | ||
3682 | sk_cloexec = false; | ||
3683 | |||
3678 | #ifdef USE_ACCEPT4 | 3684 | #ifdef USE_ACCEPT4 |
3679 | s = accept4 (fd, | 3685 | if (MHD_INVALID_SOCKET != |
3680 | (struct sockaddr *) &addrstorage, | 3686 | (s = accept4 (fd, |
3681 | &addrlen, | 3687 | (struct sockaddr *) &addrstorage, |
3682 | SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO | 3688 | &addrlen, |
3683 | | SOCK_NOSIGPIPE_OR_ZERO); | 3689 | SOCK_CLOEXEC_OR_ZERO | SOCK_NONBLOCK_OR_ZERO |
3684 | sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0); | 3690 | | SOCK_NOSIGPIPE_OR_ZERO))) |
3691 | { | ||
3692 | sk_nonbl = (SOCK_NONBLOCK_OR_ZERO != 0); | ||
3685 | #ifndef MHD_WINSOCK_SOCKETS | 3693 | #ifndef MHD_WINSOCK_SOCKETS |
3686 | sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0); | 3694 | sk_spipe_supprs = (SOCK_NOSIGPIPE_OR_ZERO != 0); |
3687 | #else /* MHD_WINSOCK_SOCKETS */ | 3695 | #else /* MHD_WINSOCK_SOCKETS */ |
3688 | sk_spipe_supprs = true; /* Nothing to suppress on W32 */ | 3696 | sk_spipe_supprs = true; /* Nothing to suppress on W32 */ |
3689 | #endif /* MHD_WINSOCK_SOCKETS */ | 3697 | #endif /* MHD_WINSOCK_SOCKETS */ |
3690 | sk_cloexec = (SOCK_CLOEXEC_OR_ZERO != 0); | 3698 | sk_cloexec = (SOCK_CLOEXEC_OR_ZERO != 0); |
3699 | } | ||
3691 | #else /* ! USE_ACCEPT4 */ | 3700 | #else /* ! USE_ACCEPT4 */ |
3692 | s = accept (fd, | 3701 | if (MHD_INVALID_SOCKET != |
3693 | (struct sockaddr *) &addrstorage, | 3702 | (s = accept (fd, |
3694 | &addrlen); | 3703 | (struct sockaddr *) &addrstorage, |
3704 | &addrlen))) | ||
3705 | { | ||
3695 | #ifdef MHD_ACCEPT_INHERIT_NONBLOCK | 3706 | #ifdef MHD_ACCEPT_INHERIT_NONBLOCK |
3696 | sk_nonbl = daemon->listen_nonblk; | 3707 | sk_nonbl = daemon->listen_nonblk; |
3697 | #else /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ | 3708 | #else /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ |
3698 | sk_nonbl = false; | 3709 | sk_nonbl = false; |
3699 | #endif /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ | 3710 | #endif /* ! MHD_ACCEPT_INHERIT_NONBLOCK */ |
3700 | #ifndef MHD_WINSOCK_SOCKETS | 3711 | #ifndef MHD_WINSOCK_SOCKETS |
3701 | sk_spipe_supprs = false; | 3712 | sk_spipe_supprs = false; |
3702 | #else /* MHD_WINSOCK_SOCKETS */ | 3713 | #else /* MHD_WINSOCK_SOCKETS */ |
3703 | sk_spipe_supprs = true; /* Nothing to suppress on W32 */ | 3714 | sk_spipe_supprs = true; /* Nothing to suppress on W32 */ |
3704 | #endif /* MHD_WINSOCK_SOCKETS */ | 3715 | #endif /* MHD_WINSOCK_SOCKETS */ |
3705 | sk_cloexec = false; | 3716 | sk_cloexec = false; |
3717 | } | ||
3706 | #endif /* ! USE_ACCEPT4 */ | 3718 | #endif /* ! USE_ACCEPT4 */ |
3707 | if ( (MHD_INVALID_SOCKET == s) || | 3719 | |
3708 | (addrlen <= 0) ) | 3720 | if (MHD_INVALID_SOCKET == s) |
3709 | { | 3721 | { |
3710 | const int err = MHD_socket_get_error_ (); | 3722 | const int err = MHD_socket_get_error_ (); |
3711 | 3723 | ||
@@ -3721,10 +3733,6 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3721 | _ ("Error accepting connection: %s\n"), | 3733 | _ ("Error accepting connection: %s\n"), |
3722 | MHD_socket_strerr_ (err)); | 3734 | MHD_socket_strerr_ (err)); |
3723 | #endif | 3735 | #endif |
3724 | if (MHD_INVALID_SOCKET != s) | ||
3725 | { | ||
3726 | MHD_socket_close_chk_ (s); | ||
3727 | } | ||
3728 | if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) | 3736 | if (MHD_SCKT_ERR_IS_LOW_RESOURCES_ (err) ) |
3729 | { | 3737 | { |
3730 | /* system/process out of resources */ | 3738 | /* system/process out of resources */ |
@@ -3762,6 +3770,35 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3762 | return MHD_NO; | 3770 | return MHD_NO; |
3763 | } | 3771 | } |
3764 | 3772 | ||
3773 | sk_non_ip = daemon->listen_is_unix; | ||
3774 | if (0 >= addrlen) | ||
3775 | { | ||
3776 | /* Should not happen as 'sockaddr_storage' must be large enough to | ||
3777 | * store any address supported by the system. */ | ||
3778 | #ifdef HAVE_MESSAGES | ||
3779 | if (_MHD_NO != daemon->listen_is_unix) | ||
3780 | MHD_DLOG (daemon, | ||
3781 | _ ("Accepted socket has zero-length address. " | ||
3782 | "Processing the new socket as a socket with " \ | ||
3783 | "unknown type.\n")); | ||
3784 | #endif | ||
3785 | addrlen = 0; | ||
3786 | sk_non_ip = _MHD_YES; /* IP-type addresses have non-zero length */ | ||
3787 | } | ||
3788 | if (((socklen_t) sizeof (addrstorage)) < addrlen) | ||
3789 | { | ||
3790 | /* Should not happen as 'sockaddr_storage' must be large enough to | ||
3791 | * store any address supported by the system. */ | ||
3792 | #ifdef HAVE_MESSAGES | ||
3793 | MHD_DLOG (daemon, | ||
3794 | _ ("Accepted socket address is larger than expected by " \ | ||
3795 | "system headers. Processing the new socket as a socket with " \ | ||
3796 | "unknown type.\n")); | ||
3797 | #endif | ||
3798 | addrlen = 0; | ||
3799 | sk_non_ip = _MHD_YES; /* IP-type addresses must fit */ | ||
3800 | } | ||
3801 | |||
3765 | if (! sk_nonbl && ! MHD_socket_nonblocking_ (s)) | 3802 | if (! sk_nonbl && ! MHD_socket_nonblocking_ (s)) |
3766 | { | 3803 | { |
3767 | #ifdef HAVE_MESSAGES | 3804 | #ifdef HAVE_MESSAGES |
@@ -3825,7 +3862,7 @@ MHD_accept_connection (struct MHD_Daemon *daemon) | |||
3825 | false, | 3862 | false, |
3826 | sk_nonbl, | 3863 | sk_nonbl, |
3827 | sk_spipe_supprs, | 3864 | sk_spipe_supprs, |
3828 | daemon->listen_is_unix); | 3865 | sk_non_ip); |
3829 | return MHD_YES; | 3866 | return MHD_YES; |
3830 | } | 3867 | } |
3831 | 3868 | ||