If all of these shells have the same umask when I call them manually, why does the umask get changed when perl calls a different shell (/bin/sh in this case)?
That is the key question. I'm unable to reproduce your findings regarding the different umasks but then our operating systems (and maybe shells and maybe perls) are probably quite different. I suggest that instead of fixing just on umask you look at the entire environment to determine what is being set/reset and hopefully by that method determine the cause. If umask turns out to be the only difference then that may point to a bug somewhere.