{"record":{"id":"ffdc274910eb4cce","repo":"livekit/livekit","slug":"dependencydescriptorreader-too-many-templates","errorCode":null,"errorMessage":"DependencyDescriptorReader: too many templates","messagePattern":"DependencyDescriptorReader: too many templates","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"pkg/sfu/rtpextension/dependencydescriptor/dependencydescriptorreader.go","lineNumber":24,"sourceCode":"//\n//     http://www.apache.org/licenses/LICENSE-2.0\n//\n// Unless required by applicable law or agreed to in writing, software\n// distributed under the License is distributed on an \"AS IS\" BASIS,\n// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n// See the License for the specific language governing permissions and\n// limitations under the License.\n\npackage dependencydescriptor\n\nimport (\n\t\"errors\"\n)\n\nvar (\n\tErrDDReaderNoStructure              = errors.New(\"DependencyDescriptorReader: Structure is nil\")\n\tErrDDReaderTemplateWithoutStructure = errors.New(\"DependencyDescriptorReader: has templateDependencyStructurePresentFlag but AttachedStructure is nil\")\n\tErrDDReaderTooManyTemplates         = errors.New(\"DependencyDescriptorReader: too many templates\")\n\tErrDDReaderTooManyTemporalLayers    = errors.New(\"DependencyDescriptorReader: too many temporal layers\")\n\tErrDDReaderTooManySpatialLayers     = errors.New(\"DependencyDescriptorReader: too many spatial layers\")\n\tErrDDReaderInvalidTemplateIndex     = errors.New(\"DependencyDescriptorReader: invalid template index\")\n\tErrDDReaderInvalidSpatialLayer      = errors.New(\"DependencyDescriptorReader: invalid spatial layer, should be less than the number of resolutions\")\n\tErrDDReaderNumDTIMismatch           = errors.New(\"DependencyDescriptorReader: decode target indications length mismatch with structure num decode targets\")\n\tErrDDReaderNumChainDiffsMismatch    = errors.New(\"DependencyDescriptorReader: chain diffs length mismatch with structure num chains\")\n)\n\ntype DependencyDescriptorReader struct {\n\t// Output.\n\tdescriptor *DependencyDescriptor\n\n\t// Values that are needed while reading the descriptor, but can be discarded\n\t// when reading is complete.\n\tbuffer                         *BitStreamReader\n\tframeDependencyTemplateId      int\n\tactiveDecodeTargetsPresentFlag bool\n\tcustomDtisFlag                 bool","sourceCodeStart":6,"sourceCodeEnd":42,"githubUrl":"https://github.com/livekit/livekit/blob/ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6/pkg/sfu/rtpextension/dependencydescriptor/dependencydescriptorreader.go#L6-L42","documentation":"ErrDDReaderTooManyTemplates is returned by readTemplateLayers when a structure declares MaxTemplates templates, exceeding the AV1 spec limit. It is a guard against unbounded allocation and hostile descriptors.","triggerScenarios":"readTemplateLayers loop hits len(templates) == MaxTemplates while parsing templateDependencyStructure (line 218); caused by a corrupt template count in the payload.","commonSituations":"Malformed/attacker-crafted dependency descriptor payloads; interoperability with non-conformant encoders emitting more templates than allowed.","solutions":["Drop the packet / invalidate the descriptor when the limit is hit (spec-conformant behavior)","Sanity-check the descriptor payload size before parsing to reject oversized counts early","Update encoder/library versions if a legit encoder is exceeding the limit"],"exampleFix":"// before\nfor {\n    templates = append(templates, t)\n}\n// after\nfor {\n    if len(templates) == MaxTemplates {\n        return ErrDDReaderTooManyTemplates // bounded, spec-compliant\n    }\n    templates = append(templates, t)\n}","handlingStrategy":"validation","validationCode":"if payloadLen > maxReasonableDescriptorSize {\n    return errors.New(\"descriptor payload too large\")\n}","typeGuard":null,"tryCatchPattern":"err := reader.ReadTemplateLayers()\nif errors.Is(err, dd.ErrDDReaderTooManyTemplates) {\n    reader.Buffer().Invalidate() // drop packet\n}","preventionTips":["Reject oversized descriptor payloads before parsing","Keep spec limits (MaxTemplates) enforced; never disable them","Fuzz the parser to confirm bounded memory"],"tags":["webrtc","dependency-descriptor","limits"],"backgroundTag":"dependency-descriptor-limit-exceeded","analyzedSha":"ee45c3f0b1a83bf4352dbccb6607ebf70b2a5de6","analyzedAt":"2026-09-02T03:56:08.477Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}