rpms/netcf/devel netcf-0.1.0-fix-initialization-of-libxslt.patch, NONE, 1.1 netcf.spec, 1.2, 1.3

Mark McLoughlin markmc at fedoraproject.org
Tue Sep 15 09:47:42 UTC 2009


Author: markmc

Update of /cvs/pkgs/rpms/netcf/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv9648

Modified Files:
	netcf.spec 
Added Files:
	netcf-0.1.0-fix-initialization-of-libxslt.patch 
Log Message:
* Tue Sep 15 2009 Mark McLoughlin <markmc at redhat.com> - 0.1.0-3
- Fix libvirtd segfault caused by libxslt init issue (#523382)


netcf-0.1.0-fix-initialization-of-libxslt.patch:
 drv_initscripts.c |   60 ++++++++++++++++++++++++++++++++++++++++++------------
 internal.h        |    5 ++--
 netcf.c           |    3 +-
 netcf.h           |    3 +-
 xslt_ext.c        |   40 ++++++++++++++----------------------
 5 files changed, 70 insertions(+), 41 deletions(-)

--- NEW FILE netcf-0.1.0-fix-initialization-of-libxslt.patch ---
>From 7badcfa2462599fbcdb11225486f771b06e5876a Mon Sep 17 00:00:00 2001
From: Daniel Veillard <veillard at redhat.com>
Date: Fri, 14 Aug 2009 11:38:23 -0700
Subject: [PATCH] Fix initialization of libxslt

We used to initialize libxslt (and register extension modules) every time
ncf_init was called, and deregister/free libxslt globals every time
ncf_close was called. That breaks when libnetcf is used together with other
libraries that use libxslt, since they might continue using it after a call
to ncf_close.

To work around this, we now initialize and register our extension modules
every time we transform an XML doc, which obviates the need for global
cleanup (there's a small leak caused by global variables that libxslt
maintains, but that's negligible).

As a side-effect, we also capture error messages from the transform and
report them back with ncf_error.
---
 src/drv_initscripts.c |   60 ++++++++++++++++++++++++++++++++++++++----------
 src/internal.h        |    5 ++-
 src/netcf.c           |    3 +-
 src/netcf.h           |    3 +-
 src/xslt_ext.c        |   39 +++++++++++++------------------
 5 files changed, 70 insertions(+), 40 deletions(-)

diff --git a/src/drv_initscripts.c b/src/drv_initscripts.c
index 66d668f..f39357e 100644
--- a/src/drv_initscripts.c
+++ b/src/drv_initscripts.c
@@ -45,6 +45,7 @@
 #include <libxslt/xslt.h>
 #include <libxslt/xsltInternals.h>
 #include <libxslt/transform.h>
+#include <libxslt/xsltutils.h>
 
 static const char *const ifcfg_path =
     "/files/etc/sysconfig/network-scripts/*";
@@ -480,8 +481,6 @@ error:
 }
 
 int drv_init(struct netcf *ncf) {
-    int r;
-
     if (ALLOC(ncf->driver) < 0)
         return -1;
 
@@ -489,8 +488,6 @@ int drv_init(struct netcf *ncf) {
 
     // FIXME: Check for errors
     xsltInit();
-    r = xslt_ext_register();
-    ERR_THROW(r < 0, ncf, EINTERNAL, "xsltRegisterExtModule failed");
     ncf->driver->get = parse_stylesheet(ncf, "initscripts-get.xsl");
     ncf->driver->put = parse_stylesheet(ncf, "initscripts-put.xsl");
     ncf->driver->rng = rng_parse(ncf, "interface.rng");
@@ -513,8 +510,6 @@ int drv_init(struct netcf *ncf) {
 void drv_close(struct netcf *ncf) {
     xsltFreeStylesheet(ncf->driver->get);
     xsltFreeStylesheet(ncf->driver->put);
-    xslt_ext_unregister();
-    xsltCleanupGlobals();
     if (ncf->driver->ioctl_fd >= 0)
         close(ncf->driver->ioctl_fd);
     aug_close(ncf->driver->augeas);
@@ -777,6 +772,44 @@ error:
     return NULL;
 }
 
+ATTRIBUTE_FORMAT(printf, 2, 3)
+static void apply_stylesheet_error(void *ctx, const char *format, ...) {
+    struct netcf *ncf = ctx;
+    va_list ap;
+
+    va_start(ap, format);
+    vreport_error(ncf, NETCF_EXSLTFAILED, format, ap);
+    va_end(ap);
+}
+
+static xmlDocPtr apply_stylesheet(struct netcf *ncf, xsltStylesheetPtr style,
+                                  xmlDocPtr doc) {
+    xsltTransformContextPtr ctxt;
+    xmlDocPtr res = NULL;
+    int r;
+
+    ctxt = xsltNewTransformContext(style, doc);
+    ERR_COND_BAIL(ctxt == NULL, ncf, ENOMEM);
+
+    xsltSetTransformErrorFunc(ctxt, ncf, apply_stylesheet_error);
+
+    r = xslt_register_exts(ctxt);
+    ERR_COND_BAIL(r < 0, ncf, ENOMEM);
+
+    res = xsltApplyStylesheetUser(style, doc, NULL, NULL, NULL, ctxt);
+    if ((ctxt->state == XSLT_STATE_ERROR) ||
+        (ctxt->state == XSLT_STATE_STOPPED)) {
+        xmlFreeDoc(res);
+        res = NULL;
+        /* Fallback, in case our error handler isn't called */
+        report_error(ncf, NETCF_EXSLTFAILED, NULL);
+    }
+
+error:
+    xsltFreeTransformContext(ctxt);
+    return res;
+}
+
 char *drv_xml_desc(struct netcf_if *nif) {
     char *path = NULL, *result = NULL;
     struct augeas *aug;
@@ -801,7 +834,8 @@ char *drv_xml_desc(struct netcf_if *nif) {
     FREE(path);
 
     aug_xml = aug_get_xml(ncf, nint, intf);
-    ncf_xml = xsltApplyStylesheet(ncf->driver->put, aug_xml, NULL);
+    ncf_xml = apply_stylesheet(ncf, ncf->driver->put, aug_xml);
+    ERR_BAIL(ncf);
 
     xmlDocDumpFormatMemory(ncf_xml, (xmlChar **) &result, NULL, 1);
 
@@ -974,8 +1008,8 @@ struct netcf_if *drv_define(struct netcf *ncf, const char *xml_str) {
     r = aug_rm(aug, path);
     ERR_COND_BAIL(r < 0, ncf, EOTHER);
 
-    // FIXME: Check for errors from ApplyStylesheet
-    aug_xml = xsltApplyStylesheet(ncf->driver->get, ncf_xml, NULL);
+    aug_xml = apply_stylesheet(ncf, ncf->driver->get, ncf_xml);
+    ERR_BAIL(ncf);
 
     aug_put_xml(ncf, aug_xml);
     ERR_BAIL(ncf);
@@ -1197,8 +1231,8 @@ int drv_get_aug(struct netcf *ncf, const char *ncf_xml, char **aug_xml) {
     rng_validate(ncf, ncf_doc);
     ERR_BAIL(ncf);
 
-    // FIXME: Check for errors from ApplyStylesheet
-    aug_doc = xsltApplyStylesheet(ncf->driver->get, ncf_doc, NULL);
+    aug_doc = apply_stylesheet(ncf, ncf->driver->get, ncf_doc);
+    ERR_BAIL(ncf);
 
     xmlDocDumpFormatMemory(aug_doc, (xmlChar **) aug_xml, NULL, 1);
     ERR_COND_BAIL(*aug_xml == NULL, ncf, EXMLINVALID);
@@ -1218,8 +1252,8 @@ int drv_put_aug(struct netcf *ncf, const char *aug_xml, char **ncf_xml) {
     aug_doc = parse_xml(ncf, aug_xml);
     ERR_BAIL(ncf);
 
-    // FIXME: Check for errors from ApplyStylesheet
-    ncf_doc = xsltApplyStylesheet(ncf->driver->put, aug_doc, NULL);
+    ncf_doc = apply_stylesheet(ncf, ncf->driver->put, aug_doc);
+    ERR_BAIL(ncf);
 
     xmlDocDumpFormatMemory(ncf_doc, (xmlChar **) ncf_xml, NULL, 1);
     ERR_COND_BAIL(*ncf_xml == NULL, ncf, EXMLINVALID);
diff --git a/src/internal.h b/src/internal.h
index a11648b..d083dc6 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -30,6 +30,8 @@
 #include <string.h>
 #include <stdarg.h>
 
+#include <libxslt/transform.h>
+
 /*
  * Macros for gcc's attributes
  */
@@ -177,8 +179,7 @@ char *argv_to_string(const char *const *argv);
 /*
  * XSLT extension functions in xslt_ext.c
  */
-int xslt_ext_register(void);
-void xslt_ext_unregister(void);
+int xslt_register_exts(xsltTransformContextPtr ctxt);
 
 /*
  * Useful for debugging, used by ncftransform
diff --git a/src/netcf.c b/src/netcf.c
index e9e8e22..252a8e5 100644
--- a/src/netcf.c
+++ b/src/netcf.c
@@ -51,7 +51,8 @@ static const char *const errmsgs[] = {
     "XML invalid",                        /* EXMLINVALID */
     "required entry missing",             /* ENOENT */
     "failed to execute external program", /* EEXEC */
-    "instance still in use"               /* EINUSE */
+    "instance still in use",              /* EINUSE */
+    "XSLT transformation failed"          /* EXSLTFAILED */
 };
 
 static void free_netcf(struct netcf *ncf) {
diff --git a/src/netcf.h b/src/netcf.h
index 032be78..e08e94b 100644
--- a/src/netcf.h
+++ b/src/netcf.h
@@ -48,8 +48,9 @@ typedef enum {
     NETCF_ENOENT,        /* Required entry in a tree is missing */
     NETCF_EEXEC,         /* external program execution failed or returned
                           * non-0 */
-    NETCF_EINUSE         /* attempt to close a netcf instance that is still
+    NETCF_EINUSE,        /* attempt to close a netcf instance that is still
                           * used by other data structures */
+    NETCF_EXSLTFAILED    /* XSLT transformation failed */
 } netcf_errcode_t;
 
 
diff --git a/src/xslt_ext.c b/src/xslt_ext.c
index ea6d916..07e2b41 100644
--- a/src/xslt_ext.c
+++ b/src/xslt_ext.c
@@ -169,32 +169,25 @@ static void bond_option(xmlXPathParserContextPtr ctxt, int nargs) {
     xmlFree(bond_opts);
 }
 
-static void *xslt_ipcalc_init(ATTRIBUTE_UNUSED xsltTransformContextPtr ctxt,
-                              ATTRIBUTE_UNUSED const xmlChar *URI) {
-    xsltRegisterExtModuleFunction(BAD_CAST "netmask", XSLT_EXT_IPCALC_NS,
-                                  ipcalc_netmask);
-    xsltRegisterExtModuleFunction(BAD_CAST "prefix", XSLT_EXT_IPCALC_NS,
-                                  ipcalc_prefix);
-    return NULL;
-}
+int xslt_register_exts(xsltTransformContextPtr ctxt) {
+    int r;
 
-static void *xslt_bond_init(ATTRIBUTE_UNUSED xsltTransformContextPtr ctxt,
-                            ATTRIBUTE_UNUSED const xmlChar *URI) {
-    xsltRegisterExtModuleFunction(BAD_CAST "option", XSLT_EXT_BOND_NS,
-                                  bond_option);
-    return NULL;
-}
+    r = xsltRegisterExtFunction(ctxt, BAD_CAST "netmask",
+                                XSLT_EXT_IPCALC_NS, ipcalc_netmask);
+    if (r < 0)
+        return r;
 
-int xslt_ext_register(void) {
-    int r = 0;
-    r = xsltRegisterExtModule(XSLT_EXT_IPCALC_NS, xslt_ipcalc_init, NULL);
-    if (r < 0) return r;
-    r = xsltRegisterExtModule(XSLT_EXT_BOND_NS, xslt_bond_init, NULL);
-    return r;
-}
+    r = xsltRegisterExtFunction(ctxt, BAD_CAST "prefix",
+                                XSLT_EXT_IPCALC_NS, ipcalc_prefix);
+    if (r < 0)
+        return r;
+
+    r = xsltRegisterExtFunction(ctxt, BAD_CAST "option",
+                                XSLT_EXT_BOND_NS, bond_option);
+    if (r < 0)
+        return r;
 
-void xslt_ext_unregister(void) {
-    xsltUnregisterExtModule	(XSLT_EXT_IPCALC_NS);
+    return 0;
 }
 
 /*
-- 
1.6.2.5



Index: netcf.spec
===================================================================
RCS file: /cvs/pkgs/rpms/netcf/devel/netcf.spec,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -p -r1.2 -r1.3
--- netcf.spec	25 Jul 2009 18:04:07 -0000	1.2
+++ netcf.spec	15 Sep 2009 09:47:42 -0000	1.3
@@ -1,6 +1,6 @@
 Name:           netcf
 Version:        0.1.0
-Release:        2%{?dist}%{?extra_release}
+Release:        3%{?dist}%{?extra_release}
 Summary:        Cross-platform network configuration library
 
 Group:          System Environment/Libraries
@@ -13,6 +13,8 @@ BuildRequires:  readline-devel augeas-de
 BuildRequires:  libxml2-devel libxslt-devel
 Requires:       %{name}-libs = %{version}-%{release}
 
+Patch01: netcf-0.1.0-fix-initialization-of-libxslt.patch
+
 %description
 A library for modifying the network configuration of a system. Network
 configurations are expresed in a platform-independent XML format, which
@@ -39,6 +41,8 @@ The libraries for %{name}.
 %prep
 %setup -q
 
+%patch01 -p1
+
 %build
 %configure --disable-static
 make %{?_smp_mflags}
@@ -73,6 +77,9 @@ rm -rf $RPM_BUILD_ROOT
 %{_libdir}/pkgconfig/netcf.pc
 
 %changelog
+* Tue Sep 15 2009 Mark McLoughlin <markmc at redhat.com> - 0.1.0-3
+- Fix libvirtd segfault caused by libxslt init issue (#523382)
+
 * Sat Jul 25 2009 Fedora Release Engineering <rel-eng at lists.fedoraproject.org> - 0.1.0-2
 - Rebuilt for https://fedoraproject.org/wiki/Fedora_12_Mass_Rebuild
 




More information about the fedora-extras-commits mailing list