[libbluray-devel] [Git][videolan/libbluray][master] darwin: rewrite mount_get_mountpoint

Petri Hintukainen gitlab at videolan.org
Fri Oct 4 09:25:11 CEST 2019



Petri Hintukainen pushed to branch master at VideoLAN / libbluray


Commits:
406a4302 by Marvin Scholz at 2019-10-04T07:18:31Z
darwin: rewrite mount_get_mountpoint

Rewrite most of mount_get_mountpoint for Darwin using the
DiskArbitration API instead of the more low level getfsstat.

This fixes a memory over-read leading to a crash when the system
has more than 128 mounts.

Additionally it changes the logic a bit, now it is first checked
if the path exists and is a folder, if that is not the case, try
to interpret it as BSD mount name, this makes BSD names like 'disk2'
work (provided there is no folder/image with that name) as expected.

Reported by Collin Allen.

Fix #21

- - - - -


2 changed files:

- configure.ac
- src/file/mount_darwin.c


Changes:

=====================================
configure.ac
=====================================
@@ -46,6 +46,7 @@ case "${host_os}" in
     ;;
   *darwin*)
     SYS=darwin
+    EXTRA_LIBS="${EXTRA_LIBS} -framework CoreFoundation -framework DiskArbitration"
     ;;
   netbsd*)
     SYS=netbsd


=====================================
src/file/mount_darwin.c
=====================================
@@ -29,35 +29,53 @@
 
 #define _DARWIN_C_SOURCE
 #include <sys/stat.h>
-#include <sys/param.h>
-#include <sys/ucred.h>
-#include <sys/mount.h>
 
-char *mount_get_mountpoint(const char *device_path)
+#include <DiskArbitration/DADisk.h>
+
+static char *bsdname_get_mountpoint(const char *device_path)
 {
-    struct stat st;
-    if (stat (device_path, &st) ) {
-        return str_dup(device_path);
-    }
+    char *result = NULL;
 
-    /* If it's a directory, all is good */
-    if (S_ISDIR(st.st_mode)) {
-        return str_dup(device_path);
+    DASessionRef session = DASessionCreate(kCFAllocatorDefault);
+    if (session) {
+        DADiskRef disk = DADiskCreateFromBSDName(kCFAllocatorDefault, session, device_path);
+        if (disk) {
+            CFDictionaryRef desc = DADiskCopyDescription(disk);
+            if (desc) {
+                // Get Volume path as CFURL
+                CFURLRef url = CFDictionaryGetValue(desc, kDADiskDescriptionVolumePathKey);
+                if (url) {
+                    // Copy Volume path as C char array
+                    char tmp_path[PATH_MAX];
+                    if (CFURLGetFileSystemRepresentation(url, true, (UInt8*)tmp_path, sizeof(tmp_path))) {
+                        result = str_dup(tmp_path);
+                    }
+                }
+                CFRelease(desc);
+            }
+            CFRelease(disk);
+        }
+        CFRelease(session);
     }
 
-    struct statfs mbuf[128];
-    int fs_count;
-
-    if ( (fs_count = getfsstat (NULL, 0, MNT_NOWAIT)) != -1 ) {
+    return result;
+}
 
-        getfsstat (mbuf, fs_count * sizeof(mbuf[0]), MNT_NOWAIT);
 
-        for ( int i = 0; i < fs_count; ++i) {
-            if (!strcmp (mbuf[i].f_mntfromname, device_path)) {
-                return str_dup (mbuf[i].f_mntonname);
-            }
+char *mount_get_mountpoint(const char *device_path)
+{
+    struct stat st;
+    if (stat(device_path, &st) == 0) {
+        // If it's a directory, all is good
+        if (S_ISDIR(st.st_mode)) {
+            return str_dup(device_path);
         }
     }
 
-    return str_dup (device_path);
+    char *mountpoint = bsdname_get_mountpoint(device_path);
+    if (mountpoint) {
+        return mountpoint;
+    }
+
+    return str_dup(device_path);
 }



View it on GitLab: https://code.videolan.org/videolan/libbluray/commit/406a430213445654416d5bb6a15855e3fbf6d6e4

-- 
View it on GitLab: https://code.videolan.org/videolan/libbluray/commit/406a430213445654416d5bb6a15855e3fbf6d6e4
You're receiving this email because of your account on code.videolan.org.




More information about the libbluray-devel mailing list