tmp is a pointer to an int and it gets treated like an array, why is it so?
tmp is effectively a single element integer array. The array element access operator can be seen as syntactic sugar for pointer arithmetics and dereferencing. As such a[b] is equivalent to *(a + b), and as a corollary b[a]. This is legal and perfectly fine unless invalid memory locations are being accessed: You shall not access memory regions that were not allocated for your variables.
What is the author trying to illustrate with this example called "destroying the stack" ?
The author tries to demonstrate what may happens when invalid memory regions are accessed. Technically, anything can happen. Nothing special included.
When is it a good idea to use a pointer like an array? Is it strictly legal to program like that?
Yes of course, this is a very common operation. You just have to know what array indices are valid (usually 0 to size-1). (You may need to pass the size alongside the pointer to the array: struct my_arr { int *arr; size_t size; };.)
(I don't think that the author wanted to demonstrate that the access violations in the lower memory regions are practically not a problem because that space on the stack wasn't used so far, but in contrast the access violations in the higher memory regions would overwrite besides the variable param, the return address of the function called and trigger stack corruption protection mechanisms (e.g., canaries) and thereby trigger a segmentation fault. But for anyone interested here's the obligatory link to Smashing The Stack For Fun And Profit by Aleph One.)