Skip to content

PSIP table parsing should be more robust #623

@linuxdude42

Description

@linuxdude42

Given the recent issue with noisy recordings (#596) and the ~40 Coverity errors related to blindly trusting data received from the network, I thought I'd take a look at trying to fix some of these errors.

As it stands today, the only validity checking that the PSIP table parsers perform is to validate the CRC (if present). Once processing of a table begins, there are no checks to ensure that the table is consistent or to ensure that processing doesn't read past the end of the received data. If any errors have crept into the tables before the application of the CRC (most tables require a CRC, but not all) then it is entirely possible for the parser to access memory past the end of the received data. This could cause unexpected behavior, anything from a glitch in AV processing to a crash of the system. MythTV should be able to recognize malformed tables, drop the portions that run out of bounds or drop them entirely, and then continue running.

I have a tree where I've enhanced the ATSC table parsers to perform bounds checking at each step, and to protect the system by dropping any field in a table that exceeds those bounds (and drop all subsequent fields). This should prevent MythTV from processing any data that could potentially crash the system. These parsers currently perform better than the existing parsers, in large part because they calculate the maximum table size up front and perform a single memory allocation, making those parts of the functions O(1) instead of the current O(log2 n). There's also no data copying each time the table is resized. The remainder of the functions are still O(n) processing the tables.

Example timing without optimization:

     Old: 0.0018 msecs per iteration (total: 61, iterations: 32768)
     New: 0.0011 msecs per iteration (total: 75, iterations: 65536)

     Old: 0.0048 msecs per iteration (total: 80, iterations: 16384)
     New: 0.0021 msecs per iteration (total: 72, iterations: 32768)

and with optimization

     Old: 0.00024 msecs per iteration (total: 65, iterations: 262144)
     New: 0.00017 msecs per iteration (total: 93, iterations: 524288)

     Old: 0.00047 msecs per iteration (total: 62, iterations: 131072)
     New: 0.00036 msecs per iteration (total: 95, iterations: 262144)

I don't believe that these changes go far enough. I think MythTV should completely drop any PSIP table when it detects that any of the fields exceeds the bounds of the received data. It should just throw an error from the constructor and let the caller handle it.

If there's agreement that this level of checking is worthwhile, then all the other *tables.cpp files should have similar changes.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions