提交 5ae2d9c2 编写于 作者: L Ladi Prosek 提交者: John Ferlan

hyperv: Escape WQL queries

The code was vulnerable to SQL injection. Likely not a security issue due to
WMI SQL and other constraints but still lame. For example:

  virsh # dominfo \"
  error: failed to get domain '"'
  error: internal error: SOAP fault during enumeration: code 's:Sender', subcode
  'n:CannotProcessFilter', reason 'The data source could not process the filter.
  The filter might be missing or it might be invalid. Change the filter and try
  the request again.  ', detail 'The WS-Management service cannot process the
  request. The WQL query is invalid. '

This commit fixes the Hyper-V driver by escaping all WMI SQL string parameters.

The same command with the fix:

  virsh # dominfo \"
  error: failed to get domain '"'
  error: Domain not found: No domain with name "
Signed-off-by: NLadi Prosek <lprosek@redhat.com>
上级 bb8c2a76
...@@ -301,12 +301,12 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info) ...@@ -301,12 +301,12 @@ hypervNodeGetInfo(virConnectPtr conn, virNodeInfoPtr info)
} }
/* Get Win32_Processor list */ /* Get Win32_Processor list */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Win32_ComputerSystem.Name=\"%s\"} " "{Win32_ComputerSystem.Name=\"%s\"} "
"where AssocClass = Win32_ComputerSystemProcessor " "where AssocClass = Win32_ComputerSystemProcessor "
"ResultClass = Win32_Processor", "ResultClass = Win32_Processor",
computerSystem->data.common->Name); computerSystem->data.common->Name);
if (hypervGetWin32ProcessorList(priv, &query, &processorList) < 0) if (hypervGetWin32ProcessorList(priv, &query, &processorList) < 0)
goto cleanup; goto cleanup;
...@@ -493,7 +493,7 @@ hypervDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid) ...@@ -493,7 +493,7 @@ hypervDomainLookupByUUID(virConnectPtr conn, const unsigned char *uuid)
virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT); virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
virBufferAddLit(&query, "where "); virBufferAddLit(&query, "where ");
virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL); virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
virBufferAsprintf(&query, "and Name = \"%s\"", uuid_string); virBufferEscapeSQL(&query, "and Name = \"%s\"", uuid_string);
if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0)
goto cleanup; goto cleanup;
...@@ -525,7 +525,7 @@ hypervDomainLookupByName(virConnectPtr conn, const char *name) ...@@ -525,7 +525,7 @@ hypervDomainLookupByName(virConnectPtr conn, const char *name)
virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT); virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_SELECT);
virBufferAddLit(&query, "where "); virBufferAddLit(&query, "where ");
virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL); virBufferAddLit(&query, MSVM_COMPUTERSYSTEM_WQL_VIRTUAL);
virBufferAsprintf(&query, "and ElementName = \"%s\"", name); virBufferEscapeSQL(&query, "and ElementName = \"%s\"", name);
if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0) if (hypervGetMsvmComputerSystemList(priv, &query, &computerSystem) < 0)
goto cleanup; goto cleanup;
...@@ -673,13 +673,13 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) ...@@ -673,13 +673,13 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
goto cleanup; goto cleanup;
/* Get Msvm_VirtualSystemSettingData */ /* Get Msvm_VirtualSystemSettingData */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\"," "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
"Name=\"%s\"} " "Name=\"%s\"} "
"where AssocClass = Msvm_SettingsDefineState " "where AssocClass = Msvm_SettingsDefineState "
"ResultClass = Msvm_VirtualSystemSettingData", "ResultClass = Msvm_VirtualSystemSettingData",
uuid_string); uuid_string);
if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
&virtualSystemSettingData) < 0) { &virtualSystemSettingData) < 0) {
...@@ -695,12 +695,12 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) ...@@ -695,12 +695,12 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
} }
/* Get Msvm_ProcessorSettingData */ /* Get Msvm_ProcessorSettingData */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
"where AssocClass = Msvm_VirtualSystemSettingDataComponent " "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
"ResultClass = Msvm_ProcessorSettingData", "ResultClass = Msvm_ProcessorSettingData",
virtualSystemSettingData->data.common->InstanceID); virtualSystemSettingData->data.common->InstanceID);
if (hypervGetMsvmProcessorSettingDataList(priv, &query, if (hypervGetMsvmProcessorSettingDataList(priv, &query,
&processorSettingData) < 0) { &processorSettingData) < 0) {
...@@ -716,12 +716,12 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info) ...@@ -716,12 +716,12 @@ hypervDomainGetInfo(virDomainPtr domain, virDomainInfoPtr info)
} }
/* Get Msvm_MemorySettingData */ /* Get Msvm_MemorySettingData */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
"where AssocClass = Msvm_VirtualSystemSettingDataComponent " "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
"ResultClass = Msvm_MemorySettingData", "ResultClass = Msvm_MemorySettingData",
virtualSystemSettingData->data.common->InstanceID); virtualSystemSettingData->data.common->InstanceID);
if (hypervGetMsvmMemorySettingDataList(priv, &query, if (hypervGetMsvmMemorySettingDataList(priv, &query,
&memorySettingData) < 0) { &memorySettingData) < 0) {
...@@ -810,13 +810,13 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) ...@@ -810,13 +810,13 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
goto cleanup; goto cleanup;
/* Get Msvm_VirtualSystemSettingData */ /* Get Msvm_VirtualSystemSettingData */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\"," "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
"Name=\"%s\"} " "Name=\"%s\"} "
"where AssocClass = Msvm_SettingsDefineState " "where AssocClass = Msvm_SettingsDefineState "
"ResultClass = Msvm_VirtualSystemSettingData", "ResultClass = Msvm_VirtualSystemSettingData",
uuid_string); uuid_string);
if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query, if (hypervGetMsvmVirtualSystemSettingDataList(priv, &query,
&virtualSystemSettingData) < 0) { &virtualSystemSettingData) < 0) {
...@@ -832,12 +832,12 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) ...@@ -832,12 +832,12 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
} }
/* Get Msvm_ProcessorSettingData */ /* Get Msvm_ProcessorSettingData */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
"where AssocClass = Msvm_VirtualSystemSettingDataComponent " "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
"ResultClass = Msvm_ProcessorSettingData", "ResultClass = Msvm_ProcessorSettingData",
virtualSystemSettingData->data.common->InstanceID); virtualSystemSettingData->data.common->InstanceID);
if (hypervGetMsvmProcessorSettingDataList(priv, &query, if (hypervGetMsvmProcessorSettingDataList(priv, &query,
&processorSettingData) < 0) { &processorSettingData) < 0) {
...@@ -853,12 +853,12 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags) ...@@ -853,12 +853,12 @@ hypervDomainGetXMLDesc(virDomainPtr domain, unsigned int flags)
} }
/* Get Msvm_MemorySettingData */ /* Get Msvm_MemorySettingData */
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} " "{Msvm_VirtualSystemSettingData.InstanceID=\"%s\"} "
"where AssocClass = Msvm_VirtualSystemSettingDataComponent " "where AssocClass = Msvm_VirtualSystemSettingDataComponent "
"ResultClass = Msvm_MemorySettingData", "ResultClass = Msvm_MemorySettingData",
virtualSystemSettingData->data.common->InstanceID); virtualSystemSettingData->data.common->InstanceID);
if (hypervGetMsvmMemorySettingDataList(priv, &query, if (hypervGetMsvmMemorySettingDataList(priv, &query,
&memorySettingData) < 0) { &memorySettingData) < 0) {
...@@ -1397,7 +1397,7 @@ hypervDomainSendKey(virDomainPtr domain, unsigned int codeset, ...@@ -1397,7 +1397,7 @@ hypervDomainSendKey(virDomainPtr domain, unsigned int codeset,
if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0) if (hypervMsvmComputerSystemFromDomain(domain, &computerSystem) < 0)
goto cleanup; goto cleanup;
virBufferAsprintf(&query, virBufferEscapeSQL(&query,
"associators of " "associators of "
"{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\"," "{Msvm_ComputerSystem.CreationClassName=\"Msvm_ComputerSystem\","
"Name=\"%s\"} " "Name=\"%s\"} "
...@@ -1534,7 +1534,7 @@ hypervDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory, ...@@ -1534,7 +1534,7 @@ hypervDomainSetMemoryFlags(virDomainPtr domain, unsigned long memory,
} }
virBufferAddLit(&eprQuery, MSVM_COMPUTERSYSTEM_WQL_SELECT); virBufferAddLit(&eprQuery, MSVM_COMPUTERSYSTEM_WQL_SELECT);
virBufferAsprintf(&eprQuery, "where Name = \"%s\"", uuid_string); virBufferEscapeSQL(&eprQuery, "where Name = \"%s\"", uuid_string);
if (hypervAddEprParam(params, "ComputerSystem", priv, &eprQuery, if (hypervAddEprParam(params, "ComputerSystem", priv, &eprQuery,
Msvm_ComputerSystem_WmiInfo) < 0) Msvm_ComputerSystem_WmiInfo) < 0)
......
...@@ -895,7 +895,7 @@ hypervInvokeMethod(hypervPrivate *priv, hypervInvokeParamsListPtr params, ...@@ -895,7 +895,7 @@ hypervInvokeMethod(hypervPrivate *priv, hypervInvokeParamsListPtr params,
*/ */
while (!completed && timeout >= 0) { while (!completed && timeout >= 0) {
virBufferAddLit(&query, MSVM_CONCRETEJOB_WQL_SELECT); virBufferAddLit(&query, MSVM_CONCRETEJOB_WQL_SELECT);
virBufferAsprintf(&query, "where InstanceID = \"%s\"", instanceID); virBufferEscapeSQL(&query, "where InstanceID = \"%s\"", instanceID);
if (hypervGetMsvmConcreteJobList(priv, &query, &job) < 0 if (hypervGetMsvmConcreteJobList(priv, &query, &job) < 0
|| job == NULL) || job == NULL)
......
...@@ -1384,6 +1384,7 @@ virBufferEscapeN; ...@@ -1384,6 +1384,7 @@ virBufferEscapeN;
virBufferEscapeRegex; virBufferEscapeRegex;
virBufferEscapeSexpr; virBufferEscapeSexpr;
virBufferEscapeShell; virBufferEscapeShell;
virBufferEscapeSQL;
virBufferEscapeString; virBufferEscapeString;
virBufferFreeAndReset; virBufferFreeAndReset;
virBufferGetIndent; virBufferGetIndent;
......
...@@ -574,6 +574,26 @@ virBufferEscapeRegex(virBufferPtr buf, ...@@ -574,6 +574,26 @@ virBufferEscapeRegex(virBufferPtr buf,
virBufferEscape(buf, '\\', "^$.|?*+()[]{}\\", format, str); virBufferEscape(buf, '\\', "^$.|?*+()[]{}\\", format, str);
} }
/**
* virBufferEscapeSQL:
* @buf: the buffer to append to
* @format: a printf like format string but with only one %s parameter
* @str: the string argument which needs to be escaped
*
* Do a formatted print with a single string to a buffer. The @str is
* escaped to prevent SQL injection (format is expected to contain \"%s\").
* Auto indentation may be applied.
*/
void
virBufferEscapeSQL(virBufferPtr buf,
const char *format,
const char *str)
{
virBufferEscape(buf, '\\', "'\"\\", format, str);
}
/** /**
* virBufferEscape: * virBufferEscape:
* @buf: the buffer to append to * @buf: the buffer to append to
......
...@@ -93,6 +93,9 @@ void virBufferEscapeSexpr(virBufferPtr buf, const char *format, ...@@ -93,6 +93,9 @@ void virBufferEscapeSexpr(virBufferPtr buf, const char *format,
void virBufferEscapeRegex(virBufferPtr buf, void virBufferEscapeRegex(virBufferPtr buf,
const char *format, const char *format,
const char *str); const char *str);
void virBufferEscapeSQL(virBufferPtr buf,
const char *format,
const char *str);
void virBufferEscapeShell(virBufferPtr buf, const char *str); void virBufferEscapeShell(virBufferPtr buf, const char *str);
void virBufferURIEncodeString(virBufferPtr buf, const char *str); void virBufferURIEncodeString(virBufferPtr buf, const char *str);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册