Report information
The Basics
Id:
37237
Status:
resolved
Priority:
Medium/Medium
Queue:

People
BugTracker
Version Fixed:
9.9.7, 9.10.2, 9.11.0
Version Found:
(no value)
Versions Affected:
(no value)
Versions Planned:
(no value)
Priority:
(no value)
Severity:
S2 Normal
CVSS Score:
(no value)
CVE ID:
(no value)
Component:
Other
Area:
bug

Attachments
0001-Don-t-free-alias-to-ldapdb-data-that-is-cleaned-up-d.patch

Dates
Created:Sat, 20 Sep 2014 01:22:30 -0400
Updated:Mon, 26 Jun 2017 19:43:58 -0400
Closed:Mon, 06 Apr 2015 16:51:44 -0400



This bug tracker is no longer active.

Please go to our Gitlab to submit issues (both feature requests and bug reports) for active projects maintained by Internet Systems Consortium (ISC).

Due to security and confidentiality requirements, full access is limited to the primary maintainers.

Subject: Crash in named-sdb -- freeing an invalid pointer.
Date: Fri, 19 Sep 2014 23:20:01 -0600
To: bind-bugs@isc.org
From: Troy Noble <econoplas@gmail.com>
Hello bind developers!

I wanted to report a bug we found in sdbldap.c recently. I know sdb is a contrib module so I am not sure if it is officially supported by the bind-bugs maintainers the original author.

In short, several bugs could potentially be fixed by correcting a few "ism's" related to potentially unsafe use of "free" in contrib/sdb/ldap/ldapdb.c by adding appropriate if ( ... != NULL) checks before things like free(conndata->index) at line 136... which is the location that caused our particular crash, and free(threaddata->index) at line 133, etc.

For best cross-platform/cross-compiler compatibility it would probably also be good practice to be setting conndata->index = NULL after calling free(conndata->index) so the if ( ... != NULL) checks would always prevent double-freeing of blocks if the implementation of "free" doesn't happen to also zero out the pointer on all platforms.

I am referring to what I hope is the latest code here:


The crash we encountered specifically occurred at line 136 below when free(conndata->index) tried to free an invalid pointer.  Unfortunately the code optimizer had optimized away conndata->index so I could not tell if it was NULL or just a double-free of a dangling pointer reference.  But as soon as I looked at the code and saw that they were checking for NULL sometime and not other times, that seemed like a likely cause & good place for a NULL check.

127         if (data == NULL) {
128                 /* cleanup */
129                 /* lock out other threads */
130                 ldapdb_lock(1);
131                 while (allthreadsdata != NULL) {
132                         threaddata = allthreadsdata;
133                         free(threaddata->index);
134                         while (threaddata->data != NULL) {
135                                 conndata = threaddata->data;
136                                 free(conndata->index);
137                                 if (conndata->data != NULL)
138                                         ldap_unbind((LDAP *)conndata->data);
139                                 threaddata->data = conndata->next;
140                                 free(conndata);
141                         }
142                         allthreadsdata = threaddata->next;
143                         free(threaddata);
144                 }
145                 ldapdb_lock(-1);
146                 return (NULL);
147         }

I could supply a coredump file, but would probably be difficult to debug unless you have an RHEL 6.5 machine with latest patches to debug with, so I thought it would be better just to describe what appears to be a somewhat pervasive problem in several places in this particular module.

If you would rather I compile up the latest code & try to make the fixes myself, and then submit a patch against the latest code repo (assuming I am looking at the latest repo) let me know and I would be glad to contribute.

Thanks for your support & contributions to the internet community.  Your efforts are appreciated!

Troy


