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

sgi-xp: incoming XPC channel messages can come in after the channel's partition structures have been torn down

Under some workloads, some channel messages have been observed being
delayed on the sending side past the point where the receiving side has
been able to tear down its partition structures.

This condition is already detected in xpc_handle_activate_IRQ_uv(), but
that information is not given to xpc_handle_activate_mq_msg_uv(). As a
result, xpc_handle_activate_mq_msg_uv() assumes the structures still exist
and references them, causing a NULL-pointer deref.

Signed-off-by: Robin Holt <holt@sgi.com>
Cc: <stable@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>

authored by

Robin Holt and committed by
Linus Torvalds
09358972 482db6df

+17
+17
drivers/misc/sgi-xp/xpc_uv.c
··· 417 417 static void 418 418 xpc_handle_activate_mq_msg_uv(struct xpc_partition *part, 419 419 struct xpc_activate_mq_msghdr_uv *msg_hdr, 420 + int part_setup, 420 421 int *wakeup_hb_checker) 421 422 { 422 423 unsigned long irq_flags; ··· 482 481 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREQUEST_UV: { 483 482 struct xpc_activate_mq_msg_chctl_closerequest_uv *msg; 484 483 484 + if (!part_setup) 485 + break; 486 + 485 487 msg = container_of(msg_hdr, struct 486 488 xpc_activate_mq_msg_chctl_closerequest_uv, 487 489 hdr); ··· 501 497 case XPC_ACTIVATE_MQ_MSG_CHCTL_CLOSEREPLY_UV: { 502 498 struct xpc_activate_mq_msg_chctl_closereply_uv *msg; 503 499 500 + if (!part_setup) 501 + break; 502 + 504 503 msg = container_of(msg_hdr, struct 505 504 xpc_activate_mq_msg_chctl_closereply_uv, 506 505 hdr); ··· 517 510 } 518 511 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREQUEST_UV: { 519 512 struct xpc_activate_mq_msg_chctl_openrequest_uv *msg; 513 + 514 + if (!part_setup) 515 + break; 520 516 521 517 msg = container_of(msg_hdr, struct 522 518 xpc_activate_mq_msg_chctl_openrequest_uv, ··· 538 528 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENREPLY_UV: { 539 529 struct xpc_activate_mq_msg_chctl_openreply_uv *msg; 540 530 531 + if (!part_setup) 532 + break; 533 + 541 534 msg = container_of(msg_hdr, struct 542 535 xpc_activate_mq_msg_chctl_openreply_uv, hdr); 543 536 args = &part->remote_openclose_args[msg->ch_number]; ··· 557 544 } 558 545 case XPC_ACTIVATE_MQ_MSG_CHCTL_OPENCOMPLETE_UV: { 559 546 struct xpc_activate_mq_msg_chctl_opencomplete_uv *msg; 547 + 548 + if (!part_setup) 549 + break; 560 550 561 551 msg = container_of(msg_hdr, struct 562 552 xpc_activate_mq_msg_chctl_opencomplete_uv, hdr); ··· 637 621 638 622 part_referenced = xpc_part_ref(part); 639 623 xpc_handle_activate_mq_msg_uv(part, msg_hdr, 624 + part_referenced, 640 625 &wakeup_hb_checker); 641 626 if (part_referenced) 642 627 xpc_part_deref(part);