Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[TIPC]: fix tipc_link_create error handling

if printbuf allocation or tipc_node_attach_link() fails, invalid
references to the link are left in the associated node and bearer
structures.
Fix by allocating printbuf early and moving timer initialization
and the addition of the new link to the b_ptr->links list after
tipc_node_attach_link() succeeded.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

Florian Westphal and committed by
David S. Miller
94571065 0ed72ec4

+15 -13
+15 -13
net/tipc/link.c
··· 423 423 return NULL; 424 424 } 425 425 426 + if (LINK_LOG_BUF_SIZE) { 427 + char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); 428 + 429 + if (!pb) { 430 + kfree(l_ptr); 431 + warn("Link creation failed, no memory for print buffer\n"); 432 + return NULL; 433 + } 434 + tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); 435 + } 436 + 426 437 l_ptr->addr = peer; 427 438 if_name = strchr(b_ptr->publ.name, ':') + 1; 428 439 sprintf(l_ptr->name, "%u.%u.%u:%s-%u.%u.%u:", ··· 443 432 tipc_zone(peer), tipc_cluster(peer), tipc_node(peer)); 444 433 /* note: peer i/f is appended to link name by reset/activate */ 445 434 memcpy(&l_ptr->media_addr, media_addr, sizeof(*media_addr)); 446 - k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 447 - list_add_tail(&l_ptr->link_list, &b_ptr->links); 448 435 l_ptr->checkpoint = 1; 449 436 l_ptr->b_ptr = b_ptr; 450 437 link_set_supervision_props(l_ptr, b_ptr->media->tolerance); ··· 468 459 469 460 l_ptr->owner = tipc_node_attach_link(l_ptr); 470 461 if (!l_ptr->owner) { 462 + if (LINK_LOG_BUF_SIZE) 463 + kfree(l_ptr->print_buf.buf); 471 464 kfree(l_ptr); 472 465 return NULL; 473 466 } 474 467 475 - if (LINK_LOG_BUF_SIZE) { 476 - char *pb = kmalloc(LINK_LOG_BUF_SIZE, GFP_ATOMIC); 477 - 478 - if (!pb) { 479 - kfree(l_ptr); 480 - warn("Link creation failed, no memory for print buffer\n"); 481 - return NULL; 482 - } 483 - tipc_printbuf_init(&l_ptr->print_buf, pb, LINK_LOG_BUF_SIZE); 484 - } 485 - 468 + k_init_timer(&l_ptr->timer, (Handler)link_timeout, (unsigned long)l_ptr); 469 + list_add_tail(&l_ptr->link_list, &b_ptr->links); 486 470 tipc_k_signal((Handler)tipc_link_start, (unsigned long)l_ptr); 487 471 488 472 dbg("tipc_link_create(): tolerance = %u,cont intv = %u, abort_limit = %u\n",