Yes - really! It would be undefined behavior if the runtime doesn't make any promises about it. But some do make the promises that it will work. I think both async-std and tokio make sure IO related futures work from tasks that are driven by a different runtime - otherwise stuff like `future::executor::block_on(task)` would also not work, and neither would the blocking wrappers around some of the HTTP clients.
However the IO objects might need to be initialized within a certain context (e.g. some TLS variables need to be set for tokio). And there might be a few different things one need watch out for. E.g. if you stop the background runtime things might get weird - however this e.g. can't happen with async-std since the background runtime will never shut down.