mirror of
https://github.com/SpigotMC/BungeeCord.git
synced 2024-12-25 18:17:38 +01:00
Implement Security Manager
This commit adds the basis for the intergration of a security manager into BungeeCord. The goal of the security manager is to prevent plugins from doing potentially dangerous or otherwise undesirable behaviour that may damage the stability of Bungee itself or pose a risk to the user's server. One common theme in some Bungee plugins, especially those which were written in the very early days, is using Threads and ExecutorServices for scheduling purposes. Not only is this inefficient as there is no use of the thread caching features provided by the scheduler, it is also difficult to track who created which thread. Additionally creating threads not managed by the BungeeCord scheduler poses issues for when|if a plugin reload system is implemented, as these threads cannot be appropriately cleaned up and may continue to leak class references or perhaps even continue executing. At this stage the SecurityManager is set to warn of prohibited actions, but not block them. For some plugins using external APIs, where usage of an ExecutorService is unavoidable, we have included an Unsafe interface to the scheduler which allows direct access to the underlying ExecutorService, or potentially a compatability wrapper.
This commit is contained in:
parent
7347daf203
commit
5d1b660e32
@ -1,5 +1,6 @@
|
|||||||
package net.md_5.bungee.api.scheduler;
|
package net.md_5.bungee.api.scheduler;
|
||||||
|
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
import net.md_5.bungee.api.plugin.Plugin;
|
import net.md_5.bungee.api.plugin.Plugin;
|
||||||
|
|
||||||
@ -71,4 +72,22 @@ public interface TaskScheduler
|
|||||||
* @return the scheduled task
|
* @return the scheduled task
|
||||||
*/
|
*/
|
||||||
ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit);
|
ScheduledTask schedule(Plugin owner, Runnable task, long delay, long period, TimeUnit unit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the unsafe methods of this class.
|
||||||
|
*
|
||||||
|
* @return the unsafe method interface
|
||||||
|
*/
|
||||||
|
Unsafe unsafe();
|
||||||
|
|
||||||
|
interface Unsafe
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An executor service which underlies this scheduler.
|
||||||
|
*
|
||||||
|
* @return the underlying executor service or compatible wrapper
|
||||||
|
*/
|
||||||
|
ExecutorService getExecutorService();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,6 +159,8 @@ public class BungeeCord extends ProxyServer
|
|||||||
|
|
||||||
public BungeeCord() throws IOException
|
public BungeeCord() throws IOException
|
||||||
{
|
{
|
||||||
|
System.setSecurityManager( new BungeeSecurityManager() );
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bundle = ResourceBundle.getBundle( "messages" );
|
bundle = ResourceBundle.getBundle( "messages" );
|
||||||
|
@ -0,0 +1,58 @@
|
|||||||
|
package net.md_5.bungee;
|
||||||
|
|
||||||
|
import java.security.AccessControlException;
|
||||||
|
import java.security.Permission;
|
||||||
|
import java.util.logging.Level;
|
||||||
|
import net.md_5.bungee.api.ProxyServer;
|
||||||
|
|
||||||
|
public class BungeeSecurityManager extends SecurityManager
|
||||||
|
{
|
||||||
|
|
||||||
|
private static final boolean ENFORCE = false;
|
||||||
|
|
||||||
|
private void checkRestricted(String text)
|
||||||
|
{
|
||||||
|
Class[] context = getClassContext();
|
||||||
|
for ( int i = 2; i < context.length; i++ )
|
||||||
|
{
|
||||||
|
ClassLoader loader = context[i].getClassLoader();
|
||||||
|
|
||||||
|
// Bungee can do everything
|
||||||
|
if ( loader == ClassLoader.getSystemClassLoader() )
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Everyone but system can't do anything
|
||||||
|
if ( loader != null )
|
||||||
|
{
|
||||||
|
AccessControlException ex = new AccessControlException( "Plugin violation: " + text );
|
||||||
|
if ( ENFORCE )
|
||||||
|
{
|
||||||
|
throw ex;
|
||||||
|
}
|
||||||
|
|
||||||
|
ProxyServer.getInstance().getLogger().log( Level.WARNING, "Plugin performed restricted action, please inform them to use proper API methods: " + text, ex );
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkExit(int status)
|
||||||
|
{
|
||||||
|
checkRestricted( "Exit: Cannot close VM" );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ThreadGroup getThreadGroup()
|
||||||
|
{
|
||||||
|
checkRestricted( "Thread Creation: Use scheduler" );
|
||||||
|
return super.getThreadGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void checkPermission(Permission perm)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -25,6 +25,16 @@ public class BungeeScheduler implements TaskScheduler
|
|||||||
private final AtomicInteger taskCounter = new AtomicInteger();
|
private final AtomicInteger taskCounter = new AtomicInteger();
|
||||||
private final TIntObjectMap<BungeeTask> tasks = TCollections.synchronizedMap( new TIntObjectHashMap<BungeeTask>() );
|
private final TIntObjectMap<BungeeTask> tasks = TCollections.synchronizedMap( new TIntObjectHashMap<BungeeTask>() );
|
||||||
private final Multimap<Plugin, BungeeTask> tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.<Plugin, BungeeTask>create() );
|
private final Multimap<Plugin, BungeeTask> tasksByPlugin = Multimaps.synchronizedMultimap( HashMultimap.<Plugin, BungeeTask>create() );
|
||||||
|
//
|
||||||
|
private final Unsafe unsafe = new Unsafe()
|
||||||
|
{
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ExecutorService getExecutorService()
|
||||||
|
{
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
public void shutdown()
|
public void shutdown()
|
||||||
{
|
{
|
||||||
@ -82,4 +92,10 @@ public class BungeeScheduler implements TaskScheduler
|
|||||||
s.execute( prepared );
|
s.execute( prepared );
|
||||||
return prepared;
|
return prepared;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Unsafe unsafe()
|
||||||
|
{
|
||||||
|
return unsafe;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user