changeset 235:5ba9c2a51405

8133577: DeviceManager.register() and DeviceManager.unregister() must check the permissions FIRST Summary: SE is checked first Reviewed-by: alkonsta
author snazarki
date Thu, 13 Aug 2015 21:02:44 +0300
parents 8a3ef39ecad5
children 2c4078b58289
files src/se/classes/com/oracle/dio/registry/RegistryImpl.java src/share/classes/com/oracle/dio/impl/PeripheralDescriptorImpl.java src/share/classes/com/oracle/dio/registry/Registry.java src/share/classes/jdk/dio/DeviceManager.java
diffstat 4 files changed, 113 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/src/se/classes/com/oracle/dio/registry/RegistryImpl.java	Thu Aug 13 17:49:28 2015 +0300
+++ b/src/se/classes/com/oracle/dio/registry/RegistryImpl.java	Thu Aug 13 21:02:44 2015 +0300
@@ -76,10 +76,10 @@
     }
 
     @Override
-    public synchronized void register(DeviceDescriptor<? super T> descriptor)
+    public synchronized int register(PeripheralDescriptorImpl<? super T> descriptor)
                                       throws UnsupportedOperationException, IOException {
+        int id = super.register(descriptor);
         Class<? extends Device> intf = descriptor.getInterface();
-        int id = descriptor.getID();
         Properties registry = loadRegistry();
         RegistryContent content = readRegistryContent(registry);
         String factory = DeviceRegistryFactory.registryFactoryName(intf);
@@ -87,8 +87,6 @@
             throw new UnsupportedDeviceTypeException("Unsupported type: " + intf.getName());
         }
 
-        Registry.checkPermission(descriptor, DeviceMgmtPermission.REGISTER);
-
         RegistryData data = null;
         try {
             data = ((DeviceRegistryFactory)Class.forName(factory).newInstance()).createRegistryData(descriptor);
@@ -104,10 +102,15 @@
             registry.remove(Integer.toString(id));
             throw e;
         }
+
+        return id;
     }
 
     @Override
     public synchronized DeviceDescriptor unregister(int id) {
+        Registry.checkPermission(null, id, DeviceMgmtPermission.UNREGISTER);
+        Registry.checkID(id);
+
         Properties registry = loadRegistry();
         RegistryContent content = readRegistryContent(registry);
         RegistryData config = content.get(id);
@@ -120,8 +123,6 @@
             throw new IllegalArgumentException("Device cannot be unregistered");
         }
 
-        Registry.checkPermission(d, DeviceMgmtPermission.UNREGISTER);
-
         content.remove(id);
         registry.remove(Integer.toString(id));
         try {
--- a/src/share/classes/com/oracle/dio/impl/PeripheralDescriptorImpl.java	Thu Aug 13 17:49:28 2015 +0300
+++ b/src/share/classes/com/oracle/dio/impl/PeripheralDescriptorImpl.java	Thu Aug 13 21:02:44 2015 +0300
@@ -32,7 +32,7 @@
 
 import com.oracle.dio.utils.Constants;
 import com.oracle.dio.utils.Logging;
- import com.oracle.dio.impl.Platform;
+import com.oracle.dio.impl.Platform;
 
 import jdk.dio.Device;
 import jdk.dio.DeviceConfig;
@@ -146,5 +146,9 @@
         }
     }
 
+    public void setNewID(int new_id) {
+        id = new_id;
+    }
+
 }
 
--- a/src/share/classes/com/oracle/dio/registry/Registry.java	Thu Aug 13 17:49:28 2015 +0300
+++ b/src/share/classes/com/oracle/dio/registry/Registry.java	Thu Aug 13 21:02:44 2015 +0300
@@ -29,6 +29,12 @@
 import java.security.AccessController;
 import java.util.Hashtable;
 import java.util.Iterator;
+import java.util.Random;
+
+import com.oracle.dio.impl.PeripheralDescriptorImpl;
+import com.oracle.dio.utils.ExceptionMessage;
+import com.oracle.dio.utils.PrivilegeController;
+import com.oracle.dio.utils.PrivilegedAction;
 
 import jdk.dio.Device;
 import jdk.dio.DeviceAlreadyExistsException;
@@ -38,6 +44,7 @@
 import jdk.dio.DeviceMgmtPermission;
 import jdk.dio.DeviceNotFoundException;
 import jdk.dio.InvalidDeviceConfigException;
+import jdk.dio.UnavailableDeviceException;
 import jdk.dio.UnsupportedDeviceTypeException;
 /**
  * Device configuration registry.
@@ -85,6 +92,15 @@
      */
     public abstract Iterator<DeviceDescriptor<? super T>> get(String name, Class<T> intf, String... properties);
 
