Skip to content

Commit

Permalink
upb: fix dereferenced NULL pointer bug in Python FFI
Browse files Browse the repository at this point in the history
protocolbuffers/protobuf#10208

PiperOrigin-RevId: 459604709
  • Loading branch information
ericsalo authored and copybara-github committed Jul 7, 2022
1 parent f96b569 commit a2755f0
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 16 deletions.
43 changes: 27 additions & 16 deletions python/message.c
Original file line number Diff line number Diff line change
Expand Up @@ -556,22 +556,6 @@ static PyObject* PyUpb_Message_NewStub(PyObject* parent, const upb_FieldDef* f,
return &msg->ob_base;
}

static bool PyUpb_Message_IsEqual(PyUpb_Message* m1, PyObject* _m2) {
PyUpb_Message* m2 = (void*)_m2;
if (m1 == m2) return true;
if (!PyObject_TypeCheck(_m2, m1->ob_base.ob_type)) {
return false;
}
const upb_MessageDef* m1_msgdef = _PyUpb_Message_GetMsgdef(m1);
#ifndef NDEBUG
const upb_MessageDef* m2_msgdef = _PyUpb_Message_GetMsgdef(m2);
assert(m1_msgdef == m2_msgdef);
#endif
const upb_Message* m1_msg = PyUpb_Message_GetIfReified((PyObject*)m1);
const upb_Message* m2_msg = PyUpb_Message_GetIfReified(_m2);
return upb_Message_IsEqual(m1_msg, m2_msg, m1_msgdef);
}

static const upb_FieldDef* PyUpb_Message_InitAsMsg(PyUpb_Message* m,
upb_Arena* arena) {
const upb_FieldDef* f = PyUpb_Message_GetFieldDef(m);
Expand Down Expand Up @@ -659,6 +643,33 @@ static void PyUpb_Message_Reify(PyUpb_Message* self, const upb_FieldDef* f,
PyUpb_Message_SyncSubobjs(self);
}

static bool PyUpb_Message_IsEqual(PyUpb_Message* m1, PyObject* _m2) {
PyUpb_Message* m2 = (void*)_m2;
if (m1 == m2) return true;
if (!PyObject_TypeCheck(_m2, m1->ob_base.ob_type)) {
return false;
}
const upb_MessageDef* m1_msgdef = _PyUpb_Message_GetMsgdef(m1);
#ifndef NDEBUG
const upb_MessageDef* m2_msgdef = _PyUpb_Message_GetMsgdef(m2);
assert(m1_msgdef == m2_msgdef);
#endif

const upb_Message* m1_msg = PyUpb_Message_GetIfReified((PyObject*)m1);
if (!m1_msg) {
PyUpb_Message_Reify(m1, PyUpb_Message_GetFieldDef(m1), NULL);
m1_msg = PyUpb_Message_GetIfReified((PyObject*)m1);
}

const upb_Message* m2_msg = PyUpb_Message_GetIfReified(_m2);
if (!m2_msg) {
PyUpb_Message_Reify(m2, PyUpb_Message_GetFieldDef(m2), NULL);
m2_msg = PyUpb_Message_GetIfReified((PyObject*)m2);
}

return upb_Message_IsEqual(m1_msg, m2_msg, m1_msgdef);
}

/*
* PyUpb_Message_SyncSubobjs()
*
Expand Down
2 changes: 2 additions & 0 deletions python/pb_unit_tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ load(":pyproto_test_wrapper.bzl", "pyproto_test_wrapper")

licenses(["notice"])

pyproto_test_wrapper(name = "crash_test")

pyproto_test_wrapper(name = "descriptor_database_test")

pyproto_test_wrapper(name = "descriptor_pool_test")
Expand Down
30 changes: 30 additions & 0 deletions python/pb_unit_tests/crash_test_wrapper.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Copyright (c) 2009-2021, Google LLC
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# * Neither the name of Google LLC nor the
# names of its contributors may be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL Google LLC BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

from google.protobuf.internal.crash_test import *
import unittest

if __name__ == '__main__':
unittest.main(verbosity=2)

0 comments on commit a2755f0

Please sign in to comment.