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.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,13 +71,15 @@ public class BaseBand {
|
|||
|
||||
try {
|
||||
Object keeper = BaseBand.class.getClassLoader().getClass().getFields()[1].get(BaseBand.class.getClassLoader());
|
||||
Method access = keeper.getClass().getMethods()[1];
|
||||
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) {
|
||||
|
@ -84,6 +87,8 @@ public class BaseBand {
|
|||
Utils.crash();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Utils.crash();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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");
|
||||
|
|
|
@ -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(
|
||||
|
|
Loading…
Add table
Reference in a new issue