[libbluray-devel] Restrict Xlet file write access

hpi1 git at videolan.org
Fri Feb 27 12:46:41 CET 2015


libbluray | branch: master | hpi1 <hpi1 at anonymous.org> | Thu Feb 26 11:38:24 2015 +0200| [31867072bee6f10fbbb14e406afa1607e92856b3] | committer: hpi1

Restrict Xlet file write access

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

 .../bdj/java/org/videolan/BDJSecurityManager.java  |   72 +++++++++++++++++++-
 src/libbluray/bdj/java/org/videolan/CacheDir.java  |   11 +++
 src/libbluray/bdj/java/org/videolan/Libbluray.java |   16 ++---
 3 files changed, 90 insertions(+), 9 deletions(-)

diff --git a/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java b/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java
index 8a7b682..dfe2da6 100644
--- a/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java
+++ b/src/libbluray/bdj/java/org/videolan/BDJSecurityManager.java
@@ -21,12 +21,45 @@
 package org.videolan;
 
 import java.io.FilePermission;
+import java.io.File;
 import java.security.Permission;
 
 /*
  * Dummy security manager to grab all file access
  */
 class BDJSecurityManager extends SecurityManager {
+
+    private String discRoot;
+    private String cacheRoot;
+    private String budaRoot;
+    private String persistentRoot;
+    private boolean usingUdf = false;
+
+    BDJSecurityManager(String discRoot, String persistentRoot, String budaRoot) {
+        this.discRoot  = discRoot;
+        this.cacheRoot = null;
+        this.budaRoot  = budaRoot;
+        this.persistentRoot = persistentRoot;
+        if (discRoot == null) {
+            usingUdf = true;
+        }
+    }
+
+    protected void setCacheRoot(String root) {
+        if (cacheRoot != null) {
+            // limit only
+            if (!root.startsWith(cacheRoot)) {
+                logger.error("setCacheRoot(" + root + ") denied\n" + Logger.dumpStack());
+                throw new SecurityException("cache root already set");
+            }
+        }
+        cacheRoot = root;
+    }
+
+    /*
+     *
+     */
+
     public void checkPermission(Permission perm) {
         /*
         try {
@@ -50,7 +83,44 @@ class BDJSecurityManager extends SecurityManager {
 
     public void checkRead(String file) {
         //super.checkRead(file);
-        BDJLoader.accessFile(file);
+        if (usingUdf) {
+            BDJLoader.accessFile(file);
+        }
+    }
+
+    /*
+     * File write access
+     */
+
+    private boolean canReadWrite(String file) {
+        if (budaRoot != null && file.startsWith(budaRoot)) {
+            return true;
+        }
+        if (persistentRoot != null && file.startsWith(persistentRoot)) {
+            return true;
+        }
+        return false;
+    }
+
+    public void checkWrite(String file) {
+        BDJXletContext ctx = BDJXletContext.getCurrentContext();
+
+        if (ctx != null) {
+            // Xlet can write to persistent storage and binding unit
+            if (canReadWrite(file)) {
+                return;
+            }
+            logger.error("Xlet write " + file + " denied at\n" + Logger.dumpStack());
+        } else  {
+            // BD-J core can write to cache
+            if (cacheRoot != null && file.startsWith(cacheRoot)) {
+                return;
+            }
+            logger.error("BD-J write " + file + " denied at\n" + Logger.dumpStack());
+        }
+
+
+        throw new SecurityException("write access denied");
     }
 
     /*
diff --git a/src/libbluray/bdj/java/org/videolan/CacheDir.java b/src/libbluray/bdj/java/org/videolan/CacheDir.java
index a21d793..1993ff7 100644
--- a/src/libbluray/bdj/java/org/videolan/CacheDir.java
+++ b/src/libbluray/bdj/java/org/videolan/CacheDir.java
@@ -53,15 +53,26 @@ class CacheDir {
             return cacheRoot;
         }
 
+        SecurityManager sm = System.getSecurityManager();
+        if (sm != null && sm instanceof BDJSecurityManager) {
+            ((BDJSecurityManager)sm).setCacheRoot(baseDir);
+        }
+
         cleanupCache();
 
         for (int i = 0; i < 100; i++) {
             File tmpDir = new File(baseDir + System.nanoTime());
             tmpDir = new File(tmpDir.getCanonicalPath());
+
             if (tmpDir.mkdirs()) {
                 cacheRoot = tmpDir;
                 lockFile  = lockCache(cacheRoot.getPath());
                 logger.info("Created cache in " + tmpDir.getPath());
+
+                if (sm != null && sm instanceof BDJSecurityManager) {
+                    ((BDJSecurityManager)sm).setCacheRoot(cacheRoot.getPath());
+                }
+
                 return cacheRoot;
             }
             logger.error("error creating " + tmpDir.getPath());
diff --git a/src/libbluray/bdj/java/org/videolan/Libbluray.java b/src/libbluray/bdj/java/org/videolan/Libbluray.java
index 73355d1..0ca830a 100644
--- a/src/libbluray/bdj/java/org/videolan/Libbluray.java
+++ b/src/libbluray/bdj/java/org/videolan/Libbluray.java
@@ -54,17 +54,17 @@ public class Libbluray {
         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 {
+        if (discRoot != null) {
             System.setProperty("bluray.vfs.root", discRoot);
         }
 
+        try {
+            System.setSecurityManager(new BDJSecurityManager(discRoot, persistentRoot, budaRoot));
+        } catch (Exception ex) {
+            System.err.println("System.setSecurityManager() failed: " + ex);
+            throw new SecurityException("Failed initializing SecurityManager");
+        }
+
             Libbluray.nativePointer = nativePointer;
             DiscManager.getDiscManager().setCurrentDisc(discID);
 



More information about the libbluray-devel mailing list