Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

random.seed(int) breaks the game unit isolation #107

Open
darkshark007 opened this issue Apr 18, 2020 · 4 comments
Open

random.seed(int) breaks the game unit isolation #107

darkshark007 opened this issue Apr 18, 2020 · 4 comments
Labels

Comments

@darkshark007
Copy link

TLDR: The random built-in library does not seem to be isolated globally, which is exploitable in a few potential ways, but might also indicate that other libraries may not be isolated.

On a whim, I added random.seed(9001) to the global/class layer of my bot, to see if I could change the seed and get a new game, but found some interesting bugs.

Right away, I noticed that the examplefuncsplayer I was playing against immediately started putting all its new bots in a single lane.....which suggested to me that, even though I was setting the seed in mybot, it was affecting examplefuncsplayer as well. I was able to confirm this by adding some logging statements:

# In mybot global section, so that when a new bot spawns on one team, it sets the seed
random.seed(9001)
dlog('Setting Random Seed!')
# In both mybot and examplefuncsplayer, inside the turn() function, so every single unit prints the next 5 on its turn
dlog('Next 5 Randoms: %s, %s, %s, %s, %s' % (random.randint(0,get_board_size()-1), random.randint(0,get_board_size()-1), random.randint(0,get_board_size()-1), random.randint(0,get_board_size()-1), random.randint(0,get_board_size()-1)))

Inspecting the prints, for a few turns in a row, after the seed gets set, I was able to confirm this behavior with the print statements:

Turn 15
[Robot 28 BLACK log] Setting Random Seed!
[Robot 28 BLACK log] Next 5 Randoms: 1, 9, 8, 2, 8
[Robot 29 WHITE log] Next 5 Randoms: 1, 8, 11, 9, 2
[Robot WHITE HQ log] Next 5 Randoms: 14, 7, 14, 12, 7
[Robot BLACK HQ log] Next 5 Randoms: 15, 4, 9, 7, 5
[Robot 2 WHITE log] Next 5 Randoms: 12, 8, 5, 9, 15
[Robot 3 BLACK log] Next 5 Randoms: 3, 12, 0, 6, 0
[Robot 4 BLACK log] Next 5 Randoms: 15, 8, 1, 13, 11
[Robot 6 WHITE log] Next 5 Randoms: 3, 7, 11, 9, 9
[Robot 7 BLACK log] Next 5 Randoms: 11, 0, 9, 13, 1

Turn 16
[Robot 31 BLACK log] Setting Random Seed!
[Robot 31 BLACK log] Next 5 Randoms: 1, 9, 8, 2, 8
[Robot BLACK HQ log] Next 5 Randoms: 1, 8, 11, 9, 2
[Robot WHITE HQ log] Next 5 Randoms: 7, 14, 12, 7, 7
[Robot 2 WHITE log] Next 5 Randoms: 4, 9, 7, 5, 12
[Robot 3 BLACK log] Next 5 Randoms: 12, 8, 5, 9, 15
[Robot 4 BLACK log] Next 5 Randoms: 3, 12, 0, 6, 0
[Robot 6 WHITE log] Next 5 Randoms: 15, 8, 1, 13, 11
[Robot 7 BLACK log] Next 5 Randoms: 3, 7, 11, 9, 9
[Robot 8 BLACK log] Next 5 Randoms: 11, 0, 9, 13, 1

Turn 17
[Robot 32 BLACK log] Setting Random Seed!
[Robot 32 BLACK log] Next 5 Randoms: 1, 9, 8, 2, 8
[Robot 33 WHITE log] Next 5 Randoms: 1, 8, 11, 9, 2
[Robot WHITE HQ log] Next 5 Randoms: 14, 7, 14, 12, 7
[Robot BLACK HQ log] Next 5 Randoms: 15, 4, 9, 7, 5
[Robot 2 WHITE log] Next 5 Randoms: 12, 8, 5, 9, 15
[Robot 3 BLACK log] Next 5 Randoms: 3, 12, 0, 6, 0
[Robot 4 BLACK log] Next 5 Randoms: 15, 8, 1, 13, 11
[Robot 6 WHITE log] Next 5 Randoms: 3, 7, 11, 9, 9
[Robot 7 BLACK log] Next 5 Randoms: 11, 0, 9, 13, 1

Even though Black team is the only team setting the seed, once the seed gets changed, it affects not only all of Black teams other units, but all of White teams units too. Collectively, they will all produce/receive the same sequence of random numbers.

This implies that the random package is not isolated unit-to-unit, and is global for all units on both teams. This could be exploited by one team to predict and/or control the other team. For example, as I mentioned, I first noticed that examplefuncsplayer immediately just started to put all of its units in only one or two columns, instead of "randomly". This is because, once I reset the same seed statically over and over, every time White team examplefuncsplayer "randomly" chose a column, it was getting the same sequence over and over again because the pawn that Black mybot spawned immediately reset the random seed sequence.

This makes me wonder, ifhe random built-in library does not seem to be isolated globally, other libraries/packages might not be isolated either. 🤷‍♂️

@darkshark007 darkshark007 changed the title random.seed(int) breaks the game random.seed(int) breaks the game unit isolation Apr 18, 2020
@npfoss
Copy link
Contributor

npfoss commented Apr 18, 2020

suggestion from cooljoseph (unvalidated):

To fix that, you could probably set random._seed = random.seed; random.seed = None in your Runner.py script. That would make it so competitors can't set the seed in their robot

@npfoss
Copy link
Contributor

npfoss commented Apr 18, 2020

(also for the record, seems like a duplicate of #106 but is waay better documented)

@darkshark007
Copy link
Author

darkshark007 commented Apr 18, 2020

Ahh, dangit, I didn't see a duplicate when I started typing. 🤣 Missed it by thaaat much.

@cooljoseph1
Copy link

Fix idea (validated on my computer):
In runner.py, add the following imports to the beginning:

import importlib
import random

and then edit the following lines:

if name == 'random':
    import random
    return random

to

if name == 'random':
    importlib.reload(random)
    return random

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants