That's the way references work - what you're passing to your 'pass1' function is a pointer to the hash '$hashref' points to, not a copy of it, so local changes get applied to that global copy.
If you want to pass a local copy, specify that:
pass1({ params => {%$hashref} }); # {%$hashref} makes a (shallow) cop
+y of the hash '$hashref'
# points to and creates a new ref t
+o it.
If you do that, then you get:
before pass1: 1
Inside pass1...
2
3
after pass1: 1
which is what I think you expect.
Added (shallow) note, AnomalousMonk is correct in his reply below!