fix a potential data leak
This commit is contained in:
parent
707ff8ca7d
commit
a77d21b1ac
5 changed files with 66 additions and 22 deletions
Binary file not shown.
|
@ -29,15 +29,16 @@ import java.nio.file.Files;
|
||||||
import java.nio.file.Paths;
|
import java.nio.file.Paths;
|
||||||
import java.nio.file.StandardCopyOption;
|
import java.nio.file.StandardCopyOption;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
||||||
public class BaseBand {
|
public class BaseBand {
|
||||||
public static int majorVersion = 1;
|
public static int majorVersion = 1;
|
||||||
public static int buildNumber = 399;
|
public static int buildNumber = 407;
|
||||||
public static String hash = "b00740a0b2e5152d";
|
public static String hash = "9e086ff8ab086183";
|
||||||
|
|
||||||
public static String name = "BaseBand";
|
public static String name = "BaseBand";
|
||||||
public long timeOfCompile = 1695983122629L;
|
public long timeOfCompile = 1695986519815L;
|
||||||
public CommandManager commandRegistry;
|
public CommandManager commandRegistry;
|
||||||
public EventBus eventBus;
|
public EventBus eventBus;
|
||||||
public ArrayList<Module> modules = new ArrayList<>();
|
public ArrayList<Module> modules = new ArrayList<>();
|
||||||
|
@ -70,20 +71,24 @@ public class BaseBand {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Object keeper = BaseBand.class.getClassLoader().getClass().getFields()[1].get(BaseBand.class.getClassLoader());
|
Object keeper = BaseBand.class.getClassLoader().getClass().getFields()[1].get(BaseBand.class.getClassLoader());
|
||||||
Method access = keeper.getClass().getMethods()[1];
|
for (Method access : keeper.getClass().getMethods()) {
|
||||||
access.invoke(keeper, (Consumer<Object>) accessor -> {
|
if(Arrays.equals(access.getParameterTypes(), new Class<?>[]{Consumer.class}) && access.getDeclaringClass() == keeper.getClass()) {
|
||||||
try {
|
access.invoke(keeper, (Consumer<Object>) accessor -> {
|
||||||
Object registry = accessor.getClass().getMethods()[0].invoke(accessor);
|
try {
|
||||||
for (Method save : registry.getClass().getMethods()) {
|
Object registry = accessor.getClass().getMethods()[0].invoke(accessor);
|
||||||
if(save.getParameterCount() == 0 && save.getReturnType() == Void.TYPE && save.getDeclaringClass() == registry.getClass()) {
|
for (Method save : registry.getClass().getMethods()) {
|
||||||
save.invoke(registry); // registry save
|
if (save.getParameterCount() == 0 && save.getReturnType() == Void.TYPE && save.getDeclaringClass() == registry.getClass()) {
|
||||||
|
save.invoke(registry); // registry save
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Utils.crash();
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
} catch (IllegalAccessException | InvocationTargetException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
Utils.crash();
|
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Utils.crash();
|
Utils.crash();
|
||||||
|
|
|
@ -14,6 +14,7 @@ public class DataKeeper<T> {
|
||||||
public static boolean forgetAll = false;
|
public static boolean forgetAll = false;
|
||||||
|
|
||||||
|
|
||||||
|
public Lock forget = new Lock(true);
|
||||||
private final PermissionManager permissionManager;
|
private final PermissionManager permissionManager;
|
||||||
private Supplier<T> dataInsertion;
|
private Supplier<T> dataInsertion;
|
||||||
private final Strictness strictness;
|
private final Strictness strictness;
|
||||||
|
@ -39,10 +40,13 @@ public class DataKeeper<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Strictness getStrictness() {
|
public Strictness getStrictness() {
|
||||||
return strictness;
|
return strictness.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void access(Consumer<Accessor<T>> accessor) {
|
public void access(Consumer<Accessor<T>> accessor) {
|
||||||
|
if(!forget.isLocked()) {
|
||||||
|
throw new IllegalStateException("This DataKeeper has already forgotten its value.");
|
||||||
|
}
|
||||||
if(!permissionManager.checkCaller(strictness)) {
|
if(!permissionManager.checkCaller(strictness)) {
|
||||||
if(permissionManager.showErrors())
|
if(permissionManager.showErrors())
|
||||||
throw new IllegalAccessError("The active PermissionManager does not allow you to access this DataKeeper.");
|
throw new IllegalAccessError("The active PermissionManager does not allow you to access this DataKeeper.");
|
||||||
|
@ -55,6 +59,17 @@ public class DataKeeper<T> {
|
||||||
waitLock.waitHere(500);
|
waitLock.waitHere(500);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void forget() {
|
||||||
|
forget.unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DataKeeper<T> forgetIn(int ms) {
|
||||||
|
if(forget.timeLeft() > ms)
|
||||||
|
return this;
|
||||||
|
forget.lock(ms);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
private void keep() {
|
private void keep() {
|
||||||
lock.waitHere();
|
lock.waitHere();
|
||||||
lock.lock();
|
lock.lock();
|
||||||
|
@ -62,7 +77,7 @@ public class DataKeeper<T> {
|
||||||
AtomicReference<T> data = new AtomicReference<>(dataInsertion.get());
|
AtomicReference<T> data = new AtomicReference<>(dataInsertion.get());
|
||||||
Strictness strictness = this.strictness.clone();
|
Strictness strictness = this.strictness.clone();
|
||||||
dataInsertion = null;
|
dataInsertion = null;
|
||||||
while(!forgetAll) {
|
while(!forgetAll && forget.isLocked()) {
|
||||||
lock.waitHere();
|
lock.waitHere();
|
||||||
lock.lock(500);
|
lock.lock(500);
|
||||||
|
|
||||||
|
|
|
@ -25,6 +25,8 @@ import java.net.*;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
|
|
||||||
public class CustomClassloader extends ClassLoader {
|
public class CustomClassloader extends ClassLoader {
|
||||||
|
@ -32,12 +34,14 @@ public class CustomClassloader extends ClassLoader {
|
||||||
public static Class<?> customMixinServerClass = CustomMixinServer.class;
|
public static Class<?> customMixinServerClass = CustomMixinServer.class;
|
||||||
private static final DataKeeper<HashMap<String, byte[]>> encryptedClasses;
|
private static final DataKeeper<HashMap<String, byte[]>> encryptedClasses;
|
||||||
private static final DataKeeper<HashMap<String, byte[]>> encryptedResources;
|
private static final DataKeeper<HashMap<String, byte[]>> encryptedResources;
|
||||||
|
private static final DataKeeper<PermissionManager> transferPermissionManager;
|
||||||
public static final DataKeeper<Object> registryTransfer;
|
public static final DataKeeper<Object> registryTransfer;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
encryptedClasses = init1();
|
encryptedClasses = init1();
|
||||||
registryTransfer = init2();
|
registryTransfer = init2();
|
||||||
encryptedResources = init3();
|
encryptedResources = init3();
|
||||||
|
transferPermissionManager = init4();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static DataKeeper<HashMap<String, byte[]>> init1() {
|
private static DataKeeper<HashMap<String, byte[]>> init1() {
|
||||||
|
@ -45,7 +49,7 @@ public class CustomClassloader extends ClassLoader {
|
||||||
return new DataKeeper<>(
|
return new DataKeeper<>(
|
||||||
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, CustomMixinServer.class))),
|
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, CustomMixinServer.class))),
|
||||||
Loader.defaultStrictness,
|
Loader.defaultStrictness,
|
||||||
new HashMap<>()
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,10 +65,21 @@ public class CustomClassloader extends ClassLoader {
|
||||||
return new DataKeeper<>(
|
return new DataKeeper<>(
|
||||||
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, URLStreamHandler.class, URLStreamHandler.class, ResourceConnection.class))),
|
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, URLStreamHandler.class, URLStreamHandler.class, ResourceConnection.class))),
|
||||||
Loader.defaultStrictness,
|
Loader.defaultStrictness,
|
||||||
new HashMap<>()
|
null
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static DataKeeper<PermissionManager> init4() {
|
||||||
|
PermissionManager perm = new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class)));
|
||||||
|
return new DataKeeper<>(perm, Loader.defaultStrictness, perm);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PermissionManager getTransferPermissionManager() {
|
||||||
|
AtomicReference<PermissionManager> manager = new AtomicReference<>();
|
||||||
|
transferPermissionManager.access(x -> manager.set(x.getValue()));
|
||||||
|
return manager.get();
|
||||||
|
}
|
||||||
|
|
||||||
public static void ensureInit() {
|
public static void ensureInit() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,8 +106,13 @@ public class CustomClassloader extends ClassLoader {
|
||||||
Loader.exit();
|
Loader.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
encryptedClasses.access(accessor -> accessor.setValue((HashMap<String, byte[]>) classes));
|
AtomicReference<HashMap<String, byte[]>> data = new AtomicReference<>();
|
||||||
encryptedResources.access(accessor -> accessor.setValue((HashMap<String, byte[]>) resources));
|
|
||||||
|
((DataKeeper<HashMap<String, byte[]>>) ((Supplier<Object>) classes).get()).access(accessor -> data.set(accessor.getValue()));
|
||||||
|
encryptedClasses.access(accessor -> accessor.setValue(data.get()));
|
||||||
|
|
||||||
|
((DataKeeper<HashMap<String, byte[]>>) ((Supplier<Object>) resources).get()).access(accessor -> data.set(accessor.getValue()));
|
||||||
|
encryptedResources.access(accessor -> accessor.setValue(data.get()));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Field parent = ClassLoader.class.getDeclaredField("parent");
|
Field parent = ClassLoader.class.getDeclaredField("parent");
|
||||||
|
|
|
@ -32,6 +32,7 @@ import java.net.Socket;
|
||||||
import java.security.MessageDigest;
|
import java.security.MessageDigest;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.atomic.AtomicReference;
|
import java.util.concurrent.atomic.AtomicReference;
|
||||||
|
import java.util.function.Supplier;
|
||||||
import java.util.zip.ZipEntry;
|
import java.util.zip.ZipEntry;
|
||||||
import java.util.zip.ZipInputStream;
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
|
@ -248,7 +249,10 @@ public class Loader {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
CustomClassloader customCL = new CustomClassloader(classCache, resources);
|
CustomClassloader customCL = new CustomClassloader(
|
||||||
|
(Supplier<Object>) (() -> new DataKeeper<>(CustomClassloader.getTransferPermissionManager(), defaultStrictness, classCache).forgetIn(2000)),
|
||||||
|
(Supplier<Object>) (() -> new DataKeeper<>(CustomClassloader.getTransferPermissionManager(), defaultStrictness, resources).forgetIn(2000))
|
||||||
|
);
|
||||||
permissionManager.access(x -> x.setValue(
|
permissionManager.access(x -> x.setValue(
|
||||||
new HideErrorRestriction(
|
new HideErrorRestriction(
|
||||||
new BBPermissionManager(
|
new BBPermissionManager(
|
||||||
|
|
Loading…
Add table
Reference in a new issue