From b79b5162927a2f7ec939917cde1822f3b8aee82c Mon Sep 17 00:00:00 2001 From: gpotter2 Date: Mon, 24 Jun 2019 23:06:57 +0200 Subject: [PATCH 1/3] Fix race conditions on Init --- scapy/packet.py | 39 +++++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 16 deletions(-) diff --git a/scapy/packet.py b/scapy/packet.py index 97b47f025a2..2f8e2f8736d 100644 --- a/scapy/packet.py +++ b/scapy/packet.py @@ -206,8 +206,9 @@ def do_init_cached_fields(self): self.prepare_cached_fields(self.fields_desc) # Use fields information from cache - if not Packet.class_default_fields.get(cls_name, None) is None: - self.default_fields = Packet.class_default_fields[cls_name] + default_fields = Packet.class_default_fields.get(cls_name, None) + if default_fields: + self.default_fields = default_fields self.fieldtype = Packet.class_fieldtype[cls_name] self.packetfields = Packet.class_packetfields[cls_name] @@ -228,32 +229,38 @@ def prepare_cached_fields(self, flist): cls_name = self.__class__ # Fields cache initialization - if flist: - Packet.class_default_fields[cls_name] = dict() - Packet.class_default_fields_ref[cls_name] = list() - Packet.class_fieldtype[cls_name] = dict() - Packet.class_packetfields[cls_name] = list() + if not flist: + return + + class_default_fields = dict() + class_default_fields_ref = list() + class_fieldtype = dict() + class_packetfields = list() # Fields initialization for f in flist: if isinstance(f, MultipleTypeField): - del Packet.class_default_fields[cls_name] - del Packet.class_default_fields_ref[cls_name] - del Packet.class_fieldtype[cls_name] - del Packet.class_packetfields[cls_name] + # Abort self.class_dont_cache[cls_name] = True self.do_init_fields(self.fields_desc) - break + return tmp_copy = copy.deepcopy(f.default) - Packet.class_default_fields[cls_name][f.name] = tmp_copy - Packet.class_fieldtype[cls_name][f.name] = f + class_default_fields[f.name] = tmp_copy + class_fieldtype[f.name] = f if f.holds_packets: - Packet.class_packetfields[cls_name].append(f) + class_packetfields.append(f) # Remember references if isinstance(f.default, (list, dict, set, RandField, Packet)): - Packet.class_default_fields_ref[cls_name].append(f.name) + class_default_fields_ref.append(f.name) + + # Apply + Packet.class_default_fields_ref[cls_name] = class_default_fields_ref + Packet.class_fieldtype[cls_name] = class_fieldtype + Packet.class_packetfields[cls_name] = class_packetfields + # Last to avoid racing issues + Packet.class_default_fields[cls_name] = class_default_fields def dissection_done(self, pkt): """DEV: will be called after a dissection is completed""" From 53ef8de2a47a17db268a7b83aa3a4264c3810de8 Mon Sep 17 00:00:00 2001 From: gpotter2 Date: Thu, 27 Jun 2019 01:09:06 +0200 Subject: [PATCH 2/3] Follows guedou's remark --- scapy/packet.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/scapy/packet.py b/scapy/packet.py index 2f8e2f8736d..790f63a297c 100644 --- a/scapy/packet.py +++ b/scapy/packet.py @@ -187,11 +187,14 @@ def do_init_fields(self, flist): """ Initialize each fields of the fields_desc dict """ + default_fields = {} for f in flist: - self.default_fields[f.name] = copy.deepcopy(f.default) + default_fields[f.name] = copy.deepcopy(f.default) self.fieldtype[f.name] = f if f.holds_packets: self.packetfields.append(f) + # We set default_fields last to avoid race issues + self.default_fields = default_fields def do_init_cached_fields(self): """ From ec33df0b753deb476602a73e650dfcfc776397a3 Mon Sep 17 00:00:00 2001 From: gpotter2 Date: Thu, 11 Jul 2019 19:14:40 +0000 Subject: [PATCH 3/3] Fix initialization of MultipleTypeField --- scapy/fields.py | 3 +++ test/fields.uts | 1 + 2 files changed, 4 insertions(+) diff --git a/scapy/fields.py b/scapy/fields.py index 62f81e742f6..a071f0bc408 100644 --- a/scapy/fields.py +++ b/scapy/fields.py @@ -336,6 +336,9 @@ def _find_fld(self): except KeyError: pass else: + if not pkt.default_fields: + # Packet not initialized + return self.dflt if isinstance(pkt, tuple(self.dflt.owners)): return self._find_fld_pkt(pkt) frame = frame.f_back diff --git a/test/fields.uts b/test/fields.uts index 87e0d630b3f..d68d68e70ba 100644 --- a/test/fields.uts +++ b/test/fields.uts @@ -1252,6 +1252,7 @@ assert Dot11().FCfield.to_DS is False ######## ######## + MultipleTypeField +~ mtf = Test initialization order