93 lines
3.1 KiB
Diff
93 lines
3.1 KiB
Diff
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
|