I'm not sure what your question is. Yes, using strcpy to put too much data into an array (more data than there is space in the array) is a buffer overrun, which is undefined behaviour. Your program may crash some of the time, and certainly it's a security risk.
The strcpy function "returns a pointer to dest", according to the documentation. So
Code:
strcpy(str1, strcpy(str2, "abcd"));
would be the equivalent of
Code:
strcpy(str2, "abcd");
strcpy(str1, str2);
which is fine. It's not recursion. Recursion is where one function calls itself (directly or indirectly). strcpy() would only be recursive if it called strcpy(). Here you're just invoking strcpy() twice in succession, one after another.