python: Fix crash by leaving struct members intact
Closed, ResolvedPublic

Description

The python bindings tried to parse deprecated functions
out of gpgme.h. This fails for the current gpgme.h in
that it removes an entire field in the key sig struct (_obsolete_class).
Hence, the fields were off by an int and the bindings accessed struct
members via the wrong offset. That caused python program to crash.
At least on 32bit platforms, the crash can be easily triggered by
accessing key.uids[0].signatures. On 64bit platforms the compiler
probably aligns the struct so that the missing 4 bytes are not noticed.

With this change, the python bindings will expose all functions
that gpgme exposes, including the deprecated ones.

Credits go to Justus Winter for debugging and identying the issue.

4tmuelle created this task.Apr 10 2018, 3:30 PM

reproducer

dunno how to attach a patch here... trying to copy it verbatim

  • lang/python/setup.py.in: Copy gpgme.h instead of parsing it. --

The python bindings tried to parse deprecated functions
out of gpgme.h. This fails for the current gpgme.h in
that it removes an entire field in the key sig struct (_obsolete_class).
Hence, the fields were off by an int and the bindings accessed struct
members via the wrong offset. That caused python program to crash.
At least on 32bit platforms, the crash can be easily triggered by
accessing key.uids[0].signatures. On 64bit platforms the compiler
probably aligns the struct so that the missing 4 bytes are not noticed.

With this change, the python bindings will expose all functions
that gpgme exposes, including the deprecated ones.

Credits go to Justus Winter for debugging and identying the issue.

Signed-off-by: Tobias Mueller <muelli@cryptobitch.de>

lang/python/setup.py.in | 19 +------------------
1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/lang/python/setup.py.in b/lang/python/setup.py.in
index f9dda20f..2595073f 100755

  • a/lang/python/setup.py.in

+++ b/lang/python/setup.py.in
@@ -152,25 +152,8 @@ class BuildExtFirstHack(build):

        sink.write(content)
 
def _generate_gpgme_h(self, source_name, sink_name):
  • if up_to_date(source_name, sink_name):
  • return - print("Using gpgme.h from {}".format(source_name)) -
  • deprec_func = re.compile(r'^(.*typedef.*|.*\(.*\)|[^#]+\s+.+)'
  • + r'\s*_GPGME_DEPRECATED(_OUTSIDE_GPGME)?\(.*\);\s*',
  • re.S)
  • line_break = re.compile(';|\\$|\\x0c|^\s*#|{') -
  • with open(sink_name, "w") as sink, open(source_name) as source:
  • text = ''
  • for line in source:
  • text += re.sub(' class ', ' _py_obsolete_class ', line)
  • if line_break.search(line):
  • if not deprec_func.search(text):
  • sink.write(text)
  • text = ''
  • sink.write(text)

+ shutil.copy2(source_name, sink_name)

def _generate_errors_i(self):
werner triaged this task as High priority.
werner closed this task as Resolved.Apr 17 2018, 10:31 AM
werner claimed this task.
werner added a subscriber: werner.

To attach a file use the cloud-with-arrow icon in the edit toolbox.

I took your patch from the mail and pushed it for use in 1.11. Thanks.