-
Type: Bug
-
Status: Resolved (View Workflow)
-
Priority: Medium
-
Resolution: Fixed
-
Affects Version/s: VOLTHA v2.8
-
Fix Version/s: VOLTHA v2.8, VOLTHA v2.10
-
Component/s: openonu-adapter
-
Labels:None
-
Environment:
-
Story Points:5
-
Epic Link:
There Panic in isSuccessfulResponseWithMibDataSync handler if the decoded msgLayer is nil. The nil pointer is dereferenced causing panic.
The main issue here is that the EVTOCD create request is being responded with a create response of OMCI message with ME ID of Vdsl2LineInventoryAndStatusDataPart3 (possibly due to some corruption) and this is an ill formed packet. The returned msgLayer with call
"msgLayer := (*packet).Layer(nextLayer)" is a nil message layer. This nil pointer is dereferenced later causing panic.
Per suggestion from Chip, use lazy decode so that we decode only what is needed for validation at that point in time. A full decode can be done and handled closer to actual processing of that packet.
Below is the code snippet shared for lazy decode logic from Chip.
func RxExample(data []byte) { // Here is the very start of OMCI packet Rx processing decodeOptions := gopacket.DecodeOptions{ Lazy: true, NoCopy: true, } packet := gopacket.NewPacket(data, LayerTypeOMCI, decodeOptions) if packet != nil { omciLayer := packet.Layer(LayerTypeOMCI) if omciLayer != nil { if omciMsg, ok := omciLayer.(*OMCI); ok { switch omciMsg.MessageType { case MibUploadNextResponseType: handleMibUploadNext(packet) default: fmt.Printf("opps, no case for this one") } } else { fmt.Print("Would never expect this since packet.Layer() above worked") } } else if errLayer := packet.ErrorLayer(); errLayer != nil { // Some decode error information may be available for logging fmt.Printf("Got an error during OMCI layer decode %v", errLayer.Error()) // Other steps here that you may wish to do... // Also see the more involved ErrorLayer handling in the next function below } } } func handleMibUploadNext(packet gopacket.Packet) { msgLayer := packet.Layer(LayerTypeMibUploadNextResponse) if msgLayer != nil { // Here if layer was present. Note you may still have a // relaxed decode error tacked onto the layers now. if response, ok := msgLayer.(*MibUploadNextResponse); ok { // Process the packet some here if you want, or first check for relaxed decode // error if you would rather do that first. Here is the relaxed decode check if failure := packet.ErrorLayer(); failure != nil { // If here, we got the message layer but there is now an error layer present // which should only be one of our relaxed decode errors. This code below // may be excessive to what you need, but I figured I would make it as // comprehensive as possible. err := response.NextLayerType() switch err { case LayerTypeUnknownAttributes: unknownAttrLayer := packet.Layer(LayerTypeUnknownAttributes) fmt.Printf("Handle this: %v", unknownAttrLayer) default: // Some other, reason fmt.Printf("Some other failure: %v", failure.Error()) } } } } else if failure := packet.ErrorLayer(); failure != nil { // Here if message layer was not found. Any useful error information if decodeFailure, ok := failure.(*gopacket.DecodeFailure); ok && decodeFailure != nil { fmt.Printf("Got an error during MIB Upload Next layer decode %v", decodeFailure.String()) } } }