From: Dan Carpenter via Ocfs2-devel <ocfs2-devel@oss.oracle.com>
To: Joseph Qi <jiangqi903@gmail.com>
Cc: Jakob Koschel <jakobkoschel@gmail.com>, ocfs2-devel@oss.oracle.com
Subject: Re: [Ocfs2-devel] [bug report] ocfs2/dlm: Fix race in adding/removing lockres' to/from the tracking list
Date: Wed, 9 Mar 2022 17:57:17 +0300 [thread overview]
Message-ID: <20220309145717.GX3315@kadam> (raw)
In-Reply-To: <82b26a4a-2351-f2b3-dd7c-265308e6b384@gmail.com>
On Wed, Mar 09, 2022 at 03:46:11PM +0800, Joseph Qi wrote:
>
>
> On 3/7/22 10:51 PM, Dan Carpenter via Ocfs2-devel wrote:
> > Hello OCFS Devs,
> >
> > There is a big push to re-write list_for_each_entry() so that you
> > can't use the list iterator outside the loop. I wrote a check for that
> > but this code has me puzzled.
> >
> > The patch b0d4f817ba5d: "ocfs2/dlm: Fix race in adding/removing
> > lockres' to/from the tracking list" from Dec 16, 2008, leads to the
> > following Smatch static checker warning:
> >
> > fs/ocfs2/dlm/dlmdebug.c:573 lockres_seq_start()
> > warn: iterator used outside loop: 'res'
> >
> > fs/ocfs2/dlm/dlmdebug.c
> > 539 static void *lockres_seq_start(struct seq_file *m, loff_t *pos)
> > 540 {
> > 541 struct debug_lockres *dl = m->private;
> > 542 struct dlm_ctxt *dlm = dl->dl_ctxt;
> > 543 struct dlm_lock_resource *oldres = dl->dl_res;
> > 544 struct dlm_lock_resource *res = NULL;
> > 545 struct list_head *track_list;
> > 546
> > 547 spin_lock(&dlm->track_lock);
> > 548 if (oldres)
> > 549 track_list = &oldres->tracking;
> > 550 else {
> > 551 track_list = &dlm->tracking_list;
> > 552 if (list_empty(track_list)) {
> > 553 dl = NULL;
> > 554 spin_unlock(&dlm->track_lock);
> > 555 goto bail;
> > 556 }
> >
> > Why not do the list_empty() check after the else statement. In the
> > current code if "&oldres->tracking" is empty it will lead to a crash.
> >
> lockres will be added into tracking_list during initialize.
>
I am not sure we understand each other.
This function is iterating over the list. Nothing should be modifying
the list until after we have released the spinlock. Any modifications
is a race condition. Which initialize function are you talking about?
In the currect code if oldres is non-NULL and list_empty(&oldres->tracking)
is true then it leads to a crash. There is no reason that we cannot do:
if (oldres)
track_list = &oldres->tracking;
else
track_list = &dlm->tracking_list;
if (list_empty(track_list)) {
dl = NULL;
spin_unlock(&dlm->track_lock);
goto bail;
}
This is cleaner and now we do not have know from outside context
whether the &oldres->tracking list can be empty.
>
> > 557 }
> > 558
> > 559 list_for_each_entry(res, track_list, tracking) {
> > 560 if (&res->tracking == &dlm->tracking_list)
> > ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > This should never be possible. How is it possible? If
> > &dlm->tracking_list is the list head the it's not possible without
> > memory corruption. If &oldres->tracking is the list head then I do not
> > see how it is possible without memory corruption. We can't mix different
> > types of list entries on the same list head?>
> In case of oldres, and the iterator points to dlm_ctxt.
> In this case, the lockres is not a valid one.
That doesn't make sense. :/ This condition is doing pointer math.
The offset of ->tracking is 136 bytes and ->tracking list is 88 bytes
into the dlm struct.
if ((void *)res + 136 == (void *)dlm_ctxt + 88)
Use algebra to subtract 88 from both sides.
if ((void *)res + 48 == (void *)dlm_ctxt)
So dlm points to somewhere in the middle of "res" struct.
>
> > 561 res = NULL;
> > 562 else
> > 563 dlm_lockres_get(res);
> > 564 break;
> >
regards,
dan carpenter
_______________________________________________
Ocfs2-devel mailing list
Ocfs2-devel@oss.oracle.com
https://oss.oracle.com/mailman/listinfo/ocfs2-devel
next prev parent reply other threads:[~2022-03-09 14:57 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-03-07 14:51 [Ocfs2-devel] [bug report] ocfs2/dlm: Fix race in adding/removing lockres' to/from the tracking list Dan Carpenter via Ocfs2-devel
2022-03-09 7:46 ` Joseph Qi via Ocfs2-devel
2022-03-09 14:57 ` Dan Carpenter via Ocfs2-devel [this message]
2022-03-10 3:13 ` Joseph Qi via Ocfs2-devel
2022-03-10 13:39 ` Dan Carpenter via Ocfs2-devel
2022-03-11 1:50 ` Joseph Qi via Ocfs2-devel
2022-03-11 3:08 ` Joseph Qi via Ocfs2-devel
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=20220309145717.GX3315@kadam \
--to=ocfs2-devel@oss.oracle.com \
--cc=dan.carpenter@oracle.com \
--cc=jakobkoschel@gmail.com \
--cc=jiangqi903@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.