[libbluray-devel] Use dummy SecurityManager to grab all Xlet file access

hpi1 git at videolan.org
Thu Feb 19 19:50:23 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Thu Feb 19 13:33:10 2015 +0200| [b6961182bcb01f2d59824cf1df8f7aba87d091ae] | committer: hpi1

Use dummy SecurityManager to grab all Xlet file access

Cache all accessed files on demand when VFS root is not accessible with Java I/O.

> http://git.videolan.org/gitweb.cgi/libbluray.git/?a=commit;h=b6961182bcb01f2d59824cf1df8f7aba87d091ae
---

 contrib/libudfread                                 |    2 +-
 src/libbluray/bdj/java/org/videolan/BDJLoader.java |    7 ++
 .../bdj/java/org/videolan/BDJSecurityManager.java  |   45 +++++++++++
 src/libbluray/bdj/java/org/videolan/Libbluray.java |   19 ++++-
 src/libbluray/bdj/java/org/videolan/VFSCache.java  |   78 ++++++++++++++++++++
 src/libbluray/bdj/native/org_videolan_Libbluray.c  |    2 +-
 src/libbluray/bluray.c                             |    4 -
 7 files changed, 150 insertions(+), 7 deletions(-)

diff --git a/contrib/libudfread b/contrib/libudfread
index 3f1bc24..f73b9e1 160000
--- a/contrib/libudfread
+++ b/contrib/libudfread
@@ -1 +1 @@
-Subproject commit 3f1bc248626598a9f05f6f0131a0e37f8817edc5
+Subproject commit f73b9e1ebbf940814cc118c2e9f258e372088595
diff --git a/src/libbluray/bdj/java/org/videolan/BDJLoader.java b/src/libbluray/bdj/java/org/videolan/BDJLoader.java
index 1b59dcd..c802b1c 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJLoader.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJLoader.java
@@ -60,6 +60,13 @@ public class BDJLoader {
         return null;
     }
 
