From 3f1d9c9ac81a321eee7b141e21c277c89281a798 Mon Sep 17 00:00:00 2001 From: Telesphoreo Date: Sun, 22 May 2022 21:18:57 -0500 Subject: [PATCH] Create 0032-Prevent-crash-paintings-and-similar-entity-OOB-explo.patch --- ...intings-and-similar-entity-OOB-explo.patch | 231 ++++++++++++++++++ 1 file changed, 231 insertions(+) create mode 100644 patches/server/0032-Prevent-crash-paintings-and-similar-entity-OOB-explo.patch diff --git a/patches/server/0032-Prevent-crash-paintings-and-similar-entity-OOB-explo.patch b/patches/server/0032-Prevent-crash-paintings-and-similar-entity-OOB-explo.patch new file mode 100644 index 0000000..63d5e2b --- /dev/null +++ b/patches/server/0032-Prevent-crash-paintings-and-similar-entity-OOB-explo.patch @@ -0,0 +1,231 @@ +From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 +From: Telesphoreo +Date: Sun, 22 May 2022 21:15:51 -0500 +Subject: [PATCH] Prevent crash paintings and similar entity OOB exploits + + +diff --git a/src/main/java/com/github/atlasmediagroup/scissors/MathUtility.java b/src/main/java/com/github/atlasmediagroup/scissors/MathUtility.java +new file mode 100644 +index 0000000000000000000000000000000000000000..7965cf3abd02d415dd0e71a0de73987e5fdf11ec +--- /dev/null ++++ b/src/main/java/com/github/atlasmediagroup/scissors/MathUtility.java +@@ -0,0 +1,29 @@ ++package com.github.atlasmediagroup.scissors; ++ ++public class MathUtility ++{ ++ public static int clampInt(int number, int minimum, int maximum) ++ { ++ return Math.min(Math.max(number, minimum), maximum); ++ } ++ ++ public static long clampLong(long number, long minimum, long maximum) ++ { ++ return Math.min(Math.max(number, minimum), maximum); ++ } ++ ++ public static double clampDouble(double number, double minimum, double maximum) ++ { ++ return Math.min(Math.max(number, minimum), maximum); ++ } ++ ++ public static int safeDoubleToInt(double number) ++ { ++ return (int) clampDouble(number, Integer.MIN_VALUE, Integer.MAX_VALUE); ++ } ++ ++ public static int safeLongToInt(long number) ++ { ++ return (int) clampLong(number, Integer.MIN_VALUE, Integer.MAX_VALUE); ++ } ++} +diff --git a/src/main/java/com/github/atlasmediagroup/scissors/NbtUtility.java b/src/main/java/com/github/atlasmediagroup/scissors/NbtUtility.java +index 978cb98c81195640fb3704d2077148f2be0dca36..59a4ff3593e74f72c3843554c2e14b82912c0a54 100644 +--- a/src/main/java/com/github/atlasmediagroup/scissors/NbtUtility.java ++++ b/src/main/java/com/github/atlasmediagroup/scissors/NbtUtility.java +@@ -1,13 +1,9 @@ + package com.github.atlasmediagroup.scissors; + +-import com.google.common.base.Strings; +-import com.google.common.collect.Lists; + import net.minecraft.nbt.*; + + import javax.annotation.Nullable; + import java.nio.charset.StandardCharsets; +-import java.util.Collections; +-import java.util.List; + + public class NbtUtility + { +diff --git a/src/main/java/com/github/atlasmediagroup/scissors/PositionUtility.java b/src/main/java/com/github/atlasmediagroup/scissors/PositionUtility.java +new file mode 100644 +index 0000000000000000000000000000000000000000..fd22a200e070ca5a594802d2f201c6b27d6cddcf +--- /dev/null ++++ b/src/main/java/com/github/atlasmediagroup/scissors/PositionUtility.java +@@ -0,0 +1,83 @@ ++package com.github.atlasmediagroup.scissors; ++ ++import net.minecraft.core.BlockPos; ++import net.minecraft.world.entity.Entity; ++import net.minecraft.world.level.Level; ++import net.minecraft.world.level.border.WorldBorder; ++import net.minecraft.world.phys.Vec3; ++ ++public class PositionUtility ++{ ++ public static Vec3 getValidVec3(double x, double y, double z, Entity entity) ++ { ++ final Level level = entity.level; ++ ++ try ++ { ++ if (level.isInWorldBounds(new BlockPos(Math.floor(MathUtility.safeDoubleToInt(x)), Math.floor(MathUtility.safeDoubleToInt(y)), Math.floor(MathUtility.safeDoubleToInt(z))))) ++ { ++ return new Vec3(x, y, z); ++ } ++ else ++ { ++ final WorldBorder worldBorder = level.getWorldBorder(); ++ ++ final double maxX = worldBorder.getMaxX(); ++ final double maxY = level.getMaxBuildHeight(); ++ final double maxZ = worldBorder.getMaxZ(); ++ ++ final double minX = worldBorder.getMinX(); ++ final double minY = level.getMinBuildHeight(); ++ final double minZ = worldBorder.getMinZ(); ++ ++ return new Vec3(MathUtility.clampDouble(x, minX, maxX), MathUtility.clampDouble(y, minY, maxY), MathUtility.clampDouble(z, minZ, maxZ)); ++ } ++ } ++ catch (Exception e) ++ { // If we throw some sort of exception due to the position being crazy, catch it ++ return new Vec3(0, 0, 0); ++ } ++ } ++ ++ public static Vec3 getValidVec3FromBlockPos(BlockPos blockPos, Entity entity) ++ { ++ final BlockPos validBlockPos = getValidBlockPos(blockPos, entity); ++ ++ return new Vec3(validBlockPos.getX(), validBlockPos.getY(), validBlockPos.getZ()); ++ } ++ ++ public static BlockPos getValidBlockPos(BlockPos blockPos, Entity entity) ++ { ++ final Level level = entity.level; ++ ++ try ++ { ++ if (level.isInWorldBounds(blockPos)) ++ { ++ return blockPos; ++ } ++ else ++ { ++ final int x = blockPos.getX(); ++ final int y = blockPos.getY(); ++ final int z = blockPos.getZ(); ++ ++ final WorldBorder worldBorder = level.getWorldBorder(); ++ ++ final int maxX = MathUtility.safeDoubleToInt(worldBorder.getMaxX()); ++ final int maxY = level.getMaxBuildHeight(); ++ final int maxZ = MathUtility.safeDoubleToInt(worldBorder.getMaxZ()); ++ ++ final int minX = MathUtility.safeDoubleToInt(worldBorder.getMinX()); ++ final int minY = level.getMinBuildHeight(); ++ final int minZ = MathUtility.safeDoubleToInt(worldBorder.getMinZ()); ++ ++ return new BlockPos(MathUtility.clampInt(x, minX, maxX), MathUtility.clampInt(y, minY, maxY), MathUtility.clampInt(z, minZ, maxZ)); ++ } ++ } ++ catch (Exception e) ++ { // If we throw some sort of exception due to the position being crazy, catch it ++ return new BlockPos(0, 0, 0); ++ } ++ } ++} +diff --git a/src/main/java/net/minecraft/world/entity/Entity.java b/src/main/java/net/minecraft/world/entity/Entity.java +index bc9e6a2403d2e0d174c87f9bcb54dc4af47c610b..5fffd4f1661a20522d1bb85308901826dfaf7dd9 100644 +--- a/src/main/java/net/minecraft/world/entity/Entity.java ++++ b/src/main/java/net/minecraft/world/entity/Entity.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.entity; + ++import com.github.atlasmediagroup.scissors.PositionUtility; + import com.google.common.collect.ImmutableList; + import com.google.common.collect.ImmutableList.Builder; + import com.google.common.collect.Iterables; +@@ -1774,6 +1775,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + } + + public void moveTo(double x, double y, double z, float yaw, float pitch) { ++ // Scissors start - Reassign x, y & z to make sure entities can't move out of the world border ++ Vec3 vec3 = PositionUtility.getValidVec3(x, y, z, this); ++ x = vec3.x; ++ y = vec3.y; ++ z = vec3.z; ++ // Scissors end ++ + // Paper - cancel entity velocity if teleported + if (!preserveMotion) { + this.deltaMovement = Vec3.ZERO; +@@ -3208,6 +3216,10 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + + @Nullable + public Entity teleportTo(ServerLevel worldserver, BlockPos location) { ++ // Scissors start - Reassign location to a safe value ++ location = PositionUtility.getValidBlockPos(location, this); ++ // Scissors end ++ + // CraftBukkit end + // Paper start - fix bad state entities causing dupes + if (!isAlive() || !valid) { +@@ -4102,6 +4114,13 @@ public abstract class Entity implements Nameable, EntityAccess, CommandSource { + this.setPosRaw(x, y, z, false); + } + public final void setPosRaw(double x, double y, double z, boolean forceBoundingBoxUpdate) { ++ // Scissors start - Reassign x, y & z to prevent entities from moving outside the world border ++ Vec3 vec = PositionUtility.getValidVec3(x, y, z, this); ++ x = vec.x; ++ y = vec.y; ++ z = vec.z; ++ // Scissors end ++ + // Paper start - block invalid positions + if (!checkPosition(this, x, y, z)) { + return; +diff --git a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java +index 2805ebfe4ffe769bcde778a1225b3101c91538d8..7c988395567c170d825af2bd99121f2d4d05cd8d 100644 +--- a/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java ++++ b/src/main/java/net/minecraft/world/entity/decoration/HangingEntity.java +@@ -1,5 +1,6 @@ + package net.minecraft.world.entity.decoration; + ++import com.github.atlasmediagroup.scissors.PositionUtility; + import java.util.function.Predicate; + import javax.annotation.Nullable; + import net.minecraft.core.BlockPos; +@@ -265,7 +266,9 @@ public abstract class HangingEntity extends Entity { + + @Override + public void readAdditionalSaveData(CompoundTag nbt) { +- this.pos = new BlockPos(nbt.getInt("TileX"), nbt.getInt("TileY"), nbt.getInt("TileZ")); ++ // Scissors start - Stop this stupid bullshit ++ this.pos = PositionUtility.getValidBlockPos(new BlockPos(nbt.getInt("TileX"), nbt.getInt("TileY"), nbt.getInt("TileZ")), this); ++ // Scissors end + } + + public abstract int getWidth(); +@@ -292,7 +295,9 @@ public abstract class HangingEntity extends Entity { + + @Override + public void setPos(double x, double y, double z) { +- this.pos = new BlockPos(x, y, z); ++ // Scissors start - Fix this stupid bullshit ++ this.pos = PositionUtility.getValidBlockPos(new BlockPos(x, y, z), this); ++ // Scissors end + this.recalculateBoundingBox(); + this.hasImpulse = true; + }