[nspluginwrapper/f18] Final dlopen patch for Bug #870108

Martin Stransky stransky at fedoraproject.org
Fri Dec 14 11:11:59 UTC 2012


commit 96f6d76c386e53f086dfd05afe28c2a6fa6b8da3
Author: Martin Stransky <stransky at anakreon.cz>
Date:   Fri Dec 14 12:11:53 2012 +0100

    Final dlopen patch for Bug #870108

 nspluginwrapper.spec       |   10 +-
 plugin-config-dlopen.patch |  379 ++++++++++++++++++++++++++++++++++++++++++++
 plugin-config-help.patch   |   25 +++
 3 files changed, 413 insertions(+), 1 deletions(-)
---
diff --git a/nspluginwrapper.spec b/nspluginwrapper.spec
index 5a64a72..b94f4ca 100644
--- a/nspluginwrapper.spec
+++ b/nspluginwrapper.spec
@@ -85,7 +85,7 @@
 Summary:	A compatibility layer for Netscape 4 plugins
 Name:		nspluginwrapper
 Version:	1.4.4
-Release:	12%{?dist}
+Release:	16%{?dist}
 License:	GPLv2+
 Group:		Applications/Internet
 Url:		http://gwenole.beauchesne.info/projects/nspluginwrapper/
@@ -107,6 +107,8 @@ Patch101:	plugin-config-umask.patch
 Patch102:	plugin-config-print.patch
 Patch103:	plugin-config-non-native.patch
 Patch104:	plugin-config-time-check.patch
+Patch105:	plugin-config-dlopen.patch
+Patch106:	plugin-config-help.patch
 
 Provides:	%{name} = %{version}-%{release}
 Requires:	mozilla-filesystem
@@ -146,7 +148,9 @@ pushd %plugin_config_name
 %patch102 -p2 -b .print
 %patch103 -p2 -b .non-native
 %patch104 -p2 -b .time
+%patch106 -p2 -b .help
 popd
+%patch105 -p1 -b .dlopen
 
 %build
 # Build wrapper
@@ -263,6 +267,10 @@ fi;
 
 
 %changelog
+* Thu Dec 13 2012 Martin Stransky <stransky at redhat.com> 1.4.4-16
+- Fixed bug #870108 - plugin-config should not call dlopen()
+- Fixed plugin-config help
+
 * Mon Aug 13 2012 Martin Stransky <stransky at redhat.com> 1.4.4-11
 - Fixed bug #841798 - don't wrap plugins with the same arch
 
