The check 'offset + size > buffer.Length' ought to be 'size > buffer.Length - offset'... otherwise, I can make both of them overflow and get past the check.
In any case, I have made a Github patch which fixes this and also centralizes all bounds checking for Socket into a single function (presently it is spread out in each function and done two different ways). I will reference this bug number in the pull request.
Applied the pull request 281 to master. I will backport this to mono-2-10.