Fix bugs found by static analysis (#85705)

These PR fixes a number of bugs found by Svace static analyzer:

1. DEREF_AFTER_FREE at qnnpack_utils.h:
Pointer '&convolution->zero_buffer' is dereferenced at qnnpack_utils.h:258 after the referenced memory was deallocated at operator-delete.c:25 by passing as 1st parameter to function 'pytorch_qnnp_delete_operator' at qnnpack_utils.h:251.
2. DEREF_AFTER_NULL at impl.cpp:
After having been compared to NULL value at impl.cpp:1892, pointer 'schema' is passed as 2nd parameter in call to function 'c10::operator<<' at impl.cpp:1921, where it is dereferenced at function_schema_inl.h:13.
3. DEREF_OF_NULL  at stmt.h:
After having been compared to NULL value at stmt.h:744, pointer 'body->_M_ptr' is passed in call to function 'torch::jit::tensorexpr::malformed_input::malformed_input' at stmt.h:745, where it is dereferenced at exceptions.h:67.
4. DEREF_OF_NULL  at loopnest.h:
Pointer 'f->ptr' that can have only NULL value (checked at loopnest.cpp:1482), is passed in call to function 'torch::jit::tensorexpr::malformed_input::malformed_input' at loopnest.cpp:1483, where it is dereferenced at exceptions.h:67.
This is the same error as 3: forwarding a nullptr to malformed_input().
4. TAINTED_INT.LOOP in python_arg_parser:
Integer value 'this->size' obtained from untrusted source at python_arg_parser.cpp:118 without checking its bounds is used as a loop bound at python_arg_parser.cpp:698 by calling function 'torch::FunctionParameter::set_default_str' at python_arg_parser.cpp:133.
Pull Request resolved: https://github.com/pytorch/pytorch/pull/85705
Approved by: https://github.com/kit1980
This commit is contained in:
Daniil Kutz
2022-10-28 23:51:53 +00:00
committed by PyTorch MergeBot
parent 376acf7625
commit 1eba3f220e
5 changed files with 15 additions and 13 deletions

View File

@ -272,8 +272,9 @@ struct PackedConvWeightsQnnp : public ConvPackedParamsBase<kSpatialDim> {
void* zero_buffer = malloc(zero_size);
if (zero_buffer == nullptr) {
pytorch_qnnp_delete_operator(convolution);
pytorch_qnnp_log_error(
"failed to allocate %zu bytes for zero padding", zero_size);
TORCH_INTERNAL_ASSERT(
false, "failed to allocate %zu bytes for zero padding",
zero_size);
}
// Need to set to input zero point
// memset(zero_buffer, input_zero_point, zero_size);

View File

@ -2062,7 +2062,7 @@ bool ProcessedNode::verify_inputs_dont_overlap_outputs(bool force_check) const {
bool skip_check = !schema ||
((schema->is_mutable() || !fn_->checkMemoryOverlap()) &&
num_outputs() == 1);
if (!force_check && skip_check) {
if (!schema || (!force_check && skip_check)) {
if (!schema) {
VLOG(2) << "Detected that op schema is null";
return true;

View File

@ -1506,12 +1506,12 @@ void LoopNest::sliceHead(ForPtr f, int factor, ForPtr* head, ForPtr* tail) {
}
if (!f) {
throw malformed_input("sliceHead attempted on null loop", f);
throw malformed_input("sliceHead attempted on null loop");
}
BlockPtr p = to<Block>(f->get_parent());
if (!p) {
throw malformed_input("sliceHead attempted on loop with no parent", p);
throw malformed_input("sliceHead attempted on loop with no parent");
}
ExprPtr head_end = alloc<Min>(
@ -1546,12 +1546,12 @@ void LoopNest::sliceTail(ForPtr f, int factor, ForPtr* head, ForPtr* tail) {
}
if (!f) {
throw malformed_input("sliceTail attempted on null loop", f);
throw malformed_input("sliceTail attempted on null loop");
}
BlockPtr p = to<Block>(f->get_parent());
if (!p) {
throw malformed_input("sliceTail attempted on loop with no parent", p);
throw malformed_input("sliceTail attempted on loop with no parent");
}
ExprPtr tail_start = alloc<Max>(
@ -1585,12 +1585,12 @@ void LoopNest::splitWithTail(
ForPtr* inner,
ForPtr* tail) {
if (!f) {
throw malformed_input("splitWithTail attempted on null loop", f);
throw malformed_input("splitWithTail attempted on null loop");
}
BlockPtr p = to<Block>(f->get_parent());
if (!p) {
throw malformed_input("splitWithTail attempted on loop with no parent", p);
throw malformed_input("splitWithTail attempted on loop with no parent");
}
// Normalize the loop to simplify start and stop bound computation

View File

@ -754,13 +754,13 @@ class TORCH_API For : public StmtNode<For> {
stop_(stop),
loop_options_(std::move(loop_options)) {
if (!var) {
throw malformed_input("invalid Var in For loop", var);
throw malformed_input("invalid Var in For loop");
} else if (!start) {
throw malformed_input("invalid Start in For loop", start);
throw malformed_input("invalid Start in For loop");
} else if (!stop) {
throw malformed_input("invalid Stop in For loop", stop);
throw malformed_input("invalid Stop in For loop");
} else if (!body || body->get_parent()) {
throw malformed_input("invalid Body in For loop", body);
throw malformed_input("invalid Body in For loop");
}
BlockPtr b = to<Block>(body);

View File

@ -931,6 +931,7 @@ static inline std::vector<int64_t> parse_intlist_args(
// case 1. s is an int (e.g., s=2)
if (s[0] != '{') {
TORCH_CHECK(size > 0, "Incorrect size of IntArrayRef: ", size);
return std::vector<int64_t>(size, std::stol(s));
}