Skip to content

Commit 96dc83d

Browse files
committed
Modify validation logic to use white list instead of blacklist
1 parent 39e20a3 commit 96dc83d

File tree

1 file changed

+33
-34
lines changed

1 file changed

+33
-34
lines changed

server/src/main/java/com/cloud/vm/UserVmManagerImpl.java

Lines changed: 33 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -526,14 +526,14 @@ public class UserVmManagerImpl extends ManagerBase implements UserVmManager, Vir
526526
private static final ConfigKey<Boolean> EnableAdditionalVmConfig = new ConfigKey<>("Advanced", Boolean.class,
527527
"enable.additional.vm.configuration", "false", "allow additional arbitrary configuration to vm", true, ConfigKey.Scope.Account);
528528

529-
private static final ConfigKey<String> KvmAdditionalConfigBlackList = new ConfigKey<>("Advanced", String.class,
530-
"additional.vm.configuration.black.list.kvm", "name, uuid, memory, currentMemory", "Comma separated list of disallowed additional configuration options.", true);
529+
private static final ConfigKey<String> KvmAdditionalConfigAllowList = new ConfigKey<>("Advanced", String.class,
530+
"allow.additional.vm.configuration.list.kvm", "memoryBacking", "Comma separated list of allowed additional configuration options.", true);
531531

532-
private static final ConfigKey<String> XenServerAdditionalConfigBlackList = new ConfigKey<>("Advanced", String.class,
533-
"additional.vm.configuration.black.list.xenserver", "is-a-template, memory-static-max, memory-dynamic-max, memory-dynamic-min, memory-static-min", "Comma separated list of disallowed additional configuration options", true);
532+
private static final ConfigKey<String> XenServerAdditionalConfigAllowList = new ConfigKey<>("Advanced", String.class,
533+
"allow.additional.vm.configuration.list.xenserver", "HVM-boot-policy, PV-bootloader, PV-args", "Comma separated list of allowed additional configuration options", true);
534534

535-
private static final ConfigKey<String> VmwareAdditionalConfigBlackList = new ConfigKey<>("Advanced", String.class,
536-
"additional.vm.configuration.black.list.vmware", "guestOS, displayName, virtualHW.version, migrate.hostLog, nvram", "Comma separated list of disallowed additional configuration options.", true);
535+
private static final ConfigKey<String> VmwareAdditionalConfigAllowList = new ConfigKey<>("Advanced", String.class,
536+
"allow.additional.vm.configuration.list.vmware", "hypervisor.cpuid.v0", "Comma separated list of allowed additional configuration options.", true);
537537

538538
private static final ConfigKey<Boolean> VmDestroyForcestop = new ConfigKey<Boolean>("Advanced", Boolean.class, "vm.destroy.forcestop", "false",
539539
"On destroy, force-stop takes this value ", true);
@@ -4924,28 +4924,26 @@ public UserVm createVirtualMachine(DeployVMCmd cmd) throws InsufficientCapacityE
49244924

