if you want, you can think of this as a bug in read(2): if a file is covered up, it should be completely hidden. it turns out that actually implementing this is quite hard, that it doesn't really break much (you've found about all of it!) to leave it as is, and that it results in things like /bin/ls giving interesting information about the union.