Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Python equality operator segfaults for non-set messages (21.2) #10208

Closed
ngg opened this issue Jul 4, 2022 · 4 comments
Closed

Python equality operator segfaults for non-set messages (21.2) #10208

ngg opened this issue Jul 4, 2022 · 4 comments
Assignees
Labels

Comments

@ngg
Copy link
Contributor

ngg commented Jul 4, 2022

What version of protobuf and what language are you using?
Version: 21.2
Language: Python

What operating system (Linux, Windows, ...) and version?
Linux / Windows / macOS all affected

What runtime / compiler are you using (e.g., python version or gcc version)
Python 3.9 / 3.10 both affected

What did you do?

// x.proto
syntax = "proto3";
message A {}
message B {
  A a = 1;
}
# crash.py
import x_pb2
x_pb2.B().a == x_pb2.A()

Steps to reproduce the behavior:

  1. Save the files above
  2. Run protoc --python_out=. x.proto
  3. Run python crash.py

What did you expect to see
Python should not crash

What did you see instead?
Python crashes with a segmentation fault

Stack trace from gdb:

#0  0x00007ffff6dbb30e in _upb_Message_Getexts (msg=0x0, count=0x7fffffffb3a8) at upb/msg.c:116
#1  0x00007ffff6dbb57b in upb_Message_ExtensionCount (msg=0x0) at upb/msg.c:173
#2  0x00007ffff6d8eedb in upb_Message_IsEqual (msg1=0x0, msg2=0x55555595da38, m=0x555555819770) at python/convert.c:339
#3  0x00007ffff6d9842d in PyUpb_Message_IsEqual (m1=0x7ffff68838d0, _m2=0x7ffff6f47ec0) at python/message.c:572
#4  0x00007ffff6d98aeb in PyUpb_Message_RichCompare (_self=0x7ffff68838d0, other=0x7ffff6f47ec0, opid=2) at python/message.c:749

The bug seems to be in upb's python bindings: PyUpb_Message_IsEqual is called which calls PyUpb_Message_GetIfReified for the messages but does not handle null return values and calls upb_Message_IsEqual with a null pointer which also does not handle that case.

@ericsalo
Copy link
Member

ericsalo commented Jul 6, 2022

I cannot reproduce the crash:

$ cat crash.py
import x_pb2
x_pb2.B().a == x_pb2.A()
$ cat x.proto
// x.proto
syntax = "proto3";
message A {}
message B {
A a = 1;
}
$ protoc --version
libprotoc 3.21.2
$ protoc --python_out=. x.proto
$ python3 crash.py
$ python3 --version
Python 3.10.4

@ngg
Copy link
Contributor Author

ngg commented Jul 7, 2022

The protobuf python package must be at least version 4 to use the upb backend by default. Are you sure you're trying with that? We can reproduce this on multiple machines / operating systems.

$ python3
>>> import google.protobuf
>>> google.protobuf.__version__
'4.21.2'
>>> import google.protobuf.internal.api_implementation
>>> google.protobuf.internal.api_implementation.Type()
'upb'

@ericsalo
Copy link
Member

ericsalo commented Jul 7, 2022

Okay I finally have a test case that successfully crashes. Working on a fix now.

copybara-service bot pushed a commit to protocolbuffers/upb that referenced this issue Jul 7, 2022
copybara-service bot pushed a commit to protocolbuffers/upb that referenced this issue Jul 13, 2022
- Fix upb_Arena to correctly handle a NULL alloc pointer
- Fix upb_Encode() to use the arena API instead of the alloc API

Reference: protocolbuffers/protobuf#10208
PiperOrigin-RevId: 459604709
copybara-service bot pushed a commit to protocolbuffers/upb that referenced this issue Jul 13, 2022
also fix upb_Encode() to use the arena API instead of the alloc API

Reference: protocolbuffers/protobuf#10208
PiperOrigin-RevId: 459604709
copybara-service bot pushed a commit to protocolbuffers/upb that referenced this issue Jul 13, 2022
@ericsalo
Copy link
Member

I've just pushed a fix so I am closing this ticket. Please let us know if you continue to see problems. Thank you for pointing this out.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants