znc: backport fix for CVE-2019-12816
authorJonas Gorski <jonas.gorski@gmail.com>
Mon, 24 Jun 2019 12:08:06 +0000 (14:08 +0200)
committerJonas Gorski <jonas.gorski@gmail.com>
Mon, 24 Jun 2019 12:46:56 +0000 (14:46 +0200)
Backport the fix for CVE-2019-12816 from 1.7.4 to 1.6.x.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
net/znc/Makefile
net/znc/patches/004-Fix-remote-code-execution-and-privilege-escalation-v.patch [new file with mode: 0644]

index 546b43f79f2ab6b81672895814df439869690c83..b04e1fc5f1010efb908fb399bef80eddc62fe320 100644 (file)
@@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
 
 PKG_NAME:=znc
 PKG_VERSION:=1.6.6
-PKG_RELEASE:=3
+PKG_RELEASE:=4
 
 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
 PKG_SOURCE_URL:=https://znc.in/releases \
diff --git a/net/znc/patches/004-Fix-remote-code-execution-and-privilege-escalation-v.patch b/net/znc/patches/004-Fix-remote-code-execution-and-privilege-escalation-v.patch
new file mode 100644 (file)
index 0000000..f9648ab
--- /dev/null
@@ -0,0 +1,92 @@
+From a06aa79a308585cc6048f725f2dc3c1d55ff9991 Mon Sep 17 00:00:00 2001
+From: Alexey Sokolov <alexey+znc@asokolov.org>
+Date: Wed, 12 Jun 2019 08:57:29 +0100
+Subject: [PATCH] Fix remote code execution and privilege escalation
+ vulnerability.
+
+To trigger this, need to have a user already.
+
+Thanks for Jeriko One <jeriko.one@gmx.us> for finding and reporting this.
+
+CVE-2019-12816
+---
+ include/znc/Modules.h |  1 +
+ src/Modules.cpp       | 33 ++++++++++++++++++++++++++++-----
+ 2 files changed, 29 insertions(+), 5 deletions(-)
+
+--- a/include/znc/Modules.h
++++ b/include/znc/Modules.h
+@@ -1253,6 +1253,7 @@ public:
+ private:
+       static ModHandle OpenModule(const CString& sModule, const CString& sModPath,
+                       bool &bVersionMismatch, CModInfo& Info, CString& sRetMsg);
++      static bool ValidateModuleName(const CString& sModule, CString& sRetMsg);
+ protected:
+       CUser*        m_pUser;
+--- a/src/Modules.cpp
++++ b/src/Modules.cpp
+@@ -1014,9 +1014,26 @@ CModule* CModules::FindModule(const CStr
+       return NULL;
+ }
++bool CModules::ValidateModuleName(const CString& sModule, CString& sRetMsg) {
++      for (unsigned int a = 0; a < sModule.length(); a++) {
++              if (((sModule[a] < '0') || (sModule[a] > '9')) &&
++                  ((sModule[a] < 'a') || (sModule[a] > 'z')) &&
++                  ((sModule[a] < 'A') || (sModule[a] > 'Z')) && (sModule[a] != '_')) {
++                      sRetMsg = "Module names can only contain letters, numbers and underscores, [" + sModule + "] is invalid.";
++                      return false;
++              }
++      }
++
++      return true;
++}
++
+ bool CModules::LoadModule(const CString& sModule, const CString& sArgs, CModInfo::EModuleType eType, CUser* pUser, CIRCNetwork *pNetwork, CString& sRetMsg) {
+       sRetMsg = "";
++      if (!ValidateModuleName(sModule, sRetMsg)) {
++              return false;
++      }
++
+       if (FindModule(sModule) != NULL) {
+               sRetMsg = "Module [" + sModule + "] already loaded.";
+               return false;
+@@ -1167,6 +1184,10 @@ bool CModules::ReloadModule(const CStrin
+ bool CModules::GetModInfo(CModInfo& ModInfo, const CString& sModule, CString& sRetMsg) {
+       CString sModPath, sTmp;
++      if (!ValidateModuleName(sModule, sRetMsg)) {
++              return false;
++      }
++
+       bool bSuccess;
+       bool bHandled = false;
+       GLOBALMODULECALL(OnGetModInfo(ModInfo, sModule, bSuccess, sRetMsg), &bHandled);
+@@ -1183,6 +1204,10 @@ bool CModules::GetModInfo(CModInfo& ModI
+ bool CModules::GetModPathInfo(CModInfo& ModInfo, const CString& sModule, const CString& sModPath, CString& sRetMsg) {
+       bool bVersionMismatch;
++      if (!ValidateModuleName(sModule, sRetMsg)) {
++              return false;
++      }
++
+       ModHandle p = OpenModule(sModule, sModPath, bVersionMismatch, ModInfo, sRetMsg);
+       if (!p)
+@@ -1302,11 +1327,9 @@ ModHandle CModules::OpenModule(const CSt
+       bVersionMismatch = false;
+       sRetMsg.clear();
+-      for (unsigned int a = 0; a < sModule.length(); a++) {
+-              if (((sModule[a] < '0') || (sModule[a] > '9')) && ((sModule[a] < 'a') || (sModule[a] > 'z')) && ((sModule[a] < 'A') || (sModule[a] > 'Z')) && (sModule[a] != '_')) {
+-                      sRetMsg = "Module names can only contain letters, numbers and underscores, [" + sModule + "] is invalid.";
+-                      return NULL;
+-              }
++
++      if (!ValidateModuleName(sModule, sRetMsg)) {
++              return NULL;
+       }
+       // The second argument to dlopen() has a long history. It seems clear