Message ID | 20220628083122.26942-1-hbh25y@gmail.com (mailing list archive) |
---|---|
State | Changes Requested |
Delegated to: | Netdev Maintainers |
Headers | show |
Series | [v2] net: tipc: fix possible infoleak in tipc_mon_rcv() | expand |
> -----Original Message----- > From: Hangyu Hua <hbh25y@gmail.com> > Sent: Tuesday, June 28, 2022 3:31 PM > To: jmaloy@redhat.com; ying.xue@windriver.com; davem@davemloft.net; edumazet@google.com; kuba@kernel.org; > pabeni@redhat.com; Tung Quang Nguyen <tung.q.nguyen@dektech.com.au> > Cc: netdev@vger.kernel.org; tipc-discussion@lists.sourceforge.net; linux-kernel@vger.kernel.org; Hangyu Hua <hbh25y@gmail.com> > Subject: [PATCH v2] net: tipc: fix possible infoleak in tipc_mon_rcv() > > dom_bef is use to cache current domain record only if current domain > exists. But when current domain does not exist, dom_bef will still be used > in mon_identify_lost_members. This may lead to an information leak. > > Fix this by adding a memset before using dom_bef. > > Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") > Signed-off-by: Hangyu Hua <hbh25y@gmail.com> > --- > > v2: remove redundant 'dom_bef.member_cnt = 0;' > > net/tipc/monitor.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c > index 2f4d23238a7e..03b5d0b65169 100644 > --- a/net/tipc/monitor.c > +++ b/net/tipc/monitor.c > @@ -534,7 +534,7 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, > state->peer_gen = new_gen; > > /* Cache current domain record for later use */ > - dom_bef.member_cnt = 0; > + memset(&dom_bef, 0, sizeof(dom_bef)); > dom = peer->domain; > if (dom) > memcpy(&dom_bef, dom, dom->len); > -- > 2.25.1 Reviewed-by: Tung Nguyen <tung.q.nguyen@dektech.com.au>
On Tue, 28 Jun 2022 16:31:22 +0800 Hangyu Hua wrote: > dom_bef is use to cache current domain record only if current domain > exists. But when current domain does not exist, dom_bef will still be used > in mon_identify_lost_members. This may lead to an information leak. AFAICT applied_bef must be zero if peer->domain was 0, so I don't think mon_identify_lost_members() will do anything. > Fix this by adding a memset before using dom_bef. > > Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") > Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
On 2022/6/30 11:31, Jakub Kicinski wrote: > On Tue, 28 Jun 2022 16:31:22 +0800 Hangyu Hua wrote: >> dom_bef is use to cache current domain record only if current domain >> exists. But when current domain does not exist, dom_bef will still be used >> in mon_identify_lost_members. This may lead to an information leak. > > AFAICT applied_bef must be zero if peer->domain was 0, so I don't think > mon_identify_lost_members() will do anything. > void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, struct tipc_mon_state *state, int bearer_id) { ... if (!dom || (dom->len < new_dlen)) { kfree(dom); dom = kmalloc(new_dlen, GFP_ATOMIC); <--- [1] peer->domain = dom; if (!dom) goto exit; } ... } peer->domain will be NULL when [1] fails. But there will not change peer->applied to 0. In this case, if tipc_mon_rcv is called again then an information leak will happen. Thanks, Hangyu. >> Fix this by adding a memset before using dom_bef. >> >> Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") >> Signed-off-by: Hangyu Hua <hbh25y@gmail.com>
On Thu, 30 Jun 2022 17:19:21 +0800 Hangyu Hua wrote: > On 2022/6/30 11:31, Jakub Kicinski wrote: > > On Tue, 28 Jun 2022 16:31:22 +0800 Hangyu Hua wrote: > >> dom_bef is use to cache current domain record only if current domain > >> exists. But when current domain does not exist, dom_bef will still be used > >> in mon_identify_lost_members. This may lead to an information leak. > > > > AFAICT applied_bef must be zero if peer->domain was 0, so I don't think > > mon_identify_lost_members() will do anything. > > > > void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, > struct tipc_mon_state *state, int bearer_id) > { > ... > if (!dom || (dom->len < new_dlen)) { > kfree(dom); > dom = kmalloc(new_dlen, GFP_ATOMIC); <--- [1] > peer->domain = dom; > if (!dom) > goto exit; > } > ... > } > > peer->domain will be NULL when [1] fails. But there will not change > peer->applied to 0. In this case, if tipc_mon_rcv is called again then > an information leak will happen. I see, good analysis! Jon, Xue - is there a reason domain gets wiped on memory allocation failure? I'd think we should leave the previous pointer in place instead of freeing it first.
diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c index 2f4d23238a7e..03b5d0b65169 100644 --- a/net/tipc/monitor.c +++ b/net/tipc/monitor.c @@ -534,7 +534,7 @@ void tipc_mon_rcv(struct net *net, void *data, u16 dlen, u32 addr, state->peer_gen = new_gen; /* Cache current domain record for later use */ - dom_bef.member_cnt = 0; + memset(&dom_bef, 0, sizeof(dom_bef)); dom = peer->domain; if (dom) memcpy(&dom_bef, dom, dom->len);
dom_bef is use to cache current domain record only if current domain exists. But when current domain does not exist, dom_bef will still be used in mon_identify_lost_members. This may lead to an information leak. Fix this by adding a memset before using dom_bef. Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework") Signed-off-by: Hangyu Hua <hbh25y@gmail.com> --- v2: remove redundant 'dom_bef.member_cnt = 0;' net/tipc/monitor.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)