There is a write-beyond-bounds bug in h2_util_header_print() (modules/http2/h2_util.c) in httpd 2.4.53+. [1] The bug appears to be latent in httpd 2.4.53 because nothing seems to call h2_util_header_print(). The bug is caused by using the condition |offset < maxlen; ... ++offset| in various |for| loops when indexing a buffer, then following the loops with |buffer[offset] ='\0';| . Thus sufficiently-long data causes |offset| to become == |maxlen| after a |for| loop, causing the |'\0'| to be written beyond bounds and the out-of-bounds value of |offset| to be returned to the caller: 79: size_t h2_util_header_print(char *buffer, size_t maxlen, 80: const char *name, size_t namelen, 81: const char *value, size_t valuelen) 82: { 83: size_t offset = 0; 84: size_t i; 85: for (i = 0; i < namelen && offset < maxlen; ++i, ++offset) { 86: buffer[offset] = name[i]; 87: } 88: for (i = 0; i < 2 && offset < maxlen; ++i, ++offset) { 89: buffer[offset] = ": "[i]; 90: } 91: for (i = 0; i < valuelen && offset < maxlen; ++i, ++offset) { 92: buffer[offset] = value[i]; 93: } 94: buffer[offset] = '\0'; 95: return offset; 96: } You can demonstrate the bug by copying the function into a scratch file, then calling in thusly: char buf[20]; const char name[]="0123456789"; const char val[]="0123456789"; size_t s = h2_util_header_print(buf, sizeof(buf), name, strlen(name), val, strlen(val)); and stepping h2_util_header_print() in a debugger, watching |buf| for the overwrite. Note also that the function can create a malformed |buffer| if, e.g., |namelen >= maxlen| (|buffer| will contain only |name| followed by '\0'). [1] The security team has asked me to file "hardening" (latent) bugs publicly.
Fixed in r1900356 in trunk, proposed backport to 2.4.x. Thanks for finding this!