znc: backport fix for CVE-2019-12816

Backport the fix for CVE-2019-12816 from 1.7.4 to 1.6.x.

Signed-off-by: Jonas Gorski <jonas.gorski@gmail.com>
This commit is contained in:
Jonas Gorski 2019-06-24 14:08:06 +02:00
parent 7879bbdb4b
commit 5779614d26
2 changed files with 93 additions and 1 deletions

View 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 \

View File

@ -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