Well done. You've made a good attempt at answering the questions (unlike some who simply ask someone to do their homework for them, without trying).
In question 1, you've correctly picked up that the code as given yields undefined behaviour, as getbuf() returns a local (auto) variable. The answer isn't actually that the function "returns junk", but that the behaviour of the program upon assigning "q = *b;" could be anything. The program could also simply crash at that point, by trying to dereference a pointer that points at nothing valid. In other words, it is possible no value is stored in q as the program might simply terminate. The code always yields undefined behaviour, but the symptoms exhibited when it does could be anything.
Your answer to question 2 is one possibility. Another, if the intent is that the string returned by getbuf() will only be read, is to return a const pointer.
Question 3 : you are correct that the function is unreasonable, as any attempt to dereference the pointer returned by getbuf() yields undefined behaviour.
Your answers to questions 4 and 5 are essentially correct. The compiler treats any usage of "buff" as a pointer operation if required, due to equivalence of pointers and arrays. However, keep in mind that arrays and pointers are different things.
Question 6: you're right that the function is not good practice, but your reasoning needs improvement. The reason that it is not good practice is that it causes an innocent caller to exhibit undefined behaviour. Apart from the option you suggested (a static variable), another way around the problem (other than the one you suggested) is to dynamically allocate memory (using malloc(), for example) as such memory exists until explicitly released. The caveat of that alternative is that the caller needs to ensure that the memory is released, or a memory leak will occur. One more alternative is for the caller to allocate memory, and pass a pointer as an argument.
Question 8: lines 50-300 need to be within a function (eg within main()). If the body of getbuf() is below main(), or in another source file, the function needs to be declared via a prototype (eg "char *getbuf(void);") so that it can be called.
Question 9. Your answer is incorrect, as it requires the caller to know the size of the buffers to pass. What I suspect they're looking for is;
typedef struct
{
char first_buffer[8];
char second_buffer[10];
} Retval;
Retval getbuf()
{
Retval value;
/* sample implementation */
strcpy(value.first_buffer, "Hello");
strcpy(value.second_buffer, "Bye");
return value;
} This approach also avoids all of the problems with the original getbuf(). No undefined behaviour. No need to pass a buffer as an argument. No need to use dynamic memory allocation. The only cost is that lengths of strings must be known to the programmer.