1 /*
   2  * Copyright (c) 2013,2014, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.
   8  *
   9  * This code is distributed in the hope that it will be useful, but WITHOUT
  10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  12  * version 2 for more details (a copy is included in the LICENSE file that
  13  * accompanied this code).
  14  *
  15  * You should have received a copy of the GNU General Public License version
  16  * 2 along with this work; if not, write to the Free Software Foundation,
  17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  18  *
  19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  20  * or visit www.oracle.com if you need additional information or have any
  21  * questions.
  22  */
  23 
  24 /*
  25  * @test
  26  * @bug 8050281
  27  * @summary Test limited doprivileged action with trhead calls.
  28  * @run main/othervm/policy=policy LimitedDoPrivilegedWithThread
  29  */
  30 import java.io.FilePermission;
  31 import java.security.AccessControlContext;
  32 import java.security.AccessControlException;
  33 import java.security.AccessController;
  34 import java.security.Permission;
  35 import java.security.PrivilegedAction;
  36 import java.security.ProtectionDomain;
  37 import java.util.PropertyPermission;
  38 
  39 public class LimitedDoPrivilegedWithThread {
  40 
  41     private static final Permission PROPERTYPERM
  42             = new PropertyPermission("user.name", "read");
  43     private static final Permission FILEPERM
  44             = new FilePermission("*", "read");
  45     private static final AccessControlContext ACC
  46             = new AccessControlContext(
  47                     new ProtectionDomain[]{new ProtectionDomain(null, null)});
  48 
  49     public static void main(String args[]) {
  50         //parent thread without any permission
  51         AccessController.doPrivileged(
  52                 (PrivilegedAction) () -> {
  53                     Thread ct = new Thread(
  54                             new ChildThread(PROPERTYPERM, FILEPERM));
  55                     ct.start();
  56                     try {
  57                         ct.join();
  58                     } catch (InterruptedException ie) {
  59                         Thread.currentThread().interrupt();
  60                         ie.printStackTrace();
  61                         throw new RuntimeException("Unexpected InterruptedException");
  62                     }
  63                     return null;
  64                 }, ACC);
  65     }
  66 }
  67 
  68 class ChildThread implements Runnable {
  69 
  70     private final Permission P1;
  71     private final Permission P2;
  72     private boolean catchACE = false;
  73 
  74     public ChildThread(Permission p1, Permission p2) {
  75         this.P1 = p1;
  76         this.P2 = p2;
  77     }
  78 
  79     @Override
  80     public void run() {
  81         //Verified that child thread has permission p1,
  82         runTest(null, P1, false, 1);
  83         //Verified that child thread inherits parent thread's access control context
  84         AccessControlContext childAcc = AccessController.getContext();
  85         runTest(childAcc, P1, true, 2);
  86         //Verified that we can give permision p2 to limit the "privilege" of the
  87         //class calling doprivileged action, stack walk will continue
  88         runTest(null, P2, true, 3);
  89 
  90     }
  91 
  92     public void runTest(AccessControlContext acc, Permission perm,
  93             boolean expectACE, int id) {
  94 
  95         AccessController.doPrivileged(
  96                 (PrivilegedAction) () -> {
  97                     try {
  98                         AccessController.getContext().checkPermission(P1);
  99                     } catch (AccessControlException ace) {
 100                         catchACE = true;
 101                     }
 102                     if (catchACE ^ expectACE) {
 103                         throw new RuntimeException("test" + id + " failed");
 104                     }
 105                     return null;
 106                 }, acc, perm);
 107     }
 108 }