Accepting request 715233 from games:tools

OBS-URL: https://build.opensuse.org/request/show/715233
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/mumble?expand=0&rev=56
This commit is contained in:
Dominique Leuenberger 2019-07-16 06:40:59 +00:00 committed by Git OBS Bridge
commit a2a3cc463e
4 changed files with 242 additions and 31 deletions

View File

@ -0,0 +1,195 @@
From 44b9004d2c208b42c6f8ffa99938361e31f5a071
From: MadMaurice <madmaurice@zom.bi>
Date: Thu Aug 30 15:08:01 2018 +0200
Prevent instability and crash due to message flood
This patch adds a rate limiting to selected patches. The underlying rate limiter
used is the Leaky-Bucket algorithm. It allows for a burst of messages, but
limits them after a specified amount of messages within a time frame.
From: Ferdinand Thiessen <rpm@fthiessen.de>
Modified this diff, to make it work with 1.2.19 tarball.
"Backported" by manually change the 1.2.19 version according to the original diff.
diff -Nur mumble-1.2.19/src/murmur/Messages.cpp new/src/murmur/Messages.cpp
--- mumble-1.2.19/src/murmur/Messages.cpp 2017-01-27 07:48:33.000000000 +0100
+++ new/src/murmur/Messages.cpp 2019-07-13 00:45:48.281780195 +0200
@@ -42,6 +42,11 @@
#include "ServerUser.h"
#include "Version.h"
+#define RATELIMIT(user) \
+ if (user->leakyBucket.ratelimit(1)) { \
+ return; \
+ }
+
#define MSG_SETUP(st) \
if (uSource->sState != st) { \
return; \
@@ -491,6 +496,10 @@
msg.set_session(pDstServerUser->uiSession);
msg.set_actor(uSource->uiSession);
+ if (uSource == pDstServerUser) {
+ RATELIMIT(uSource);
+ }
+
if (msg.has_channel_id()) {
Channel *c = qhChannels.value(msg.channel_id());
if (!c || (c == pDstServerUser->cChannel))
@@ -798,6 +807,8 @@
p = qhChannels.value(msg.parent());
if (! p)
return;
+ } else {
+ RATELIMIT(uSource);
}
msg.clear_links();
@@ -1074,6 +1085,8 @@
QSet<ServerUser *> users;
QQueue<Channel *> q;
+ RATELIMIT(uSource);
+
QString text = u8(msg.message());
bool changed = false;
@@ -1176,6 +1189,8 @@
return;
}
+ RATELIMIT(uSource);
+
if (msg.has_query() && msg.query()) {
QStack<Channel *> chans;
Channel *p;
@@ -1417,6 +1432,8 @@
}
void Server::msgVersion(ServerUser *uSource, MumbleProto::Version &msg) {
+ RATELIMIT(uSource);
+
if (msg.has_version())
uSource->uiVersion=msg.version();
if (msg.has_release())
diff -Nur mumble-1.2.19/src/murmur/ServerUser.cpp new/src/murmur/ServerUser.cpp
--- mumble-1.2.19/src/murmur/ServerUser.cpp 2017-01-27 07:48:33.000000000 +0100
+++ new/src/murmur/ServerUser.cpp 2019-07-13 00:47:25.974498227 +0200
@@ -128,3 +128,61 @@
return static_cast<int>((sum * 1000000ULL) / elapsed);
}
+#if __cplusplus > 199711LL
+
+inline static
+time_point now() {
+ return std::chrono::steady_clock::now();
+}
+
+inline static
+unsigned long millisecondsBetween(time_point start, time_point end) {
+ return std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count();
+}
+
+#else
+
+inline static
+time_point now() {
+ return clock();
+}
+
+inline static
+unsigned long millisecondsBetween(time_point start, time_point end) {
+ return 1000 * (end - start) / CLOCKS_PER_SEC;
+}
+
+#endif
+
+// Rate limiting: burst up to 30, 4 message per sec limit over longer time
+LeakyBucket::LeakyBucket() : tokensPerSec(4), maxTokens(30), currentTokens(0) {
+ lastUpdate = now();
+}
+
+bool LeakyBucket::ratelimit(int tokens) {
+ // First remove tokens we leaked over time
+ time_point tnow = now();
+ long ms = millisecondsBetween(lastUpdate, tnow);
+
+ long drainTokens = (ms * tokensPerSec) / 1000;
+
+ // Prevent constant starvation due to too many updates
+ if (drainTokens > 0) {
+ this->lastUpdate = tnow;
+
+ this->currentTokens -= drainTokens;
+ if (this->currentTokens < 0) {
+ this->currentTokens = 0;
+ }
+ }
+
+ // Then try to add tokens
+ bool limit = this->currentTokens > ((static_cast<long>(maxTokens)) - tokens);
+
+ // If the bucket is not overflowed, allow message and add tokens
+ if (!limit) {
+ this->currentTokens += tokens;
+ }
+
+ return limit;
+}
diff -Nur mumble-1.2.19/src/murmur/ServerUser.h new/src/murmur/ServerUser.h
--- mumble-1.2.19/src/murmur/ServerUser.h 2017-01-27 07:48:33.000000000 +0100
+++ new/src/murmur/ServerUser.h 2019-07-13 00:49:28.023395272 +0200
@@ -40,6 +40,13 @@
#include <winsock2.h>
#endif
+// <chrono> was introduced in C++11
+#if __cplusplus > 199711LL
+#include <chrono>
+#else
+#include <ctime>
+#endif
+
#include "Connection.h"
#include "Net.h"
#include "Timer.h"
@@ -80,6 +87,26 @@
class Server;
+#if __cplusplus > 199711L
+ typedef std::chrono::time_point<std::chrono::steady_clock> time_point;
+#else
+ typedef clock_t time_point;
+#endif
+
+// Simple algorithm for rate limiting
+class LeakyBucket {
+ private:
+ unsigned int tokensPerSec, maxTokens;
+ long currentTokens;
+ time_point lastUpdate;
+
+ public:
+ // Returns true if packets should be dropped
+ bool ratelimit(int tokens);
+
+ LeakyBucket();
+};
+
class ServerUser : public Connection, public User {
private:
Q_OBJECT
@@ -119,6 +146,8 @@
QMap<int, TargetCache> qmTargetCache;
QMap<QString, QString> qmWhisperRedirect;
+ LeakyBucket leakyBucket;
+
int iLastPermissionCheck;
QMap<int, unsigned int> qmPermissionSent;
#ifdef Q_OS_UNIX

View File

@ -0,0 +1,22 @@
From: 4761ca41ab1f611cd4a6d117f9f6cfd7c64f6b55
From: MadMaurice <madmaurice@zom.bi>
Date: Fri Aug 31 00:01:40 2018 +0200
Lower bucket params
Use 1 tokens per second and 5 burst instead of 4 tokens per second and 30 burst
diff -Nur old/src/murmur/ServerUser.cpp new/src/murmur/ServerUser.cpp
--- old/src/murmur/ServerUser.cpp 2019-07-13 01:28:14.972194419 +0200
+++ new/src/murmur/ServerUser.cpp 2019-07-13 01:29:36.724758470 +0200
@@ -154,8 +154,8 @@
#endif
-// Rate limiting: burst up to 30, 4 message per sec limit over longer time
-LeakyBucket::LeakyBucket() : tokensPerSec(4), maxTokens(30), currentTokens(0) {
+// Rate limiting: burst up to 5, 1 message per sec limit over longer time
+LeakyBucket::LeakyBucket() : tokensPerSec(1), maxTokens(5), currentTokens(0) {
lastUpdate = now();
}

View File

@ -1,3 +1,14 @@
-------------------------------------------------------------------
Fri Jul 12 23:30:49 UTC 2019 - Ferdinand Thiessen <rpm@fthiessen.de>
- Added patches to fix boo#1123334 (CVE-2018-20743), instability
and crash due to crafted message flooding
* added mumble-1.2.19-limit-amount-of-messages.patch (backported
version of upstream patch)
* added mumble-1.2.19-stricter-message-limit.patch (backported
version of upstream patch)
- Cleaned spec file, removed old EOL openSUSE and Fedora versions
-------------------------------------------------------------------
Wed Jun 26 13:05:06 UTC 2019 - Dirk Mueller <dmueller@suse.com>

View File

@ -16,27 +16,15 @@
#
%if 0%{?suse_version} > 1100
%bcond_without pulseaudio
%else
%if 0%{?fedora_version} > 9
%bcond_without pulseaudio
%else
%bcond_with pulseaudio
%endif
%endif
%if 0%{?fedora_version} > 11
%if 0%{?fedora_version}
%bcond_without ice
%else
%bcond_with ice
%endif
%if 0%{?suse_version} && 0%{?suse_version} < 1230
%bcond_with systemd
%else
%bcond_without pulseaudio
%bcond_without systemd
%endif
%bcond_with mumble11x
%bcond_without bonjour
%bcond_with mumble11x
%bcond_without bonjour
# mumble must be able to talk to other clients which may use
# differnt versions of celt. Since each celt release is
# incompatible to each other mumble bundles some specific
@ -67,6 +55,11 @@ Patch3: initialize-soundfile-format.patch
Patch4: 0001-AudioOutput-do-not-use-non-existant-template-version.patch
Patch5: add-speechd-include-path.patch
Patch6: mumble-pr-3623-protobuf37.patch
# PATCH-FIX-UPSTREAM mumble-1.2.19-limit-amount-of-messages.patch -- https://github.com/mumble-voip/mumble/pull/3510
Patch7: mumble-1.2.19-limit-amount-of-messages.patch
# PATCH-FIX-UPSTREAM mumble-1.2.19-stricter-message-limit.patch -- https://github.com/mumble-voip/mumble/pull/3512
Patch8: mumble-1.2.19-stricter-message-limit.patch
%if 0%{?suse_version} > 1325
BuildRequires: libboost_headers-devel
%else
@ -96,14 +89,10 @@ BuildRequires: pkgconfig(speexdsp)
%endif
%if 0%{?suse_version}
BuildRequires: alsa-devel
BuildRequires: libopenssl-devel
BuildRequires: libqt4-devel
BuildRequires: pkg-config
BuildRequires: update-desktop-files
%if 0%{?suse_version} > 1020
BuildRequires: libopenssl-devel
%else
BuildRequires: openssl-devel
%endif
%endif
%if 0%{?fedora_version}
BuildRequires: alsa-lib-devel
@ -135,10 +124,6 @@ Source1: https://github.com/mumble-voip/mumble/releases/download/%{versio
%endif
%if 0%{?suse_version}
Requires: qt-sql-sqlite
%else
Requires: qt4-sqlite
%endif
%if 0%{?suse_version} > 1010
%ifarch x86_64
Recommends: %{name}-32bit
Conflicts: %{name}-32bit < %{version}
@ -147,12 +132,13 @@ Conflicts: %{name}-32bit < %{version}
Recommends: %{name}-64bit
Conflicts: %{name}-64bit < %{version}
%endif
%else
Requires: qt4-sqlite
%endif
#
%if 0%{?snapshot:1}
Conflicts: mumble < %{version}
Provides: mumble = %{version}
#
%endif
#
@ -191,6 +177,8 @@ won't be audible to other players.
%patch4 -p1
%patch5 -p1
%patch6 -p1
%patch7 -p1
%patch8 -p1
%if !%{with system_celt}
%if 0%{?snapshot:1}
@ -351,9 +339,6 @@ install -D -m 0755 %{SOURCE2} %{buildroot}%{_initddir}/mumble-server
ln -s %{_initddir}/mumble-server %{buildroot}%{_sbindir}/rcmumble-server
%endif
install -D -m 0644 %{SOURCE3} %{buildroot}%{_sysconfdir}/apparmor.d/usr.sbin.murmurd
%if 0%{?suse_version} < 1220
sed -i -e 's,%{_bindir}/grep,/bin/grep,;s,%{_bindir}/sed,/bin/sed,' %{buildroot}%{_sysconfdir}/apparmor.d/usr.sbin.murmurd
%endif
install -d -m 0755 %{buildroot}%{_bindir}
# can be launched as user too but apparmor profile doesn't make
# sense in that case. So use link to avoid the profile.
@ -466,9 +451,7 @@ systemd-tmpfiles --create %{_libexecdir}/tmpfiles.d/mumble-server.conf || true
%{_mandir}/man1/murmur-user-wrapper.*
%dir %attr(-,mumble-server,mumble-server) %{_localstatedir}/lib/mumble-server
%dir %{_localstatedir}/log/mumble-server
%if 0%{?suse_version} > 1310
%ghost %{_rundir}/mumble-server
%endif
%dir %{_datadir}/appdata/
%{_datadir}/appdata/mumble.appdata.xml