You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@johnzon.apache.org by "Romain Manni-Bucau (JIRA)" <ji...@apache.org> on 2018/10/02 13:48:00 UTC

[jira] [Resolved] (JOHNZON-190) Issues when call close method more than twice using Queue as buffer strategy.

     [ https://issues.apache.org/jira/browse/JOHNZON-190?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Romain Manni-Bucau resolved JOHNZON-190.
----------------------------------------
       Resolution: Fixed
    Fix Version/s: 1.1.11

> Issues when call close method more than twice using Queue as buffer strategy.
> -----------------------------------------------------------------------------
>
>                 Key: JOHNZON-190
>                 URL: https://issues.apache.org/jira/browse/JOHNZON-190
>             Project: Johnzon
>          Issue Type: Bug
>          Components: JSON-B
>    Affects Versions: 1.1.10
>            Reporter: Otavio Goncalves de Santana
>            Priority: Major
>             Fix For: 1.1.11
>
>
> Title: Issues when calling the close method more than twice using Queue as a buffer strategy.
>  
> Hello everyone.
>  
> I would like to report a bug within JsonGeneratorImpl. In the JsonGeneratorImpl has the BufferStrategy.BufferProvider<char[]> as an attribute.
> This BufferStrategy.BufferProvider either [put the buffer in the Queue|https://github.com/apache/johnzon/blob/d7a4a2f9de8c39b84fbb8b73b13c6f7f6514a9cf/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java#L466], whose uses the release *method*, and [feed|https://github.com/apache/johnzon/blob/d7a4a2f9de8c39b84fbb8b73b13c6f7f6514a9cf/johnzon-core/src/main/java/org/apache/johnzon/core/JsonGeneratorImpl.java#L72] the buffer using the *newBuffer* method.
>  
> As consequences of this behavior there are two failures:
>  
>  # Waste of memory issue
>  
> The code below, it will put the same value in the queue six times.
> {code:java}
> public class App {
>    public static void main(String[] args) throws IOException {
>        Path path = Paths.get("generated.json");
>        OutputStream out = Files.newOutputStream(path);
>        JsonGenerator jsonGen = Json.createGenerator(out);
>        jsonGen.writeStartObject();
>        jsonGen.write("false", JsonValue.FALSE);
>        jsonGen.write("true", JsonValue.TRUE);
>        jsonGen.writeEnd();
>        jsonGen.close();
>        jsonGen.close();
>        jsonGen.close();
>        jsonGen.close();
>        jsonGen.close();
>        jsonGen.close();
>    }
> }
> {code}
> Doing a malicious code such as below, it will use a huge number of memory.
> {code:java}
> public class App1 {
>    public static void main(String[] args) throws IOException {
>        Path path = Paths.get("generated.json");
>        OutputStream out = Files.newOutputStream(path);
>        JsonGenerator jsonGen = Json.createGenerator(out);
>        jsonGen.writeStartObject();
>        jsonGen.write("false", JsonValue.FALSE);
>        jsonGen.write("true", JsonValue.TRUE);
>        jsonGen.writeEnd();
>        while (true) {
>            jsonGen.close();
>        }
>    }
> }
> {code}
>  # The security issue
> It uses the value in the queue as a buffer; thereby, it is a security failure once a request can read information from another application, thus, an isolation issue.
> {code:java}
> public class App2 {
>    public static void main(String[] args) throws Exception {
>        Path path = Paths.get("generated2.json");
>        OutputStream out = Files.newOutputStream(path);
>        JsonGenerator jsonGen = Json.createGenerator(out);
>        jsonGen.writeStartObject();
>        jsonGen.write("keyA", JsonValue.FALSE);
>        jsonGen.write("keyB", JsonValue.TRUE);
>        jsonGen.writeEnd();
>        jsonGen.close();
>        Path path3 = Paths.get("generated3.json");
>        OutputStream out2 = Files.newOutputStream(path3);
>        JsonGenerator jsonGen2 = Json.createGenerator(out2);
>        jsonGen2.writeStartObject();
>        Field fieldBuffer = jsonGen2.getClass().getDeclaredField("buffer");
>        fieldBuffer.setAccessible(true);
>        char[] buffer = (char[]) fieldBuffer.get(jsonGen);
>        String json = String.valueOf(buffer);
>        System.out.println(json);
>        jsonGen2.flush();
>    }
> }
> {code}
> # Race condition issue:
> As the code below shows, given a mistake of twice close, To class can write using the same buffer, thereby, a write JSON mistake.
> {code:java}
> public class App3 {
>    public static void main(String[] args) throws IOException {
>        Path path = Paths.get("generated.json");
>        OutputStream out = Files.newOutputStream(path);
>        JsonGenerator jsonGen = Json.createGenerator(out);
>        jsonGen.writeStartObject();
>        jsonGen.write("false", JsonValue.FALSE);
>        jsonGen.write("true", JsonValue.TRUE);
>        jsonGen.writeEnd();
>        jsonGen.close();
>        jsonGen.close();
>        Path path2 = Paths.get("generated2.json");
>        OutputStream out2 = Files.newOutputStream(path2);
>        JsonGenerator jsonGen2 = Json.createGenerator(out2);
>        Path path3 = Paths.get("generated3.json");
>        OutputStream out3 = Files.newOutputStream(path3);
>        JsonGenerator jsonGen3 = Json.createGenerator(out3);
>        jsonGen2.writeStartObject();
>        jsonGen2.write("false1", JsonValue.FALSE);
>        jsonGen2.write("true2", JsonValue.TRUE);
>        jsonGen2.writeEnd();
>        jsonGen3.writeStartObject();
>        jsonGen3.write("false3", JsonValue.FALSE);
>        jsonGen3.write("true4", JsonValue.TRUE);
>        jsonGen3.writeEnd();
>        jsonGen2.close();
>        jsonGen3.close();
>    }
> }
> {code}
> Output 
> {code:json}
> Generated.json: {"false":false,"true":true}
> Generated2.json: {"false3":false,"true4":true}
> Generated3.json: {"false3":false,"true4":true}
> {code}



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)