[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#579850: pu: package openttd/0.6.2-1+lenny2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: pu

Hi,

The openttd package contains a few vulnerabilities published by upstream
today. Since (the stable version of) openttd is in contrib, this fix is
not going through the stable-security repository.

The debdiff is attached. The actual patch is the combined patch of
upstream's patches at http://security.openttd.org/en/CVE-2010-0401,
http://security.openttd.org/en/CVE-2010-0402 and
http://security.openttd.org/en/CVE-2010-0406, with no further changes
made.

Okay to upload this fixed package?

Gr.

Matthijs
diff -u openttd-0.6.2/debian/changelog openttd-0.6.2/debian/changelog
--- openttd-0.6.2/debian/changelog
+++ openttd-0.6.2/debian/changelog
@@ -1,3 +1,15 @@
+openttd (0.6.2-1+lenny2) stable; urgency=high
+
+  * Fix three security issues, patches supplied by upstream. See
+    http://security.openttd.org/ for details.
+    - CVE-2010-0401 (Access restriction circumvention, remote crash)
+    - CVE-2010-0402 (Denial of service via improperly validated
+      commands)
+    - CVE-2010-0406 (Denial of service (server) via leaking file
+      descriptors)
+
+ -- Matthijs Kooijman <matthijs@stdin.nl>  Sat, 01 May 2010 12:39:39 +0200
+
 openttd (0.6.2-1+lenny1) stable; urgency=low
 
   * Backport upstream r18462 to fix remote crash vulnerability
diff -u openttd-0.6.2/src/train_cmd.cpp openttd-0.6.2/src/train_cmd.cpp
--- openttd-0.6.2/src/train_cmd.cpp
+++ openttd-0.6.2/src/train_cmd.cpp
@@ -765,6 +765,7 @@
  */
 CommandCost CmdBuildRailVehicle(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	/* Check if the engine-type is valid (for the player) */
 	if (!IsEngineBuildable(p1, VEH_TRAIN, _current_player)) return_cmd_error(STR_RAIL_VEHICLE_NOT_AVAILABLE);
 
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/roadveh_cmd.cpp
+++ openttd-0.6.2/src/roadveh_cmd.cpp
@@ -172,6 +172,7 @@
 	UnitID unit_num;
 	Engine *e;
 
+	p1 = GB(p1, 0, 16);
 	if (!IsEngineBuildable(p1, VEH_ROAD, _current_player)) return_cmd_error(STR_ROAD_VEHICLE_NOT_AVAILABLE);
 
 	cost = EstimateRoadVehCost(p1);
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/order_cmd.cpp
+++ openttd-0.6.2/src/order_cmd.cpp
@@ -173,7 +173,7 @@
 
 	v = GetVehicle(veh);
 
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	/* Check if the inserted order is to the correct destination (owner, type),
 	 * and has the correct flags if any */
@@ -455,15 +455,15 @@
 CommandCost CmdDeleteOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v, *u;
-	VehicleID veh_id = p1;
-	VehicleOrderID sel_ord = p2;
+	VehicleID veh_id = GB(p1, 0, 16);
+	VehicleOrderID sel_ord = GB(p2, 0, 8);
 	Order *order;
 
 	if (!IsValidVehicleID(veh_id)) return CMD_ERROR;
 
 	v = GetVehicle(veh_id);
 
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	/* If we did not select an order, we maybe want to de-clone the orders */
 	if (sel_ord >= v->num_orders)
@@ -535,14 +535,14 @@
 CommandCost CmdSkipToOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Vehicle *v;
-	VehicleID veh_id = p1;
-	VehicleOrderID sel_ord = p2;
+	VehicleID veh_id = GB(p1, 0, 16);
+	VehicleOrderID sel_ord = GB(p2, 0, 8);
 
 	if (!IsValidVehicleID(veh_id)) return CMD_ERROR;
 
 	v = GetVehicle(veh_id);
 
-	if (!CheckOwnership(v->owner) || sel_ord == v->cur_order_index ||
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner) || sel_ord == v->cur_order_index ||
 			sel_ord >= v->num_orders || v->num_orders < 2) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
@@ -579,14 +579,14 @@
  */
 CommandCost CmdMoveOrder(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	VehicleID veh = p1;
+	VehicleID veh = GB(p1, 0, 16);
 	VehicleOrderID moving_order = GB(p2,  0, 16);
 	VehicleOrderID target_order = GB(p2, 16, 16);
 
 	if (!IsValidVehicleID(veh)) return CMD_ERROR;
 
 	Vehicle *v = GetVehicle(veh);
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	/* Don't make senseless movements */
 	if (moving_order >= v->num_orders || target_order >= v->num_orders ||
@@ -675,7 +675,7 @@
 
 	v = GetVehicle(veh);
 
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	/* Is it a valid order? */
 	if (sel_ord >= v->num_orders) return CMD_ERROR;
@@ -753,7 +753,7 @@
 
 	dst = GetVehicle(veh_dst);
 
-	if (!CheckOwnership(dst->owner)) return CMD_ERROR;
+	if (!dst->IsPrimaryVehicle() || !CheckOwnership(dst->owner)) return CMD_ERROR;
 
 	switch (p2) {
 		case CO_SHARE: {
@@ -764,7 +764,7 @@
 			src = GetVehicle(veh_src);
 
 			/* Sanity checks */
-			if (!CheckOwnership(src->owner) || dst->type != src->type || dst == src)
+			if (!src->IsPrimaryVehicle() || !CheckOwnership(src->owner) || dst->type != src->type || dst == src)
 				return CMD_ERROR;
 
 			/* Trucks can't share orders with busses (and visa versa) */
@@ -811,7 +811,7 @@
 			src = GetVehicle(veh_src);
 
 			/* Sanity checks */
-			if (!CheckOwnership(src->owner) || dst->type != src->type || dst == src)
+			if (!src->IsPrimaryVehicle() || !CheckOwnership(src->owner) || dst->type != src->type || dst == src)
 				return CMD_ERROR;
 
 			/* Trucks can't copy all the orders from busses (and visa versa) */
@@ -886,11 +886,12 @@
 	CargoID cargo = GB(p2, 0, 8);
 	byte subtype  = GB(p2, 8, 8);
 
+	if (cargo >= NUM_CARGO) return CMD_ERROR;
 	if (!IsValidVehicleID(veh)) return CMD_ERROR;
 
 	v = GetVehicle(veh);
 
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	order = GetVehicleOrder(v, order_number);
 	if (order == NULL) return CMD_ERROR;
@@ -1033,12 +1034,13 @@
 	VehicleOrderID cur_ord = GB(p2,  0, 16);
 	uint16 serv_int = GB(p2, 16, 16);
 
+	p1 = GB(p1, 0, 16);
 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
 	/* Check the vehicle type and ownership, and if the service interval and order are in range */
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 	if (serv_int != GetServiceIntervalClamped(serv_int) || cur_ord >= v->num_orders) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/waypoint.cpp
+++ openttd-0.6.2/src/waypoint.cpp
@@ -364,6 +364,7 @@
  */
 CommandCost CmdRenameWaypoint(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	Waypoint *wp;
 
 	if (!IsValidWaypointID(p1)) return CMD_ERROR;
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/water_cmd.cpp
+++ openttd-0.6.2/src/water_cmd.cpp
@@ -347,7 +347,7 @@
 	int y;
 	int sx, sy;
 
-	if (p1 >= MapSize()) return CMD_ERROR;
+	if (p1 >= MapSize() || p2 > 2) return CMD_ERROR;
 
 	/* Outside of the editor you can only build canals, not oceans */
 	if (p2 != 0 && _game_mode != GM_EDITOR) return CMD_ERROR;
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/vehicle.cpp
+++ openttd-0.6.2/src/vehicle.cpp
@@ -1706,6 +1706,7 @@
 	CommandCost cost;
 	VehicleType vehicle_type = (VehicleType)GB(p1, 0, 8);
 
+	if (!IsPlayerBuildableVehicleType(vehicle_type)) return CMD_ERROR;
 	if (!IsDepotTile(tile) || !IsTileOwner(tile, _current_player)) return CMD_ERROR;
 
 	/* Get the list of vehicles in the depot */
@@ -1769,8 +1770,10 @@
 	CommandCost cost, total_cost(EXPENSES_NEW_VEHICLES);
 	uint32 build_argument = 2;
 
+	p1 = GB(p1, 0, 16);
 	if (!IsValidVehicleID(p1)) return CMD_ERROR;
 	v = GetVehicle(p1);
+	if (!v->IsPrimaryVehicle()) return CMD_ERROR;
 	v_front = v;
 	w = NULL;
 	w_front = NULL;
@@ -2105,7 +2108,7 @@
 			}
 			break;
 
-		default: NOT_REACHED(); break;
+		default: return 0;
 	}
 
 	if ((n + 100) < *length_of_array) {
@@ -2338,11 +2341,12 @@
 {
 	Vehicle *v;
 
+	p1 = GB(p1, 0, 16);
 	if (!IsValidVehicleID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	if (!IsUniqueVehicleName(_cmd_text)) return_cmd_error(STR_NAME_MUST_BE_UNIQUE);
 
@@ -2368,11 +2372,12 @@
 	Vehicle* v;
 	uint16 serv_int = GetServiceIntervalClamped(p2); /* Double check the service interval from the user-input */
 
+	p1 = GB(p1, 0, 16);
 	if (serv_int != p2 || !IsValidVehicleID(p1)) return CMD_ERROR;
 
 	v = GetVehicle(p1);
 
-	if (!CheckOwnership(v->owner)) return CMD_ERROR;
+	if (!v->IsPrimaryVehicle() || !CheckOwnership(v->owner)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
 		v->service_interval = serv_int;
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/console_cmds.cpp
+++ openttd-0.6.2/src/console_cmds.cpp
@@ -549,7 +549,8 @@
 {
 	static const char* const stat_str[] = {
 		"inactive",
-		"authorizing",
+		"authorizing (server password)",
+		"authorizing (company password)",
 		"authorized",
 		"waiting",
 		"loading map",
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/rail.cpp
+++ openttd-0.6.2/src/rail.cpp
@@ -186,7 +186,7 @@
 
 bool ValParamRailtype(const RailType rail)
 {
-	return HasRailtypeAvail(_current_player, rail);
+	return rail < RAILTYPE_END && HasRailtypeAvail(_current_player, rail);
 }
 
 RailType GetBestRailtype(const PlayerID p)
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/aircraft_cmd.cpp
+++ openttd-0.6.2/src/aircraft_cmd.cpp
@@ -276,6 +276,7 @@
  */
 CommandCost CmdBuildAircraft(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	if (!IsEngineBuildable(p1, VEH_AIRCRAFT, _current_player)) return_cmd_error(STR_AIRCRAFT_NOT_AVAILABLE);
 
 	const AircraftVehicleInfo *avi = AircraftVehInfo(p1);
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/group_cmd.cpp
+++ openttd-0.6.2/src/group_cmd.cpp
@@ -88,7 +88,7 @@
  */
 CommandCost CmdCreateGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	VehicleType vt = (VehicleType)p1;
+	VehicleType vt = (VehicleType)GB(p1, 0, 3);
 	if (!IsPlayerBuildableVehicleType(vt)) return CMD_ERROR;
 
 	if (!Group::CanAllocateItem()) return CMD_ERROR;
@@ -114,6 +114,7 @@
  */
 CommandCost CmdDeleteGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	if (!IsValidGroupID(p1)) return CMD_ERROR;
 
 	Group *g = GetGroup(p1);
@@ -176,6 +177,7 @@
  */
 CommandCost CmdRenameGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	if (!IsValidGroupID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
 
 	Group *g = GetGroup(p1);
@@ -206,6 +208,8 @@
  */
 CommandCost CmdAddVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
+	p2 = GB(p2, 0, 16);
 	GroupID new_g = p1;
 
 	if (!IsValidVehicleID(p2) || (!IsValidGroupID(new_g) && !IsDefaultGroupID(new_g))) return CMD_ERROR;
@@ -253,12 +257,12 @@
  */
 CommandCost CmdAddSharedVehicleGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	VehicleType type = (VehicleType)p2;
+	p1 = GB(p1, 0, 16);
+	VehicleType type = (VehicleType)GB(p2, 0, 3);
 	if (!IsValidGroupID(p1) || !IsPlayerBuildableVehicleType(type)) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
 		Vehicle *v;
-		VehicleType type = (VehicleType)p2;
 		GroupID id_g = p1;
 
 		/* Find the first front engine which belong to the group id_g
@@ -290,7 +294,8 @@
  */
 CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	VehicleType type = (VehicleType)p2;
+	p1 = GB(p1, 0, 16);
+	VehicleType type = (VehicleType)GB(p2, 0, 3);
 	if (!IsValidGroupID(p1) || !IsPlayerBuildableVehicleType(type)) return CMD_ERROR;
 
 	Group *g = GetGroup(p1);
@@ -327,6 +332,7 @@
  */
 CommandCost CmdSetGroupReplaceProtection(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	if (!IsValidGroupID(p1)) return CMD_ERROR;
 
 	Group *g = GetGroup(p1);
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/economy.cpp
+++ openttd-0.6.2/src/economy.cpp
@@ -1497,7 +1497,6 @@
 			SetBit(v->vehicle_flags, VF_CARGO_UNLOADING);
 			continue;
 		}
-
 		GoodsEntry *ge = &st->goods[v->cargo_type];
 		const CargoList::List *cargos = v->cargo.Packets();
 
@@ -1883,6 +1882,7 @@
 {
 	Player *p;
 	CommandCost cost(EXPENSES_OTHER);
+	p1 = GB(p1, 0, 8);
 
 	/* Check if buying shares is allowed (protection against modified clients) */
 	/* Cannot buy own shares */
@@ -1932,6 +1932,7 @@
 {
 	Player *p;
 	Money cost;
+	p1 = GB(p1, 0, 8);
 
 	/* Check if selling shares is allowed (protection against modified clients) */
 	/* Cannot sell own shares */
@@ -1969,6 +1970,7 @@
  */
 CommandCost CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 8);
 	Player *p;
 	PlayerID pid = (PlayerID)p1;
 
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/industry_cmd.cpp
+++ openttd-0.6.2/src/industry_cmd.cpp
@@ -1622,7 +1622,10 @@
  */
 CommandCost CmdBuildIndustry(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	const IndustrySpec *indspec = GetIndustrySpec(GB(p1, 0, 16));
+	IndustryType it = GB(p1, 0, 16);
+	if (it >= NUM_INDUSTRYTYPES) return CMD_ERROR;
+
+	const IndustrySpec *indspec = GetIndustrySpec(it);
 
 	/* Check if the to-be built/founded industry is available for this climate. */
 	if (!indspec->enabled) {
@@ -1646,7 +1649,7 @@
 					 * because parameter evaluation order is not guaranteed in the c++ standard
 					 */
 					tile = RandomTile();
-					const Industry *ind = CreateNewIndustryHelper(tile, p1, flags, indspec, RandomRange(indspec->num_table), p2);
+					const Industry *ind = CreateNewIndustryHelper(tile, it, flags, indspec, RandomRange(indspec->num_table), p2);
 					if (ind != NULL) {
 						SetDParam(0, indspec->name);
 						if (indspec->new_industry_text > STR_LAST_STRINGID) {
@@ -1673,7 +1676,7 @@
 			if (--num < 0) num = indspec->num_table - 1;
 		} while (!CheckIfIndustryTilesAreFree(tile, itt[num], num, p1));
 
-		if (CreateNewIndustryHelper(tile, p1, flags, indspec, num, p2) == NULL) return CMD_ERROR;
+		if (CreateNewIndustryHelper(tile, it, flags, indspec, num, p2) == NULL) return CMD_ERROR;
 	}
 
 	return CommandCost(EXPENSES_OTHER, indspec->GetConstructionCost());
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/ship_cmd.cpp
+++ openttd-0.6.2/src/ship_cmd.cpp
@@ -810,6 +810,7 @@
 	UnitID unit_num;
 	Engine *e;
 
+	p1 = GB(p1, 0, 16);
 	if (!IsEngineBuildable(p1, VEH_SHIP, _current_player)) return_cmd_error(STR_SHIP_NOT_AVAILABLE);
 
 	value = EstimateShipCost(p1);
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/terraform_cmd.cpp
+++ openttd-0.6.2/src/terraform_cmd.cpp
@@ -365,7 +365,7 @@
 	oldh = TileHeight(p1);
 
 	/* compute new height */
-	h = oldh + p2;
+	h = oldh + (int8)p2;
 
 	/* Check range of destination height */
 	if (h > MAX_TILE_HEIGHT) return_cmd_error((oldh == 0) ? STR_1003_ALREADY_AT_SEA_LEVEL : STR_1004_TOO_HIGH);
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/station_cmd.cpp
+++ openttd-0.6.2/src/station_cmd.cpp
@@ -1320,6 +1320,7 @@
  */
 CommandCost CmdBuildRoadStop(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 2);
 	bool type = HasBit(p2, 0);
 	bool is_drive_through = HasBit(p2, 1);
 	bool build_over_road  = is_drive_through && IsNormalRoadTile(tile);
@@ -2631,6 +2632,7 @@
  */
 CommandCost CmdRenameStation(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
+	p1 = GB(p1, 0, 16);
 	if (!IsValidStationID(p1) || StrEmpty(_cmd_text)) return CMD_ERROR;
 	Station *st = GetStation(p1);
 
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/tunnelbridge_cmd.cpp
+++ openttd-0.6.2/src/tunnelbridge_cmd.cpp
@@ -218,7 +218,7 @@
 			break;
 
 		case TRANSPORT_RAIL:
-			railtype = (RailType)GB(p2, 8, 8);
+			railtype = (RailType)GB(p2, 8, 4);
 			if (!ValParamRailtype(railtype)) return CMD_ERROR;
 			break;
 
@@ -467,7 +467,7 @@
 
 	_build_tunnel_endtile = 0;
 	if (transport_type == TRANSPORT_RAIL) {
-		if (!ValParamRailtype((RailType)p1)) return CMD_ERROR;
+		if (!ValParamRailtype((RailType)GB(p1, 0, 4))) return CMD_ERROR;
 	} else {
 		const RoadTypes rts = (RoadTypes)GB(p1, 0, 3);
 		if (!AreValidRoadTypes(rts) || !HasRoadTypesAvail(_current_player, rts)) return CMD_ERROR;
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/rail_cmd.cpp
+++ openttd-0.6.2/src/rail_cmd.cpp
@@ -305,8 +305,8 @@
 CommandCost CmdBuildSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	Slope tileh;
-	RailType railtype = (RailType)p1;
-	Track track = (Track)p2;
+	RailType railtype = (RailType)GB(p1, 0, 4);
+	Track track = (Track)GB(p2, 0, 3);
 	TrackBits trackbit;
 	CommandCost cost(EXPENSES_CONSTRUCTION);
 	CommandCost ret;
@@ -438,12 +438,12 @@
  */
 CommandCost CmdRemoveSingleRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
-	Track track = (Track)p2;
+	Track track = (Track)GB(p2, 0, 3);
 	TrackBits trackbit;
 	CommandCost cost(EXPENSES_CONSTRUCTION, _price.remove_rail );
 	bool crossing = false;
 
-	if (!ValParamTrackOrientation((Track)p2)) return CMD_ERROR;
+	if (!ValParamTrackOrientation(track)) return CMD_ERROR;
 	trackbit = TrackToTrackBits(track);
 
 	/* Need to read tile owner now because it may change when the rail is removed
@@ -734,6 +734,7 @@
 	Slope tileh;
 
 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
+	p1 = GB(p1, 0, 4);
 	if (!ValParamRailtype((RailType)p1)) return CMD_ERROR;
 
 	tileh = GetTileSlope(tile, NULL);
@@ -984,10 +985,9 @@
 	bool semaphores = HasBit(p2, 4);
 	bool remove = HasBit(p2, 5);
 	bool autofill = HasBit(p2, 6);
-	Trackdir trackdir = TrackToTrackdir(track);
 	byte signal_density = GB(p2, 24, 8);
 
-	if (p1 >= MapSize()) return CMD_ERROR;
+	if (p1 >= MapSize() || !ValParamTrackOrientation(track)) return CMD_ERROR;
 	end_tile = p1;
 	if (signal_density == 0 || signal_density > 20) return CMD_ERROR;
 
@@ -997,6 +997,7 @@
 	 * since the original amount will be too dense (shorter tracks) */
 	signal_density *= 2;
 
+	Trackdir trackdir = TrackToTrackdir(track);
 	if (CmdFailed(ValidateAutoDrag(&trackdir, tile, end_tile))) return CMD_ERROR;
 
 	track = TrackdirToTrack(trackdir); /* trackdir might have changed, keep track in sync */
@@ -1178,7 +1179,7 @@
 CommandCost CmdConvertRail(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
 {
 	CommandCost cost(EXPENSES_CONSTRUCTION);
-	RailType totype = (RailType)p2;
+	RailType totype = (RailType)GB(p2, 0, 4);
 
 	if (!ValParamRailtype(totype)) return CMD_ERROR;
 	if (p1 >= MapSize()) return CMD_ERROR;
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/network/network_server.cpp
+++ openttd-0.6.2/src/network/network_server.cpp
@@ -221,7 +221,7 @@
 	/* Invalid packet when status is AUTH or higher */
 	if (cs->status >= STATUS_AUTH) return;
 
-	cs->status = STATUS_AUTHORIZING;
+	cs->status = type == NETWORK_GAME_PASSWORD ? STATUS_AUTH_GAME : STATUS_AUTH_COMPANY;
 
 	Packet *p = NetworkSend_Init(PACKET_SERVER_NEED_PASSWORD);
 	p->Send_uint8(type);
@@ -305,7 +305,7 @@
 	//      last 2 are repeated MAX_PLAYERS time
 	//
 
-	static FILE *file_pointer;
+	static FILE *file_pointer = NULL;
 	static uint sent_packets; // How many packets we did send succecfully last time
 
 	if (cs->status < STATUS_AUTH) {
@@ -321,9 +321,12 @@
 		// Make a dump of the current game
 		if (SaveOrLoad(filename, SL_SAVE, AUTOSAVE_DIR) != SL_OK) error("network savedump failed");
 
+		if (file_pointer != NULL) fclose(file_pointer);
+
 		file_pointer = FioFOpenFile(filename, "rb", AUTOSAVE_DIR);
-		fseek(file_pointer, 0, SEEK_END);
+		if (file_pointer == NULL) error("network savedump failed - could not open just saved dump");
 
+		fseek(file_pointer, 0, SEEK_END);
 		if (ftell(file_pointer) == 0) error("network savedump failed - zero sized savegame?");
 
 		// Now send the _frame_counter and how many packets are coming
@@ -365,6 +368,7 @@
 				//  to send it is ready (maybe that happens like never ;))
 				cs->status = STATUS_DONE_MAP;
 				fclose(file_pointer);
+				file_pointer = NULL;
 
 				{
 					NetworkTCPSocketHandler *new_cs;
@@ -715,7 +719,7 @@
 	type = (NetworkPasswordType)p->Recv_uint8();
 	p->Recv_string(password, sizeof(password));
 
-	if (cs->status == STATUS_AUTHORIZING && type == NETWORK_GAME_PASSWORD) {
+	if (cs->status == STATUS_AUTH_GAME && type == NETWORK_GAME_PASSWORD) {
 		// Check game-password
 		if (strcmp(password, _network_game_info.server_password) != 0) {
 			// Password is invalid
@@ -733,7 +737,7 @@
 		// Valid password, allow user
 		SEND_COMMAND(PACKET_SERVER_WELCOME)(cs);
 		return;
-	} else if (cs->status == STATUS_AUTHORIZING && type == NETWORK_COMPANY_PASSWORD) {
+	} else if (cs->status == STATUS_AUTH_COMPANY && type == NETWORK_COMPANY_PASSWORD) {
 		ci = DEREF_CLIENT_INFO(cs);
 
 		if (strcmp(password, _network_player_info[ci->client_playas].password) != 0) {
only in patch2:
unchanged:
--- openttd-0.6.2.orig/src/network/core/tcp.h
+++ openttd-0.6.2/src/network/core/tcp.h
@@ -75,13 +75,15 @@
 /** Status of a client */
 enum ClientStatus {
 	STATUS_INACTIVE,   ///< The client is not connected nor active
-	STATUS_AUTHORIZING,///< The client is authorizing
+	STATUS_AUTH_GAME,  ///< The client is authorizing with game (server) password
+	STATUS_AUTH_COMPANY, ///< The client is authorizing with company password
 	STATUS_AUTH,       ///< The client is authorized
 	STATUS_MAP_WAIT,   ///< The client is waiting as someone else is downloading the map
 	STATUS_MAP,        ///< The client is downloading the map
 	STATUS_DONE_MAP,   ///< The client has downloaded the map
 	STATUS_PRE_ACTIVE, ///< The client is catching up the delayed frames
 	STATUS_ACTIVE,     ///< The client is an active player in the game
+	STATUS_END         ///< Must ALWAYS be on the end of this list!! (period)
 };
 
 /** Base socket handler for all TCP sockets */

Reply to: