From 262db65a3873c63d720086dd88c74cef5c6f4d72 Mon Sep 17 00:00:00 2001 From: Moritz Halbritter Date: Tue, 8 Feb 2022 14:09:37 +0100 Subject: [PATCH] Ignore invalid stream types when reading log update events See gh-29675 --- .../platform/docker/LogUpdateEvent.java | 25 ++++++++++++++++-- .../platform/docker/LogUpdateEventTests.java | 10 ++++++- ...og-update-event-invalid-stream-type.stream | Bin 0 -> 91 bytes 3 files changed, 32 insertions(+), 3 deletions(-) create mode 100644 spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/log-update-event-invalid-stream-type.stream diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEvent.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEvent.java index c7a3cffe89..9ed0483139 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEvent.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEvent.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -22,6 +22,8 @@ import java.nio.charset.StandardCharsets; import java.util.function.Consumer; import java.util.regex.Pattern; +import org.springframework.util.StreamUtils; + /** * An update event used to provide log updates. * @@ -80,6 +82,16 @@ public class LogUpdateEvent extends UpdateEvent { consumer.accept(event); } } + catch (IllegalStateException ex) { + // Parsing has failed, abort further parsing + LogUpdateEvent abortedEvent = new LogUpdateEvent(StreamType.STD_ERR, + ex.getMessage().getBytes(StandardCharsets.UTF_8)); + consumer.accept(abortedEvent); + + // At this point, the inputStream is burned, consume it fully to prevent + // further processing + StreamUtils.drain(inputStream); + } finally { inputStream.close(); } @@ -90,12 +102,21 @@ public class LogUpdateEvent extends UpdateEvent { if (header == null) { return null; } - StreamType streamType = StreamType.values()[header[0]]; + + // First byte denotes stream type. 0 = stdin, 1 = stdout, 2 = stderr + byte streamTypeId = header[0]; + if (streamTypeId < 0 || streamTypeId >= StreamType.values().length) { + throw new IllegalStateException("Stream type is out of bounds. Must be >= 0 and < " + + StreamType.values().length + ", but was " + streamTypeId + ". Will abort parsing."); + } + long size = 0; for (int i = 0; i < 4; i++) { size = (size << 8) + (header[i + 4] & 0xff); } byte[] payload = read(inputStream, size); + + StreamType streamType = StreamType.values()[streamTypeId]; return new LogUpdateEvent(streamType, payload); } diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEventTests.java b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEventTests.java index d794c307b8..577eb012dc 100644 --- a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEventTests.java +++ b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/docker/LogUpdateEventTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2020 the original author or authors. + * Copyright 2012-2022 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -53,6 +53,14 @@ class LogUpdateEventTests { assertThat(events.get(2).toString()).isEqualTo(" OpenJDK JRE 11.0.5: Reusing cached layer"); } + @Test + void readSucceedsWhenStreamTypeIsInvalid() throws IOException { + List events = readAll("log-update-event-invalid-stream-type.stream"); + assertThat(events).hasSize(1); + assertThat(events.get(0).toString()) + .isEqualTo("Stream type is out of bounds. Must be >= 0 and < 3, but was 3. Will abort parsing."); + } + private List readAll(String name) throws IOException { List events = new ArrayList<>(); try (InputStream inputStream = getClass().getResourceAsStream(name)) { diff --git a/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/log-update-event-invalid-stream-type.stream b/spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/resources/org/springframework/boot/buildpack/platform/docker/log-update-event-invalid-stream-type.stream new file mode 100644 index 0000000000000000000000000000000000000000..f9ddbfa14e6ab781d438bc9a5fb27385a1900589 GIT binary patch literal 91 zcmW;3yA6Oa3)832k{Ou5c_a}M(8Kgd+>OI;TW>p`_qh9fT-NLCgfd7N k0o5#tP)Q)RwuETD)tF2n;0#ty8gnS@GyE=EXc06weLcVz+5i9m literal 0 HcmV?d00001