bug-sourceinstall
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug-sourceinstall] Re: invalid write


From: Claudio Fontana
Subject: [bug-sourceinstall] Re: invalid write
Date: Sun, 06 Dec 2009 01:01:04 +0100
User-agent: Thunderbird 2.0.0.23 (X11/20090812)

Brian Gough wrote:
It doesn't cause any major problem but there's a invalid write in the
function srcinst_close_package() in srcinst.c

    if (info->onclose & SRCINST_ONCLOSE_UPDATE) {
        rv = _update_package(&_srcinst_state.packages, e);
    }

    info->onclose = SRCINST_ONCLOSE_NOP;

When _update_package(&_srcinst_state.packages, e) is called and takes
the branch with _remove_package_list() it causes e to be freed.  This
causes a memory error for info->onclose = ... because info is actually
set to e->info earlier in srcinst_close_package().  I'm not sure what
the best fix is for that -- maybe just to return after
_update_package()?

I think this should fix it. Can you check if it makes sense to you?


Index: actions.c
===================================================================
RCS file: /sources/sourceinstall/sourceinstall2/libsrcinst/actions.c,v
retrieving revision 1.33
diff -u -r1.33 actions.c
--- actions.c   22 Jun 2008 15:25:11 -0000      1.33
+++ actions.c   5 Dec 2009 23:54:54 -0000
@@ -875,9 +875,10 @@
     return packdir;
 }
 
-/* decide what to do based on current state */
-
-int _update_package(struct _package_list *l, struct _package_element *e)
+/* decide what to do based on current state.
+   Returns 1 on error, 0 on success.
+   If the package has been freed, *e is set to NULL. */
+int _update_package(struct _package_list *l, struct _package_element **e)
 {
 
     /* update package information on the disk based on information stored
@@ -886,17 +887,18 @@
     int rv;
     struct _package_info *info;
 
-    info = e->info;
+    info = (*e)->info;
 
     if (!info->source_location && !info->installed) {
        /* we have to remove the package. First from the filesystem, if it is
           persistant */
 
-       rv = _unlink_package_info(e->info);     /* from the filesystem */
-       _remove_package_list(l, e);     /* then from memory */
+       rv = _unlink_package_info(info); /* from the filesystem */
+       _remove_package_list(l, *e);    /* then from memory */
+       *e = 0;                         /* inform caller that it's freed. */
 
     } else {
-       rv = _save_package_info(e->info);
+       rv = _save_package_info(info);
     }
 
     return rv;
Index: actions.h
===================================================================
RCS file: /sources/sourceinstall/sourceinstall2/libsrcinst/actions.h,v
retrieving revision 1.7
diff -u -r1.7 actions.h
--- actions.h   8 Sep 2007 14:43:24 -0000       1.7
+++ actions.h   5 Dec 2009 23:54:54 -0000
@@ -74,8 +74,9 @@
 SRCINST_ERR _action_upgrade(struct _package_info *from,
                            struct _package_info *to);
 
-/* decide what to do based on current state */
-int _update_package(struct _package_list *l, struct _package_element *e);
+/* decide what to do based on current state.
+   Sets *e = NULL if the element is freed during the update. */
+int _update_package(struct _package_list *l, struct _package_element **e);
 
 /* detect a configure script, running autogen scripts if necessary. */
 
Index: srcinst.c
===================================================================
RCS file: /sources/sourceinstall/sourceinstall2/libsrcinst/srcinst.c,v
retrieving revision 1.24
diff -u -r1.24 srcinst.c
--- srcinst.c   8 Dec 2007 15:51:29 -0000       1.24
+++ srcinst.c   5 Dec 2009 23:54:54 -0000
@@ -655,10 +655,13 @@
     }
 
     if (info->onclose & SRCINST_ONCLOSE_UPDATE) {
-       rv = _update_package(&_srcinst_state.packages, e);
+       rv = _update_package(&_srcinst_state.packages, &e);
     }
 
-    info->onclose = SRCINST_ONCLOSE_NOP;
+    if (e) {
+       /* package was not freed by _update_package */
+       info->onclose = SRCINST_ONCLOSE_NOP;
+    }
     return rv;
 }
 

reply via email to

[Prev in Thread] Current Thread [Next in Thread]