I'm asking and answering my own question because Google and StackOverflow were unable to help me with this one, at least with the search terms I was using. As we started researching, we found that SQL Server treats tinyint as an unsigned byte (0 to 255), while Oracle treats it as a signed byte (-128 to 127). But we were importing into a NUMBER(3) column, which is appropriate. The guy who wrote the data migration script needed to use Oracle's to_number function to read the SQL Server tinyint columns for some reason. So this query returned some curious characters in the second column if you ran it on our dev and test environments, but it returned the same negative number in both columns in our production environment.
SELECT to_number("SomeTinyIntColumn"), "SomeTinyIntColumn"
FROM MySQLServerDBLink@mydomain.com
We eventually discovered that the reason it worked in the dev and test environments was because the character set was UTF-8 there, but in production it was a Western European 8-bit character set:
SELECT value$ FROM sys.props$ WHERE name = 'NLS_CHARACTERSET';
-- Dev and Test: AL32UTF8
-- Prod: WE8ISO8859P1
So it seems that reading a SQL Server tinyint column as a single UTF-8 character through a DBLink and converting that to an Oracle NUMBER(3) column works, provided you are using a UTF-8 character set for your Oracle database. It would have been nice if the DBLink had handled the conversion itself (making the to_number conversion unnecessary), but it seems it doesn't really know what to do with a SQL Server tinyint.
I hope this helps someone else someday!