+    public static void checkID(int ID) throws IllegalArgumentException {
+        if (ID < 0) {
+            throw new IllegalArgumentException(
+                ExceptionMessage.format(ExceptionMessage.DEVICE_NEGATIVE_ID)
+            );
+        }
+    }
+
+
     /**
      *
      * @return new Periprheal ID
@@ -93,8 +109,83 @@
      * @see jdk.dio.DeviceManager#register(int,
      *      Class, DeviceConfig, String, String...)
      */
-    public abstract void register(DeviceDescriptor<? super T> d)
-    throws UnsupportedOperationException, IOException;
+    public int register(PeripheralDescriptorImpl<? super T> d)
+    throws UnsupportedOperationException, IOException {
+        checkPermission(d.getName(), d.getID(), DeviceMgmtPermission.REGISTER);
+
+        if (!Registry.canRegister) {
+            throw new UnsupportedOperationException();
+        }
+
+        if (d.getID() < DeviceManager.UNSPECIFIED_ID) {
+            throw new IllegalArgumentException(
+                ExceptionMessage.format(ExceptionMessage.DEVICE_INVALID_ID)
+            );
+        }
+
+        int new_id = checkConfig(d);
+
+        return new_id;
+    }
+
+    private static int checkConfig(final DeviceDescriptor d)
+    throws IOException, UnsupportedDeviceTypeException, InvalidDeviceConfigException, DeviceNotFoundException, DeviceAlreadyExistsException {
+
+        int new_id = PrivilegeController.doPrivileged(new PrivilegedAction<Integer>() {
+                public Integer run() throws IOException {
+                    Random rnd = new Random();
+                    int new_id = d.getID();
+
+                    do {
+                        if (d.getID() == DeviceManager.UNSPECIFIED_ID) {
+                            //  verify generated ID
+                            new_id = rnd.nextInt();
+                            if (new_id < 1) {
+                                continue;
+                            }
+                        }
+                        try {
+                            Device p = DeviceManager.open(new_id);
+                            p.close();
+                        } catch (DeviceNotFoundException pnfe1) {
+                            // this is the only right way to break "while" condition
+                            break;
+                        } catch (UnavailableDeviceException pnae1) {}
+                        if (d.getID()  != DeviceManager.UNSPECIFIED_ID) {
+                            throw new DeviceAlreadyExistsException(
+                                ExceptionMessage.format(ExceptionMessage.DEVICE_NONUNIQUE_ID)
+                            );
+                        }
+                        continue;
+                    } while (true);
+
+                    do {
+                        try {
+                            Device p = DeviceManager.open(d.getName(), d.getInterface(), d.getProperties());
+                            p.close();
+                        } catch (DeviceNotFoundException | IllegalArgumentException e1) {
+                            // this is the only right way to continue.
+                            // catch IAE to avoid duplicate of name/properties verification
+                            break;
+                        } catch (UnavailableDeviceException pnae2) {}
+                        throw new DeviceAlreadyExistsException(
+                            ExceptionMessage.format(ExceptionMessage.DEVICE_ALREADY_EXISTING_CONFIG)
+                        );
+                    } while(false);
+
+                    try {
+                        Device p = DeviceManager.open(d.getInterface(), d.getConfiguration());
+                        p.close();
+                    } catch (UnavailableDeviceException pnae3) {}
+
+                    return new_id;
+                }
+
+        }).intValue();
+
+        return new_id;
+    }
+
 
     /**
      * @see
@@ -110,9 +201,9 @@
      * @param d      ID and NAME holder
      * @param action <code>DeviceMgmtPermission</code> action
      */
