YARN-9718. Fixed yarn.service.am.java.opts shell injection. Contributed by Eric Yang

This commit is contained in:
Billie Rinaldi 2019-09-05 12:49:16 -07:00
parent 72d8b92ba5
commit 2e2e5401f2
4 changed files with 22 additions and 0 deletions

View File

@ -1203,6 +1203,9 @@ private String buildCommandLine(Service app, Configuration conf,
jvmOpts += DEFAULT_AM_JVM_XMX; jvmOpts += DEFAULT_AM_JVM_XMX;
} }
// validate possible command injection.
ServiceApiUtil.validateJvmOpts(jvmOpts);
CLI.setJVMOpts(jvmOpts); CLI.setJVMOpts(jvmOpts);
if (hasSliderAMLog4j) { if (hasSliderAMLog4j) {
CLI.sysprop(SYSPROP_LOG4J_CONFIGURATION, YARN_SERVICE_LOG4J_FILENAME); CLI.sysprop(SYSPROP_LOG4J_CONFIGURATION, YARN_SERVICE_LOG4J_FILENAME);

View File

@ -127,4 +127,5 @@ public interface RestApiErrorMessages {
" not contain a hostname."; " not contain a hostname.";
String ERROR_KERBEROS_PRINCIPAL_MISSING = "Kerberos principal or keytab is" + String ERROR_KERBEROS_PRINCIPAL_MISSING = "Kerberos principal or keytab is" +
" missing."; " missing.";
String ERROR_JVM_OPTS = "Invalid character in yarn.service.am.java.opts.";
} }

View File

@ -64,6 +64,8 @@
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static org.apache.hadoop.yarn.service.exceptions.RestApiErrorMessages.ERROR_COMP_DOES_NOT_NEED_UPGRADE; import static org.apache.hadoop.yarn.service.exceptions.RestApiErrorMessages.ERROR_COMP_DOES_NOT_NEED_UPGRADE;
import static org.apache.hadoop.yarn.service.exceptions.RestApiErrorMessages.ERROR_COMP_INSTANCE_DOES_NOT_NEED_UPGRADE; import static org.apache.hadoop.yarn.service.exceptions.RestApiErrorMessages.ERROR_COMP_INSTANCE_DOES_NOT_NEED_UPGRADE;
@ -246,6 +248,16 @@ public static void validateAndResolveService(Service service,
} }
} }
public static void validateJvmOpts(String jvmOpts)
throws IllegalArgumentException {
Pattern pattern = Pattern.compile("[!~#?@*&%${}()<>\\[\\]|\"\\/,`;]");
Matcher matcher = pattern.matcher(jvmOpts);
if (matcher.find()) {
throw new IllegalArgumentException(
RestApiErrorMessages.ERROR_JVM_OPTS);
}
}
public static void validateKerberosPrincipal( public static void validateKerberosPrincipal(
KerberosPrincipal kerberosPrincipal) throws IOException { KerberosPrincipal kerberosPrincipal) throws IOException {
if (!StringUtils.isEmpty(kerberosPrincipal.getPrincipalName())) { if (!StringUtils.isEmpty(kerberosPrincipal.getPrincipalName())) {

View File

@ -766,6 +766,12 @@ public void run() {
Assert.assertTrue(thread.isAlive()); Assert.assertTrue(thread.isAlive());
} }
@Test(expected = IllegalArgumentException.class)
public void testJvmOpts() {
String jvmOpts = "`ping -c 3 example.com`";
ServiceApiUtil.validateJvmOpts(jvmOpts);
}
public static Service createExampleApplication() { public static Service createExampleApplication() {
Service exampleApp = new Service(); Service exampleApp = new Service();