If times_until_zero had the type you suggest, then a caller would be allowed to do the following:
times_until_zero (string_to_int, 10)
where string_to_int : string -> int parses a string into an integer. Clearly, the call to f would not be type-correct anymore.
The subtlety here is where 'a is quantified, i.e., who gets to choose an instantiation. In the ML type system, the quantifier is always implicitly placed at the outermost position. That is, the type
('a -> int) * int -> int
actually means
forall 'a. (('a -> int) * int -> int)
Consequently, the caller of the function gets to pick a type for 'a.
For your example to be type-correct, you'd need the type
(forall 'a. ('a -> int)) * int -> int
With this the callee, i.e., your function, gets to pick a type for 'a, and can in fact pick a different one every time it calls f. On the flip-side, applying string_to_int would no longer be type-correct, since that function does not have the necessary polymorphic type.
However, types like the above with inner quantifiers (called higher-rank polymorphism) are not supported in plain ML, simply because type inference for them is not decidable in general.