* [PATCH] xfsprogs: fix use after free in inode_item_done()
@ 2014-03-03 20:41 Eric Sandeen
2014-03-03 22:36 ` Dave Chinner
` (2 more replies)
0 siblings, 3 replies; 10+ messages in thread
From: Eric Sandeen @ 2014-03-03 20:41 UTC (permalink / raw)
To: xfs-oss
Commit "3a19fb7 libxfs: stop caching inode structures"
introduced a use after free.
libxfs_iput() already does the check for ip->i_itemp, and a
kmem_zone_free() if it's present, and then frees the ip pointer.
Re-checking ip->i_itemp after the libxfs_iput call will access
the freed ip pointer, as will setting ip_>i_itemp to NULL.
Simply remove the offending code to fix this up.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 6c9d202..2e6720e 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -694,7 +694,6 @@ inode_item_done(
xfs_mount_t *mp;
xfs_buf_t *bp;
int error;
- extern kmem_zone_t *xfs_ili_zone;
ip = iip->ili_inode;
mp = iip->ili_item.li_mountp;
@@ -739,12 +738,6 @@ ili_done:
} else {
libxfs_iput(ip, 0);
}
-
- if (ip->i_itemp)
- kmem_zone_free(xfs_ili_zone, ip->i_itemp);
- else
- ASSERT(0);
- ip->i_itemp = NULL;
}
static void
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH] xfsprogs: fix use after free in inode_item_done()
2014-03-03 20:41 [PATCH] xfsprogs: fix use after free in inode_item_done() Eric Sandeen
@ 2014-03-03 22:36 ` Dave Chinner
2014-03-03 22:48 ` Eric Sandeen
2014-03-03 22:58 ` [PATCH V2] " Eric Sandeen
2014-03-05 17:02 ` [PATCH] " Christoph Hellwig
2 siblings, 1 reply; 10+ messages in thread
From: Dave Chinner @ 2014-03-03 22:36 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs-oss
On Mon, Mar 03, 2014 at 02:41:54PM -0600, Eric Sandeen wrote:
> Commit "3a19fb7 libxfs: stop caching inode structures"
> introduced a use after free.
>
> libxfs_iput() already does the check for ip->i_itemp, and a
> kmem_zone_free() if it's present, and then frees the ip pointer.
> Re-checking ip->i_itemp after the libxfs_iput call will access
> the freed ip pointer, as will setting ip_>i_itemp to NULL.
>
> Simply remove the offending code to fix this up.
which leaves the rest of the ili_done: code looking a little
strange.
can you convert that now to be:
ili_done:
if (iip->ili_lock_flags) {
iip->ili_lock_flags = 0;
return;
}
/* free the inode */
libxfs_iput(ip, 0);
}
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] xfsprogs: fix use after free in inode_item_done()
2014-03-03 22:36 ` Dave Chinner
@ 2014-03-03 22:48 ` Eric Sandeen
2014-03-03 22:55 ` Dave Chinner
2014-03-04 13:04 ` Roger Willcocks
0 siblings, 2 replies; 10+ messages in thread
From: Eric Sandeen @ 2014-03-03 22:48 UTC (permalink / raw)
To: Dave Chinner; +Cc: xfs-oss
On 3/3/14, 4:36 PM, Dave Chinner wrote:
> On Mon, Mar 03, 2014 at 02:41:54PM -0600, Eric Sandeen wrote:
>> Commit "3a19fb7 libxfs: stop caching inode structures"
>> introduced a use after free.
>>
>> libxfs_iput() already does the check for ip->i_itemp, and a
>> kmem_zone_free() if it's present, and then frees the ip pointer.
>> Re-checking ip->i_itemp after the libxfs_iput call will access
>> the freed ip pointer, as will setting ip_>i_itemp to NULL.
>>
>> Simply remove the offending code to fix this up.
>
> which leaves the rest of the ili_done: code looking a little
> strange.
>
> can you convert that now to be:
>
> ili_done:
> if (iip->ili_lock_flags) {
> iip->ili_lock_flags = 0;
> return;
> }
> /* free the inode */
> libxfs_iput(ip, 0);
> }
yeah, I actually had that first. Not sure why I didn't go with it ;)
(Still looks strange to my untrained eye; "if lock flags are set, unset them and don't free the inode, otherwise free it")
Anyway, I'll resend. No need to educate me on these details, for now. ;)
-Eric
> Cheers,
>
> Dave.
>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] xfsprogs: fix use after free in inode_item_done()
2014-03-03 22:48 ` Eric Sandeen
@ 2014-03-03 22:55 ` Dave Chinner
2014-03-04 13:04 ` Roger Willcocks
1 sibling, 0 replies; 10+ messages in thread
From: Dave Chinner @ 2014-03-03 22:55 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs-oss
On Mon, Mar 03, 2014 at 04:48:29PM -0600, Eric Sandeen wrote:
> On 3/3/14, 4:36 PM, Dave Chinner wrote:
> > On Mon, Mar 03, 2014 at 02:41:54PM -0600, Eric Sandeen wrote:
> >> Commit "3a19fb7 libxfs: stop caching inode structures"
> >> introduced a use after free.
> >>
> >> libxfs_iput() already does the check for ip->i_itemp, and a
> >> kmem_zone_free() if it's present, and then frees the ip pointer.
> >> Re-checking ip->i_itemp after the libxfs_iput call will access
> >> the freed ip pointer, as will setting ip_>i_itemp to NULL.
> >>
> >> Simply remove the offending code to fix this up.
> >
> > which leaves the rest of the ili_done: code looking a little
> > strange.
> >
> > can you convert that now to be:
> >
> > ili_done:
> > if (iip->ili_lock_flags) {
> > iip->ili_lock_flags = 0;
> > return;
> > }
> > /* free the inode */
> > libxfs_iput(ip, 0);
> > }
>
> yeah, I actually had that first. Not sure why I didn't go with it ;)
>
> (Still looks strange to my untrained eye; "if lock flags are set, unset them and don't free the inode, otherwise free it")
If the lock falgs are set, it means the caller expects the
transaction commit to return the inode to it in a locked state.
Exactly the same semantics as the kernel code - the lock flags track
how the transaction releases the inode...
Cheers,
Dave.
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] xfsprogs: fix use after free in inode_item_done()
2014-03-03 22:48 ` Eric Sandeen
2014-03-03 22:55 ` Dave Chinner
@ 2014-03-04 13:04 ` Roger Willcocks
1 sibling, 0 replies; 10+ messages in thread
From: Roger Willcocks @ 2014-03-04 13:04 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs-oss
On Mon, 2014-03-03 at 16:48 -0600, Eric Sandeen wrote:
> On 3/3/14, 4:36 PM, Dave Chinner wrote:
...
> > which leaves the rest of the ili_done: code looking a little
> > strange.
> >
> > can you convert that now to be:
> >
> > ili_done:
> > if (iip->ili_lock_flags) {
> > iip->ili_lock_flags = 0;
> > return;
> > }
> > /* free the inode */
> > libxfs_iput(ip, 0);
> > }
>
> yeah, I actually had that first. Not sure why I didn't go with it ;)
>
> (Still looks strange to my untrained eye; "if lock flags are set, unset them and don't free the inode, otherwise free it")
>
I'd be tempted to write:
ili_done:
if (iip->ili_lock_flags == 0) /* don't return locked inode */
libxfs_iput(ip, 0);
iip->ili_lock_flags = 0;
--
Roger Willcocks <roger@filmlight.ltd.uk>
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH V2] xfsprogs: fix use after free in inode_item_done()
2014-03-03 20:41 [PATCH] xfsprogs: fix use after free in inode_item_done() Eric Sandeen
2014-03-03 22:36 ` Dave Chinner
@ 2014-03-03 22:58 ` Eric Sandeen
2014-03-03 23:09 ` Dave Chinner
2014-03-05 17:02 ` [PATCH] " Christoph Hellwig
2 siblings, 1 reply; 10+ messages in thread
From: Eric Sandeen @ 2014-03-03 22:58 UTC (permalink / raw)
To: Eric Sandeen, xfs-oss
Commit "3a19fb7 libxfs: stop caching inode structures"
introduced a use after free.
libxfs_iput() already does the check for ip->i_itemp, and a
kmem_zone_free() if it's present, and then frees the ip pointer.
Re-checking ip->i_itemp after the libxfs_iput call will access
the freed ip pointer, as will setting ip_>i_itemp to NULL.
Simply remove the offending code to fix this up.
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
---
V2: Make it prettier based on Dave's comments.
diff --git a/libxfs/trans.c b/libxfs/trans.c
index 6c9d202..c443863 100644
--- a/libxfs/trans.c
+++ b/libxfs/trans.c
@@ -694,7 +694,6 @@ inode_item_done(
xfs_mount_t *mp;
xfs_buf_t *bp;
int error;
- extern kmem_zone_t *xfs_ili_zone;
ip = iip->ili_inode;
mp = iip->ili_item.li_mountp;
@@ -736,15 +735,9 @@ ili_done:
if (iip->ili_lock_flags) {
iip->ili_lock_flags = 0;
return;
- } else {
- libxfs_iput(ip, 0);
}
-
- if (ip->i_itemp)
- kmem_zone_free(xfs_ili_zone, ip->i_itemp);
- else
- ASSERT(0);
- ip->i_itemp = NULL;
+ /* free the inode */
+ libxfs_iput(ip, 0);
}
static void
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [PATCH V2] xfsprogs: fix use after free in inode_item_done()
2014-03-03 22:58 ` [PATCH V2] " Eric Sandeen
@ 2014-03-03 23:09 ` Dave Chinner
0 siblings, 0 replies; 10+ messages in thread
From: Dave Chinner @ 2014-03-03 23:09 UTC (permalink / raw)
To: Eric Sandeen; +Cc: Eric Sandeen, xfs-oss
On Mon, Mar 03, 2014 at 04:58:44PM -0600, Eric Sandeen wrote:
> Commit "3a19fb7 libxfs: stop caching inode structures"
> introduced a use after free.
>
> libxfs_iput() already does the check for ip->i_itemp, and a
> kmem_zone_free() if it's present, and then frees the ip pointer.
> Re-checking ip->i_itemp after the libxfs_iput call will access
> the freed ip pointer, as will setting ip_>i_itemp to NULL.
>
> Simply remove the offending code to fix this up.
>
> Signed-off-by: Eric Sandeen <sandeen@redhat.com>
> ---
>
> V2: Make it prettier based on Dave's comments.
looks good.
Reviewed-by: Dave Chinner <dchinner@redhat.com>
--
Dave Chinner
david@fromorbit.com
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH] xfsprogs: fix use after free in inode_item_done()
2014-03-03 20:41 [PATCH] xfsprogs: fix use after free in inode_item_done() Eric Sandeen
2014-03-03 22:36 ` Dave Chinner
2014-03-03 22:58 ` [PATCH V2] " Eric Sandeen
@ 2014-03-05 17:02 ` Christoph Hellwig
2014-03-05 17:19 ` Eric Sandeen
2 siblings, 1 reply; 10+ messages in thread
From: Christoph Hellwig @ 2014-03-05 17:02 UTC (permalink / raw)
To: Eric Sandeen; +Cc: xfs-oss
On Mon, Mar 03, 2014 at 02:41:54PM -0600, Eric Sandeen wrote:
> Commit "3a19fb7 libxfs: stop caching inode structures"
> introduced a use after free.
I see the use after free, but I don't see how I would have introduced it
in that commit. Before that libxfs_iput already was freeing the inode
through the cache code, now we do it directly.
> @@ -739,12 +738,6 @@ ili_done:
> } else {
> libxfs_iput(ip, 0);
> }
> -
> - if (ip->i_itemp)
> - kmem_zone_free(xfs_ili_zone, ip->i_itemp);
> - else
> - ASSERT(0);
> - ip->i_itemp = NULL;
> }
Seems like inode_item_done should call into inode_item_unlock, which
factors the exact sequence we want into a nice helper.
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [PATCH] xfsprogs: fix use after free in inode_item_done()
2014-03-05 17:02 ` [PATCH] " Christoph Hellwig
@ 2014-03-05 17:19 ` Eric Sandeen
[not found] ` <20140305223612.GA25639@infradead.org>
0 siblings, 1 reply; 10+ messages in thread
From: Eric Sandeen @ 2014-03-05 17:19 UTC (permalink / raw)
To: Christoph Hellwig, Eric Sandeen; +Cc: xfs-oss
On 3/5/14, 11:02 AM, Christoph Hellwig wrote:
> On Mon, Mar 03, 2014 at 02:41:54PM -0600, Eric Sandeen wrote:
>> Commit "3a19fb7 libxfs: stop caching inode structures"
>> introduced a use after free.
>
> I see the use after free, but I don't see how I would have introduced it
> in that commit. Before that libxfs_iput already was freeing the inode
> through the cache code, now we do it directly.
Ok, sorry if I wrongly implicated that commit.
>> @@ -739,12 +738,6 @@ ili_done:
>> } else {
>> libxfs_iput(ip, 0);
>> }
>> -
>> - if (ip->i_itemp)
>> - kmem_zone_free(xfs_ili_zone, ip->i_itemp);
>> - else
>> - ASSERT(0);
>> - ip->i_itemp = NULL;
>> }
>
> Seems like inode_item_done should call into inode_item_unlock, which
> factors the exact sequence we want into a nice helper.
Yeah, that does seem better! Thanks for spotting that.
The difference when calling inode_item_unlock is a bit more zeroing-out:
ip->i_transp = NULL;
iip->ili_flags = 0;
I'm not sure of the implications of that offhand, TBH.
Dave, hold off on my commit I guess ;)
-Eric
_______________________________________________
xfs mailing list
xfs@oss.sgi.com
http://oss.sgi.com/mailman/listinfo/xfs
^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2014-03-05 22:41 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-03-03 20:41 [PATCH] xfsprogs: fix use after free in inode_item_done() Eric Sandeen
2014-03-03 22:36 ` Dave Chinner
2014-03-03 22:48 ` Eric Sandeen
2014-03-03 22:55 ` Dave Chinner
2014-03-04 13:04 ` Roger Willcocks
2014-03-03 22:58 ` [PATCH V2] " Eric Sandeen
2014-03-03 23:09 ` Dave Chinner
2014-03-05 17:02 ` [PATCH] " Christoph Hellwig
2014-03-05 17:19 ` Eric Sandeen
[not found] ` <20140305223612.GA25639@infradead.org>
2014-03-05 22:40 ` Eric Sandeen
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox