linux-sparse.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pavel Roskin <proski@gnu.org>
To: linux-sparse@vger.kernel.org
Subject: Re: Crash, apparent memory corruption
Date: Wed, 13 Feb 2008 18:18:01 -0500	[thread overview]
Message-ID: <1202944681.8941.29.camel@dv> (raw)
In-Reply-To: <1202929482.2565.11.camel@dv>

OK, I think I know what's wrong.

The "phi_list" field in "struct instruction" should only be accessed if
"opcode" in the same structure is OP_PHI.  "phi_list" is a part of a
transparent union, and thus could overlap with other data, including
data of the "pseudo_t" type.

linearize_compound_statement() uses "phi_list" unconditionally, but
"opcode" can be OP_INLINED_CALL in some cases.

It's a pure coincidence that pseudo_list_size() avoids crashing in most
cases and returns some number.  That number has to be 1 to enable some
additional logic, which is quite unlikely for invalid data.

I don't know the code enough to fix it properly.  I don't know if it's
OK for "opcode" not to be OP_PHI in linearize_compound_statement().

One approach would be to use assert() to ensure it.  The problem is,
it's triggered on several files in the testsuite.  Here's the patch
anyway:

diff --git a/linearize.c b/linearize.c
index 8a68f05..a907c50 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1636,6 +1636,7 @@ static pseudo_t linearize_compound_statement(struct entrypoint *ep, struct state
 		if (!phi_node)
 			return pseudo;
 
+		assert(phi_node->opcode != OP_PHI);
 		if (pseudo_list_size(phi_node->phi_list)==1) {
 			pseudo = first_pseudo(phi_node->phi_list);
 			assert(pseudo->type == PSEUDO_PHI);

Another approach would be to act like pseudo_list_size() returns a
number other than 1 if opcode is not OP_PHI:

diff --git a/linearize.c b/linearize.c
index 8a68f05..11f3a8b 100644
--- a/linearize.c
+++ b/linearize.c
@@ -1636,7 +1636,8 @@ static pseudo_t linearize_compound_statement(struct entrypoint *ep, struct state
 		if (!phi_node)
 			return pseudo;
 
-		if (pseudo_list_size(phi_node->phi_list)==1) {
+		if (phi_node->opcode == OP_PHI
+		    && pseudo_list_size(phi_node->phi_list) == 1) {
 			pseudo = first_pseudo(phi_node->phi_list);
 			assert(pseudo->type == PSEUDO_PHI);
 			return pseudo->def->src1;

Not only the testsuite passes, but I can also check the kernel and
ndiswrapper without sparse crashes.

But I don't know whether the patch is hiding the problem instead of
fixing it.  And we may want to have an additional tag in memory to make
sure that the lists are of the correct type.

-- 
Regards,
Pavel Roskin

      reply	other threads:[~2008-02-13 23:18 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-02-13  3:30 Crash, apparent memory corruption Pavel Roskin
2008-02-13 19:04 ` Pavel Roskin
2008-02-13 23:18   ` Pavel Roskin [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1202944681.8941.29.camel@dv \
    --to=proski@gnu.org \
    --cc=linux-sparse@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).