diff --git a/plugin-config-dlopen.patch b/plugin-config-dlopen.patch
new file mode 100644
index 0000000..a2665a6
--- /dev/null
+++ b/plugin-config-dlopen.patch
@@ -0,0 +1,379 @@
+diff -up nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.c.dlopen nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.c
+--- nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.c.dlopen	2012-12-14 11:48:58.414171680 +0100
++++ nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.c	2012-12-14 11:48:58.415171685 +0100
+@@ -257,39 +257,46 @@ int is_setuid(void)
+   return(geteuid() == 0 && getuid() != 0);
+ }
+ 
+-/*
+- * Drop root UID
+- */
+-int drop_setuid(void)
+-{  
+-  if(is_setuid()) {
+-    if(setgid(getgid()) < 0)
+-      return(FALSE);
+-    if(setuid(getuid()) < 0)
+-      return(FALSE);
+-  }  
+-  return(TRUE);
++
++int get_user_uid_gid(const char *username, uid_t *uid, gid_t *gid)
++{
++    struct passwd *passwd_entry;
++
++    if ((passwd_entry = getpwnam(username)) == NULL)
++        return FALSE;
++
++    *uid = passwd_entry->pw_uid;
++    *gid = passwd_entry->pw_gid;
++
++    return TRUE;
+ }
+ 
+ /*
+- * Drop root UID, leave it only for filesystem
++ * Drop root UID
+  */
+ int drop_root(void)
+-{
+-  if(is_setuid()) {
+-    return(drop_setuid());
++{  
++  static uid_t user_uid = -1;
++  static gid_t user_gid = -1;
++  const char* username = "nobody";
++
++  // get user uid and gid
++  if (user_uid == -1 || user_gid == -1) {
++      if (!get_user_uid_gid(username, &user_uid, &user_gid))
++          return FALSE;
++  }
++
++  //identify as nspluginwrapper user
++  if(setgid(user_gid) == -1) {
++      return FALSE;
++  }
++  if(setuid(user_uid) == -1) {
++      return FALSE;
+   }
+   
+-  return(TRUE);
++  return TRUE;
+ }
+ 
+-enum
+-{
+-	EXIT_VIEWER_NOT_FOUND = -2,
+-	EXIT_VIEWER_ERROR = -1,
+-	EXIT_VIEWER_OK = 0,
+-};
+-
+ char * get_prefix(char *p_prefix, int max_len, int s_bits, int t_bits)
+ {  
+   snprintf(p_prefix,max_len,"nswrapper_%d_%d",s_bits,t_bits);
+@@ -321,7 +328,7 @@ int check_plugin_viewer(const char *plug
+     return(FALSE);
+   }
+   else if (pid == 0) {
+-    if(!drop_setuid())
++    if(!drop_root())
+       exit(EXIT_VIEWER_ERROR);
+ 
+     if(access(p_viewer, X_OK) != 0) {
+diff -up nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.h.dlopen nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.h
+--- nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.h.dlopen	2007-10-31 10:46:34.000000000 +0100
++++ nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.h	2012-12-14 11:48:58.416171689 +0100
+@@ -36,6 +36,13 @@ typedef struct _WRAP_PLUGIN {
+ 
+ } WRAP_PLUGIN;
+ 
++enum
++{
++  EXIT_VIEWER_NOT_FOUND = -2,
++  EXIT_VIEWER_ERROR = -1,
++  EXIT_VIEWER_OK = 0,
++};
++
+ #define NPW_WRAPPER_PLUGIN   "npwrapper.so"  // Don't process this plugin
+ 
+ void warning(const char *format,...);
+@@ -43,6 +50,6 @@ void error(const char *format,...);
+ void info(const char *format, ...);
+ 
+ int is_setuid(void);
+-int drop_setuid(void);
++int drop_root(void);
+ 
+ #endif // __PLUGIN_CONFIG_H__
+diff -up nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.c.dlopen nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.c
+--- nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.c.dlopen	2007-11-06 12:48:18.000000000 +0100
++++ nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.c	2012-12-14 11:48:58.416171689 +0100
+@@ -49,6 +49,9 @@
+ #include <asm/types.h>
+ 
+ #include "plugin-detection.h"
++#include "plugin-path.h"
++#include "plugin-dir.h"
++#include "plugin-config.h"
+ 
+ 
+ /* ELF decoder derived from QEMU code */
+@@ -817,37 +820,96 @@ int is_wrapper_plugin_fd (int fd)
+ 
+ int get_wrapper_plugin_info(const char *plugin_path, NPW_PLUGININFO *out_plugin_info)
+ {
+-  void *handle = dlopen(plugin_path, RTLD_LAZY);
+-  if (handle == NULL)
+-        return FALSE;
+-  if (dlsym(handle, "NP_Initialize") == NULL)
+-        return FALSE;
+-  if (dlsym(handle, "NP_Shutdown") == NULL)
+-        return FALSE;
+-  if (dlsym(handle, "NP_GetMIMEDescription") == NULL)
++    int fd[2];
++
++    // initialize pipe
++    if (pipe(fd) == -1)
+         return FALSE;
+-  NPW_PLUGININFO *pi;
+-  if ((pi = (NPW_PLUGININFO *)dlsym(handle, "NPW_Plugin")) == NULL)
++
++    int pid = fork();
++    if (pid < 0) {
+         return FALSE;
+-  if (out_plugin_info) {
+-        strncpy(out_plugin_info->ident, pi->ident, NPW_PLUGIN_IDENT_SIZE);
+-        strncpy(out_plugin_info->path, pi->path, PATH_MAX);
+-        out_plugin_info->mtime = pi->mtime;
+-        out_plugin_info->target_arch[0] = '\0';
+-        out_plugin_info->target_os[0] = '\0';
+-        if (strncmp(pi->ident, "NPW:0.9.9", 9) != 0) {
+-          strncpy(out_plugin_info->target_arch, pi->target_arch, NPW_PLUGININFO_TARGET_LENGTH-2);
+-          strncpy(out_plugin_info->target_os, pi->target_os, NPW_PLUGININFO_TARGET_LENGTH-2);
+-          out_plugin_info->target_arch[NPW_PLUGININFO_TARGET_LENGTH-1] = '\0';
+-          out_plugin_info->target_os[NPW_PLUGININFO_TARGET_LENGTH-1] = '\0';
++    }
++    else if (pid == 0) {
++        //close read
++        close(fd[0]);
++    
++        if(!drop_root())
++            exit(EXIT_VIEWER_ERROR);
++
++        void *handle = dlopen(plugin_path, RTLD_LAZY);
++
++        NPW_PLUGININFO plugin_info;
++        NPW_PLUGININFO *pi;
++
++        if ((pi = (NPW_PLUGININFO *)dlsym(handle, "NPW_Plugin")) == NULL) {
++            // Send expected data to parent but invalidate them with error 
++            // return code
++            write(fd[1], &plugin_info, sizeof(NPW_PLUGININFO));
++            exit(EXIT_VIEWER_ERROR);
++        }
++        else {
++            //check if necessary symbols are presented
++            if ((dlsym(handle, "NP_Initialize") == NULL) ||
++                (dlsym(handle, "NP_Shutdown") == NULL) ||
++                (dlsym(handle, "NP_GetMIMEDescription") == NULL)) {
++
++                // Send expected data to parent but invalidate them with error
++                // return code
++                write(fd[1], &plugin_info, sizeof(NPW_PLUGININFO));
++                exit(EXIT_VIEWER_ERROR);
++            }
++
++            if (out_plugin_info) {
++                strncpy(plugin_info.ident, pi->ident, NPW_PLUGIN_IDENT_SIZE);
++                strncpy(plugin_info.path, pi->path, PATH_MAX);
++                plugin_info.mtime = pi->mtime;
++                plugin_info.target_arch[0] = '\0';
++                plugin_info.target_os[0] = '\0';
++                if (strncmp(pi->ident, "NPW:0.9.9", 9) != 0) {
++                    strncpy(plugin_info.target_arch, pi->target_arch, NPW_PLUGININFO_TARGET_LENGTH-2);
++                    strncpy(plugin_info.target_os, pi->target_os, NPW_PLUGININFO_TARGET_LENGTH-2);
++                    plugin_info.target_arch[NPW_PLUGININFO_TARGET_LENGTH-1] = '\0';
++                    plugin_info.target_os[NPW_PLUGININFO_TARGET_LENGTH-1] = '\0';
++                }
++            }
+         }
+-  }
+-  dlclose(handle);
+-  return TRUE;
++
++        /* Intentionally leak the handle; many libraries crash when unloaded. */
++        /* dlclose(handle); */
++        if (write(fd[1], &plugin_info, sizeof(NPW_PLUGININFO)) == -1)
++            exit(EXIT_VIEWER_ERROR);
++
++        exit(EXIT_VIEWER_OK);
++    }
++    else {
++        //close write
++        close(fd[1]);
++        int status;
++        NPW_PLUGININFO info;
++
++        //read result from child
++        if (read(fd[0], &info, sizeof(NPW_PLUGININFO)) == -1)
++            return FALSE;
++
++        while (waitpid(pid, &status, 0) != pid)
++            ;
++
++        if (WIFEXITED(status)) {
++            if (WEXITSTATUS(status) != EXIT_VIEWER_OK)
++                return FALSE;
++        }
++
++        if (out_plugin_info)
++            *out_plugin_info = info;
++    }
++
++    return TRUE;
+ }
+ 
+ int is_wrapper_plugin (const char *plugin_path, NPW_PLUGININFO * out_plugin_info)
+ {
++
+ 	int fd = open (plugin_path, O_RDONLY);
+ 	if (fd < 0)
+ 		return FALSE;
+diff -up nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.h.dlopen nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.h
+--- nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.h.dlopen	2007-10-29 14:52:54.000000000 +0100
++++ nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-detection.h	2012-12-14 11:48:58.417171693 +0100
+@@ -53,6 +53,8 @@ int  is_plugin_fd_64(int fd, NPW_PLUGINI
+ int  is_plugin_fd(int fd, NPW_PLUGININFO * out_plugin_info);
+ int  is_plugin(const char *filename, NPW_PLUGININFO * out_plugin_info);
+ 
++int get_user_uid_gid(const char *username, uid_t *uid, gid_t *gid);
++
+ int  is_wrapper_plugin_handle(void *handle, NPW_PLUGININFO * out_plugin_info);
+ int  is_wrapper_plugin(const char *plugin_path, NPW_PLUGININFO * out_plugin_info);
+ 
+diff -up nspluginwrapper-1.4.4/src/npw-config.c.dlopen nspluginwrapper-1.4.4/src/npw-config.c
+--- nspluginwrapper-1.4.4/src/npw-config.c.dlopen	2012-12-14 11:48:58.383171524 +0100
++++ nspluginwrapper-1.4.4/src/npw-config.c	2012-12-14 11:59:45.276355433 +0100
+@@ -126,6 +126,42 @@ static int strexpand(char *dst, int dstl
+   return 0;
+ }
+ 
++static int get_user_uid_gid(const char *username, uid_t *uid, gid_t *gid)
++{
++    struct passwd *passwd_entry;
++
++    if ((passwd_entry = getpwnam(username)) == NULL)
++        return FALSE;
++
++    *uid = passwd_entry->pw_uid;
++    *gid = passwd_entry->pw_gid;
++
++    return TRUE;
++}
++
++static int drop_root(void)
++{  
++  static uid_t user_uid = -1;
++  static gid_t user_gid = -1;
++  const char* username = "nobody";
++
++  // get user uid and gid
++  if (user_uid == -1 || user_gid == -1) {
++      if (!get_user_uid_gid(username, &user_uid, &user_gid))
++          return FALSE;
++  }
++
++  //identify as nspluginwrapper user
++  if(setgid(user_gid) == -1) {
++      return FALSE;
++  }
++  if(setuid(user_uid) == -1) {
++      return FALSE;
++  }
++  
++  return TRUE;
++}
++
+ static const char *get_system_mozilla_plugin_dir(void)
+ {
+   static const char default_dir[] = LIBDIR "/mozilla/plugins";
+@@ -363,6 +399,8 @@ static bool is_plugin_viewer_ok(const ch
+   if (pid < 0)
+ 	return false;
+   if (pid == 0) {
++	if(!drop_root())
++	  exit(1);
+ 	if (!g_verbose) {
+ 	  // don't spit out errors in non-verbose mode, we only need
+ 	  // to know whether there is a valid viewer or not
+@@ -531,16 +569,62 @@ static bool is_wrapper_plugin_handle(voi
+   return true;
+ }
+ 
++#define EXIT_ERROR        (-1)
++#define EXIT_WRAPPED      (0)
++#define EXIT_NOT_WRAPPED  (1)
++
+ static bool is_wrapper_plugin(const char *plugin_path, NPW_PluginInfo *out_plugin_info)
+ {
+-  void *handle = dlopen(plugin_path, RTLD_LAZY);
+-  if (handle == NULL)
+-	return false;
++  int fd[2];
+ 
+-  bool ret = is_wrapper_plugin_handle(handle, out_plugin_info);
+-  /* Intentionally leak the handle; many libraries crash when unloaded. */
+-  /* dlclose(handle); */
+-  return ret;
++  // initialize pipe
++  if (pipe(fd) == -1)
++      return FALSE;
++
++  int pid = fork();
++  if (pid < 0) {
++      return FALSE;
++  }
++  else if (pid == 0) {
++      NPW_PluginInfo  plugin_info;
++      bool            is_wrapped = false;
++  
++      //close read
++      close(fd[0]);
++  
++      if(!drop_root())
++          exit(EXIT_ERROR);
++  
++      void *handle = dlopen(plugin_path, RTLD_LAZY);
++      if (handle != NULL) {
++          is_wrapped = is_wrapper_plugin_handle(handle, &plugin_info);
++          /* Intentionally leak the handle; many libraries crash when unloaded. */
++          /* dlclose(handle); */
++      }
++    
++      if (write(fd[1], &plugin_info, sizeof(NPW_PluginInfo)) == -1)
++          exit(EXIT_ERROR);
++      
++      exit(is_wrapped ? EXIT_WRAPPED : EXIT_NOT_WRAPPED);
++  }
++  else {
++      //close write
++      close(fd[1]);
++      int status;
++      NPW_PluginInfo info;
++
++      //read result from child
++      if (read(fd[0], &info, sizeof(NPW_PluginInfo)) == -1)
++          return FALSE;
++
++      while (waitpid(pid, &status, 0) != pid)
++          ;
++
++      if (out_plugin_info)
++          *out_plugin_info = info;
++      
++      return (WEXITSTATUS(status) == EXIT_WRAPPED);
++  }
+ }
+ 
+ static bool is_master_wrapper_plugin(const char *plugin_path)
diff --git a/plugin-config-help.patch b/plugin-config-help.patch
new file mode 100644
index 0000000..491af4f
--- /dev/null
+++ b/plugin-config-help.patch
@@ -0,0 +1,25 @@
+--- nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.c	2012-12-13 09:24:27.988306638 +0100
++++ nspluginwrapper-1.4.4/plugin-config-1.9/src/plugin-config.c.help	2012-12-13 09:25:23.015335592 +0100
+@@ -889,11 +889,11 @@ to \n\
+                                                                           \n\
+ Usage:                                                                    \n\
+                                                                           \n\
+-  plugin-setup  [options]                                                 \n\
++  plugin-config  [options]                                                \n\
+                                                                           \n\
+ Options:                                                                  \n\
+                                                                           \n\
+-  -i  --install Install/wrap all availabile plug-ins                      \n\
++  -i  --install Install/wrap all available plug-ins                       \n\
+   -r  --remove  Remove all installed plug-ins                             \n\
+                                                                           \n\
+   -l  --list    List all installed plug-ins                               \n\
+@@ -908,7 +908,7 @@ Options:
+   -v  --verbose Verbose mode                                              \n\
+   -h  --help    This help                                                 \n\
+                                                                           \n\
+-  If it is run without any command line argument, --check is used.        \n\\n",
++  If it is run without any command line argument, --check is used.        \n\n",
+   NPW_PLUGIN_DIR_32,NPW_PLUGIN_DIR_64,
+   NPW_PLUGIN_DIR_32_WRAPPED,NPW_PLUGIN_DIR_64_WRAPPED );
+   


More information about the scm-commits mailing list