forked from pool/openvpn
Marius Tomaschewski
9c3259ca06
- Preform deferred authentication in the background to not cause main daemon processing delays when the underlying pam mechanism (e.g. ldap) needs longer to response (bsc#959511). [+ 0001-preform-deferred-authentication-in-the-background.patch] - Added fix for possible heap overflow on read accessing getaddrinfo result (bsc#959714). [+openvpn-2.3.9-Fix-heap-overflow-on-getaddrinfo-result.patch] - Added a patch to fix multiple low severity issues (bsc#934237). [+openvpn-2.3.x-fixed-multiple-low-severity-issues.patch] OBS-URL: https://build.opensuse.org/request/show/489820 OBS-URL: https://build.opensuse.org/package/show/network:vpn/openvpn?expand=0&rev=115
239 lines
8.0 KiB
Diff
239 lines
8.0 KiB
Diff
diff --git a/src/openvpn/crypto.c b/src/openvpn/crypto.c
|
|
index 4261795..44c1f9e 100644
|
|
--- a/src/openvpn/crypto.c
|
|
+++ b/src/openvpn/crypto.c
|
|
@@ -151,7 +151,7 @@ openvpn_encrypt (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,
|
|
@@ -278,7 +278,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
|
|
const int iv_size = cipher_ctx_iv_length (ctx->cipher);
|
|
const cipher_kt_t *cipher_kt = cipher_ctx_get_cipher_kt (ctx->cipher);
|
|
uint8_t iv_buf[OPENVPN_MAX_IV_LENGTH];
|
|
- int outlen;
|
|
+ int outlen = 0;
|
|
|
|
/* initialize work buffer with FRAME_HEADROOM bytes of prepend capacity */
|
|
ASSERT (buf_init (&work, FRAME_HEADROOM_ADJ (frame, FRAME_HEADROOM_MARKER_DECRYPT)));
|
|
@@ -305,7 +305,7 @@ openvpn_decrypt (struct buffer *buf, struct buffer work,
|
|
CRYPT_ERROR ("cipher init failed");
|
|
|
|
/* 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");
|
|
|
|
/* Decrypt packet ID, payload */
|
|
diff --git a/src/openvpn/crypto_openssl.h b/src/openvpn/crypto_openssl.h
|
|
index 2ed0bef..ae9f24d 100644
|
|
--- a/src/openvpn/crypto_openssl.h
|
|
+++ b/src/openvpn/crypto_openssl.h
|
|
@@ -53,6 +53,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 089e3c4..e03a3e6 100644
|
|
--- a/src/openvpn/init.c
|
|
+++ b/src/openvpn/init.c
|
|
@@ -2614,8 +2614,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 ENABLE_LZO
|
|
diff --git a/src/openvpn/proxy.c b/src/openvpn/proxy.c
|
|
index 89989d1..5809daa 100644
|
|
--- a/src/openvpn/proxy.c
|
|
+++ b/src/openvpn/proxy.c
|
|
@@ -76,6 +76,9 @@ recv_line (socket_descriptor_t sd,
|
|
struct buffer la;
|
|
int lastc = 0;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return false;
|
|
+
|
|
CLEAR (la);
|
|
if (lookahead)
|
|
la = *lookahead;
|
|
@@ -283,11 +286,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))
|
|
{
|
|
*data = NULL;
|
|
return HTTP_AUTH_NONE;
|
|
@@ -498,9 +501,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;
|
|
@@ -586,7 +589,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
|
|
goto error;
|
|
|
|
/* receive reply from proxy */
|
|
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line (sd, buf, sizeof(buf) - 1 , p->options.timeout, true, NULL, signal_received))
|
|
goto error;
|
|
|
|
/* remove trailing CR, LF */
|
|
@@ -615,7 +619,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
|
|
|
|
while (true)
|
|
{
|
|
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line (sd, buf, sizeof(buf) - 1, p->options.timeout, true, NULL, signal_received))
|
|
goto error;
|
|
chomp (buf);
|
|
msg (D_PROXY, "HTTP proxy returned: '%s'", buf);
|
|
@@ -685,7 +690,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
|
|
goto error;
|
|
|
|
/* receive reply from proxy */
|
|
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line (sd, buf, sizeof(buf) - 1, p->options.timeout, true, NULL, signal_received))
|
|
goto error;
|
|
|
|
/* remove trailing CR, LF */
|
|
@@ -795,7 +801,8 @@ establish_http_proxy_passthru (struct http_proxy_info *p,
|
|
goto error;
|
|
|
|
/* receive reply from proxy */
|
|
- if (!recv_line (sd, buf, sizeof(buf), p->options.timeout, true, NULL, signal_received))
|
|
+ memset(buf, 0, sizeof(buf));
|
|
+ if (!recv_line (sd, buf, sizeof(buf) - 1, p->options.timeout, true, NULL, signal_received))
|
|
goto error;
|
|
|
|
/* remove trailing CR, LF */
|
|
diff --git a/src/openvpn/socket.c b/src/openvpn/socket.c
|
|
index 3474f18..dfd9d6c 100644
|
|
--- a/src/openvpn/socket.c
|
|
+++ b/src/openvpn/socket.c
|
|
@@ -832,6 +832,9 @@ socket_listen_accept (socket_descriptor_t sd,
|
|
struct openvpn_sockaddr remote_verify = act->dest;
|
|
int new_sd = SOCKET_UNDEFINED;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return -1;
|
|
+
|
|
CLEAR (*act);
|
|
socket_do_listen (sd, local, do_listen, true);
|
|
|
|
@@ -919,6 +922,9 @@ openvpn_connect (socket_descriptor_t sd,
|
|
{
|
|
int status = 0;
|
|
|
|
+ if (sd >= FD_SETSIZE)
|
|
+ return -1;
|
|
+
|
|
#ifdef CONNECT_NONBLOCK
|
|
set_nonblock (sd);
|
|
status = connect (sd, &remote->addr.sa, af_addr_size(remote->addr.sa.sa_family));
|
|
diff --git a/src/openvpn/socks.c b/src/openvpn/socks.c
|
|
index 57dc02a..8954e91 100644
|
|
--- a/src/openvpn/socks.c
|
|
+++ b/src/openvpn/socks.c
|
|
@@ -97,13 +97,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))
|
|
{
|
|
@@ -189,7 +192,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;
|
|
@@ -198,6 +201,8 @@ socks_handshake (struct socks_proxy_info *p,
|
|
char method_sel[3] = { 0x05, 0x01, 0x00 };
|
|
if (p->authfile[0])
|
|
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))
|
|
@@ -302,9 +307,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;
|
|
@@ -381,7 +389,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;
|
|
++len;
|
|
}
|
|
@@ -411,7 +419,7 @@ establish_socks_proxy_passthru (struct socks_proxy_info *p,
|
|
const int port, /* openvpn server port */
|
|
volatile int *signal_received)
|
|
{
|
|
- char buf[128];
|
|
+ char buf[128] = {0};
|
|
size_t len;
|
|
|
|
if (!socks_handshake (p, sd, signal_received))
|