fix a potential data leak

This commit is contained in:
Daniella / Tove 2023-09-29 13:28:29 +02:00
parent 707ff8ca7d
commit a77d21b1ac
Signed by: TudbuT
GPG key ID: 7D63D5634B7C417F
5 changed files with 66 additions and 22 deletions

Binary file not shown.

View file

@ -29,15 +29,16 @@ import java.nio.file.Files;
import java.nio.file.Paths;
import java.nio.file.StandardCopyOption;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.function.Consumer;
public class BaseBand {
public static int majorVersion = 1;
public static int buildNumber = 399;
public static String hash = "b00740a0b2e5152d";
public static int buildNumber = 407;
public static String hash = "9e086ff8ab086183";
public static String name = "BaseBand";
public long timeOfCompile = 1695983122629L;
public long timeOfCompile = 1695986519815L;
public CommandManager commandRegistry;
public EventBus eventBus;
public ArrayList<Module> modules = new ArrayList<>();
@ -70,20 +71,24 @@ public class BaseBand {
try {
Object keeper = BaseBand.class.getClassLoader().getClass().getFields()[1].get(BaseBand.class.getClassLoader());
Method access = keeper.getClass().getMethods()[1];
access.invoke(keeper, (Consumer<Object>) accessor -> {
try {
Object registry = accessor.getClass().getMethods()[0].invoke(accessor);
for (Method save : registry.getClass().getMethods()) {
if(save.getParameterCount() == 0 && save.getReturnType() == Void.TYPE && save.getDeclaringClass() == registry.getClass()) {
save.invoke(registry); // registry save
for (Method access : keeper.getClass().getMethods()) {
if(Arrays.equals(access.getParameterTypes(), new Class<?>[]{Consumer.class}) && access.getDeclaringClass() == keeper.getClass()) {
access.invoke(keeper, (Consumer<Object>) accessor -> {
try {
Object registry = accessor.getClass().getMethods()[0].invoke(accessor);
for (Method save : registry.getClass().getMethods()) {
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) {
e.printStackTrace();
Utils.crash();

View file

@ -14,6 +14,7 @@ public class DataKeeper<T> {
public static boolean forgetAll = false;
public Lock forget = new Lock(true);
private final PermissionManager permissionManager;
private Supplier<T> dataInsertion;
private final Strictness strictness;
@ -39,10 +40,13 @@ public class DataKeeper<T> {
}
public Strictness getStrictness() {
return strictness;
return strictness.clone();
}
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.showErrors())
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);
}
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() {
lock.waitHere();
lock.lock();
@ -62,7 +77,7 @@ public class DataKeeper<T> {
AtomicReference<T> data = new AtomicReference<>(dataInsertion.get());
Strictness strictness = this.strictness.clone();
dataInsertion = null;
while(!forgetAll) {
while(!forgetAll && forget.isLocked()) {
lock.waitHere();
lock.lock(500);

View file

@ -25,6 +25,8 @@ import java.net.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
public class CustomClassloader extends ClassLoader {
@ -32,12 +34,14 @@ public class CustomClassloader extends ClassLoader {
public static Class<?> customMixinServerClass = CustomMixinServer.class;
private static final DataKeeper<HashMap<String, byte[]>> encryptedClasses;
private static final DataKeeper<HashMap<String, byte[]>> encryptedResources;
private static final DataKeeper<PermissionManager> transferPermissionManager;
public static final DataKeeper<Object> registryTransfer;
static {
encryptedClasses = init1();
registryTransfer = init2();
encryptedResources = init3();
transferPermissionManager = init4();
}
private static DataKeeper<HashMap<String, byte[]>> init1() {
@ -45,7 +49,7 @@ public class CustomClassloader extends ClassLoader {
return new DataKeeper<>(
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, CustomMixinServer.class))),
Loader.defaultStrictness,
new HashMap<>()
null
);
}
@ -61,10 +65,21 @@ public class CustomClassloader extends ClassLoader {
return new DataKeeper<>(
new HideErrorRestriction(new BBPermissionManager(new CallClassRestriction(CustomClassloader.class, URLStreamHandler.class, URLStreamHandler.class, ResourceConnection.class))),
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() {
}
@ -91,8 +106,13 @@ public class CustomClassloader extends ClassLoader {
Loader.exit();
}
encryptedClasses.access(accessor -> accessor.setValue((HashMap<String, byte[]>) classes));
encryptedResources.access(accessor -> accessor.setValue((HashMap<String, byte[]>) resources));
AtomicReference<HashMap<String, byte[]>> data = new AtomicReference<>();
((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 {
Field parent = ClassLoader.class.getDeclaredField("parent");

View file

@ -32,6 +32,7 @@ import java.net.Socket;
import java.security.MessageDigest;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Supplier;
import java.util.zip.ZipEntry;
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(
new HideErrorRestriction(
new BBPermissionManager(