Make market command unavailable to visitors, and set C_MOD flag
authorMarkus Armbruster <armbru@pond.sub.org>
Wed, 8 Feb 2012 18:11:12 +0000 (19:11 +0100)
committerMarkus Armbruster <armbru@pond.sub.org>
Tue, 21 Feb 2012 17:11:13 +0000 (18:11 +0100)
commit87c3a853fdc937f7220bd93b55e377e67725a423
treee81268c6eb96b1970800d8fe37265b4460a981fd
parent78dc17c02c247a89227e39206df59e192e0c51f7
Make market command unavailable to visitors, and set C_MOD flag

The market command executes all trades that have become ready, by
calling check_market() and check_trade().  This modifies game state,
but market lacks C_MOD.  That's wrong.  But can it do harm?

Turns out yes.  check_trade() looks safe, but check_market() telexes
seller and buyer while holding a copy of the commodity struct.  If
this telexes the player who sent the market command, and he has
NF_INFORM on, the telegram notification may yield the processor.  It
then writes back its copy, triggering a generation oops.  Any updates
made by other threads meanwhile are wiped out, triggering a seqno
mismatch oops.

This can cause commodity trades to be executed multiple times,
multiplying the sold commodities.  Abuse seems tricky, but possible:
conspiring trade partners trade commodities back and forth to multiply
them.  One of them needs to get the output backlog just right to make
the telegram notification yield, and the timing right so that the
MarketUpdate thread or another player's buy, market, reset, sell, set
or trade command runs check_market() before his thread resumes.

Closely related bug: visitors can trigger execution of trades by means
of command market.  That's clearly inappropriate.

Broken in Empire 3.  Reported by Scott C. Zielinski.
src/lib/player/empmod.c