Buffer overflows should be relatively easy to avoid in modern code, but some C programmers insist on doing handrolled calculations for buffer sizes that wind up being wrong (the WebP vuln was a great example of this), and not having buffer length checks because they assume their calculations are right (it’s faster!).
But buffer overflows are a small part of the vulnerability space. For instance, memory allocation bugs, like double free/use-after-free are much more insidious with large codebases, and harder to detect due to problems like unclear or undocumented ownership. C doesn’t provide any mechanism for communicating ownership or lifetime information for all but the simplest objects, leaving this up to the programmer to manage.