-    public static void checkPermission(DeviceDescriptor d, String action) {
-        String perm = (DeviceManager.UNSPECIFIED_ID == d.getID()) ? "" : ":"+d.getID();
-        perm = (null == d.getName()) ? perm : d.getName() + perm;
+    public static void checkPermission(String name, int id, String action) {
+        String perm = (DeviceManager.UNSPECIFIED_ID == id) ? ":*" : ":"+id;
+        perm = ((null == name) ? "*" : name) + perm;
         AccessController.checkPermission(new DeviceMgmtPermission(perm, action));
     }
 
--- a/src/share/classes/jdk/dio/DeviceManager.java	Thu Aug 13 17:49:28 2015 +0300
+++ b/src/share/classes/jdk/dio/DeviceManager.java	Thu Aug 13 21:02:44 2015 +0300
@@ -463,10 +463,10 @@
     public static <P extends Device<? super P>> P open(int id, Class<P> intf, int mode) throws IOException,
         UnsupportedDeviceTypeException, DeviceNotFoundException, UnavailableDeviceException,
         UnsupportedAccessModeException {
-        checkID(id);
+        Registry.checkID(id);
 
         do {
-            AccessController.checkPermission(new DeviceMgmtPermission(":" + id, DeviceMgmtPermission.OPEN));
+            AccessController.checkPermission(new DeviceMgmtPermission("*:" + id, DeviceMgmtPermission.OPEN));
         } while (false);
 
 
@@ -721,7 +721,7 @@
         }
 
         do {
-            AccessController.checkPermission(new DeviceMgmtPermission((null == name)? "" : name, DeviceMgmtPermission.OPEN));
+            AccessController.checkPermission(new DeviceMgmtPermission(((null == name)? "" : name) + ":*", DeviceMgmtPermission.OPEN));
         } while (false);
 
 
@@ -917,92 +917,21 @@
                                                                  String name, String... properties) throws IOException, UnsupportedDeviceTypeException, InvalidDeviceConfigException,
         DeviceNotFoundException, DeviceAlreadyExistsException {
 
-        if (id < UNSPECIFIED_ID) {
-            throw new IllegalArgumentException(
-                ExceptionMessage.format(ExceptionMessage.DEVICE_INVALID_ID)
-            );
-        }
-
-        int new_id = checkConfig(id, intf, config, name, properties);
-
         // quick fix: need info about custom DeviceConfig factory (if any)
-        PeripheralDescriptorImpl<P> dscr = new PeripheralDescriptorImpl(new_id, name, config, intf, properties);
+        PeripheralDescriptorImpl<P> dscr = new PeripheralDescriptorImpl(id, name, config, intf, properties);
         // this fills dscr with correct provider
         try (Device d = loadFromDriver(dscr, EXCLUSIVE)) {
         } catch (Exception e) {
             // intentionally ignored
         }
 
-        Registry.getInstance().register(dscr);
+        int new_id = Registry.getInstance().register(dscr);
 
-        // send notification in non-priveleged mode
         RegistrationEventSender.notifyRegistered(null, dscr);
 
         return new_id;
     }
 
-    private static <P extends Device<? super P>> int checkConfig(final int id, final Class<P> intf, final DeviceConfig<? super P> config,
-                                                                      final String name, final String... properties)
-    throws IOException, UnsupportedDeviceTypeException, InvalidDeviceConfigException, DeviceNotFoundException, DeviceAlreadyExistsException {
-
-        if (!Registry.canRegister) {
-            throw new UnsupportedOperationException();
-        }
-
-        int new_id = PrivilegeController.doPrivileged(new PrivilegedAction<Integer>() {
-                public Integer run() throws IOException {
-                    Random rnd = new Random();
-                    int new_id = id;
-
-                    do {
-                        if (id == UNSPECIFIED_ID) {
-                            //  verify generated ID
-                            new_id = rnd.nextInt();
-                            if (new_id < 1) {
-                                continue;
-                            }
-                        }
-                        try {
-                            Device p = open(new_id);
-                            p.close();
-                        } catch (DeviceNotFoundException pnfe1) {
-                            // this is the only right way to break "while" condition
-                            break;
-                        } catch (UnavailableDeviceException pnae1) {}
-                        if (id  != UNSPECIFIED_ID) {
-                            throw new DeviceAlreadyExistsException(
-                                ExceptionMessage.format(ExceptionMessage.DEVICE_NONUNIQUE_ID)
-                            );
-                        }
-                        continue;
-                    } while (true);
-
-                    do {
-                        try {
-                            Device p = open(name, intf, properties);
-                            p.close();
-                        } catch (DeviceNotFoundException | IllegalArgumentException e1) {
-                            // this is the only right way to continue.
-                            // catch IAE to avoid duplicate of name/properties verification
-                            break;
-                        } catch (UnavailableDeviceException pnae2) {}
-                        throw new DeviceAlreadyExistsException(
-                            ExceptionMessage.format(ExceptionMessage.DEVICE_ALREADY_EXISTING_CONFIG)
-                        );
-                    } while(false);
-
-                    try {
-                        Device p = open(intf, config);
-                        p.close();
-                    } catch (UnavailableDeviceException pnae3) {}
-
-                    return new_id;
-                }
-
-        }).intValue();
-
-        return new_id;
-    }
 
     /**
      * Unregisters the device associated with the specified ID. Upon successful
@@ -1029,8 +958,6 @@
      *             {@link DeviceMgmtPermission#UNREGISTER}).
      */
     public static void unregister(int id) {
-        checkID(id);
-
         final Registry r = Registry.getInstance();
         DeviceDescriptor unreg_d = r.unregister(id);
         // send notify
@@ -1090,14 +1017,6 @@
 
     /* ------------------- Private API ---------------- */
 
-    private static void checkID(int ID) throws IllegalArgumentException {
-        if (ID < 0) {
-            throw new IllegalArgumentException(
-                ExceptionMessage.format(ExceptionMessage.DEVICE_NEGATIVE_ID)
-            );
-        }
-    }
-
     private static void checkMode(int mode) throws UnsupportedAccessModeException {
         if (SHARED != mode && EXCLUSIVE != mode) {
             throw new UnsupportedAccessModeException();