forked from pool/openvpn
774c998664
- Update to 2.4.3 (bsc#1045489) - Ignore auth-nocache for auth-user-pass if auth-token is pushed - crypto: Enable SHA256 fingerprint checking in --verify-hash - copyright: Update GPLv2 license texts - auth-token with auth-nocache fix broke --disable-crypto builds - OpenSSL: don't use direct access to the internal of X509 - OpenSSL: don't use direct access to the internal of EVP_PKEY - OpenSSL: don't use direct access to the internal of RSA - OpenSSL: don't use direct access to the internal of DSA - OpenSSL: force meth->name as non-const when we free() it - OpenSSL: don't use direct access to the internal of EVP_MD_CTX - OpenSSL: don't use direct access to the internal of EVP_CIPHER_CTX - OpenSSL: don't use direct access to the internal of HMAC_CTX - Fix NCP behaviour on TLS reconnect. - Remove erroneous limitation on max number of args for --plugin - Fix edge case with clients failing to set up cipher on empty PUSH_REPLY. - Fix potential 1-byte overread in TCP option parsing. - Fix remotely-triggerable ASSERT() on malformed IPv6 packet. - Preparing for release v2.4.3 (ChangeLog, version.m4, Changes.rst) - refactor my_strupr - Fix 2 memory leaks in proxy authentication routine - Fix memory leak in add_option() for option 'connection' - Ensure option array p[] is always NULL-terminated - Fix a null-pointer dereference in establish_http_proxy_passthru() - Prevent two kinds of stack buffer OOB reads and a crash for invalid input data - Fix an unaligned access on OpenBSD/sparc64 - Missing include for socket-flags TCP_NODELAY on OpenBSD - Make openvpn-plugin.h self-contained again. - Pass correct buffer size to GetModuleFileNameW() - Log the negotiated (NCP) cipher OBS-URL: https://build.opensuse.org/request/show/505857 OBS-URL: https://build.opensuse.org/package/show/network:vpn/openvpn?expand=0&rev=124
258 lines
9.1 KiB
Diff
258 lines
9.1 KiB
Diff
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
|
|
index ff0f9a7..fb27b36 100644
|
|
--- a/src/openvpn/crypto.c
|
|
+++ b/src/openvpn/crypto.c
|
|
@@ -118,7 +118,7 @@ openvpn_encrypt_aead(struct buffer *buf, struct buffer work,
|
|
dmsg(D_PACKET_CONTENT, "ENCRYPT FROM: %s", format_hex(BPTR(buf), BLEN(buf), 80, &gc));
|
|
|
|
/* Buffer overflow check */
|
|
- if (!buf_safe(&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
|
|
+ if (!buf_safe(&work, buf->len + OPENVPN_MAX_BLOCK_LENGTH))
|
|
{
|
|
msg(D_CRYPT_ERRORS,
|
|
"ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d",
|
|
@@ -237,7 +237,7 @@ openvpn_encrypt_v1(struct buffer *buf, struct buffer work,
|
|
ASSERT(cipher_ctx_reset(ctx->cipher, iv_buf));
|
|
|
|
/* Buffer overflow check */
|
|
- if (!buf_safe(&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
|
|
+ if (!buf_safe(&work, buf->len + OPENVPN_MAX_BLOCK_LENGTH))
|
|
{
|
|
msg(D_CRYPT_ERRORS, "ENCRYPT: buffer size error, bc=%d bo=%d bl=%d wc=%d wo=%d wl=%d cbs=%d",
|
|
buf->capacity,
|
|
@@ -378,7 +378,7 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
|
|
const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt(ctx->cipher);
|
|
uint8_t *tag_ptr = NULL;
|
|
int tag_size = 0;
|
|
- int outlen;
|
|
+ int outlen = 0;
|
|
struct gc_arena gc;
|
|
|
|
gc_init(&gc);
|
|
@@ -455,7 +455,7 @@ openvpn_decrypt_aead(struct buffer *buf, struct buffer work,
|
|
dmsg(D_PACKET_CONTENT, "DECRYPT FROM: %s", format_hex(BPTR(buf), BLEN(buf), 0, &gc));
|
|
|
|
/* Buffer overflow check (should never fail) */
|
|
- if (!buf_safe(&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
|
|
+ if (!buf_safe(&work, buf->len + OPENVPN_MAX_BLOCK_LENGTH))
|
|
{
|
|
CRYPT_ERROR("potential buffer overflow");
|
|
}
|
|
@@ -601,7 +601,7 @@ openvpn_decrypt_v1(struct buffer *buf, struct buffer work,
|
|
}
|
|
|
|
/* Buffer overflow check (should never happen) */
|
|
- if (!buf_safe(&work, buf->len + cipher_ctx_block_size(ctx->cipher)))
|
|
+ if (!buf_safe(&work, buf->len + OPENVPN_MAX_BLOCK_LENGTH))
|
|
{
|
|
CRYPT_ERROR("potential buffer overflow");
|
|
}
|
|
diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h
|
|
index 60a2812..c191695 100644
|
|
--- a/src/openvpn/crypto_openssl.h
|
|
+++ b/src/openvpn/crypto_openssl.h
|
|
@@ -52,6 +52,9 @@ typedef HMAC_CTX hmac_ctx_t;
|
|
/** Maximum length of an IV */
|
|
#define OPENVPN_MAX_IV_LENGTH EVP_MAX_IV_LENGTH
|
|
|
|
+/** Maximum length of a cipher block */
|
|
+#define OPENVPN_MAX_BLOCK_LENGTH EVP_MAX_BLOCK_LENGTH
|
|
+
|
|
/** Cipher is in CBC mode */
|
|
#define OPENVPN_MODE_CBC EVP_CIPH_CBC_MODE
|
|
|
|
diff --git a/src/openvpn/init.c b/src/openvpn/init.c
|
|
index 0652ef4..9fa3352 100644
|
|
--- a/src/openvpn/init.c
|
|
+++ b/src/openvpn/init.c
|
|
@@ -3067,8 +3067,8 @@ init_context_buffers(const struct frame *frame)
|
|
b->aux_buf = alloc_buf(BUF_SIZE(frame));
|
|
|
|
#ifdef ENABLE_CRYPTO
|
|
- b->encrypt_buf = alloc_buf(BUF_SIZE(frame));
|
|
- b->decrypt_buf = alloc_buf(BUF_SIZE(frame));
|
|
+ b->encrypt_buf = alloc_buf(BUF_SIZE(frame) + OPENVPN_MAX_BLOCK_LENGTH);
|
|
+ b->decrypt_buf = alloc_buf(BUF_SIZE(frame) + OPENVPN_MAX_BLOCK_LENGTH);
|
|
#endif
|
|
|
|
#ifdef USE_COMP
|
|
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
|
|
index 7a737ea..592bd97 100644
|
|
--- a/src/openvpn/proxy.c
|
|
+++ b/src/openvpn/proxy.c
|
|
@@ -73,6 +73,9 @@ recv_line(socket_descriptor_t sd,
|
|
struct buffer la;
|
|
int lastc = 0;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return false;
|
|
+
|
|
CLEAR(la);
|
|
if (lookahead)
|
|
{
|
|
@@ -311,11 +314,11 @@ get_proxy_authenticate(socket_descriptor_t sd,
|
|
struct gc_arena *gc,
|
|
volatile int *signal_received)
|
|
{
|
|
- char buf[256];
|
|
+ char buf[256] = {0};
|
|
int ret = HTTP_AUTH_NONE;
|
|
while (true)
|
|
{
|
|
- if (!recv_line(sd, buf, sizeof(buf), timeout, true, NULL, signal_received))
|
|
+ if (!recv_line(sd, buf, sizeof(buf) - 1, timeout, true, NULL, signal_received))
|
|
{
|
|
free(*data);
|
|
*data = NULL;
|
|
@@ -631,9 +634,9 @@ establish_http_proxy_passthru(struct http_proxy_info *p,
|
|
volatile int *signal_received)
|
|
{
|
|
struct gc_arena gc = gc_new();
|
|
- char buf[512];
|
|
- char buf2[129];
|
|
- char get[80];
|
|
+ char buf[512] = {0};
|
|
+ char buf2[129] = {0};
|
|
+ char get[80] = {0};
|
|
int status;
|
|
int nparms;
|
|
bool ret = false;
|
|
@@ -723,7 +726,8 @@ establish_http_proxy_passthru(struct http_proxy_info *p,
|
|
}
|
|
|
|
/* receive reply from proxy */
|
|
- if (!recv_line(sd, buf, sizeof(buf), get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line(sd, buf, sizeof(buf) - 1, get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
{
|
|
goto error;
|
|
}
|
|
@@ -754,7 +758,8 @@ establish_http_proxy_passthru(struct http_proxy_info *p,
|
|
|
|
while (true)
|
|
{
|
|
- if (!recv_line(sd, buf, sizeof(buf), get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line(sd, buf, sizeof(buf) - 1, get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
{
|
|
goto error;
|
|
}
|
|
@@ -834,7 +839,8 @@ establish_http_proxy_passthru(struct http_proxy_info *p,
|
|
}
|
|
|
|
/* receive reply from proxy */
|
|
- if (!recv_line(sd, buf, sizeof(buf), get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line(sd, buf, sizeof(buf) - 1, get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
{
|
|
goto error;
|
|
}
|
|
@@ -959,7 +965,8 @@ establish_http_proxy_passthru(struct http_proxy_info *p,
|
|
}
|
|
|
|
/* receive reply from proxy */
|
|
- if (!recv_line(sd, buf, sizeof(buf), get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line(sd, buf, sizeof(buf) - 1, get_server_poll_remaining_time(server_poll_timeout), true, NULL, signal_received))
|
|
{
|
|
goto error;
|
|
}
|
|
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
|
|
index 4e7e3f9..93ea889 100644
|
|
--- a/src/openvpn/socket.c
|
|
+++ b/src/openvpn/socket.c
|
|
@@ -1162,6 +1162,9 @@ socket_listen_accept(socket_descriptor_t sd,
|
|
/* struct openvpn_sockaddr *remote = &act->dest; */
|
|
struct openvpn_sockaddr remote_verify = act->dest;
|
|
socket_descriptor_t new_sd = SOCKET_UNDEFINED;
|
|
+
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return -1;
|
|
|
|
CLEAR(*act);
|
|
socket_do_listen(sd, local, do_listen, true);
|
|
@@ -1314,6 +1317,9 @@ openvpn_connect(socket_descriptor_t sd,
|
|
{
|
|
int status = 0;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return -1;
|
|
+
|
|
#ifdef TARGET_ANDROID
|
|
protect_fd_nonlocal(sd, remote);
|
|
#endif
|
|
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
|
|
index 92747ec..f8e02a4 100644
|
|
--- a/src/openvpn/socks.c
|
|
+++ b/src/openvpn/socks.c
|
|
@@ -98,13 +98,16 @@ socks_username_password_auth(struct socks_proxy_info *p,
|
|
socket_descriptor_t sd,
|
|
volatile int *signal_received)
|
|
{
|
|
- char to_send[516];
|
|
- char buf[2];
|
|
+ char to_send[516] = {0};
|
|
+ char buf[2] = {0};
|
|
int len = 0;
|
|
const int timeout_sec = 5;
|
|
struct user_pass creds;
|
|
ssize_t size;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return false;
|
|
+
|
|
creds.defined = 0;
|
|
if (!get_user_pass(&creds, p->authfile, UP_TYPE_SOCKS, GET_USER_PASS_MANAGEMENT))
|
|
{
|
|
@@ -193,7 +196,7 @@ socks_handshake(struct socks_proxy_info *p,
|
|
socket_descriptor_t sd,
|
|
volatile int *signal_received)
|
|
{
|
|
- char buf[2];
|
|
+ char buf[2] = {0};
|
|
int len = 0;
|
|
const int timeout_sec = 5;
|
|
ssize_t size;
|
|
@@ -205,6 +208,9 @@ socks_handshake(struct socks_proxy_info *p,
|
|
method_sel[2] = 0x02; /* METHODS = [2 (plain login)] */
|
|
|
|
}
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return false;
|
|
+
|
|
size = send(sd, method_sel, sizeof(method_sel), MSG_NOSIGNAL);
|
|
if (size != sizeof(method_sel))
|
|
{
|
|
@@ -312,9 +318,12 @@ recv_socks_reply(socket_descriptor_t sd,
|
|
char atyp = '\0';
|
|
int alen = 0;
|
|
int len = 0;
|
|
- char buf[22];
|
|
+ char buf[22] = {0};
|
|
const int timeout_sec = 5;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return false;
|
|
+
|
|
if (addr != NULL)
|
|
{
|
|
addr->addr.in4.sin_family = AF_INET;
|
|
@@ -395,7 +404,7 @@ recv_socks_reply(socket_descriptor_t sd,
|
|
}
|
|
|
|
/* store char in buffer */
|
|
- if (len < (int)sizeof(buf))
|
|
+ if (len < (int)sizeof(buf) && len >= 0)
|
|
{
|
|
buf[len] = c;
|
|
}
|
|
@@ -447,7 +456,7 @@ establish_socks_proxy_passthru(struct socks_proxy_info *p,
|
|
const char *servname, /* openvpn server port */
|
|
volatile int *signal_received)
|
|
{
|
|
- char buf[128];
|
|
+ char buf[128] = {0};
|
|
size_t len;
|
|
|
|
if (!socks_handshake(p, sd, signal_received))
|