summaryrefslogtreecommitdiffstats
path: root/webkit
diff options
context:
space:
mode:
authorevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-18 21:49:42 +0000
committerevan@chromium.org <evan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-18 21:49:42 +0000
commit6d9e355a4421e37895a8492ab300cf918a8e1334 (patch)
treea9a27beb710600ddeb54201a85efa9a981c8589f /webkit
parentd42a545e83f9057fb40399589f7f2ce625789d46 (diff)
downloadchromium_src-6d9e355a4421e37895a8492ab300cf918a8e1334.zip
chromium_src-6d9e355a4421e37895a8492ab300cf918a8e1334.tar.gz
chromium_src-6d9e355a4421e37895a8492ab300cf918a8e1334.tar.bz2
linux: unwrap nspluginwrapper-wrapped plugins if possible
Since we already run plugins out of process, nspluginwrapper is just an extra source of problems. We'll still use nspluginwrapper when it's necessary, e.g. to run 32-bit plugins on a 64-bit computer. Review URL: http://codereview.chromium.org/998006 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@41999 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit')
-rw-r--r--webkit/glue/plugins/plugin_lib_posix.cc53
1 files changed, 53 insertions, 0 deletions
diff --git a/webkit/glue/plugins/plugin_lib_posix.cc b/webkit/glue/plugins/plugin_lib_posix.cc
index 1097b24..e738b67 100644
--- a/webkit/glue/plugins/plugin_lib_posix.cc
+++ b/webkit/glue/plugins/plugin_lib_posix.cc
@@ -64,7 +64,57 @@ bool ELFMatchesCurrentArchitecture(const FilePath& filename) {
return false;
}
+// This structure matches enough of nspluginwrapper's NPW_PluginInfo
+// for us to extract the real plugin path.
+struct __attribute__((packed)) NSPluginWrapperInfo {
+ char ident[32]; // NSPluginWrapper magic identifier (includes version).
+ char path[PATH_MAX]; // Path to wrapped plugin.
+};
+
+// Test a plugin for whether it's been wrapped by NSPluginWrapper, and
+// if so attempt to unwrap it. Pass in an opened plugin handle; on
+// success, |dl| and |unwrapped_path| will be filled in with the newly
+// opened plugin. On failure, params are left unmodified.
+void UnwrapNSPluginWrapper(void **dl, FilePath* unwrapped_path) {
+ NSPluginWrapperInfo* info =
+ reinterpret_cast<NSPluginWrapperInfo*>(dlsym(*dl, "NPW_Plugin"));
+ if (!info)
+ return; // Not a NSPW plugin.
+
+ // Here we could check the NSPW ident field for the versioning
+ // information, but the path field is available in all versions
+ // anyway.
+
+ // Grab the path to the wrapped plugin. Just in case the structure
+ // format changes, protect against the path not being null-terminated.
+ char* path_end = static_cast<char*>(memchr(info->path, '\0',
+ sizeof(info->path)));
+ if (!path_end)
+ path_end = info->path + sizeof(info->path);
+ FilePath path = FilePath(std::string(info->path, path_end - info->path));
+
+ if (!ELFMatchesCurrentArchitecture(path)) {
+ LOG(WARNING) << path.value() << " is nspluginwrapper wrapping a "
+ << "plugin for a different architecture; it will "
+ << "work better if you instead use a native plugin.";
+ return;
+ }
+
+ void* newdl = base::LoadNativeLibrary(path);
+ if (!newdl) {
+ // We couldn't load the unwrapped plugin for some reason, despite
+ // being able to load the wrapped one. Just use the wrapped one.
+ return;
+ }
+
+ // Unload the wrapped plugin, and use the wrapped plugin instead.
+ base::UnloadNativeLibrary(*dl);
+ *dl = newdl;
+ *unwrapped_path = path;
+}
+
} // anonymous namespace
+
namespace NPAPI {
bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
@@ -82,6 +132,9 @@ bool PluginLib::ReadWebPluginInfo(const FilePath& filename,
info->path = filename;
+ // Attempt to swap in the wrapped plugin if this is nspluginwrapper.
+ UnwrapNSPluginWrapper(&dl, &info->path);
+
// See comments in plugin_lib_mac regarding this symbol.
typedef const char* (*NP_GetMimeDescriptionType)();
NP_GetMimeDescriptionType NP_GetMIMEDescription =