+    public static void accessFile(String file) {
+        VFSCache localCache = vfsCache;
+        if (localCache != null) {
+            localCache.accessFile(file);
+        }
+    }
+
     public static String getCachedFile(String path) {
         VFSCache localCache = vfsCache;
         if (localCache != null) {
diff --git a/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java b/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java
new file mode 100644
index 0000000..1944886
--- /dev/null
+++ b/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java
@@ -0,0 +1,45 @@
+/*
+ * This file is part of libbluray
+ * Copyright (C) 2015  Petri Hintukainen <phintuka at users.sourceforge.net>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library. If not, see
+ * <http://www.gnu.org/licenses/>.
+ */
+
+
+package org.videolan;
+
+import java.io.FilePermission;
+import java.security.Permission;
+
+/*
+ * Dummy security manager to grab all file access
+ */
+class BDJSecurityManager extends SecurityManager {
+    public void checkPermission(Permission perm) {
+        /*
+        try {
+            java.security.AccessController.checkPermission(perm);
+        } catch (java.security.AccessControlException ex) {
+            System.err.println(" *** caught " + ex + " at " + Logger.dumpStack());
+            throw ex;
+        }
+        */
+    }
+
+    public void checkRead(String file) {
+        //super.checkRead(file);
+        BDJLoader.accessFile(file);
+    }
+}
diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index a46d192..94095a1 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -49,10 +49,20 @@ public class Libbluray {
     protected static void init(long nativePointer, String discID, String discRoot,
                                String persistentRoot, String budaRoot) {
 
-        System.setProperty("bluray.vfs.root", discRoot);
         System.setProperty("dvb.persistent.root", persistentRoot);
         System.setProperty("bluray.bindingunit.root", budaRoot);
 
+        if (discRoot == null) {
+            try {
+                System.setSecurityManager(new BDJSecurityManager());
+            } catch (Exception ex) {
+                System.err.println("System.setSecurityManager() failed: " + ex);
+                System.err.println("BD-J file access won't work");
+            }
+        } else {
+            System.setProperty("bluray.vfs.root", discRoot);
+        }
+
             Libbluray.nativePointer = nativePointer;
             DiscManager.getDiscManager().setCurrentDisc(discID);
 
@@ -141,6 +151,13 @@ public class Libbluray {
             stopTitle(true);
             BDJLoader.shutdown();
             BDJActionManager.shutdown();
+
+            try {
+                System.setSecurityManager(null);
+            } catch (Exception ex) {
+                System.err.println("System.setSecurityManager(null) failed: " + ex);
+            }
+
             MountManager.unmountAll();
             GUIManager.shutdown();
             BDToolkit.shutdownDisc();
diff --git a/src/libbluray/bdj/java/org/videolan/VFSCache.java b/src/libbluray/bdj/java/org/videolan/VFSCache.java
index 6c57974..d85ad04 100644
--- a/src/libbluray/bdj/java/org/videolan/VFSCache.java
+++ b/src/libbluray/bdj/java/org/videolan/VFSCache.java
@@ -54,6 +54,14 @@ class VFSCache {
         cacheRoot = CacheDir.create("VFSCache").getPath() + File.separator;
         fontRoot  = CacheDir.create("Font").getPath() + File.separator;
         vfsRoot   = System.getProperty("bluray.vfs.root");
+
+        if (vfsRoot == null) {
+            System.err.println("disc root is in UDF");
+            System.setProperty("bluray.vfs.root", cacheRoot);
+            vfsRoot = cacheRoot;
+            cacheAll = true;
+        }
+
         if (!vfsRoot.endsWith(File.separator)) {
             vfsRoot = vfsRoot + File.separator;
         }
@@ -239,6 +247,71 @@ class VFSCache {
     }
 
     /*
+     * Accessing any file triggers security manager checks.
+     * -> we cache the file (on demand) so that it will be accessible by standard Java I/O.
+     */
+    boolean inAccessFile = false;
+    protected void accessFile(String absPath) {
+        if (!cacheAll) {
+            /* BD-ROM filesystem is accessible with standard I/O */
+            return;
+        }
+
+        if (!absPath.startsWith(vfsRoot)) {
+            /* path does not map to VFS */
+            return;
+        }
+
+        accessFileSynced(absPath);
+    }
+
+    protected synchronized void accessFileSynced(String absPath) {
+
+        if (inAccessFile) {
+            /* avoid recursion from SecurityManager checks */
+            return;
+        }
+
+        inAccessFile = true;
+        accessFileImp(absPath);
+        inAccessFile = false;
+    }
+
+    private void accessFileImp(String absPath) {
+
+        if (BDFileSystem.nativeFileExists(absPath)) {
+            /* file is already cached */
+            return;
+        }
+
+        String relPath = absPath.substring(vfsRootLength);
+        String[] names = org.videolan.Libbluray.listBdFiles(relPath, true);
+        if (names == null) {
+            /* this is regular file */
+        } else {
+            /* this is directory, make sure it exists */
+            new File(absPath).mkdirs();
+            return;
+        }
+
+        /* do not cache .m2ts streams */
+        if (relPath.startsWith("BDMV" + File.separator + "STREAM" + File.separator)) {
+            return;
+        }
+
+        /* create the directory */
+        int sepPos = relPath.lastIndexOf(File.separatorChar);
+        if (sepPos > 0) {
+            String absDir = cacheRoot + relPath.substring(0, sepPos);
+            new File(absDir).mkdirs();
+        }
+
+        /* finally, copy the file to cache */
+        Libbluray.cacheBdRomFile(relPath, cacheRoot + relPath);
+    }
+
+
+    /*
      * Add file from binding unit data area to cache
      */
     protected synchronized boolean add(String vpFile, String budaFile) {
@@ -257,6 +330,10 @@ class VFSCache {
      */
     public synchronized String map(String absPath) {
 
+        if (cacheAll) {
+            return absPath;
+        }
+
         if (!absPath.startsWith(vfsRoot)) {
             //logger.info(absPath + " not in BDMV/JAR");
             return absPath;
@@ -276,6 +353,7 @@ class VFSCache {
     private String vfsRoot = null;
     private String fontRoot = null;
     private int    vfsRootLength = 0;
+    private boolean cacheAll = false;
 
     private static final String jarDir = "BDMV" + File.separator + "JAR" + File.separator;
     private static final String fontDir = "BDMV" + File.separator + "AUXDATA" + File.separator;
diff --git a/src/libbluray/bdj/native/org_videolan_Libbluray.c b/src/libbluray/bdj/native/org_videolan_Libbluray.c
index dcfdd8e..19c3046 100644
--- a/src/libbluray/bdj/native/org_videolan_Libbluray.c
+++ b/src/libbluray/bdj/native/org_videolan_Libbluray.c
@@ -382,7 +382,7 @@ JNIEXPORT jobjectArray JNICALL Java_org_videolan_Libbluray_listBdFilesN(JNIEnv *
         dp = disc_open_dir(disc, path);
     }
     if (!dp) {
-        BD_DEBUG(DBG_JNI | DBG_CRIT, "failed opening directory %s\n", path);
+        BD_DEBUG(DBG_JNI, "failed opening directory %s\n", path);
         (*env)->ReleaseStringUTFChars(env, jpath, path);
         return NULL;
     }
diff --git a/src/libbluray/bluray.c b/src/libbluray/bluray.c
index e6c7a47..50f7a98 100644
--- a/src/libbluray/bluray.c
+++ b/src/libbluray/bluray.c
@@ -1206,10 +1206,6 @@ static int _start_bdj(BLURAY *bd, unsigned title)
 #ifdef USING_BDJAVA
     if (bd->bdjava == NULL) {
         const char *root = disc_root(bd->disc);
-        if (!root) {
-            BD_DEBUG(DBG_BLURAY | DBG_CRIT, "Title %d: BD-J with disc images is not supported yet\n", title);
-            return 0;
-        }
         bd->bdjava = bdj_open(root, bd, bd->disc_info.bdj_disc_id, &bd->bdjstorage);
         if (!bd->bdjava) {
             return 0;



More information about the libbluray-devel mailing list