49254925
/**
49264926
* Persist extra configuration data in the user_vm_details table as key/value pair
4927-
*
49284927
* @param decodedUrl String consisting of the extra config data to appended onto the vmx file for VMware instances
4929-
* @param vm
49304928
*/
49314929
protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) {
49324930
boolean isValidConfig = isValidKeyValuePair(decodedUrl);
49334931
if (isValidConfig) {
49344932
String[] extraConfigs = decodedUrl.split("\\r?\\n");
49354933
for (String cfg : extraConfigs) {
49364934
// Validate cfg against unsupported operations set by admin here
4937-
String[] blackList = VmwareAdditionalConfigBlackList.value().split(",");
4938-
boolean isValidAgainstBlacklistedCfg = isValidXenOrVmwareConfiguration(cfg, blackList);
4935+
String[] allowedKeyList = VmwareAdditionalConfigAllowList.value().split(",");
4936+
boolean validXenOrVmwareConfiguration = isValidXenOrVmwareConfiguration(cfg, allowedKeyList);
49394937
String[] paramArray = cfg.split("=");
4940-
if (isValidAgainstBlacklistedCfg && paramArray.length == 2) {
4938+
if (validXenOrVmwareConfiguration && paramArray.length == 2) {
49414939
try {
49424940
userVmDetailsDao.addDetail(vm.getId(), paramArray[0].trim(), paramArray[1].trim(), true);
49434941
} catch (ArrayIndexOutOfBoundsException e) {
49444942
throw new CloudRuntimeException("Issue occurred during parsing of:" + cfg);
49454943
}
49464944

49474945
} else {
4948-
throw new CloudRuntimeException("Extra config " + cfg + " contains a blacklisted key operations by Root admin");
4946+
throw new CloudRuntimeException("Extra config " + cfg + " is not on the list of allowed keys for VMware hypervisor hosts.");
49494947
}
49504948
}
49514949
} else {
@@ -4960,7 +4958,6 @@ protected void persistExtraConfigVmware(String decodedUrl, UserVm vm) {
49604958
*
49614959
* @param decodedUrl A string containing extra configuration settings as key/value pairs seprated by newline escape character
49624960
* e.x PV-bootloader=pygrub\nPV-args=console\nHV-Boot-policy=""
4963-
* @param vm
49644961
*/
49654962
protected void persistExtraConfigXenServer(String decodedUrl, UserVm vm) {
49664963
boolean isValidConfig = isValidKeyValuePair(decodedUrl);
@@ -4970,9 +4967,9 @@ protected void persistExtraConfigXenServer(String decodedUrl, UserVm vm) {
49704967
String extraConfigKey = ApiConstants.EXTRA_CONFIG + "-";
49714968
for (String cfg : extraConfigs) {
49724969
// Validate cfg against unsupported operations set by admin here
4973-
String[] blackList = XenServerAdditionalConfigBlackList.value().split(",");
4974-
boolean isValidAgainstBlacklistedCfg = isValidXenOrVmwareConfiguration(cfg, blackList);
4975-
if (isValidAgainstBlacklistedCfg) {
4970+
String[] allowedKeyList = XenServerAdditionalConfigAllowList.value().split(",");
4971+
boolean validXenOrVmwareConfiguration = isValidXenOrVmwareConfiguration(cfg, allowedKeyList);
4972+
if (validXenOrVmwareConfiguration) {
49764973
userVmDetailsDao.addDetail(vm.getId(), extraConfigKey + String.valueOf(i), cfg, true);
49774974
i++;
49784975
} else {
@@ -5011,29 +5008,34 @@ protected boolean isValidKeyValuePair(String decodedUrl) {
50115008
return matcher.matches();
50125009
}
50135010

5014-
protected boolean isValidXenOrVmwareConfiguration(String cfg, String[] blackList) {
5011+
/**
5012+
* Validates key/value pair strings passed as extra configuration for XenServer and Vmware
5013+
* @param cfg configuration key-value pair
5014+
* @param allowedKeyList list of allowed configuration keys for XenServer and VMware
5015+
* @return
5016+
*/
5017+
protected boolean isValidXenOrVmwareConfiguration(String cfg, String[] allowedKeyList) {
50155018
// This should be of minimum length 1
50165019
// Value is ignored in case it is empty
50175020
String[] cfgKeyValuePair = cfg.split("=");
50185021
if (cfgKeyValuePair.length >= 1) {
5019-
for (String diallowedKey : blackList) {
5020-
if (cfgKeyValuePair[0].equalsIgnoreCase(diallowedKey.trim())) {
5021-
return false;
5022+
for (String allowedKey : allowedKeyList) {
5023+
if (cfgKeyValuePair[0].equalsIgnoreCase(allowedKey.trim())) {
5024+
return true;
50225025
}
50235026
}
50245027
} else {
50255028
String msg = String.format("An incorrect configuration %s has been passed", cfg);
50265029
throw new CloudRuntimeException(msg);
50275030
}
5028-
return true;
5031+
return false;
50295032
}
50305033

50315034
/**
50325035
* Persist extra configuration data on KVM
50335036
* persisted in the user_vm_details DB as extraconfig-1, and so on depending on the number of configurations
50345037
* For KVM, extra config is passed as XML
5035-
*
5036-
* @param decodedUrl
5038+
* @param decodedUrl string containing xml configuration to be persisted into user_vm_details table
50375039
* @param vm
50385040
*/
50395041
protected void persistExtraConfigKvm(String decodedUrl, UserVm vm) {
@@ -5061,24 +5063,23 @@ protected void persistExtraConfigKvm(String decodedUrl, UserVm vm) {
50615063
* This method is called by the persistExtraConfigKvm
50625064
* Validates passed extra configuration data for KVM and validates against blacklist of unwanted commands
50635065
* controlled by Root admin
5064-
*
5065-
* @param decodedUrl
5066+
* @param decodedUrl string containing xml configuration to be validated
50665067
*/
50675068
protected void validateKvmExtraConfig(String decodedUrl) {
5068-
String[] configOptionBlackList = KvmAdditionalConfigBlackList.value().split(",");
5069+
String[] allowedConfigOptionList = KvmAdditionalConfigAllowList.value().split(",");
50695070
String msg = "An invalid extra configuration option has been supplied: ";
5070-
// Skip blacklist validation for DPDK
5071+
// Skip allowed keys validation validation for DPDK
50715072
if (!decodedUrl.contains(":")) {
50725073
try {
50735074
DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
50745075
InputSource src = new InputSource();
50755076
src.setCharacterStream(new StringReader(String.format("<config>\n%s\n</config>", decodedUrl)));
50765077
Document doc = builder.parse(src);
50775078
doc.getDocumentElement().normalize();
5078-
for (String tag : configOptionBlackList) {
5079+
for (String tag : allowedConfigOptionList) {
50795080
NodeList nodeList = doc.getElementsByTagName(tag.trim());
5080-
// Node list should be empty to show blacklisted command is not contained in passed XML
5081-
if (nodeList.getLength() != 0) {
5081+
// Node list should not be empty to show that allowed command is contained in passed XML
5082+
if (nodeList.getLength() == 0) {
50825083
throw new CloudRuntimeException(msg + tag);
50835084
}
50845085
}
@@ -5090,8 +5091,6 @@ protected void validateKvmExtraConfig(String decodedUrl) {
50905091

50915092
/**
50925093
* Adds extra config data to guest VM instances
5093-
*
5094-
* @param vm
50955094
* @param extraConfig Extra Configuration settings to be added in UserVm instances for KVM, XenServer and VMware
50965095
*/
50975096
protected void addExtraConfig(UserVm vm, String extraConfig) {
@@ -6673,8 +6672,8 @@ public String getConfigComponentName() {
66736672
@Override
66746673
public ConfigKey<?>[] getConfigKeys() {
66756674
return new ConfigKey<?>[] {EnableDynamicallyScaleVm, AllowUserExpungeRecoverVm, VmIpFetchWaitInterval, VmIpFetchTrialMax, VmIpFetchThreadPoolMax,
6676-
VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, KvmAdditionalConfigBlackList,
6677-
XenServerAdditionalConfigBlackList, VmwareAdditionalConfigBlackList};
6675+
VmIpFetchTaskWorkers, AllowDeployVmIfGivenHostFails, EnableAdditionalVmConfig, KvmAdditionalConfigAllowList,
6676+
XenServerAdditionalConfigAllowList, VmwareAdditionalConfigAllowList};
66786677
}
66796678

66806679
@Override

0 commit comments

Comments
 (0)