summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorivan <ivan@13f79535-47bb-0310-9956-ffa450edef68>2022-06-29 14:46:27 +0000
committerivan <ivan@13f79535-47bb-0310-9956-ffa450edef68>2022-06-29 14:46:27 +0000
commit14887eb7c41c19e8b71a763ed17b60ecc5854bba (patch)
tree020cb3a94ba821cb6147bd6810ddc4cbe3e08aaf
parent5de1d6b83485b13d6df553ec88fc36e7dc99ca57 (diff)
downloadlibapr-thread-name.tar.gz
On 'thread-name' branch: Merge changes from trunk.thread-name
git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/thread-name@1902353 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--crypto/apr_crypto.c31
-rw-r--r--crypto/apr_crypto_prng.c15
-rw-r--r--crypto/apr_md4.c7
-rw-r--r--encoding/apr_base64.c100
-rw-r--r--include/apr_strings.h10
-rw-r--r--network_io/unix/sendrecv.c17
-rw-r--r--network_io/win32/sendrecv.c33
-rw-r--r--strings/apr_strings.c32
8 files changed, 134 insertions, 111 deletions
diff --git a/crypto/apr_crypto.c b/crypto/apr_crypto.c
index 7572a5904..fa08092e5 100644
--- a/crypto/apr_crypto.c
+++ b/crypto/apr_crypto.c
@@ -120,7 +120,7 @@ static apr_status_t crypto_clear(void *ptr)
{
apr_crypto_clear_t *clear = (apr_crypto_clear_t *)ptr;
- apr_crypto_memzero(clear->buffer, clear->size);
+ apr_memzero_explicit(clear->buffer, clear->size);
clear->buffer = NULL;
clear->size = 0;
@@ -141,36 +141,9 @@ APR_DECLARE(apr_status_t) apr_crypto_clear(apr_pool_t *pool,
return APR_SUCCESS;
}
-#if defined(HAVE_WEAK_SYMBOLS)
-void apr__memzero_explicit(void *buffer, apr_size_t size);
-
-__attribute__ ((weak))
-void apr__memzero_explicit(void *buffer, apr_size_t size)
-{
- memset(buffer, 0, size);
-}
-#endif
-
APR_DECLARE(apr_status_t) apr_crypto_memzero(void *buffer, apr_size_t size)
{
-#if defined(WIN32)
- SecureZeroMemory(buffer, size);
-#elif defined(HAVE_MEMSET_S)
- if (size) {
- return memset_s(buffer, (rsize_t)size, 0, (rsize_t)size);
- }
-#elif defined(HAVE_EXPLICIT_BZERO)
- explicit_bzero(buffer, size);
-#elif defined(HAVE_WEAK_SYMBOLS)
- apr__memzero_explicit(buffer, size);
-#else
- apr_size_t i;
- volatile unsigned char *volatile ptr = buffer;
- for (i = 0; i < size; ++i) {
- ptr[i] = 0;
- }
-#endif
- return APR_SUCCESS;
+ return apr_memzero_explicit(buffer, size);
}
APR_DECLARE(int) apr_crypto_equals(const void *buf1, const void *buf2,
diff --git a/crypto/apr_crypto_prng.c b/crypto/apr_crypto_prng.c
index 842987f95..cd4a2044d 100644
--- a/crypto/apr_crypto_prng.c
+++ b/crypto/apr_crypto_prng.c
@@ -43,12 +43,13 @@
#include "apr_crypto.h"
#include "apr_crypto_internal.h"
+#include "apr_strings.h"
+
#if APU_HAVE_CRYPTO
#if APU_HAVE_CRYPTO_PRNG
#include "apr_ring.h"
#include "apr_pools.h"
-#include "apr_strings.h"
#include "apr_thread_mutex.h"
#include "apr_thread_proc.h"
@@ -263,7 +264,7 @@ static apr_status_t cprng_cleanup(void *arg)
}
if (cprng->key) {
- apr_crypto_memzero(cprng->key, CPRNG_KEY_SIZE + cprng->len);
+ apr_memzero_explicit(cprng->key, CPRNG_KEY_SIZE + cprng->len);
}
if (!cprng->pool) {
@@ -435,7 +436,7 @@ static apr_status_t cprng_stream_bytes(apr_crypto_prng_t *cprng,
rv = cprng->crypto->provider->cprng_stream_ctx_bytes(&cprng->ctx,
cprng->key, to, len, cprng->buf);
if (rv != APR_SUCCESS && len) {
- apr_crypto_memzero(to, len);
+ apr_memzero_explicit(to, len);
}
return rv;
}
@@ -456,7 +457,7 @@ APR_DECLARE(apr_status_t) apr_crypto_prng_reseed(apr_crypto_prng_t *cprng,
cprng_lock(cprng);
cprng->pos = cprng->len;
- apr_crypto_memzero(cprng->buf, cprng->len);
+ apr_memzero_explicit(cprng->buf, cprng->len);
if (seed) {
apr_size_t n = 0;
do {
@@ -528,7 +529,7 @@ static apr_status_t cprng_bytes(apr_crypto_prng_t *cprng,
* both forward secrecy and cleared next mixed data.
*/
memcpy(ptr, cprng->buf + cprng->pos, n);
- apr_crypto_memzero(cprng->buf + cprng->pos, n);
+ apr_memzero_explicit(cprng->buf + cprng->pos, n);
cprng->pos += n;
ptr += n;
@@ -576,7 +577,7 @@ APR_DECLARE(apr_status_t) apr_crypto_prng_rekey(apr_crypto_prng_t *cprng)
/* Clear state and renew the key. */
cprng->pos = cprng->len;
- apr_crypto_memzero(cprng->buf, cprng->len);
+ apr_memzero_explicit(cprng->buf, cprng->len);
rv = cprng_stream_bytes(cprng, NULL, 0);
cprng_unlock(cprng);
@@ -627,7 +628,7 @@ APR_DECLARE(apr_status_t) apr_crypto_prng_after_fork(apr_crypto_prng_t *cprng,
* and that nothing is left over from the initial state in both processes.
*/
cprng->pos = cprng->len;
- apr_crypto_memzero(cprng->buf, cprng->len);
+ apr_memzero_explicit(cprng->buf, cprng->len);
if (!is_child) {
rv = cprng_stream_bytes(cprng, cprng->key, CPRNG_KEY_SIZE);
}
diff --git a/crypto/apr_md4.c b/crypto/apr_md4.c
index 22a0926e7..aef0a3404 100644
--- a/crypto/apr_md4.c
+++ b/crypto/apr_md4.c
@@ -41,7 +41,6 @@
#include "apr_strings.h"
#include "apr_md4.h"
#include "apr_lib.h"
-#include "apr_crypto.h" /* for apr_crypto_memzero, if available */
#if APR_HAVE_STRING_H
#include <string.h>
@@ -360,11 +359,7 @@ static void MD4Transform(apr_uint32_t state[4], const unsigned char block[64])
state[3] += d;
/* Zeroize sensitive information. */
-#if APU_HAVE_CRYPTO
- apr_crypto_memzero(x, sizeof(x));
-#else
- memset(x, 0, sizeof(x));
-#endif
+ apr_memzero_explicit(x, sizeof(x));
}
/* Encodes input (apr_uint32_t) into output (unsigned char). Assumes len is
diff --git a/encoding/apr_base64.c b/encoding/apr_base64.c
index f5c2786ad..ab200cd7e 100644
--- a/encoding/apr_base64.c
+++ b/encoding/apr_base64.c
@@ -26,7 +26,7 @@
#include "apr_base64.h"
#if APR_CHARSET_EBCDIC
#include "apr_xlate.h"
-#endif /* APR_CHARSET_EBCDIC */
+#endif /* APR_CHARSET_EBCDIC */
/* Above APR_BASE64_ENCODE_MAX length the encoding can't fit in an int >= 0 */
#define APR_BASE64_ENCODE_MAX 1610612733
@@ -141,7 +141,7 @@ APR_DECLARE(int) apr_base64_decode(char *bufplain, const char *bufcoded)
inbytes_left = outbytes_left = len;
apr_xlate_conv_buffer(xlate_to_ebcdic, bufplain, &inbytes_left,
bufplain, &outbytes_left);
-#endif /* APR_CHARSET_EBCDIC */
+#endif /* APR_CHARSET_EBCDIC */
bufplain[len] = '\0';
return len;
}
@@ -151,7 +151,7 @@ APR_DECLARE(int) apr_base64_decode(char *bufplain, const char *bufcoded)
* - on EBCDIC machines, the conversion of the output to ebcdic is left out
*/
APR_DECLARE(int) apr_base64_decode_binary(unsigned char *bufplain,
- const char *bufcoded)
+ const char *bufcoded)
{
int nbytesdecoded;
register const unsigned char *bufin;
@@ -168,24 +168,24 @@ APR_DECLARE(int) apr_base64_decode_binary(unsigned char *bufplain,
bufin = (const unsigned char *) bufcoded;
while (nprbytes >= 4) {
- *(bufout++) =
- (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
- *(bufout++) =
- (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
- *(bufout++) =
- (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
- bufin += 4;
- nprbytes -= 4;
+ *(bufout++) =
+ (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
+ *(bufout++) =
+ (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
+ *(bufout++) =
+ (unsigned char) (pr2six[bufin[2]] << 6 | pr2six[bufin[3]]);
+ bufin += 4;
+ nprbytes -= 4;
}
/* Note: (nprbytes == 1) would be an error, so just ignore that case */
if (nprbytes > 1) {
- *(bufout++) =
- (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
+ *(bufout++) =
+ (unsigned char) (pr2six[*bufin] << 2 | pr2six[bufin[1]] >> 4);
}
if (nprbytes > 2) {
- *(bufout++) =
- (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
+ *(bufout++) =
+ (unsigned char) (pr2six[bufin[1]] << 4 | pr2six[bufin[2]] >> 2);
}
return nbytesdecoded - (int)((4u - nprbytes) & 3u);
@@ -223,30 +223,30 @@ APR_DECLARE(int) apr_base64_encode(char *encoded, const char *string, int len)
p = encoded;
for (i = 0; i < len - 2; i += 3) {
- *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
- *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
- ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
- *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) |
- ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)];
- *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F];
+ *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
+ *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
+ ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
+ *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2) |
+ ((int) (os_toascii[string[i + 2]] & 0xC0) >> 6)];
+ *p++ = basis_64[os_toascii[string[i + 2]] & 0x3F];
}
if (i < len) {
- *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
- if (i == (len - 1)) {
- *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)];
- *p++ = '=';
- }
- else {
- *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
- ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
- *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)];
- }
- *p++ = '=';
+ *p++ = basis_64[(os_toascii[string[i]] >> 2) & 0x3F];
+ if (i == (len - 1)) {
+ *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4)];
+ *p++ = '=';
+ }
+ else {
+ *p++ = basis_64[((os_toascii[string[i]] & 0x3) << 4) |
+ ((int) (os_toascii[string[i + 1]] & 0xF0) >> 4)];
+ *p++ = basis_64[((os_toascii[string[i + 1]] & 0xF) << 2)];
+ }
+ *p++ = '=';
}
*p++ = '\0';
return (unsigned int)(p - encoded);
-#endif /* APR_CHARSET_EBCDIC */
+#endif /* APR_CHARSET_EBCDIC */
}
/* This is the same as apr_base64_encode() except on EBCDIC machines, where
@@ -262,25 +262,25 @@ APR_DECLARE(int) apr_base64_encode_binary(char *encoded,
p = encoded;
for (i = 0; i < len - 2; i += 3) {
- *p++ = basis_64[(string[i] >> 2) & 0x3F];
- *p++ = basis_64[((string[i] & 0x3) << 4) |
- ((int) (string[i + 1] & 0xF0) >> 4)];
- *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
- ((int) (string[i + 2] & 0xC0) >> 6)];
- *p++ = basis_64[string[i + 2] & 0x3F];
+ *p++ = basis_64[(string[i] >> 2) & 0x3F];
+ *p++ = basis_64[((string[i] & 0x3) << 4) |
+ ((int) (string[i + 1] & 0xF0) >> 4)];
+ *p++ = basis_64[((string[i + 1] & 0xF) << 2) |
+ ((int) (string[i + 2] & 0xC0) >> 6)];
+ *p++ = basis_64[string[i + 2] & 0x3F];
}
if (i < len) {
- *p++ = basis_64[(string[i] >> 2) & 0x3F];
- if (i == (len - 1)) {
- *p++ = basis_64[((string[i] & 0x3) << 4)];
- *p++ = '=';
- }
- else {
- *p++ = basis_64[((string[i] & 0x3) << 4) |
- ((int) (string[i + 1] & 0xF0) >> 4)];
- *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
- }
- *p++ = '=';
+ *p++ = basis_64[(string[i] >> 2) & 0x3F];
+ if (i == (len - 1)) {
+ *p++ = basis_64[((string[i] & 0x3) << 4)];
+ *p++ = '=';
+ }
+ else {
+ *p++ = basis_64[((string[i] & 0x3) << 4) |
+ ((int) (string[i + 1] & 0xF0) >> 4)];
+ *p++ = basis_64[((string[i + 1] & 0xF) << 2)];
+ }
+ *p++ = '=';
}
*p++ = '\0';
diff --git a/include/apr_strings.h b/include/apr_strings.h
index d5f8719d2..56f0426fc 100644
--- a/include/apr_strings.h
+++ b/include/apr_strings.h
@@ -183,6 +183,16 @@ APR_DECLARE_NONSTD(char *) apr_psprintf(apr_pool_t *p, const char *fmt, ...)
__attribute__((format(printf,2,3)));
/**
+ * zero out the buffer provided, without being optimized out by
+ * the compiler.
+ *
+ * @param buffer buffer to zero out
+ * @param size size of the buffer to zero out
+ * @return APR_SUCCESS or an errno
+ */
+APR_DECLARE(apr_status_t) apr_memzero_explicit(void *buffer, apr_size_t size);
+
+/**
* Copy up to dst_size characters from src to dst; does not copy
* past a NUL terminator in src, but always terminates dst with a NUL
* regardless.
diff --git a/network_io/unix/sendrecv.c b/network_io/unix/sendrecv.c
index b9e580b1b..1b965af50 100644
--- a/network_io/unix/sendrecv.c
+++ b/network_io/unix/sendrecv.c
@@ -196,13 +196,8 @@ apr_status_t apr_socket_sendv(apr_socket_t * sock, const struct iovec *vec,
{
#ifdef HAVE_WRITEV
apr_ssize_t rv;
- apr_size_t requested_len = 0;
apr_int32_t i;
- for (i = 0; i < nvec; i++) {
- requested_len += vec[i].iov_len;
- }
-
if (sock->options & APR_INCOMPLETE_WRITE) {
sock->options &= ~APR_INCOMPLETE_WRITE;
goto do_select;
@@ -231,8 +226,16 @@ do_select:
*len = 0;
return errno;
}
- if ((sock->timeout > 0) && (rv < requested_len)) {
- sock->options |= APR_INCOMPLETE_WRITE;
+ if (sock->timeout > 0) {
+ apr_size_t rv_len = rv;
+ for (i = 0; i < nvec; ++i) {
+ apr_size_t iov_len = vec[i].iov_len;
+ if (rv_len < iov_len) {
+ sock->options |= APR_INCOMPLETE_WRITE;
+ break;
+ }
+ rv_len -= iov_len;
+ }
}
(*len) = rv;
return APR_SUCCESS;
diff --git a/network_io/win32/sendrecv.c b/network_io/win32/sendrecv.c
index 20d802042..eb4dd241a 100644
--- a/network_io/win32/sendrecv.c
+++ b/network_io/win32/sendrecv.c
@@ -34,7 +34,10 @@
* than 8193 bytes.
*/
#define MAX_SEGMENT_SIZE 65536
+
+/* Maximum number of WSABUF allocated for a single apr_socket_sendv() */
#define WSABUF_ON_STACK 50
+#define WSABUF_ON_HEAP 500
APR_DECLARE(apr_status_t) apr_socket_send(apr_socket_t *sock, const char *buf,
apr_size_t *len)
@@ -91,18 +94,26 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
apr_status_t rc = APR_SUCCESS;
apr_ssize_t rv;
apr_size_t cur_len;
- apr_int32_t nvec = 0;
- int i, j = 0;
+ apr_size_t nvec = 0;
+ apr_size_t n;
+ int i;
DWORD dwBytes = 0;
WSABUF *pWsaBuf;
for (i = 0; i < in_vec; i++) {
cur_len = vec[i].iov_len;
- nvec++;
+
while (cur_len > APR_DWORD_MAX) {
+ if (nvec >= WSABUF_ON_HEAP) {
+ break;
+ }
nvec++;
cur_len -= APR_DWORD_MAX;
}
+ if (nvec >= WSABUF_ON_HEAP) {
+ break;
+ }
+ nvec++;
}
pWsaBuf = (nvec <= WSABUF_ON_STACK) ? _alloca(sizeof(WSABUF) * (nvec))
@@ -110,25 +121,23 @@ APR_DECLARE(apr_status_t) apr_socket_sendv(apr_socket_t *sock,
if (!pWsaBuf)
return APR_ENOMEM;
- for (i = 0; i < in_vec; i++) {
+ for (n = i = 0; n < nvec; i++) {
char * base = vec[i].iov_base;
cur_len = vec[i].iov_len;
-
+
do {
if (cur_len > APR_DWORD_MAX) {
- pWsaBuf[j].buf = base;
- pWsaBuf[j].len = APR_DWORD_MAX;
+ pWsaBuf[n].buf = base;
+ pWsaBuf[n].len = APR_DWORD_MAX;
cur_len -= APR_DWORD_MAX;
base += APR_DWORD_MAX;
}
else {
- pWsaBuf[j].buf = base;
- pWsaBuf[j].len = (DWORD)cur_len;
+ pWsaBuf[n].buf = base;
+ pWsaBuf[n].len = (DWORD)cur_len;
cur_len = 0;
}
- j++;
-
- } while (cur_len > 0);
+ } while (++n < nvec && cur_len > 0);
}
rv = WSASend(sock->socketdes, pWsaBuf, nvec, &dwBytes, 0, NULL, NULL);
if (rv == SOCKET_ERROR) {
diff --git a/strings/apr_strings.c b/strings/apr_strings.c
index beca6d480..2519f95b9 100644
--- a/strings/apr_strings.c
+++ b/strings/apr_strings.c
@@ -212,6 +212,38 @@ APR_DECLARE(char *) apr_pstrcatv(apr_pool_t *a, const struct iovec *vec,
return res;
}
+#if defined(HAVE_WEAK_SYMBOLS)
+void apr__memzero_explicit(void *buffer, apr_size_t size);
+
+__attribute__ ((weak))
+void apr__memzero_explicit(void *buffer, apr_size_t size)
+{
+ memset(buffer, 0, size);
+}
+#endif
+
+APR_DECLARE(apr_status_t) apr_memzero_explicit(void *buffer, apr_size_t size)
+{
+#if defined(WIN32)
+ SecureZeroMemory(buffer, size);
+#elif defined(HAVE_EXPLICIT_BZERO)
+ explicit_bzero(buffer, size);
+#elif defined(HAVE_MEMSET_S)
+ if (size) {
+ return memset_s(buffer, (rsize_t)size, 0, (rsize_t)size);
+ }
+#elif defined(HAVE_WEAK_SYMBOLS)
+ apr__memzero_explicit(buffer, size);
+#else
+ apr_size_t i;
+ volatile unsigned char *volatile ptr = buffer;
+ for (i = 0; i < size; ++i) {
+ ptr[i] = 0;
+ }
+#endif
+ return APR_SUCCESS;
+}
+
#if (!APR_HAVE_MEMCHR)
void *memchr(const void *s, int c, size_t n)
{