[FFmpeg-devel] [PATCH] lavf/os_support: Add safe win32 dlopen/dlclose/dlsym functions.

Michael Niedermayer michael at niedermayer.cc
Sat Oct 29 18:22:34 EEST 2016


On Sat, Oct 29, 2016 at 06:35:19PM +1100, Matt Oliver wrote:
> >
> > FYI, last time i tried to include this file from libavcodec i was told
> >> not to since it's libavformat specific.
> >>
> >> The proper place for these wrappers is probably the compat folder, in
> >> a new file similar to w32threads.h
> >>
> >
> OK finally updated the patch. it now adds the safe dll function into a new
> file "compat/w32dlfcn.h" and each source file that needs this header has
> been updated accordingly. Otherwise the code is the same as the last
> version that was tested by Michael.
> 
> If there are no other outstanding objections then let me know so i can push
> this.

>  w32dlfcn.h |   83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 83 insertions(+)
> 421c4543291a80c2e52c7e029da921ffcf071f34  0001-compat-w32dlfcn.h-Add-safe-win32-dlopen-dlclose-dlsy.patch
> From 37327de38eb366421ff66246e18cd93b0eb7026a Mon Sep 17 00:00:00 2001
> From: Matt Oliver <protogonoi at gmail.com>
> Date: Sat, 29 Oct 2016 18:28:27 +1100
> Subject: [PATCH] compat/w32dlfcn.h: Add safe win32 dlopen/dlclose/dlsym
>  functions.
> 
> ---
>  compat/w32dlfcn.h | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  1 file changed, 83 insertions(+)
>  create mode 100644 compat/w32dlfcn.h
> 
> diff --git a/compat/w32dlfcn.h b/compat/w32dlfcn.h
> new file mode 100644
> index 0000000..23db85d
> --- /dev/null
> +++ b/compat/w32dlfcn.h
> @@ -0,0 +1,83 @@
> +/*
> + * This file is part of FFmpeg.
> + *
> + * FFmpeg 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.
> + *
> + * FFmpeg 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 FFmpeg; if not, write to the Free Software
> + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
> + */
> +
> +#ifndef COMPAT_W32DLFCN_H
> +#define COMPAT_W32DLFCN_H
> +
> +#ifdef _WIN32
> +#include <windows.h>
> +#if _WIN32_WINNT < 0x0602
> +#include "libavutil/wchar_filename.h"
> +#endif
> +/**
> + * Safe function used to open dynamic libs. This attempts to improve program security
> + * by removing the current directory from the dll search path. Only dll's found in the
> + * executable or system directory are allowed to be loaded.
> + * @param name  The dynamic lib name.
> + * @return A handle to the opened lib.
> + */
> +static inline HMODULE win32_dlopen(const char *name)
> +{
> +#if _WIN32_WINNT < 0x0602
> +    // Need to check if KB2533623 is available
> +    if (!GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "SetDefaultDllDirectories")) {
> +        HMODULE module = NULL;
> +        wchar_t *path = NULL, *name_w = NULL;
> +        DWORD pathlen;
> +        if (utf8towchar(name, &name_w))
> +            goto exit;
> +        path = (wchar_t *)av_mallocz_array(MAX_PATH, sizeof(wchar_t));
> +        // Try local directory first
> +        pathlen = GetModuleFileNameW(NULL, path, MAX_PATH);
> +        pathlen = wcsrchr(path, '\\') - path;
> +        if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
> +            goto exit;
> +        path[pathlen] = '\\';
> +        wcscpy(path + pathlen + 1, name_w);
> +        module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
> +        if (module == NULL) {
> +            // Next try System32 directory
> +            pathlen = GetSystemDirectoryW(path, MAX_PATH);
> +            if (pathlen == 0 || pathlen + wcslen(name_w) + 2 > MAX_PATH)
> +                goto exit;
> +            path[pathlen] = '\\';
> +            wcscpy(path + pathlen + 1, name_w);
> +            module = LoadLibraryExW(path, NULL, LOAD_WITH_ALTERED_SEARCH_PATH);
> +        }
> +exit:
> +        av_free(path);
> +        av_free(name_w);
> +        return module;
> +    }
> +#endif
> +#ifndef LOAD_LIBRARY_SEARCH_APPLICATION_DIR
> +#   define LOAD_LIBRARY_SEARCH_APPLICATION_DIR 0x00000200
> +#endif
> +#ifndef LOAD_LIBRARY_SEARCH_SYSTEM32
> +#   define LOAD_LIBRARY_SEARCH_SYSTEM32        0x00000800
> +#endif
> +    return LoadLibraryExA(name, NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
> +}
> +#define dlopen(name, flags) win32_dlopen(name)
> +#define dlclose FreeLibrary
> +#define dlsym GetProcAddress
> +#else
> +#include <dlfcn.h>
> +#endif
> +
> +#endif /* COMPAT_W32DLFCN_H */
> \ No newline at end of file
> -- 
> 2.10.1.windows.1
> 

