From c6d358d4c6926638fe9d5194e3da112c2750c6a4 Mon Sep 17 00:00:00 2001 From: Ben Nemec Date: Tue, 8 Jan 2019 23:59:10 +0000 Subject: [PATCH] Define types for C calls in netlink_lib Previously this was not done, which meant all arguments were assumed to be ints. As long as we didn't get any large pointer addresses this worked fine, but for some reason the addition of threading to oslo.privsep triggered larger addresses that were then truncated. This caused segfaults in the underlying C library because we were passing it invalid pointers. This change sets argument and return types for all of the calls that are used in the module. Change-Id: I9dbbb01eac8cf7cded7794f8ba69797d6357eeec Closes-Bug: 1810518 --- neutron/privileged/agent/linux/netlink_lib.py | 37 ++++++++++++++++++- 1 file changed, 36 insertions(+), 1 deletion(-) diff --git a/neutron/privileged/agent/linux/netlink_lib.py b/neutron/privileged/agent/linux/netlink_lib.py index 8a10a0cc2d4..71ce3b091e8 100644 --- a/neutron/privileged/agent/linux/netlink_lib.py +++ b/neutron/privileged/agent/linux/netlink_lib.py @@ -49,9 +49,44 @@ from neutron.privileged.agent.linux import netlink_constants as nl_constants LOG = logging.getLogger(__name__) -nfct = ctypes.CDLL(util.find_library('netfilter_conntrack')) +nfct_lib = util.find_library('netfilter_conntrack') +nfct = ctypes.CDLL(nfct_lib) libc = ctypes.CDLL(util.find_library('libc.so.6')) +# In unit tests the actual nfct library may not be installed, and since we +# don't make actual calls to it we don't want to add a hard dependency. +if nfct_lib: + # It's important that the types be defined properly on all of the functions + # we call from nfct, otherwise pointers can be truncated and cause + # segfaults. + nfct.nfct_set_attr.argtypes = [ctypes.c_void_p, + ctypes.c_int, + ctypes.c_void_p] + nfct.nfct_set_attr_u8.argtypes = [ctypes.c_void_p, + ctypes.c_int, + ctypes.c_uint8] + nfct.nfct_set_attr_u16.argtypes = [ctypes.c_void_p, + ctypes.c_int, + ctypes.c_uint16] + nfct.nfct_snprintf.argtypes = [ctypes.c_char_p, + ctypes.c_uint, + ctypes.c_void_p, + ctypes.c_uint, + ctypes.c_uint, + ctypes.c_uint] + nfct.nfct_new.restype = ctypes.c_void_p + nfct.nfct_destroy.argtypes = [ctypes.c_void_p] + nfct.nfct_query.argtypes = [ctypes.c_void_p, + ctypes.c_int, + ctypes.c_void_p] + nfct.nfct_callback_register.argtypes = [ctypes.c_void_p, + ctypes.c_int, + ctypes.c_void_p, + ctypes.c_void_p] + nfct.nfct_open.restype = ctypes.c_void_p + nfct.nfct_close.argtypes = [ctypes.c_void_p] + + IP_VERSIONS = [constants.IP_VERSION_4, constants.IP_VERSION_6] DATA_CALLBACK = None