The two null-dereferences are pretty straight forward instances, the first being that when an error happens early on, a buffer is never assigned a value after the initial
NULL assignment. In generic error handling code, it gets dereferenced assuming the error happened after it had been setup. The second being attacker controlled data can be malformed, and have a
NULL where a pointer should be.
The overflow is a little more fun:
size_t maxsize = R_MAX (ss_const, ss_selrefs); // 1 maxsize = R_MIN (maxsize, objc->file_size);
It starts off with the above code to calculate the maximum size for the buffer it will allocate. Basically its going to choose between the largest of the two size values, or cap it at the
The problem here is that despite (potentially) capping it to the
objc->file_size the actual copies later in the code use the original
ss_const values to signify how much data to copy. So even though it capped the size of the buffer, it’ll still try to copy more data into the buffer.