Skip to content

Commit 74d0521

Browse files
committed
Also validate length before caring to invest time into processing
1 parent 7ad0661 commit 74d0521

File tree

3 files changed

+15
-5
lines changed

3 files changed

+15
-5
lines changed

proxy/src/main/java/com/velocitypowered/proxy/connection/client/ClientPlaySessionHandler.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -308,14 +308,17 @@ public boolean handle(PluginMessagePacket packet) {
308308
logger.warn("A plugin message was received while the backend server was not "
309309
+ "ready. Channel: {}. Packet discarded.", packet.getChannel());
310310
} else if (PluginMessageUtil.isRegister(packet)) {
311-
List<ChannelIdentifier> channels = PluginMessageUtil.getChannels(packet, this.player.getProtocolVersion());
311+
List<ChannelIdentifier> channels =
312+
PluginMessageUtil.getChannels(this.player.getClientsideChannels().size(), packet,
313+
this.player.getProtocolVersion());
312314
player.getClientsideChannels().addAll(channels);
313315
server.getEventManager()
314316
.fireAndForget(
315317
new PlayerChannelRegisterEvent(player, ImmutableList.copyOf(channels)));
316318
backendConn.write(packet.retain());
317319
} else if (PluginMessageUtil.isUnregister(packet)) {
318-
player.getClientsideChannels().removeAll(PluginMessageUtil.getChannels(packet, this.player.getProtocolVersion()));
320+
player.getClientsideChannels()
321+
.removeAll(PluginMessageUtil.getChannels(0, packet, this.player.getProtocolVersion()));
319322
backendConn.write(packet.retain());
320323
} else if (PluginMessageUtil.isMcBrand(packet)) {
321324
String brand = PluginMessageUtil.readBrandMessage(packet.content());
@@ -392,7 +395,8 @@ public boolean handle(FinishedUpdatePacket packet) {
392395
// Complete client switch
393396
player.getConnection().setActiveSessionHandler(StateRegistry.CONFIG);
394397
VelocityServerConnection serverConnection = player.getConnectedServer();
395-
server.getEventManager().fireAndForget(new PlayerEnteredConfigurationEvent(player, serverConnection));
398+
server.getEventManager()
399+
.fireAndForget(new PlayerEnteredConfigurationEvent(player, serverConnection));
396400
if (serverConnection != null) {
397401
MinecraftConnection smc = serverConnection.ensureConnected();
398402
CompletableFuture.runAsync(() -> {

proxy/src/main/java/com/velocitypowered/proxy/connection/client/ConnectedPlayer.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@
145145
public class ConnectedPlayer implements MinecraftConnectionAssociation, Player, KeyIdentifiable,
146146
VelocityInboundConnection {
147147

148-
private static final int MAX_CLIENTSIDE_PLUGIN_CHANNELS = 1024;
148+
public static final int MAX_CLIENTSIDE_PLUGIN_CHANNELS = 1024;
149149
private static final PlainTextComponentSerializer PASS_THRU_TRANSLATE =
150150
PlainTextComponentSerializer.builder().flattener(TranslatableMapper.FLATTENER).build();
151151
static final PermissionProvider DEFAULT_PERMISSIONS = s -> PermissionFunction.ALWAYS_UNDEFINED;

proxy/src/main/java/com/velocitypowered/proxy/protocol/util/PluginMessageUtil.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
import com.velocitypowered.api.proxy.messages.LegacyChannelIdentifier;
2727
import com.velocitypowered.api.proxy.messages.MinecraftChannelIdentifier;
2828
import com.velocitypowered.api.util.ProxyVersion;
29+
import com.velocitypowered.proxy.connection.client.ConnectedPlayer;
2930
import com.velocitypowered.proxy.protocol.ProtocolUtils;
3031
import com.velocitypowered.proxy.protocol.netty.MinecraftDecoder;
3132
import com.velocitypowered.proxy.protocol.packet.PluginMessagePacket;
@@ -96,10 +97,12 @@ public static boolean isUnregister(PluginMessagePacket message) {
9697
/**
9798
* Fetches all the channels in a register or unregister plugin message.
9899
*
100+
* @param existingChannels the number of channels already registered
99101
* @param message the message to get the channels from
100102
* @return the channels, as an immutable list
101103
*/
102-
public static List<ChannelIdentifier> getChannels(PluginMessagePacket message,
104+
public static List<ChannelIdentifier> getChannels(int existingChannels,
105+
PluginMessagePacket message,
103106
ProtocolVersion protocolVersion) {
104107
checkNotNull(message, "message");
105108
checkArgument(isRegister(message) || isUnregister(message), "Unknown channel type %s",
@@ -110,7 +113,10 @@ public static List<ChannelIdentifier> getChannels(PluginMessagePacket message,
110113
return ImmutableList.of();
111114
}
112115
String payload = message.content().toString(StandardCharsets.UTF_8);
116+
checkArgument(payload.length() <= Short.MAX_VALUE, "payload too long: %s", payload.length());
113117
String[] channels = payload.split("\0");
118+
checkArgument(existingChannels + channels.length <= ConnectedPlayer.MAX_CLIENTSIDE_PLUGIN_CHANNELS,
119+
"too many channels: %s + %s > %s", existingChannels, channels.length, ConnectedPlayer.MAX_CLIENTSIDE_PLUGIN_CHANNELS);
114120
ImmutableList.Builder<ChannelIdentifier> channelIdentifiers = ImmutableList.builderWithExpectedSize(channels.length);
115121
try {
116122
for (String channel : channels) {

0 commit comments

Comments
 (0)