Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings
forked fromtorvalds/linux

Commit6d06673

Browse files
Guillaume Naultdavem330
Guillaume Nault
authored andcommitted
ppp: avoid loop in xmit recursion detection code
We already detect situations where a PPP channel sends packets back toits upper PPP device. While this is enough to avoid deadlocking on xmitlocks, this doesn't prevent packets from looping between the channeland the unit.The problem is that ppp_start_xmit() enqueues packets in ppp->file.xqbefore checking for xmit recursion. Therefore, __ppp_xmit_process()might dequeue a packet from ppp->file.xq and send it on the channelwhich, in turn, loops it back on the unit. Then ppp_start_xmit()queues the packet back to ppp->file.xq and __ppp_xmit_process() picksit up and sends it again through the channel. Therefore, the packetwill loop between __ppp_xmit_process() and ppp_start_xmit() until someother part of the xmit path drops it.For L2TP, we rapidly fill the skb's headroom and pppol2tp_xmit() dropsthe packet after a few iterations. But PPTP reallocates the headroomif necessary, letting the loop run and exhaust the machine resources(as reported inhttps://bugzilla.kernel.org/show_bug.cgi?id=199109).Fix this by letting __ppp_xmit_process() enqueue the skb toppp->file.xq, so that we can check for recursion before adding it tothe queue. Now ppp_xmit_process() can drop the packet when recursion isdetected.__ppp_channel_push() is a bit special. It calls __ppp_xmit_process()without having any actual packet to send. This is used byppp_output_wakeup() to re-enable transmission on the parent unit (forimplementations like ppp_async.c, where the .start_xmit() functionmight not consume the skb, leaving it in ppp->xmit_pending anddisabling transmission).Therefore, __ppp_xmit_process() needs to handle the case where skb isNULL, dequeuing as many packets as possible from ppp->file.xq.Reported-by: xu heng <xuheng333@zoho.com>Fixes:55454a5 ("ppp: avoid dealock on recursive xmit")Signed-off-by: Guillaume Nault <g.nault@alphalink.fr>Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent8936ef7 commit6d06673

File tree

1 file changed

+14
-12
lines changed

1 file changed

+14
-12
lines changed

‎drivers/net/ppp/ppp_generic.c‎

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ struct ppp_net {
257257
/* Prototypes. */
258258
staticintppp_unattached_ioctl(structnet*net,structppp_file*pf,
259259
structfile*file,unsignedintcmd,unsigned longarg);
260-
staticvoidppp_xmit_process(structppp*ppp);
260+
staticvoidppp_xmit_process(structppp*ppp,structsk_buff*skb);
261261
staticvoidppp_send_frame(structppp*ppp,structsk_buff*skb);
262262
staticvoidppp_push(structppp*ppp);
263263
staticvoidppp_channel_push(structchannel*pch);
@@ -513,13 +513,12 @@ static ssize_t ppp_write(struct file *file, const char __user *buf,
513513
gotoout;
514514
}
515515

516-
skb_queue_tail(&pf->xq,skb);
517-
518516
switch (pf->kind) {
519517
caseINTERFACE:
520-
ppp_xmit_process(PF_TO_PPP(pf));
518+
ppp_xmit_process(PF_TO_PPP(pf),skb);
521519
break;
522520
caseCHANNEL:
521+
skb_queue_tail(&pf->xq,skb);
523522
ppp_channel_push(PF_TO_CHANNEL(pf));
524523
break;
525524
}
@@ -1267,8 +1266,8 @@ ppp_start_xmit(struct sk_buff *skb, struct net_device *dev)
12671266
put_unaligned_be16(proto,pp);
12681267

12691268
skb_scrub_packet(skb, !net_eq(ppp->ppp_net,dev_net(dev)));
1270-
skb_queue_tail(&ppp->file.xq,skb);
1271-
ppp_xmit_process(ppp);
1269+
ppp_xmit_process(ppp,skb);
1270+
12721271
returnNETDEV_TX_OK;
12731272

12741273
outf:
@@ -1420,13 +1419,14 @@ static void ppp_setup(struct net_device *dev)
14201419
*/
14211420

14221421
/* Called to do any work queued up on the transmit side that can now be done */
1423-
staticvoid__ppp_xmit_process(structppp*ppp)
1422+
staticvoid__ppp_xmit_process(structppp*ppp,structsk_buff*skb)
14241423
{
1425-
structsk_buff*skb;
1426-
14271424
ppp_xmit_lock(ppp);
14281425
if (!ppp->closing) {
14291426
ppp_push(ppp);
1427+
1428+
if (skb)
1429+
skb_queue_tail(&ppp->file.xq,skb);
14301430
while (!ppp->xmit_pending&&
14311431
(skb=skb_dequeue(&ppp->file.xq)))
14321432
ppp_send_frame(ppp,skb);
@@ -1440,15 +1440,15 @@ static void __ppp_xmit_process(struct ppp *ppp)
14401440
ppp_xmit_unlock(ppp);
14411441
}
14421442

1443-
staticvoidppp_xmit_process(structppp*ppp)
1443+
staticvoidppp_xmit_process(structppp*ppp,structsk_buff*skb)
14441444
{
14451445
local_bh_disable();
14461446

14471447
if (unlikely(*this_cpu_ptr(ppp->xmit_recursion)))
14481448
gotoerr;
14491449

14501450
(*this_cpu_ptr(ppp->xmit_recursion))++;
1451-
__ppp_xmit_process(ppp);
1451+
__ppp_xmit_process(ppp,skb);
14521452
(*this_cpu_ptr(ppp->xmit_recursion))--;
14531453

14541454
local_bh_enable();
@@ -1458,6 +1458,8 @@ static void ppp_xmit_process(struct ppp *ppp)
14581458
err:
14591459
local_bh_enable();
14601460

1461+
kfree_skb(skb);
1462+
14611463
if (net_ratelimit())
14621464
netdev_err(ppp->dev,"recursion detected\n");
14631465
}
@@ -1942,7 +1944,7 @@ static void __ppp_channel_push(struct channel *pch)
19421944
if (skb_queue_empty(&pch->file.xq)) {
19431945
ppp=pch->ppp;
19441946
if (ppp)
1945-
__ppp_xmit_process(ppp);
1947+
__ppp_xmit_process(ppp,NULL);
19461948
}
19471949
}
19481950

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp