It is POSIX UB, as the standard gives no guarantees what happens when the signal returns in such cases, so each OS is free to do whatever they feel like.
You don't have to return from the signal handler. You could also longjmp. longjmp happens to be async-signal-safe, and the standard is careful to permit longjmp out of a signal handler, so long as you're careful to avoid implicating other non-safe behaviors. SIGSEGV is a synchronous signal (that is, always delivered immediately to the same thread that triggered it), and presumably the point at which SIGSEGV is triggered was carefully orchestrated by the application. I've done this once--it permitted me to remove a boundary check on an array, improving runtime performance many fold in a machine generated, statically compiled NFA. On SIGSEGV I would longjmp back to a safe entry point, grow the array, and then restart the NFA.
Did you tried across several POSIX platforms?
It was developed on macOS and deployed on Linux/glibc. I've also longjmp'd out of signal handlers to emulate sigtimedwait on OpenBSD and NetBSD . I probably (can't remember) also tested the sigtimedwait implementation on FreeBSD, Linux, and Solaris (and maybe AIX), my typical porting targets.
(Also, SEGVs are well behaved enough to implement userspace virtual memory on top of, if that's your fetish... not sure what the spec says, but it's not UB in actual practice. Trying to resume from an assert() is indeed UB though since that'd be returning from a noreturn function.)