2013-04-07 12 views
10

bạn có biết giải thích tại sao trình quản lý bảo mật java không cấm tạo chủ đề mới hoặc bắt đầu chúng không? FileWriter mới là dưới sự quản lý bảo mật, nhưng không phải Thread mới(), cũng không phải threadInstance.start() không phải là trình quản lý bảo mật chưa được xử lý, và có thể gọi.tại sao trình quản lý bảo mật java không cấm tạo Thread mới() hoặc cũng không khởi động nó?

  1. Sẽ không hữu ích nếu cấm không?
  2. Sẽ khó thực hiện?
  3. Hoặc tạo và bắt đầu Chủ đề mới không liên quan đến việc cấm không?
+0

Ngôn ngữ lập trình nào? –

+0

java, tôi đã thêm vào chủ đề và mô tả. – bastiat

Trả lời

4

Có kiểm tra quyền truy cập được thực hiện trong trình tạo Thread để xem người gọi có quyền thay đổi ThreadGroup mà chuỗi mới sẽ được thêm vào hay không. Đó là cách bạn sẽ thực hiện một chính sách bảo mật để cấm tạo các luồng mới.

(Và có một kiểm tra về việc tạo ra các ThreadGroups ... rằng séc nếu bạn được phép thêm nhóm mới để mẹ của nó.)

Vì vậy, để giải đáp thắc mắc của bạn:

Tại sao trình quản lý bảo mật java không cấm tạo Thread mới() và cũng không khởi động nó?

Lý do là chính sách bảo mật hiện tại của JVM cho phép chủ đề chính sửa đổi ThreadGroup. Bạn sẽ có thể sửa đổi cài đặt chính sách đó để ngăn chặn điều đó và do đó ngăn chặn việc tạo các chuỗi con.

Sẽ không hữu ích nếu cấm không?

Có. Nó là không khôn ngoan để cho phép mã không đáng tin cậy tạo/bắt đầu luồng vì: 1) chủ đề khi bắt đầu không thể bị giết an toàn, và 2) tạo/bắt đầu nhiều luồng có thể mang JVM (và có thể là hệ điều hành) đến đầu gối của nó.

Sẽ khó thực hiện?

Từ quan điểm của bạn, chỉ cần thay đổi chính sách.

+0

Có rất nhiều cách để đưa JVM đến đầu gối của nó. Bạn sẽ cần phải cung cấp cho truy cập mã không đáng tin cậy để ít nhất một số chủ đề. Đó là loại khá hữu ích để có thể tạo chủ đề. –

+1

@Tom Bạn không _generally_ cần cấp quyền truy cập cho các chủ đề, nhưng trong trường hợp đó bạn thường phải cấp quyền truy cập vào các cơ sở thay thế. Nó sẽ không được như vậy xấu, ngoại trừ việc xử lý IO không đồng bộ của Java vẫn không phải là rất mạnh. –

+0

kịch bản mà tôi có thể nhận ngoại lệ khi tạo chuỗi mới trong trình quản lý bảo mật là gì? Tôi đã thử trong java chính của tôi -Djava.security.manager -Djava.security.policy = app.policy -cp bin pl.com.App với app.policy rỗng, và dưới Tomcat với (-ecurity được kích hoạt) trong servlet của tôi (trong catalina.policy không có quyền Thread) nhưng tôi luôn có thể tạo và bắt đầu luồng mới mà không có ngoại lệ. – bastiat

9

Câu trả lời được chấp nhận không chính xác: không thể xác định chính sách bảo mật sẽ ngăn mã tạo và bắt đầu chuỗi mới bằng cách sử dụng Trình quản lý bảo mật Java chuẩn.

Hãy nói rằng bạn có đoạn mã sau:

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(); 
    } 
} 

và bạn chạy nó với lệnh sau đây:

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

nó sẽ chạy tốt và đầu ra:

Secure 
Ran 

mặc dù chúng tôi đã đặt chính sách bảo mật thành/dev/null, điều này sẽ cấp không cho phép đối với bất kỳ mã nào. Do đó, không thể cấp ít quyền hơn để ngăn mã tạo chuỗi đó.

Điều này là do java.lang.SecuritManager chuẩn chỉ thực hiện kiểm tra quyền nếu mã cố gắng tạo một chuỗi trong ThreadGroup gốc. Đồng thời, getThreadGroup mehtod của SecurityManager luôn trả về nhóm luồng của Thread hiện tại, sẽ không bao giờ là nhóm chủ đề gốc, vì vậy việc cho phép tạo một Thread mới sẽ luôn được cấp.

Một cách để làm tròn điều này là phân lớp java.lang.SecurityManager và ghi đè phương thức getThreadGroup để trả về ThreadGroup gốc. Điều này sau đó sẽ cho phép bạn kiểm soát xem mã có thể tạo chủ đề dựa trên việc nó có java.lang.RuntimePermission "modifyThreadGroup" hay không.

Vì vậy, nếu bây giờ chúng ta định nghĩa một lớp con của SecurityManager như sau:

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; 
    } 
} 

và sau đó chạy lệnh của chúng tôi một lần nữa, nhưng lần này quy định cụ thể ThreadSecurityManager subclassed của chúng tôi:

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

Chúng tôi nhận được một ngoại lệ trong lớp Kiểm tra của chúng tôi khi chúng tôi cố gắng tạo chủ đề mới:

Exception in thread "main" java.security.AccessControlException: access denied ("java.lang.RuntimePermission" "modifyThreadGroup") 
Các vấn đề liên quan