Here is the assembly code (inside main) for the correct version with "char *"
movl $0, %eax
call getstr
movq %rax, %rsi
movl $.LC0, %edi
movl $0, %eax
call printf
Here is the assembly code (inside main) when "char *" is replaced with "char"
movl $0, %eax
call getstr
movsbl %al, %eax
movl %eax, %esi
movl $.LC0, %edi
movl $0, %eax
call printf
As we can see and as mentioned din the question, the change is that, due to the prototype of getstr being char, in the second case, the returned value is truncated to just 8 bits. Now this 8 bits with higher bits padded with 0's or 1's (due to sign extension and x64 calling convention) will be used as an address in the second case and that causes segmentation fault.
i.e., suppose address of s in first case is 0x 4F A1 23 43, in second case this becomes 0x 00 00 00 43.
Even the above is not a strict guarantee as we are using a char (integer) as an address and there might be alignment issue.
If we keep it simple, answer is undefined behaviour :)