mojira.dev
MC-72390

Rcon is not thread-safe

Use of Rcon to execute commands that modify server state causes a race condition that may result in a java.util.ConcurrentModificationException in the main server thread if a command modifies data during a server tick.

Conversely, executing commands via Rcon that iterate over internal data structures (such as /save-all) may cause a java.util.ConcurrentModificationException in the Rcon thread if the main thread modifies those structures (see MC-68374).

Update 2016-11-08

During reproduction of this bug, it was observed that introducing a small delay (as low as 0.003 seconds) between each command sent via rcon appears to greatly reduce the chance-per-command of the bug being triggered. However, with zero delay between commands being sent, the chance of the bug being triggered is significant, with usually less than 100 commands being enough to trigger the bug.

End update

In the following example, an external script was being used to run commands. A ConcurrentModificationException was thrown when the Rcon thread /summon ed a Creeper and added it to the world's entities list, while the main thread was simultaneously iterating over the same list due to a command block executing /kill @e[type=MinecartTNT] . (Full crash report is attached)

[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: effect RobotoRaccoon 11 60 100 true
[2014-09-26 21:14:21] [RCON Client #3/INFO]: [Rcon: Given Resistance (ID 11) * 100 to RobotoRaccoon for 60 seconds]
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: playerinfo RobotoRaccoon
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: summon Creeper 2209 86 501 {Fuse:0}
[2014-09-26 21:14:21] [RCON Client #3/INFO]: [Rcon: Object successfully summoned]
[2014-09-26 21:14:21] [Server thread/ERROR]: Encountered an unexpected exception
u: Executing command block
        at net.minecraft.server.MinecraftServer.z(SourceFile:603) ~[minecraft.jar:?]
        at po.z(po.java:228) ~[minecraft.jar:?]
        at net.minecraft.server.MinecraftServer.y(SourceFile:531) ~[minecraft.jar:?]
        at net.minecraft.server.MinecraftServer.run(SourceFile:447) [minecraft.jar:?]
        at java.lang.Thread.run(Unknown Source) [?:1.7.0_55]
Caused by: java.util.ConcurrentModificationException
        at java.util.ArrayList$Itr.checkForComodification(Unknown Source) ~[?:1.7.0_55]
        at java.util.ArrayList$Itr.next(Unknown Source) ~[?:1.7.0_55]
        at aqu.a(SourceFile:2230) ~[minecraft.jar:?]
        at ah.a(SourceFile:433) ~[minecraft.jar:?]
        at ah.b(SourceFile:136) ~[minecraft.jar:?]
        at ab.a(ab.java:71) ~[minecraft.jar:?]
        at aqf.a(SourceFile:97) ~[minecraft.jar:?]
        at auo.b(SourceFile:53) ~[minecraft.jar:?]
        at qt.a(SourceFile:527) ~[minecraft.jar:?]
        at qt.c(SourceFile:199) ~[minecraft.jar:?]
        at net.minecraft.server.MinecraftServer.z(SourceFile:599) ~[minecraft.jar:?]
        ... 4 more
[2014-09-26 21:14:21] [Server thread/ERROR]: This crash report has been saved to: /data/minecraft/18-temp/./crash-reports/crash-2014-09-26_21.14.21-server.txt
[2014-09-26 21:14:21] [RCON Client #3/INFO]: $SERVCMD Rcon: summon Creeper 2209 87 501 {Fuse:0}
[2014-09-26 21:14:21] [RCON Client #3/INFO]: [Rcon: Object successfully summoned]

Reproduction

  • Create a new Minecraft server instance.

  • Enable Rcon on the default port (25575)

  • Set Rcon password to "test"

  • Connect a Minecraft client to the server.

  • Move the player to x=0, z=0 (or use /spreadplayers 0 0 1 1 false @a) to ensure this location is loaded.

  • Use Python to run the attached rcon.py script, which will send commands to the server (spawning entities at x=0 z=0)

  • The server should crash in under 60 seconds (usually only a few seconds).

I have successfully reproduced a ConcurrentModificatonException crash using this method. Due to the nature of this bug (race condition), it may take some time before the crash occurs.

Linked issues

Attachments

Comments 38

Attached Python script used to reproduce the bug. Connects to Rcon on port 25575 with password "test" and issues a rapid series of /summon Fireball commands (server despawns the fireballs immediately).

Attached crash report generated by reproducing the bug using rcon.py


Minecraft Crash Report ----
// Shall we play a game?

Time: 10/10/14 11:04
Description: Exception in server tick loop

java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at qn.a(SourceFile:166)
at net.minecraft.server.MinecraftServer.z(SourceFile:615)
at po.z(SourceFile:305)
at net.minecraft.server.MinecraftServer.y(SourceFile:531)
at net.minecraft.server.MinecraftServer.run(SourceFile:447)
at java.lang.Thread.run(Thread.java:745)

A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

– System Details –
Details:
Minecraft Version: 1.8
Operating System: Linux (amd64) version 2.6.32-042stab092.1
Java Version: 1.8.0_20, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 2473019160 bytes (2358 MB) / 6242500608 bytes (5953 MB) up to 10522722304 bytes (10035 MB)
IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94
Profiler Position: N/A (disabled)
Is Modded: Unknown (can't tell)
Type: Dedicated Server (map_server.txt)


Minecraft Crash Report ----
// Shall we play a game?

Time: 10/10/14 21:58
Description: Exception in server tick loop

java.util.ConcurrentModificationException
at java.util.HashMap$HashIterator.nextNode(HashMap.java:1429)
at java.util.HashMap$KeyIterator.next(HashMap.java:1453)
at qn.a(SourceFile:166)
at net.minecraft.server.MinecraftServer.z(SourceFile:615)
at po.z(SourceFile:305)
at net.minecraft.server.MinecraftServer.y(SourceFile:531)
at net.minecraft.server.MinecraftServer.run(SourceFile:447)
at java.lang.Thread.run(Thread.java:745)

A detailed walkthrough of the error, its code path and all known details is as follows:
---------------------------------------------------------------------------------------

– System Details –
Details:
Minecraft Version: 1.8
Operating System: Linux (amd64) version 2.6.32-042stab092.1
Java Version: 1.8.0_20, Oracle Corporation
Java VM Version: Java HotSpot(TM) 64-Bit Server VM (mixed mode), Oracle Corporation
Memory: 1308330000 bytes (1247 MB) / 4080271360 bytes (3891 MB) up to 10522722304 bytes (10035 MB)
IntCache: cache: 0, tcache: 0, allocated: 12, tallocated: 94
Profiler Position: N/A (disabled)
Is Modded: Unknown (can't tell)
Type: Dedicated Server (map_server.txt)

@Amn3zik Out of interest, what were you attempting to do via Rcon that triggered that crash?

28 more comments

Minecraft's rcon implementation is nothing but a quick hack. Every shortcut that doesn't prevent it from working at all was taken. You may remember MC-87863 as well. I say they should just rewrite it from scratch. They wouldn't be throwing much away anyway.

Unfortunately, setting a 0.003 second delay is not a sufficient workaround to stop our hourly world backup script from occasionally crashing the server.

Confirmed for 1.13

Does someone know how to fix this ?

It's still happening on 1.14.1 😞
I guess almost commands are unsafe except "help".

TerrorBite

boq

Community Consensus

(Unassigned)

crash, rcon

Minecraft 1.8, Minecraft 1.8.8, Minecraft 15w43c, Minecraft 15w44a, Minecraft 15w44b, ..., Minecraft 17w17b, Minecraft 1.12, Minecraft 17w43b, Minecraft 1.13, Minecraft 1.14.1

Minecraft 1.14.3 Pre-Release 2

Retrieved