Subject: Re: [ISC-Bugs #37237] Crash in named-sdb -- freeing an invalid pointer.
Date: Mon, 22 Sep 2014 10:09:28 +0530
To: Troy Noble via RT <bind9-bugs@isc.org>
From: Mukund Sivaraman <muks@isc.org>
Hi Troy On Sat, Sep 20, 2014 at 05:22:32AM +0000, Troy Noble via RT wrote: > I wanted to report a bug we found in sdbldap.c recently. I know sdb is a > contrib module so I am not sure if it is officially supported by the > bind-bugs maintainers the original author. > > In short, several bugs could potentially be fixed by correcting a few > "ism's" related to potentially unsafe use of "free" in > contrib/sdb/ldap/ldapdb.c by adding appropriate if ( ... != NULL) checks > before things like free(conndata->index) at line 136... which is the > location that caused our particular crash, and free(threaddata->index) at > line 133, etc. Thank you for the bug report. Please can you try the attached patch and report if it fixes the crash? Mukund

Message body is not shown because sender requested not to inline it.

Message body not shown because it is not plain text.

Subject: Re: [ISC-Bugs #37237] Crash in named-sdb -- freeing an invalid pointer.
Date: Tue, 31 Mar 2015 06:53:31 -0600
To: bind9-bugs@isc.org
From: "Troy Noble" <econoplas@gmail.com>
Yes, this patch fixes the problem I was seeing.

Sorry for the delay.  I know it has been a few months.

I just recently had a chance to try the proposed patch you sent, and then I had to induce the crash to see if it fixed the problem during the cleanup routine.

Thank you for the response!

On Sun, Sep 21, 2014 at 10:39 PM, Mukund Sivaraman via RT <bind9-bugs@isc.org> wrote:
Hi Troy

On Sat, Sep 20, 2014 at 05:22:32AM +0000, Troy Noble via RT wrote:
> I wanted to report a bug we found in sdbldap.c recently. I know sdb is a
> contrib module so I am not sure if it is officially supported by the
> bind-bugs maintainers the original author.
>
> In short, several bugs could potentially be fixed by correcting a few
> "ism's" related to potentially unsafe use of "free" in
> contrib/sdb/ldap/ldapdb.c by adding appropriate if ( ... != NULL) checks
> before things like free(conndata->index) at line 136... which is the
> location that caused our particular crash, and free(threaddata->index) at
> line 133, etc.

Thank you for the bug report. Please can you try the attached patch and
report if it fixes the crash?

                Mukund


From 7298559361264a03b14e71af7ad3583de558f4f5 Mon Sep 17 00:00:00 2001
From: Mukund Sivaraman <muks@isc.org>
Date: Mon, 22 Sep 2014 09:24:39 +0530
Subject: [PATCH] Don't free alias to ldapdb data (that is cleaned up during
 destroy)

---
 contrib/sdb/ldap/ldapdb.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/contrib/sdb/ldap/ldapdb.c b/contrib/sdb/ldap/ldapdb.c
index caade37..c43342c 100644
--- a/contrib/sdb/ldap/ldapdb.c
+++ b/contrib/sdb/ldap/ldapdb.c
@@ -133,7 +133,6 @@ ldapdb_getconn(struct ldapdb_data *data)
                        free(threaddata->index);
                        while (threaddata->data != NULL) {
                                conndata = threaddata->data;
-                               free(conndata->index);
                                if (conndata->data != NULL)
                                        ldap_unbind((LDAP *)conndata->data);
                                threaddata->data = conndata->next;
--
1.9.3




Subject: Re: [ISC-Bugs #37237] Crash in named-sdb -- freeing an invalid pointer.
Date: Tue, 31 Mar 2015 07:03:50 -0600
To: bind9-review@isc.org
From: "Troy Noble" <econoplas@gmail.com>
Sorry, I completely forgot to mention I also had to add a check for if (threaddata->index != NULL) before free(threaddata->index)

Warning: this is not an official diff-generate patch, but rather I hand-edited the patch you sent, nor is it likely I followed preferred coding style conventions for this project.

> @@ -133,7 +133,6 @@ ldapdb_getconn(struct ldapdb_data *data)
> -                       free(threaddata->index);
> +                       if (threaddata->index != NULL) { free(threaddata->index); }
>                         while (threaddata->data != NULL) {
>                                 conndata = threaddata->data;
> -                               free(conndata->index);
>                                 if (conndata->data != NULL)
>                                         ldap_unbind((LDAP *)conndata->data);
>                                 threaddata->data = conndata->next;

On Tue, Mar 31, 2015 at 6:53 AM, Troy Noble via RT <bind9-review@isc.org> wrote:
Yes, this patch fixes the problem I was seeing.

Sorry for the delay.  I know it has been a few months.

I just recently had a chance to try the proposed patch you sent, and then I
had to induce the crash to see if it fixed the problem during the cleanup
routine.

Thank you for the response!

On Sun, Sep 21, 2014 at 10:39 PM, Mukund Sivaraman via RT <
bind9-bugs@isc.org> wrote:

> Hi Troy
>
> On Sat, Sep 20, 2014 at 05:22:32AM +0000, Troy Noble via RT wrote:
> > I wanted to report a bug we found in sdbldap.c recently. I know sdb is a
> > contrib module so I am not sure if it is officially supported by the
> > bind-bugs maintainers the original author.
> >
> > In short, several bugs could potentially be fixed by correcting a few
> > "ism's" related to potentially unsafe use of "free" in
> > contrib/sdb/ldap/ldapdb.c by adding appropriate if ( ... != NULL) checks
> > before things like free(conndata->index) at line 136... which is the
> > location that caused our particular crash, and free(threaddata->index) at
> > line 133, etc.
>
> Thank you for the bug report. Please can you try the attached patch and
> report if it fixes the crash?
>
>                 Mukund
>
>
> From 7298559361264a03b14e71af7ad3583de558f4f5 Mon Sep 17 00:00:00 2001
> From: Mukund Sivaraman <muks@isc.org>
> Date: Mon, 22 Sep 2014 09:24:39 +0530
> Subject: [PATCH] Don't free alias to ldapdb data (that is cleaned up during
>  destroy)
>
> ---
>  contrib/sdb/ldap/ldapdb.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/contrib/sdb/ldap/ldapdb.c b/contrib/sdb/ldap/ldapdb.c
> index caade37..c43342c 100644
> --- a/contrib/sdb/ldap/ldapdb.c
> +++ b/contrib/sdb/ldap/ldapdb.c
> @@ -133,7 +133,6 @@ ldapdb_getconn(struct ldapdb_data *data)
>                         free(threaddata->index);
>                         while (threaddata->data != NULL) {
>                                 conndata = threaddata->data;
> -                               free(conndata->index);
>                                 if (conndata->data != NULL)
>                                         ldap_unbind((LDAP
> *)conndata->data);
>                                 threaddata->data = conndata->next;
> --
> 1.9.3
>
>
>



Subject: Re: [ISC-Bugs #37237] Crash in named-sdb -- freeing an invalid pointer.
Date: Tue, 31 Mar 2015 19:15:10 +0530
To: "Troy Noble via RT" <bind9-review@isc.org>
From: "Mukund Sivaraman" <muks@isc.org>
Hi Troy On Tue, Mar 31, 2015 at 01:03:55PM +0000, Troy Noble via RT wrote: > Sorry, I completely forgot to mention I also had to add a check for if > (threaddata->index != NULL) before free(threaddata->index) It is unnecessary to check for NULL before calling free(). free() does this check. Mukund

Message body not shown because it is not plain text.

Subject: Re: [ISC-Bugs #37237] Crash in named-sdb -- freeing an invalid pointer.
Date: Fri, 3 Apr 2015 07:12:08 -0600
To: bind9-review@isc.org
From: "Troy Noble" <econoplas@gmail.com>
Yes, sorry you are correct f'or modern POSIX & ISO C systems (linux, freebsd, solaris).  I sometimes forget this because I work with some very old Domain/OS 10.3.5 systems where the C library based on a mix of very ancient SysV/BSD4.3 where freeing a NULL ptr was not as clearly defined.  So I think I added the extra NULL check as a safety measure in the process of trying to troubleshoot the problem.  My apologies.  I should have checked my notes more carefully, and I would have seen this artifact did not affect my testing.

Looking at my notes, the patch you provided to remove the line to "free(conndata->index);" was sufficient to fix the problem I observed.

Sorry for the confusion, and thanks for pointing that out.

On Tue, Mar 31, 2015 at 7:45 AM, Mukund Sivaraman via RT <bind9-review@isc.org> wrote:
Hi Troy

On Tue, Mar 31, 2015 at 01:03:55PM +0000, Troy Noble via RT wrote:
> Sorry, I completely forgot to mention I also had to add a check for if
> (threaddata->index != NULL) before free(threaddata->index)

It is unnecessary to check for NULL before calling free(). free() does
this check.

                Mukund