DoS via malformed packet.

Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
---
 ...essary-and-problematic-corosync-qdevice.i.patch |  78 ------------
 ...08-totemcrypto-Check-length-of-the-packet.patch |  53 ++++++++
 ...-totemudp-Check-lenght-of-message-to-sent.patch | 125 +++++++++++++++++++
 ...-msgio-Fix-reading-of-msg-longer-than-i32.patch | 137 +++++++++++++++++++++
 patches/series                                     |   4 +-
 5 files changed, 318 insertions(+), 79 deletions(-)
 delete mode 100644 
patches/0008-remove-unecessary-and-problematic-corosync-qdevice.i.patch
 create mode 100644 patches/0008-totemcrypto-Check-length-of-the-packet.patch
 create mode 100644 patches/0012-totemudp-Check-lenght-of-message-to-sent.patch
 create mode 100644 
patches/0013-qdevice-msgio-Fix-reading-of-msg-longer-than-i32.patch

diff --git 
a/patches/0008-remove-unecessary-and-problematic-corosync-qdevice.i.patch 
b/patches/0008-remove-unecessary-and-problematic-corosync-qdevice.i.patch
deleted file mode 100644
index c37216c..0000000
--- a/patches/0008-remove-unecessary-and-problematic-corosync-qdevice.i.patch
+++ /dev/null
@@ -1,78 +0,0 @@
-From f1b91ad6c1659477b72853666cde930932279d6c Mon Sep 17 00:00:00 2001
-From: Thomas Lamprecht <t.lampre...@proxmox.com>
-Date: Wed, 29 Mar 2017 09:35:19 +0200
-Subject: [PATCH 8/8] remove unecessary and problematic corosync-qdevice.init
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Signed-off-by: Thomas Lamprecht <t.lampre...@proxmox.com>
----
- debian/corosync-qdevice.init | 55 --------------------------------------------
- 1 file changed, 55 deletions(-)
- delete mode 100755 debian/corosync-qdevice.init
-
-diff --git a/debian/corosync-qdevice.init b/debian/corosync-qdevice.init
-deleted file mode 100755
-index 344666a..0000000
---- a/debian/corosync-qdevice.init
-+++ /dev/null
-@@ -1,55 +0,0 @@
--#!/bin/sh
--# kFreeBSD do not accept scripts as interpreters, using #!/bin/sh and 
sourcing.
--if [ true != "$INIT_D_SCRIPT_SOURCED" ] ; then
--    set "$0" "$@"; INIT_D_SCRIPT_SOURCED=true . /lib/init/init-d-script
--fi
--### BEGIN INIT INFO
--# Provides:           corosync-qdevice
--# Required-Start:     $remote_fs $syslog corosync
--# Required-Stop:      $remote_fs $syslog corosync
--# Default-Start:      
--# Default-Stop:               0 1 6
--# Short-Description:  Corosync Qdevice daemon
--# Description:                Starts and stops Corosync Qdevice daemon.
--### END INIT INFO
--
--NAME="corosync-qdevice"
--DESC="Corosync Qdevice daemon"
--DAEMON="/usr/sbin/$NAME"
--PIDFILE="/run/$NAME/$NAME.pid"
--
--CONFIG="/etc/default/$NAME"
--[ -f "$CONFIG" ] && . "$CONFIG"
--
--DAEMON_ARGS="$COROSYNC_QDEVICE_OPTIONS"
--
--do_start_prepare() {
--    if grep -q nocluster /proc/cmdline; then
--        log_failure_msg "not configured to run at boot"
--        exit 1
--    fi
--}
--
--# do_{start,stop}_cmd from init-d-script, but without the --name option.
--# corosync-qdevice is too long for a process name, it gets truncated,
--# which makes it incompatible with the --name option.  See #843419.
--do_start_cmd() {
--      start-stop-daemon --start --quiet ${PIDFILE:+--pidfile ${PIDFILE}} \
--          $START_ARGS \
--          --startas $DAEMON --exec $DAEMON --test > /dev/null \
--          || return 1
--      start-stop-daemon --start --quiet ${PIDFILE:+--pidfile ${PIDFILE}} \
--          $START_ARGS \
--          --startas $DAEMON --exec $DAEMON -- $DAEMON_ARGS \
--          || return 2
--}
--do_stop_cmd() {
--      start-stop-daemon --stop --quiet --retry=TERM/30/KILL/5 \
--          $STOP_ARGS \
--          ${PIDFILE:+--pidfile ${PIDFILE}} --exec $DAEMON
--      RETVAL="$?"
--      [ "$RETVAL" = 2 ] && return 2
--      # Many daemons don't delete their pidfiles when they exit.
--      rm -f $PIDFILE
--      return $RETVAL
--}
--- 
-2.1.4
-
diff --git a/patches/0008-totemcrypto-Check-length-of-the-packet.patch 
b/patches/0008-totemcrypto-Check-length-of-the-packet.patch
new file mode 100644
index 0000000..42650b8
--- /dev/null
+++ b/patches/0008-totemcrypto-Check-length-of-the-packet.patch
@@ -0,0 +1,53 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfrie...@redhat.com>
+Date: Mon, 19 Mar 2018 16:59:41 +0100
+Subject: [PATCH] totemcrypto: Check length of the packet
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Packet has to be longer than crypto_config_header and hash_len,
+otherwise unallocated memory is passed into calculate_nss_hash function,
+what may result in crash.
+
+Signed-off-by: Jan Friesse <jfrie...@redhat.com>
+Reviewed-by: Raphael Sanchez Prudencio <rasan...@redhat.com>
+Reviewed-by: Christine Caulfield <ccaul...@redhat.com>
+(cherry picked from commit fc1d5418533c1faf21616b282c2559bed7d361c4)
+Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
+---
+ exec/totemcrypto.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c
+index a97ba62f..bf30ffc2 100644
+--- a/exec/totemcrypto.c
++++ b/exec/totemcrypto.c
+@@ -627,6 +627,11 @@ static int authenticate_nss_2_3 (
+               unsigned char   tmp_hash[hash_len[instance->crypto_hash_type]];
+               int             datalen = *buf_len - 
hash_len[instance->crypto_hash_type];
+ 
++              if (*buf_len <= hash_len[instance->crypto_hash_type]) {
++                      log_printf(instance->log_level_security, "Received 
message is too short...  ignoring");
++                      return -1;
++              }
++
+               if (calculate_nss_hash(instance, buf, datalen, tmp_hash) < 0) {
+                       return -1;
+               }
+@@ -736,6 +741,12 @@ int crypto_authenticate_and_decrypt (struct 
crypto_instance *instance,
+ {
+       struct crypto_config_header *cch = (struct crypto_config_header *)buf;
+ 
++      if (*buf_len <= sizeof(struct crypto_config_header)) {
++              log_printf(instance->log_level_security, "Received message is 
too short...  ignoring");
++
++              return (-1);
++      }
++
+       if (cch->crypto_cipher_type != CRYPTO_CIPHER_TYPE_2_3) {
+               log_printf(instance->log_level_security,
+                          "Incoming packet has different crypto type. 
Rejecting");
+-- 
+2.14.2
+
diff --git a/patches/0012-totemudp-Check-lenght-of-message-to-sent.patch 
b/patches/0012-totemudp-Check-lenght-of-message-to-sent.patch
new file mode 100644
index 0000000..ec883d7
--- /dev/null
+++ b/patches/0012-totemudp-Check-lenght-of-message-to-sent.patch
@@ -0,0 +1,125 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfrie...@redhat.com>
+Date: Fri, 23 Mar 2018 16:47:42 +0100
+Subject: [PATCH] totemudp: Check lenght of message to sent
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+If message to sent is too long, encrypt and authentificate may overwrite
+stack (buf_out). Check this condition and throw message if this happens.
+
+Signed-off-by: Jan Friesse <jfrie...@redhat.com>
+Reviewed-by: Christine Caulfield <ccaul...@redhat.com>
+(cherry picked from commit 08cb2372cd3bd63a910c2618a2cc86cad8885d78)
+Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
+---
+ exec/totemcrypto.h |  3 +++
+ exec/totemcrypto.c |  8 +++++++-
+ exec/totemudp.c    | 12 ++++++++++++
+ exec/totemudpu.c   | 12 ++++++++++++
+ 4 files changed, 34 insertions(+), 1 deletion(-)
+
+diff --git a/exec/totemcrypto.h b/exec/totemcrypto.h
+index 7c06c391..b6941055 100644
+--- a/exec/totemcrypto.h
++++ b/exec/totemcrypto.h
+@@ -44,6 +44,9 @@ extern size_t crypto_sec_header_size(
+       const char *crypto_cipher_type,
+       const char *crypto_hash_type);
+ 
++extern size_t crypto_get_current_sec_header_size(
++      const struct crypto_instance *instance);
++
+ extern int crypto_authenticate_and_decrypt (
+       struct crypto_instance *instance,
+       unsigned char *buf,
+diff --git a/exec/totemcrypto.c b/exec/totemcrypto.c
+index bf30ffc2..122f15fe 100644
+--- a/exec/totemcrypto.c
++++ b/exec/totemcrypto.c
+@@ -699,6 +699,13 @@ size_t crypto_sec_header_size(
+       return hdr_size;
+ }
+ 
++size_t crypto_get_current_sec_header_size(
++      const struct crypto_instance *instance)
++{
++
++      return (instance->crypto_header_size);
++}
++
+ /*
+  * 2.0 packet format:
+  *   crypto_cipher_type | crypto_hash_type | __pad0 | __pad1 | hash | salt | 
data
+@@ -780,7 +787,6 @@ int crypto_authenticate_and_decrypt (struct 
crypto_instance *instance,
+       /*
+        * decrypt
+        */
+-
+       if (decrypt_nss_2_3(instance, buf, buf_len) != 0) {
+               return -1;
+       }
+diff --git a/exec/totemudp.c b/exec/totemudp.c
+index 31d05704..dbc6ee97 100644
+--- a/exec/totemudp.c
++++ b/exec/totemudp.c
+@@ -270,6 +270,12 @@ static inline void ucast_sendmsg (
+       struct iovec iovec;
+       int addrlen;
+ 
++      if (msg_len + crypto_get_current_sec_header_size(instance->crypto_inst) 
> sizeof(buf_out)) {
++              log_printf(LOGSYS_LEVEL_CRIT, "UDP message for ucast is too 
big. Ignoring message");
++
++              return ;
++      }
++
+       /*
+        * Encrypt and digest the message
+        */
+@@ -338,6 +344,12 @@ static inline void mcast_sendmsg (
+       struct sockaddr_storage sockaddr;
+       int addrlen;
+ 
++      if (msg_len + crypto_get_current_sec_header_size(instance->crypto_inst) 
> sizeof(buf_out)) {
++              log_printf(LOGSYS_LEVEL_CRIT, "UDP message for mcast is too 
big. Ignoring message");
++
++              return ;
++      }
++
+       /*
+        * Encrypt and digest the message
+        */
+diff --git a/exec/totemudpu.c b/exec/totemudpu.c
+index 037f82b4..78005c48 100644
+--- a/exec/totemudpu.c
++++ b/exec/totemudpu.c
+@@ -271,6 +271,12 @@ static inline void ucast_sendmsg (
+       struct iovec iovec;
+       int addrlen;
+ 
++      if (msg_len + crypto_get_current_sec_header_size(instance->crypto_inst) 
> sizeof(buf_out)) {
++              log_printf(LOGSYS_LEVEL_CRIT, "UDPU message for ucast is too 
big. Ignoring message");
++
++              return ;
++      }
++
+       /*
+        * Encrypt and digest the message
+        */
+@@ -341,6 +347,12 @@ static inline void mcast_sendmsg (
+         struct list_head *list;
+       struct totemudpu_member *member;
+ 
++      if (msg_len + crypto_get_current_sec_header_size(instance->crypto_inst) 
> sizeof(buf_out)) {
++              log_printf(LOGSYS_LEVEL_CRIT, "UDPU message for mcast is too 
big. Ignoring message");
++
++              return ;
++      }
++
+       /*
+        * Encrypt and digest the message
+        */
+-- 
+2.14.2
+
diff --git 
a/patches/0013-qdevice-msgio-Fix-reading-of-msg-longer-than-i32.patch 
b/patches/0013-qdevice-msgio-Fix-reading-of-msg-longer-than-i32.patch
new file mode 100644
index 0000000..034194a
--- /dev/null
+++ b/patches/0013-qdevice-msgio-Fix-reading-of-msg-longer-than-i32.patch
@@ -0,0 +1,137 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jan Friesse <jfrie...@redhat.com>
+Date: Fri, 23 Mar 2018 17:19:09 +0100
+Subject: [PATCH] qdevice msgio: Fix reading of msg longer than i32
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+And also remove the unused msgio_send_blocking which was used in
+the very early phases of qdevice development and it's not used
+any longer, so it make sense to delete it.
+
+Signed-off-by: Jan Friesse <jfrie...@redhat.com>
+Reviewed-by: Christine Caulfield <ccaul...@redhat.com>
+(cherry picked from commit b25b029fe186bacf089ab8136da58390945eb35c)
+Signed-off-by: Fabian Grünbichler <f.gruenbich...@proxmox.com>
+---
+ qdevices/msgio.c | 71 +++++++++++---------------------------------------------
+ 1 file changed, 14 insertions(+), 57 deletions(-)
+
+diff --git a/qdevices/msgio.c b/qdevices/msgio.c
+index cedff34a..21158c16 100644
+--- a/qdevices/msgio.c
++++ b/qdevices/msgio.c
+@@ -37,55 +37,6 @@
+ 
+ #define MSGIO_LOCAL_BUF_SIZE                  (1 << 10)
+ 
+-ssize_t
+-msgio_send(PRFileDesc *sock, const char *msg, size_t msg_len, size_t 
*start_pos)
+-{
+-      ssize_t sent_bytes;
+-
+-      if ((sent_bytes = PR_Send(sock, msg + *start_pos,
+-          msg_len - *start_pos, 0, PR_INTERVAL_NO_TIMEOUT)) != -1) {
+-              *start_pos += sent_bytes;
+-      }
+-
+-      return (sent_bytes);
+-}
+-
+-ssize_t
+-msgio_send_blocking(PRFileDesc *sock, const char *msg, size_t msg_len)
+-{
+-      PRPollDesc pfd;
+-      size_t already_sent_bytes;
+-      PRInt32 res;
+-      ssize_t ret;
+-
+-      already_sent_bytes = 0;
+-      ret = 0;
+-
+-      while (ret != -1 && already_sent_bytes < msg_len) {
+-              pfd.fd = sock;
+-              pfd.in_flags = PR_POLL_WRITE;
+-              pfd.out_flags = 0;
+-
+-              if ((res = PR_Poll(&pfd, 1, PR_INTERVAL_NO_TIMEOUT)) > 0) {
+-                      if (pfd.out_flags & PR_POLL_WRITE) {
+-                              if ((msgio_send(sock, msg, msg_len, 
&already_sent_bytes) == -1) &&
+-                                  PR_GetError() != PR_WOULD_BLOCK_ERROR) {
+-                                      ret = -1;
+-                              } else {
+-                                      ret = already_sent_bytes;
+-                              }
+-                      } else if (pfd.out_flags & (PR_POLL_ERR | PR_POLL_NVAL 
| PR_POLL_HUP)) {
+-                              PR_SetError(PR_IO_ERROR, 0);
+-                              ret = -1;
+-                      }
+-              } else {
+-                      ret = -1;
+-              }
+-      }
+-
+-      return (ret);
+-}
+-
+ /*
+  * -1 = send returned 0,
+  * -2 = unhandled error.
+@@ -96,18 +47,21 @@ int
+ msgio_write(PRFileDesc *sock, const struct dynar *msg, size_t 
*already_sent_bytes)
+ {
+       PRInt32 sent;
+-      PRInt32 to_send;
++      PRInt32 to_send_i32;
++      size_t to_send;
+ 
+       to_send = dynar_size(msg) - *already_sent_bytes;
+       if (to_send > MSGIO_LOCAL_BUF_SIZE) {
+-              to_send = MSGIO_LOCAL_BUF_SIZE;
++              to_send_i32 = MSGIO_LOCAL_BUF_SIZE;
++      } else {
++              to_send_i32 = (PRInt32)to_send;
+       }
+ 
+-      sent = PR_Send(sock, dynar_data(msg) + *already_sent_bytes, to_send, 0,
++      sent = PR_Send(sock, dynar_data(msg) + *already_sent_bytes, 
to_send_i32, 0,
+           PR_INTERVAL_NO_TIMEOUT);
+ 
+       if (sent > 0) {
+-              *already_sent_bytes += sent;
++              *already_sent_bytes += (size_t)sent;
+ 
+               if (*already_sent_bytes == dynar_size(msg)) {
+                       /*
+@@ -143,7 +97,8 @@ msgio_read(PRFileDesc *sock, struct dynar *msg, size_t 
*already_received_bytes,
+ {
+       char local_read_buffer[MSGIO_LOCAL_BUF_SIZE];
+       PRInt32 readed;
+-      PRInt32 to_read;
++      size_t to_read;
++      PRInt32 to_read_i32;
+       int ret;
+ 
+       ret = 0;
+@@ -161,12 +116,14 @@ msgio_read(PRFileDesc *sock, struct dynar *msg, size_t 
*already_received_bytes,
+       }
+ 
+       if (to_read > MSGIO_LOCAL_BUF_SIZE) {
+-              to_read = MSGIO_LOCAL_BUF_SIZE;
++              to_read_i32 = MSGIO_LOCAL_BUF_SIZE;
++      } else {
++              to_read_i32 = (PRInt32)to_read;
+       }
+ 
+-      readed = PR_Recv(sock, local_read_buffer, to_read, 0, 
PR_INTERVAL_NO_TIMEOUT);
++      readed = PR_Recv(sock, local_read_buffer, to_read_i32, 0, 
PR_INTERVAL_NO_TIMEOUT);
+       if (readed > 0) {
+-              *already_received_bytes += readed;
++              *already_received_bytes += (size_t)readed;
+ 
+               if (!*skipping_msg) {
+                       if (dynar_cat(msg, local_read_buffer, readed) == -1) {
+-- 
+2.14.2
+
diff --git a/patches/series b/patches/series
index b6afd80..5fbab33 100644
--- a/patches/series
+++ b/patches/series
@@ -5,4 +5,6 @@
 0005-add-corosync-pve-postinst-for-restart-on-dist-upgrad.patch
 0006-add-libcorosync4-pve-transitional-package.patch
 0007-only-start-corosync.service-if-conf-exists.patch
-0008-remove-unecessary-and-problematic-corosync-qdevice.i.patch
+0008-totemcrypto-Check-length-of-the-packet.patch
+0012-totemudp-Check-lenght-of-message-to-sent.patch
+0013-qdevice-msgio-Fix-reading-of-msg-longer-than-i32.patch
-- 
2.14.2


_______________________________________________
pve-devel mailing list
pve-devel@pve.proxmox.com
https://pve.proxmox.com/cgi-bin/mailman/listinfo/pve-devel

Reply via email to