2013-04-07 15 views
10

czy znasz wyjaśnienie, dlaczego menedżer bezpieczeństwa Java nie zabrania tworzenia nowych wątków lub ich uruchamiania? nowy FileWriter jest pod menedżerem bezpieczeństwa, ale ani nowy wątek(), ani threadInstance.start() nie jest uneder menedżer bezpieczeństwa, i są możliwe do wywołania.dlaczego menedżer bezpieczeństwa java nie zabrania ani tworzenia nowego wątku(), ani uruchamiania go?

  1. Czy nie byłoby to zabronione?
  2. Czy byłoby to trudne do wdrożenia?
  3. Czy tworzenie i uruchamianie nowego wątku nie jest tak istotne, aby go zabronić?
+0

Jaki język programowania? –

+0

java, dodałem do tematu i opisu. – bastiat

Odpowiedz

4

W konstruktorze wątku wykonywane jest sprawdzenie dostępu, aby sprawdzić, czy osoba dzwoniąca ma uprawnienia do zmiany grupy wątków, do której zostanie dodany nowy wątek. W ten sposób można wdrożyć politykę bezpieczeństwa, aby zabronić tworzenia nowych wątków.

(a jest to kolejny czek na tworzeniu ThreadGroups ... że sprawdza czy masz pozwolenie, aby dodać nową grupę do jego rodzica.)

Tak, aby odpowiedzieć na Twoje pytania:

Dlaczego menedżer bezpieczeństwa java nie zabrania ani tworzenia nowego wątku(), ani uruchamiania go?

Powodem jest to, że aktualna polityka bezpieczeństwa maszyny JVM umożliwia rodzicowi wątek modyfikację jego ThreadGroup. Powinieneś być w stanie zmodyfikować to ustawienie zasad, aby temu zapobiec, a tym samym zapobiec tworzeniu wątków podrzędnych.

Czy nie byłoby pożyteczne zabraniać tego?

To jest. Nierozsądnie jest pozwolić niezaufanym kodom na tworzenie/uruchamianie wątków, ponieważ: 1) uruchomione wątki nie mogą być bezpiecznie zabite, a 2) tworzenie/uruchamianie wielu wątków może doprowadzić JVM (i być może system operacyjny) do kolan.

Czy byłoby to trudne do wdrożenia?

Z Twojej perspektywy wystarczy zmienić politykę.

+0

Istnieje wiele sposobów na doprowadzenie JVM do kolan. Będziesz potrzebował dać niezaufany kod dostępu przynajmniej do niektórych wątków. To całkiem przydatne, aby móc tworzyć wątki. –

+1

@Tom Nie musisz generalnie przyznawać dostępu do wątków, ale w takim przypadku często musisz przyznać dostęp do urządzeń zastępczych. Nie byłoby tak źle, z tym, że asynchroniczna obsługa IO Java nadal nie jest bardzo silna. –

+0

jaki jest scenariusz, w którym mogę otrzymać wyjątek podczas tworzenia nowego wątku pod menedżerem zabezpieczeń? Próbowałem w moim własnym głównym java -Djava.security.manager -Djava.security.policy = app.policy -cp bin pl.com.App z pustym app.policy, a pod Tomcat z (włączona ochrona) w moim apletem (w catalina.policy nie ma pozwolenia na wątek), ale zawsze mogę tworzyć i uruchamiać nowe wątki bez wyjątku. – bastiat

9

Przyjęta odpowiedź jest niepoprawna: nie można zdefiniować strategii bezpieczeństwa, która uniemożliwi tworzenie kodu i uruchomienie nowego wątku przy użyciu standardowego oprogramowania Java SecurityManager.

Powiedzmy masz następujący kod:

public class Test { 
    public static void main(String [] args) { 
    System.out.println(System.getSecurityManager() != null ? "Secure" : ""); 
    Thread thread = new Thread(
     new Runnable() { 
     public void run() { 
      System.out.println("Ran"); 
     } 
    }); 
    thread.start(); 
    } 
} 

i go uruchomić za pomocą następującego polecenia:

java -Djava.security.manager -Djava.security.policy==/dev/null Test 

to będzie działać dobrze i wyjście:

Secure 
Ran 

mimo że ustawiliśmy politykę bezpieczeństwa na/dev/null, która przyzna zero uprawnień do dowolnego kodu. Dlatego niemożliwe jest przyznanie mniejszej liczby uprawnień, aby zapobiec tworzeniu tego wątku przez kod.

Dzieje się tak dlatego, że standardowy java.lang.SecuritManager wykonuje tylko kontrolę uprawnień, jeśli kod próbuje utworzyć wątek w katalogu głównym ThreadGroup. Jednocześnie znacznik getThreadGroup programu SecurityManager zawsze zwraca bieżącą grupę wątków wątku, która nigdy nie będzie główną grupą wątków, więc uprawnienia do tworzenia nowego wątku będą zawsze przyznawane.

Jednym ze sposobów obejścia tego jest podklasa java.lang.SecurityManager i nadpisanie metody getThreadGroup w celu zwrócenia katalogu głównego ThreadGroup. Umożliwi to kontrolę nad tym, czy kod może tworzyć wątki na podstawie tego, czy zawiera element java.lang.RuntimePermission "modifyThreadGroup".

Jeśli więc teraz zdefiniować podklasę securityManager następująco:

public class ThreadSecurityManager extends SecurityManager { 

    private static ThreadGroup rootGroup; 

    @Override 
    public ThreadGroup getThreadGroup() { 
    if (rootGroup == null) { 
     rootGroup = getRootGroup(); 
    } 
    return rootGroup; 
    } 

    private static ThreadGroup getRootGroup() { 
    ThreadGroup root = Thread.currentThread().getThreadGroup(); 
    while (root.getParent() != null) { 
    root = root.getParent(); 
    } 
    return root; 
    } 
} 

a następnie ponownie uruchomić naszą komendę, ale tym razem podając nasz podklasy ThreadSecurityManager:

java -Djava.security.manager=ThreadSecurityManager -Djava.security.policy==/dev/null Test 

Dostajemy wyjątek nasza klasa testowa, gdy próbujemy utworzyć nowy wątek:

Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup") 
Powiązane problemy