>  hwcontext_dxva2.c |   15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
> c3b4294a0e4734cfa780064ab66919f430e596bc  0002-avutil-hwcontext_dxva.c-Use-new-safe-dlopen-code.patch
> From 6b3937d020a795cb62a626c5ce1a94576b093b08 Mon Sep 17 00:00:00 2001
> From: Matt Oliver <protogonoi at gmail.com>
> Date: Sat, 29 Oct 2016 18:25:05 +1100
> Subject: [PATCH 2/4] avutil/hwcontext_dxva.c: Use new safe dlopen code.
> 
> ---
>  libavutil/hwcontext_dxva2.c | 15 ++++++++-------
>  1 file changed, 8 insertions(+), 7 deletions(-)
> 
> diff --git a/libavutil/hwcontext_dxva2.c b/libavutil/hwcontext_dxva2.c
> index e79254b..40a4a27 100644
> --- a/libavutil/hwcontext_dxva2.c
> +++ b/libavutil/hwcontext_dxva2.c
> @@ -37,6 +37,7 @@
>  #include "imgutils.h"
>  #include "pixdesc.h"
>  #include "pixfmt.h"
> +#include "compat/w32dlfcn.h"
>  
>  typedef IDirect3D9* WINAPI pDirect3DCreate9(UINT);
>  typedef HRESULT WINAPI pCreateDeviceManager9(UINT *, IDirect3DDeviceManager9 **);
> @@ -318,10 +319,10 @@ static void dxva2_device_free(AVHWDeviceContext *ctx)
>          IDirect3D9_Release(priv->d3d9);
>  
>      if (priv->d3dlib)
> -        FreeLibrary(priv->d3dlib);
> +        dlclose(priv->d3dlib);
>  
>      if (priv->dxva2lib)
> -        FreeLibrary(priv->dxva2lib);
> +        dlclose(priv->dxva2lib);
>  
>      av_freep(&ctx->user_opaque);
>  }
> @@ -352,24 +353,24 @@ static int dxva2_device_create(AVHWDeviceContext *ctx, const char *device,
>  
>      priv->device_handle = INVALID_HANDLE_VALUE;
>  
> -    priv->d3dlib = LoadLibrary("d3d9.dll");
> +    priv->d3dlib = dlopen("d3d9.dll", 0);
>      if (!priv->d3dlib) {
>          av_log(ctx, AV_LOG_ERROR, "Failed to load D3D9 library\n");
>          return AVERROR_UNKNOWN;
>      }
> -    priv->dxva2lib = LoadLibrary("dxva2.dll");
> +    priv->dxva2lib = dlopen("dxva2.dll", 0);
>      if (!priv->dxva2lib) {
>          av_log(ctx, AV_LOG_ERROR, "Failed to load DXVA2 library\n");
>          return AVERROR_UNKNOWN;
>      }
>  
> -    createD3D = (pDirect3DCreate9 *)GetProcAddress(priv->d3dlib, "Direct3DCreate9");
> +    createD3D = (pDirect3DCreate9 *)dlsym(priv->d3dlib, "Direct3DCreate9");
>      if (!createD3D) {
>          av_log(ctx, AV_LOG_ERROR, "Failed to locate Direct3DCreate9\n");
>          return AVERROR_UNKNOWN;
>      }
> -    createDeviceManager = (pCreateDeviceManager9 *)GetProcAddress(priv->dxva2lib,
> -                                                                  "DXVA2CreateDirect3DDeviceManager9");
> +    createDeviceManager = (pCreateDeviceManager9 *)dlsym(priv->dxva2lib,
> +                                                         "DXVA2CreateDirect3DDeviceManager9");
>      if (!createDeviceManager) {
>          av_log(ctx, AV_LOG_ERROR, "Failed to locate DXVA2CreateDirect3DDeviceManager9\n");
>          return AVERROR_UNKNOWN;
> -- 
> 2.10.1.windows.1
> 

>  configure              |    5 +----
>  libavformat/avisynth.c |   14 +++++---------
>  2 files changed, 6 insertions(+), 13 deletions(-)
> b1568f39504e5e14c924d27c8f11ba8f5816d68c  0003-avformat-avisynth.c-Use-new-safe-dlopen-code.patch
> From 633212cf1246b3fde61dd6515229e6a893005664 Mon Sep 17 00:00:00 2001
> From: Matt Oliver <protogonoi at gmail.com>
> Date: Sat, 29 Oct 2016 18:25:25 +1100
> Subject: [PATCH 3/4] avformat/avisynth.c: Use new safe dlopen code.

breaks --enable-avisynth on linux/ubuntu

--- config.h    2016-10-29 17:17:55.214014842 +0200
+++ delth/config.h      2016-10-29 17:15:41.906012034 +0200
@@ -1155,7 +1155,7 @@
 #define CONFIG_AST_DEMUXER 1
 #define CONFIG_AU_DEMUXER 1
 #define CONFIG_AVI_DEMUXER 1
-#define CONFIG_AVISYNTH_DEMUXER 1
+#define CONFIG_AVISYNTH_DEMUXER 0
 #define CONFIG_AVR_DEMUXER 1
 #define CONFIG_AVS_DEMUXER 1
 #define CONFIG_BETHSOFTVID_DEMUXER 1

[...]

-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Republics decline into democracies and democracies degenerate into
despotisms. -- Aristotle
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 181 bytes
Desc: Digital signature
URL: <http://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20161029/6be95161/attachment.sig>


More information about the ffmpeg-devel mailing list