diff options
author | Daiki Ueno <ueno@gnu.org> | 2020-10-19 14:43:15 +0000 |
---|---|---|
committer | Daiki Ueno <ueno@gnu.org> | 2020-10-19 14:43:15 +0000 |
commit | e2bc81590564050c872820c6b14687f1d3be279a (patch) | |
tree | e486df99b1d12a5743ad3e06c71477cb378488a0 | |
parent | 90f14691e1a269bf3247537e6da374f472b64d25 (diff) | |
parent | 38ef9af88193c42114548b0ad5776db0ac60e5d4 (diff) | |
download | gnutls-e2bc81590564050c872820c6b14687f1d3be279a.tar.gz |
Merge branch 'tmp-src-fixes' into 'master'
Add extra checks on memory allocation in src/ and examples
Closes #1102
See merge request gnutls/gnutls!1344
-rw-r--r-- | bootstrap.conf | 4 | ||||
-rw-r--r-- | doc/examples/ex-ocsp-client.c | 4 | ||||
-rw-r--r-- | lib/errors.c | 41 | ||||
-rw-r--r-- | lib/errors.h | 42 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/list.h | 446 | ||||
-rw-r--r-- | src/serv.c | 162 | ||||
-rw-r--r-- | src/udp-serv.c | 1 |
8 files changed, 158 insertions, 544 deletions
diff --git a/bootstrap.conf b/bootstrap.conf index f8de3d4be1..8f7da96fd1 100644 --- a/bootstrap.conf +++ b/bootstrap.conf @@ -28,7 +28,7 @@ required_submodules="tests/suite/tls-fuzzer/python-ecdsa tests/suite/tls-fuzzer/ # Reproduce by: gnulib-tool --import --local-dir=gl/override --lib=libgnu --source-base=gl --m4-base=gl/m4 --doc-base=doc --tests-base=gl/tests --aux-dir=build-aux --with-tests --avoid=alignof-tests --avoid=lock-tests --avoid=lseek-tests --lgpl=2 --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files alloca attribute byteswap c-ctype extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash-pjw-bare havelib intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv snprintf stdint strcase strndup strtok_r strverscmp sys_socket sys_stat threadlib time_r unistd vasprintf verify vsnprintf warnings gnulib_modules=" -alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf warnings +alloca attribute byteswap c-ctype c-strcase extensions fopen-gnu func gendocs getline gettext-h gettimeofday hash hash-pjw-bare havelib arpa_inet inet_ntop inet_pton intprops ldd lib-msvc-compat lib-symbol-versions maintainer-makefile manywarnings memmem-simple minmax netdb netinet_in pmccabe2html read-file secure_getenv setsockopt snprintf stdint stpcpy strcase strdup-posix strndup strtok_r strverscmp sys_socket sys_stat sys_types threadlib time_r unistd valgrind-tests vasprintf verify vsnprintf warnings " unistring_modules=" @@ -36,7 +36,7 @@ unictype/category-all unictype/property-default-ignorable-code-point unictype/pr " src_modules=" -accept bind close connect getaddrinfo getpass gettext-h arpa_inet inet_ntop inet_pton listen minmax parse-datetime progname read-file recv recvfrom select send sendto servent setsockopt shutdown socket sockets socklen inttypes +accept bind close connect getaddrinfo getpass gettext-h arpa_inet inet_ntop inet_pton inttypes listen linked-list minmax parse-datetime progname read-file recv recvfrom select send sendto servent setsockopt shutdown socket sockets socklen stpcpy xalloc xlist xsize " # Build prerequisites diff --git a/doc/examples/ex-ocsp-client.c b/doc/examples/ex-ocsp-client.c index f0b56fffe2..d675e77862 100644 --- a/doc/examples/ex-ocsp-client.c +++ b/doc/examples/ex-ocsp-client.c @@ -91,6 +91,10 @@ int main(int argc, char *argv[]) tmp.data); hostname = malloc(tmp.size + 1); + if (!hostname) { + fprintf(stderr, "error: cannot allocate memory\n"); + exit(1); + } memcpy(hostname, tmp.data, tmp.size); hostname[tmp.size] = 0; diff --git a/lib/errors.c b/lib/errors.c index 842afe0e24..4e59d63eb2 100644 --- a/lib/errors.c +++ b/lib/errors.c @@ -22,7 +22,6 @@ #include "gnutls_int.h" #include "errors.h" -#include <libtasn1.h> #ifdef STDC_HEADERS #include <stdarg.h> #endif @@ -590,46 +589,6 @@ const char *gnutls_strerror_name(int error) return ret; } -int _gnutls_asn2err(int asn_err) -{ - switch (asn_err) { -#ifdef ASN1_TIME_ENCODING_ERROR - case ASN1_TIME_ENCODING_ERROR: - return GNUTLS_E_ASN1_TIME_ERROR; -#endif - case ASN1_FILE_NOT_FOUND: - return GNUTLS_E_FILE_ERROR; - case ASN1_ELEMENT_NOT_FOUND: - return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; - case ASN1_IDENTIFIER_NOT_FOUND: - return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND; - case ASN1_DER_ERROR: - return GNUTLS_E_ASN1_DER_ERROR; - case ASN1_VALUE_NOT_FOUND: - return GNUTLS_E_ASN1_VALUE_NOT_FOUND; - case ASN1_GENERIC_ERROR: - return GNUTLS_E_ASN1_GENERIC_ERROR; - case ASN1_VALUE_NOT_VALID: - return GNUTLS_E_ASN1_VALUE_NOT_VALID; - case ASN1_TAG_ERROR: - return GNUTLS_E_ASN1_TAG_ERROR; - case ASN1_TAG_IMPLICIT: - return GNUTLS_E_ASN1_TAG_IMPLICIT; - case ASN1_ERROR_TYPE_ANY: - return GNUTLS_E_ASN1_TYPE_ANY_ERROR; - case ASN1_SYNTAX_ERROR: - return GNUTLS_E_ASN1_SYNTAX_ERROR; - case ASN1_MEM_ERROR: - return GNUTLS_E_SHORT_MEMORY_BUFFER; - case ASN1_MEM_ALLOC_ERROR: - return GNUTLS_E_MEMORY_ERROR; - case ASN1_DER_OVERFLOW: - return GNUTLS_E_ASN1_DER_OVERFLOW; - default: - return GNUTLS_E_ASN1_GENERIC_ERROR; - } -} - void _gnutls_mpi_log(const char *prefix, bigint_t a) { size_t binlen = 0; diff --git a/lib/errors.h b/lib/errors.h index 976a788e7c..30ed744a49 100644 --- a/lib/errors.h +++ b/lib/errors.h @@ -38,7 +38,47 @@ #define gnutls_assert() #endif -int _gnutls_asn2err(int asn_err) __GNUTLS_CONST__; +inline static int _gnutls_asn2err(int asn_err) __GNUTLS_CONST__; + +inline static int _gnutls_asn2err(int asn_err) +{ + switch (asn_err) { +#ifdef ASN1_TIME_ENCODING_ERROR + case ASN1_TIME_ENCODING_ERROR: + return GNUTLS_E_ASN1_TIME_ERROR; +#endif + case ASN1_FILE_NOT_FOUND: + return GNUTLS_E_FILE_ERROR; + case ASN1_ELEMENT_NOT_FOUND: + return GNUTLS_E_ASN1_ELEMENT_NOT_FOUND; + case ASN1_IDENTIFIER_NOT_FOUND: + return GNUTLS_E_ASN1_IDENTIFIER_NOT_FOUND; + case ASN1_DER_ERROR: + return GNUTLS_E_ASN1_DER_ERROR; + case ASN1_VALUE_NOT_FOUND: + return GNUTLS_E_ASN1_VALUE_NOT_FOUND; + case ASN1_GENERIC_ERROR: + return GNUTLS_E_ASN1_GENERIC_ERROR; + case ASN1_VALUE_NOT_VALID: + return GNUTLS_E_ASN1_VALUE_NOT_VALID; + case ASN1_TAG_ERROR: + return GNUTLS_E_ASN1_TAG_ERROR; + case ASN1_TAG_IMPLICIT: + return GNUTLS_E_ASN1_TAG_IMPLICIT; + case ASN1_ERROR_TYPE_ANY: + return GNUTLS_E_ASN1_TYPE_ANY_ERROR; + case ASN1_SYNTAX_ERROR: + return GNUTLS_E_ASN1_SYNTAX_ERROR; + case ASN1_MEM_ERROR: + return GNUTLS_E_SHORT_MEMORY_BUFFER; + case ASN1_MEM_ALLOC_ERROR: + return GNUTLS_E_MEMORY_ERROR; + case ASN1_DER_OVERFLOW: + return GNUTLS_E_ASN1_DER_OVERFLOW; + default: + return GNUTLS_E_ASN1_GENERIC_ERROR; + } +} void _gnutls_log(int, const char *fmt, ...) #ifdef __GNUC__ diff --git a/src/Makefile.am b/src/Makefile.am index 94b701a512..450700a3d0 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -140,7 +140,7 @@ nodist_libcmd_ocsp_la_SOURCES = ocsptool-args.h ocsptool-args.c endif gnutls_serv_SOURCES = \ - list.h serv.c \ + serv.c \ udp-serv.c udp-serv.h \ common.h common.c \ certtool-common.h diff --git a/src/list.h b/src/list.h deleted file mode 100644 index 1b3c9e4635..0000000000 --- a/src/list.h +++ /dev/null @@ -1,446 +0,0 @@ -/* - * Copyright (C) 2001,2002 Paul Sheer - * - * This file is part of GnuTLS. - * - * GnuTLS is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * GnuTLS is distributed in the 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#ifndef GNUTLS_SRC_LIST_H -#define GNUTLS_SRC_LIST_H - -/* - SOAP: - - Academics always want to implement hash tables (i.e. dictionaries), - singly or doubly linked lists, and queues, because ... well ... they - know how. - - These datatypes are nonsense for the following reasons: - hash tables: Hash tables are a mapping of some - string to some data, where that data is going to - be accessed COMPLETELY RANDOMLY. This is what it - is for. However it is extremely rare to have a - large number of data elements which really are - being accessed in a completely random way. - - lists: appending and searching through lists is always - slow because these operations search all the way - through the list. - - queues: what's the difference between a queue and a list? - very little really. - - The system implemented here is a doubly linked list with previous - search index that can be appended or prepended with no overhead, - implemented entirely in macros. It is hence as versatile as a - doubly/singly linked list or queue and blazingly fast. Hence doing - sequential searches where the next search result is likely to be - closely indexed to the previous (usual case), is efficient. - - Of course this doesn't mean you should use this as a hash table - where you REALLY need a hash table. - -*/ - -/********** example usage **********/ -/* - -#include "list.h" - -extern void free (void *x); -extern char *strdup (char *s); - -// consider a list of elements containing an `int' and a `char *' -LIST_TYPE_DECLARE (names, char *s; int i;); - -// for sorting, to compare elements -static int cm (names **a, names **b) -{ - return strcmp ((*a)->s, (*b)->s); -} - -// to free the contents of an element -static void free_item (names *a) -{ - free (a->s); - a->s = 0; // say - a->i = 0; // say -} - -int main (int argc, char **argv) -{ -// you can separate these into LIST_TYPE_DECLARE(), LIST_DECLARE() and linit() if needed. - LIST_DECLARE_INIT (l, names, free_item); - names *j; - - lappend (l); - l.tail->s = strdup ("hello"); - l.tail->i = 1; - lappend (l); - l.tail->s = strdup ("there"); - l.tail->i = 2; - lappend (l); - l.tail->s = strdup ("my"); - l.tail->i = 3; - lappend (l); - l.tail->s = strdup ("name"); - l.tail->i = 4; - lappend (l); - l.tail->s = strdup ("is"); - l.tail->i = 5; - lappend (l); - l.tail->s = strdup ("fred"); - l.tail->i = 6; - - printf ("%ld\n\n", lcount (l)); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - printf ("\n"); - - lsort (l, cm); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - - lloopreverse (l, j, if (j->i <= 3) ldeleteinc (l, j);); - - printf ("\n"); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - - ldeleteall (l); - - printf ("\n"); - lloopforward (l, j, printf ("%d %s\n", j->i, j->s)); - return 0; -} - -*/ - -/* the `search' member points to the last found. - this speeds up repeated searches on the same list-item, - the consecutive list-item, or the pre-consecutive list-item. - this obviates the need for a hash table for 99% of - cercumstances the time */ -struct list { - long length; - long item_size; - struct list_item { - struct list_item *next; - struct list_item *prev; - char data[1]; - } *head, *tail, *search; - void (*free_func) (struct list_item *); -}; - -/* declare a list of type `x', also called `x' having members `typelist' */ - -#define LIST_TYPE_DECLARE(type,typelist) \ - typedef struct type { \ - struct type *next; \ - struct type *prev; \ - typelist \ - } type - -#define LIST_DECLARE(l,type) \ - struct { \ - long length; \ - long item_size; \ - type *head, *tail, *search; \ - void (*free_func) (type *); \ - } l - -#define LIST_DECLARE_INIT(l,type,free) \ - struct { \ - long length; \ - long item_size; \ - type *head, *tail, *search; \ - void (*free_func) (type *); \ - } l = {0, sizeof (type), 0, 0, 0, (void (*) (type *)) free} - -#define linit(l,type,free) \ - { \ - memset (&(l), 0, sizeof (l)); \ - (l).item_size = sizeof (type); \ - (l).free_func = free; \ - } - -/* returns a pointer to the data of an item */ -#define ldata(i) ((void *) &((i)->data[0])) - -/* returns a pointer to the list head */ -#define lhead(l) ((l).head) - -/* returns a pointer to the list tail */ -#define ltail(l) ((l).tail) - -#define lnewsearch(l) \ - (l).search = 0; - -/* adds to the beginning of the list */ -#define lprepend(l) \ - { \ - struct list_item *__t; \ - __t = (struct list_item *) malloc ((l).item_size); \ - memset (__t, 0, (l).item_size); \ - __t->next = (l).head; \ - if (__t->next) \ - __t->next->prev = __t; \ - __t->prev = 0; \ - if (!(l).tail) \ - (l).tail = __t; \ - (l).head = __t; \ - length++; \ - } - -/* adds to the end of the list */ -#define lappend(l) \ - { \ - struct list_item *__t; \ - __t = (struct list_item *) malloc ((l).item_size); \ - memset (__t, 0, (l).item_size); \ - __t->prev = (struct list_item *) (l).tail; \ - if (__t->prev) \ - __t->prev->next = __t; \ - __t->next = 0; \ - if (!(l).head) \ - (l).head = (void *) __t; \ - (l).tail = (void *) __t; \ - (l).length++; \ - } - -/* you should free these manually */ -#define lunlink(l,e) \ - { \ - struct list_item *__t; \ - (l).search = 0; \ - __t = (void *) e; \ - if ((void *) (l).head == (void *) __t) \ - (l).head = (l).head->next; \ - if ((void *) (l).tail == (void *) __t) \ - (l).tail = (l).tail->prev; \ - if (__t->next) \ - __t->next->prev = __t->prev; \ - if (__t->prev) \ - __t->prev->next = __t->next; \ - (l).length--; \ - } - -/* deletes list entry at point e, and increments e to the following list entry */ -#define ldeleteinc(l,e) \ - { \ - struct list_item *__t; \ - (l).search = 0; \ - __t = (void *) e; \ - if ((void *) (l).head == (void *) __t) \ - (l).head = (l).head->next; \ - if ((void *) (l).tail == (void *) __t) \ - (l).tail = (l).tail->prev; \ - if (__t->next) \ - __t->next->prev = __t->prev; \ - if (__t->prev) \ - __t->prev->next = __t->next; \ - __t = __t->next; \ - if ((l).free_func) \ - (*(l).free_func) ((void *) e); \ - free (e); \ - e = (void *) __t; \ - (l).length--; \ - } - -/* deletes list entry at point e, and deccrements e to the preceding list emtry */ -#define ldeletedec(l,e) \ - { \ - struct list_item *__t; \ - (l).search = 0; \ - __t = (void *) e; \ - if ((void *) (l).head == (void *) __t) \ - (l).head = (l).head->next; \ - if ((void *) (l).tail == (void *) __t) \ - (l).tail = (l).tail->prev; \ - if (__t->next) \ - __t->next->prev = __t->prev; \ - if (__t->prev) \ - __t->prev->next = __t->next; \ - __t = __t->prev; \ - if ((l).free_func) \ - (*(l).free_func) ((void *) e); \ - free (e); \ - e = (void *) __t; \ - (l).length--; \ - } - -/* p and q must be consecutive and neither must be zero */ -#define linsert(l,p,q) \ - { \ - struct list_item *__t; \ - __t = (struct list_item *) malloc ((l).item_size); \ - memset (__t, 0, (l).item_size); \ - __t->prev = (void *) p; \ - __t->next = (void *) q; \ - q->prev = (void *) __t; \ - p->next = (void *) __t; \ - (l).length++; \ - } - -/* p and q must be consecutive and neither must be zero */ -#define ldeleteall(l) \ - { \ - (l).search = 0; \ - while ((l).head) { \ - struct list_item *__p; \ - __p = (struct list_item *) (l).head; \ - lunlink(l, __p); \ - if ((l).free_func) \ - (*(l).free_func) ((void *) __p); \ - free (__p); \ - } \ - } - -#define lloopstart(l,i) \ - for (i = (void *) (l).head; i;) { \ - struct list_item *__tl; \ - __tl = (void *) i->next; \ - -#define lloopend(l,i) \ - i = (void *) __tl; \ - } \ - -#define lloopforward(l,i,op) \ - { \ - for (i = (void *) (l).head; i;) { \ - struct list_item *__t; \ - __t = (void *) i->next; \ - op; \ - i = (void *) __t; \ - } \ - } - -#define lloopreverse(l,i,op) \ - { \ - for (i = (void *) (l).tail; i;) { \ - struct list_item *__t; \ - __t = (void *) i->prev; \ - op; \ - i = (void *) __t; \ - } \ - } - -#define lindex(l,i,n) \ - { \ - int __k; \ - for (__k = 0, i = (void *) (l).head; i && __k != n; i = i->next, __k++); \ - } - -#define lsearchforward(l,i,op) \ - { \ - int __found = 0; \ - if (!__found) \ - if ((i = (void *) (l).search)) { \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->next)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->prev)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - } \ - if (!__found) \ - for (i = (void *) (l).head; i; i = i->next) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - break; \ - } \ - } - -#define lsearchreverse(l,i,op) \ - { \ - int __found = 0; \ - if (!__found) \ - if ((i = (void *) (l).search)) { \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->prev)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - if (!__found) \ - if ((i = (void *) (l).search->next)) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - } \ - } \ - if (!__found) \ - for (i = (void *) (l).tail; i; i = i->prev) \ - if (op) { \ - __found = 1; \ - (l).search = (void *) i; \ - break; \ - } \ - } - -#define lcount(l) ((l).length) - -/* sort with comparison function see qsort(3) */ -#define larray(l,a) \ - { \ - long __i; \ - struct list_item *__p; \ - a = (void *) malloc (((l).length + 1) * sizeof (void *)); \ - for (__i = 0, __p = (void *) (l).head; __p; __p = __p->next, __i++) \ - a[__i] = (void *) __p; \ - a[__i] = 0; \ - } \ - -/* sort with comparison function see qsort(3) */ -#define llist(l,a) \ - { \ - struct list_item *__p; \ - (l).head = (void *) a[0]; \ - (l).search = 0; \ - __p = (void *) a[0]; \ - __p->prev = 0; \ - for (__j = 1; a[__j]; __j++, __p = __p->next) { \ - __p->next = (void *) a[__j]; \ - __p->next->prev = __p; \ - } \ - (l).tail = (void *) __p; \ - __p->next = 0; \ - } \ - -/* sort with comparison function see qsort(3) */ -#define lsort(l,compare) \ - { \ - void **__t; \ - long __j; \ - larray (l,__t); \ - qsort (__t, (l).length, sizeof (void *), (int (*) (const void *, const void *)) compare); \ - llist (l,__t); \ - free (__t); \ - } \ - -#endif /* GNUTLS_SRC_LIST_H */ diff --git a/src/serv.c b/src/serv.c index 5198b58c65..258af18d81 100644 --- a/src/serv.c +++ b/src/serv.c @@ -28,6 +28,7 @@ #include "common.h" #include "serv-args.h" +#include "udp-serv.h" #include <stdio.h> #include <stdlib.h> #include <errno.h> @@ -38,16 +39,18 @@ #include <sys/time.h> #include <sys/select.h> #include <fcntl.h> -#include <list.h> #include <netdb.h> #include <unistd.h> #include <socket.h> /* Gnulib portability files. */ -#include "read-file.h" +#include "gl_linked_list.h" +#include "gl_xlist.h" #include "minmax.h" +#include "read-file.h" #include "sockets.h" -#include "udp-serv.h" +#include "xalloc.h" +#include "xsize.h" /* konqueror cannot handle sending the page in multiple * pieces. @@ -145,16 +148,21 @@ static void cmd_parser(int argc, char **argv); #define HTTP_STATE_RESPONSE 2 #define HTTP_STATE_CLOSING 3 -LIST_TYPE_DECLARE(listener_item, char *http_request; char *http_response; - int request_length; int response_length; - int response_written; int http_state; - int listen_socket; int fd; - gnutls_session_t tls_session; - int handshake_ok; - int close_ok; - time_t start; - int earlydata_eof; - ); +typedef struct { + char *http_request; + char *http_response; + int request_length; + int response_length; + int response_written; + int http_state; + int listen_socket; + int fd; + gnutls_session_t tls_session; + int handshake_ok; + int close_ok; + time_t start; + int earlydata_eof; +} listener_item; static const char *safe_strerror(int value) { @@ -164,8 +172,9 @@ static const char *safe_strerror(int value) return ret; } -static void listener_free(listener_item * j) +static void listener_free(const void *elt) { + listener_item *j = (listener_item *)elt; free(j->http_request); free(j->http_response); @@ -275,7 +284,7 @@ get_params(gnutls_session_t session, gnutls_params_type_t type, return 0; } -LIST_DECLARE_INIT(listener_list, listener_item, listener_free); +static gl_list_t listener_list; static int cert_verify_callback(gnutls_session_t session) { @@ -554,7 +563,7 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length, char *http_buffer, *desc; gnutls_kx_algorithm_t kx_alg; size_t len = 20 * 1024 + strlen(header); - char *crtinfo = NULL, *crtinfo_old = NULL; + char *crtinfo = NULL; gnutls_protocol_t version; size_t ncrtinfo = 0; @@ -592,17 +601,22 @@ static char *peer_print_info(gnutls_session_t session, int *ret_length, && gnutls_x509_crt_print(cert, GNUTLS_CRT_PRINT_FULL, &info) == 0) { - const char *post = "</PRE><P><PRE>"; + const char post[] = "</PRE><P><PRE>"; + char *crtinfo_new; + size_t ncrtinfo_new; - crtinfo_old = crtinfo; - crtinfo = - realloc(crtinfo, - ncrtinfo + info.size + - strlen(post) + 1); - if (crtinfo == NULL) { - free(crtinfo_old); + ncrtinfo_new = xsum3(ncrtinfo, info.size, + sizeof(post)); + if (size_overflow_p(ncrtinfo_new)) { + free(crtinfo); return NULL; } + crtinfo_new = realloc(crtinfo, ncrtinfo_new); + if (crtinfo_new == NULL) { + free(crtinfo); + return NULL; + } + crtinfo = crtinfo_new; memcpy(crtinfo + ncrtinfo, info.data, info.size); ncrtinfo += info.size; @@ -865,21 +879,25 @@ const char *human_addr(const struct sockaddr *sa, socklen_t salen, int wait_for_connection(void) { - listener_item *j; fd_set rd, wr; int n, sock = -1; + gl_list_iterator_t iter; + const void *elt; FD_ZERO(&rd); FD_ZERO(&wr); n = 0; - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, NULL)) { + const listener_item *j = elt; + if (j->listen_socket) { FD_SET(j->fd, &rd); n = MAX(n, j->fd); } } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); /* waiting part */ n = select(n + 1, &rd, &wr, NULL, NULL); @@ -891,14 +909,17 @@ int wait_for_connection(void) } /* find which one is ready */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, NULL)) { + const listener_item *j = elt; + /* a new connection has arrived */ if (FD_ISSET(j->fd, &rd) && j->listen_socket) { sock = j->fd; break; } } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); return sock; } @@ -997,8 +1018,8 @@ int listen_socket(const char *name, int listen_port, int socktype) } /* new list entry for the connection */ - lappend(listener_list); - j = listener_list.tail; + j = xzalloc(sizeof(*j)); + gl_list_add_last(listener_list, j); j->listen_socket = 1; j->fd = s; @@ -1102,7 +1123,18 @@ static void terminate(int sig) __attribute__ ((__noreturn__)); static void terminate(int sig) { - fprintf(stderr, "Exiting via signal %d\n", sig); + char buf[64] = { 0 }; + char *p; + + /* This code must be async-signal-safe. */ + p = stpcpy(buf, "Exiting via signal "); + + if (sig > 10) + *p++ = '0' + sig / 10; + *p++ = '0' + sig % 10; + *p++ = '\n'; + + write(STDERR_FILENO, buf, p - buf); exit(1); } @@ -1151,6 +1183,10 @@ int main(int argc, char **argv) sockets_init(); + listener_list = gl_list_create_empty(GL_LINKED_LIST, + NULL, NULL, listener_free, + true); + if (nodb == 0) wrap_db_init(); @@ -1499,7 +1535,12 @@ static void tcp_server(const char *name, int port) exit(1); for (;;) { - listener_item *j; + gl_list_iterator_t iter; + gl_list_node_t node; + const void *elt; + gl_list_t accepted_list = gl_list_create_empty(GL_LINKED_LIST, + NULL, NULL, NULL, + true); fd_set rd, wr; time_t now = time(0); #ifndef _WIN32 @@ -1511,7 +1552,9 @@ static void tcp_server(const char *name, int port) n = 0; /* flag which connections we are reading or writing to within the fd sets */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + listener_item *j = (listener_item *)elt; #ifndef _WIN32 val = fcntl(j->fd, F_GETFL, 0); @@ -1541,8 +1584,9 @@ static void tcp_server(const char *name, int port) FD_SET(j->fd, &wr); n = MAX(n, j->fd); } + gl_list_node_set_value(listener_list, node, j); } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); /* core operation */ tv.tv_sec = 10; @@ -1556,7 +1600,9 @@ static void tcp_server(const char *name, int port) } /* read or write to each connection as indicated by select()'s return argument */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + listener_item *j = (listener_item *)elt; /* a new connection has arrived */ if (FD_ISSET(j->fd, &rd) && j->listen_socket) { @@ -1573,23 +1619,24 @@ static void tcp_server(const char *name, int port) char timebuf[SIMPLE_CTIME_BUF_SIZE]; time_t tt = time(0); char *ctt; + listener_item *jj; /* new list entry for the connection */ - lappend(listener_list); - j = listener_list.tail; - j->http_request = + jj = xzalloc(sizeof(*jj)); + gl_list_add_last(accepted_list, jj); + jj->http_request = (char *) strdup(""); - j->http_state = HTTP_STATE_REQUEST; - j->fd = accept_fd; - j->start = tt; + jj->http_state = HTTP_STATE_REQUEST; + jj->fd = accept_fd; + jj->start = tt; - j->tls_session = initialize_session(0); - gnutls_session_set_ptr(j->tls_session, j); + jj->tls_session = initialize_session(0); + gnutls_session_set_ptr(jj->tls_session, jj); gnutls_transport_set_int - (j->tls_session, accept_fd); - set_read_funcs(j->tls_session); - j->handshake_ok = 0; - j->close_ok = 0; + (jj->tls_session, accept_fd); + set_read_funcs(jj->tls_session); + jj->handshake_ok = 0; + jj->close_ok = 0; if (verbose != 0) { ctt = simple_ctime(&tt, timebuf); @@ -1775,16 +1822,27 @@ static void tcp_server(const char *name, int port) j->http_state = HTTP_STATE_REQUEST; } } + gl_list_node_set_value(listener_list, node, j); } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); /* loop through all connections, closing those that are in error */ - lloopstart(listener_list, j) { + iter = gl_list_iterator(listener_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + const listener_item *j = elt; + if (j->http_state == HTTP_STATE_CLOSING) { - ldeleteinc(listener_list, j); + gl_list_remove_node(listener_list, node); } } - lloopend(listener_list, j); + gl_list_iterator_free(&iter); + + iter = gl_list_iterator(accepted_list); + while (gl_list_iterator_next(&iter, &elt, &node)) { + gl_list_add_last(listener_list, elt); + } + gl_list_iterator_free(&iter); + gl_list_free(accepted_list); } diff --git a/src/udp-serv.c b/src/udp-serv.c index 9b71719fd2..814d698fbf 100644 --- a/src/udp-serv.c +++ b/src/udp-serv.c @@ -37,7 +37,6 @@ #include <common.h> #include "udp-serv.h" #include "serv-args.h" -#include "list.h" extern int disable_client_cert; |