T minus time to ransom!
Python 2, 90 bytes



g=lambda a:min(min(a))or-~g(map(lambda*c:map(max,(0,)+c[:-1],c,c[1:]),*a))
lambda a:g(a)/2


Try it online!

Accepts a matrix as a list of lists of 0 and 1.

How it works

g=lambda a:min(min(a))or…


If the smallest element of the matrix is 1 (it is completely infected), return 1; otherwise…

                        -~g(…                                            )


return 1 plus the recursive result on the following modified matrix…

                            map(lambda*c:…                           ,*a)


for each old column c…

                                         map(max,(0,)+c[:-1],c,c[1:])


produce a new row by zipping max over the down-shifted, original, and up-shifted versions of c.  (map fills in the gap at the end of c[1:] with None, which is falsy and smaller than both 0 and 1.)

Each iteration of g computes all vertical infections, then transposes the matrix.  This way, every 2 iterations of g compute all horizontal, vertical, and diagonal infections.

lambda a:g(a)/2


Because the base case of g with a fully infected matrix gave 1 rather than 0, the parity works out such that floored division by 2 always gives the correct result.