From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f50.google.com (mail-pj1-f50.google.com [209.85.216.50]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 242034582D8 for ; Wed, 12 Aug 2026 14:02:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.50 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786543368; cv=none; b=BVjAsGq02+6rE+2fSM3GSGlDKqvdRRCS2DS/KPFm55KwZ1eHiw3Qonoh5wiPZIHL5Uoa+ALSFl63PO60dmqRjaLlV6GsnWaq/lfOmT/cpvQSq+EkHWWu4sGqb/LmuMmt+AN+VNJQ2boLH7UIAv6IyT+p2MfpLMNFQlMgYWfepNs= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786543368; c=relaxed/simple; bh=UOSzdtNbgPVCx3TtzCdxMnWY1v408O57BFcrXhSA6EE=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version; b=tKiO1gvGbEOsh1anoOw59Dy0OlLGFXvZFK2H/y3g7Jx1+iMJImXhb0lWzZ5dzuXxnFMmlNgmEMLB0UCyabUBdsX0expT7+RyiiyxTp/v1TWwmqejJK2Cm+RhpT7tBwVO7Jw6HmWWmwuFam1985DHo6uaU230B00uS2NljLHimgs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=AaRuLyFU; arc=none smtp.client-ip=209.85.216.50 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="AaRuLyFU" Received: by mail-pj1-f50.google.com with SMTP id 98e67ed59e1d1-38a0c7e841fso1469593a91.2 for ; Wed, 12 Aug 2026 07:02:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786543365; x=1787148165; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to:content-type; bh=LG+vMzKytWNCEpJSjDGLo6pyjBGi5A+g2ffKcMGYpCw=; b=AaRuLyFUg/8svzlp3F4bC1vnqN6W9ySxQZ1P5mtaqs3arOorn7iU6yEl//llwIMTMu GvA59qlEc4bzTjE69js+tfOVFqU44BMCgxMFHWzcRLPhb1xypIwsjoitKDRddey3cpkN I8Fkydn84xZlnYJ4RNYtLuU9eP25HTLGHNRhqcIzazEDFD3eJ0IcbvkLfod1NsCQZIJP eTQkSLfD1sk7WYsl0VI/F+SxegNlhHQM6a68n4dbtUjZweHn5n1GUim3Vek9hWTDvpTV Rty8mV/25MlYJSdQwoJU5YRsTf7RM47Hpvp9i3rX7+UYSxQvArL8UVtPNauaH0EDIeRL nakA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786543365; x=1787148165; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=LG+vMzKytWNCEpJSjDGLo6pyjBGi5A+g2ffKcMGYpCw=; b=k+spfhKUqoMeHZHctBjMvzPcXJbpojmw2jbo+POPH0MV8KNuBvYGTdO+82ks4MqP7m D2GlTAOwgm1Nq3MdZeEBUZd7EETO0f6FV1ziAbCclvz3+yNt5mpknw66YYvzE/nTuoi6 L4zQBuHC0duJqw1eeTVhF0/hcf6/5R+FKBy0R2D1P5bM8A7G/nhA4DsxLi9InLTmfrNL eHUi1InEkmqvn+WJFjrYv71vdEZM8iUQo3Cys/6TlqUcbqozr+Ni549U03TfNTQ2PUlE eJDC1UsgoxIpjDyBvw5c8lG/m0j9YcqNVugyDJr+tBc72sCB7cOUOA1xmK+oOXzZq4/v q7XQ== X-Forwarded-Encrypted: i=1; AHgh+Rqmxfp/yAwkouVh4Uf7cRE2hlvYWxmJ47hEXpz9MRPiflcbvZ2GFHb08RAbR4CYWHwWYpyjjn2lGEJVViU=@vger.kernel.org X-Gm-Message-State: AOJu0YwPNE3wOexck6VbLrj4/MVVlzUUkOIry46EE5A2XacQH58THIWg QI8gCqCyg9IyQjNFg/SunjT70legpxWlSED/EcfDzJ3L3k1w7awZXHg2 X-Gm-Gg: AR+sD13Zny/XGJ6l22OVonYFBKk0BdfhoHbxE+G70BjQo/15B85Ts56i5XuISJDYvfv tnkZGWhzHQvHhEb7qrZbVmDqA3NGI5NpuYD9Pw26oUs621J0pETvFxdcuF5vgZQbDIi20kHJwUo WSQg2nfHpY+HG0o6OzAmfCuvr3cCXnfX4PUbfCrhW2hMX63IOAnTJsPSl+dOkl2XTNBaMRZDylR JY/wa7mN4a4N0xrX0Ep7p3ZY3ilwYa1Ru4VYLY9oLR5TXXUpIOS9t32Qw27GtpGVSc3djiS+ebN Wp+G/yYrV+WVPJFFT2A5NYOwqPbaMqtfNcTOtU1ud7I+mKK46FANQzwUY/0Xlg+jMp0NT3ygQ99 lxh7YtcObNzeoSip3FRnNoa8s78c9A2YQQ2SSTvy/bXf831vIHFe4I9rmFX1GrKbZrox/reaawH F1g9mKKwRtxdY3+8b6yf7zNHyANCz+VrFc0ve6iA5yA2Kgos+ns87BMw6Rfmm9ntc16avDB3udM KX6M7aYtbdhOLqQLCDJCMapzRzMvTb1foFGUw== X-Received: by 2002:a17:90b:1d51:b0:38e:6f90:eabd with SMTP id 98e67ed59e1d1-393012026e1mr6198289a91.5.1786543364264; Wed, 12 Aug 2026 07:02:44 -0700 (PDT) Received: from Harrys-Laptop.hitronhub.home ([2407:4d00:6c05:13e8:419e:d4da:8f19:22ff]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-392f94f9e47sm4004307a91.17.2026.08.12.07.02.41 (version=TLS1_3 cipher=TLS_CHACHA20_POLY1305_SHA256 bits=256/256); Wed, 12 Aug 2026 07:02:43 -0700 (PDT) From: Harry Hsu To: jpoimboe@kernel.org, jikos@kernel.org, mbenes@suse.cz, pmladek@suse.com Cc: joe.lawrence@redhat.com, live-patching@vger.kernel.org, linux-kernel@vger.kernel.org, Harry Hsu Subject: [PATCH] livepatch: Fix stack check for aliased old_func Date: Wed, 12 Aug 2026 22:02:32 +0800 Message-ID: <20260812140232.48079-1-x90613@gmail.com> X-Mailer: git-send-email 2.43.0 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit klp_check_stack_func() decides which address range to look for on a task's stack by asking whether the func preceding @func on ops->func_stack is the original kernel function or another livepatch's replacement. It uses list_is_singular(&ops->func_stack), which only tells "one func on this stack" from "more than one". That assumes every klp_func of a patch gets its own func_stack. Aliases break the assumption. Several symbols can share one address: ffffffff8ed7fef0 t __do_sys_fork ffffffff8ed7fef0 T __ia32_sys_fork ffffffff8ed7fef0 T __x64_sys_fork klp_find_ops() looks the ops up by func->old_func, i.e. by address, so two klp_funcs of the same patch naming two of these symbols resolve to the same klp_ops and are both pushed onto one func_stack. The stack is then head -> B -> A. A is the last node and does correspond to the original function, but list_is_singular() is false, so the "previously patched function" branch runs: list_next_entry() applies container_of() to &ops->func_stack, treating the list head as a struct klp_func, and reads func_addr/func_size from past the object. Besides the out-of-bounds read, the bogus range can keep matching stack entries, so tasks that are safe to switch get -EAGAIN forever and the transition never completes. Test whether @func itself is the last entry instead. The answer is derived from @func's position rather than from the list length, so it holds however many klp_funcs share a func_stack and never steps onto the list head. A single-entry stack is still trivially last, so existing behaviour is unchanged. Fixes: d83a7cb375ee ("livepatch: change to a per-task consistency model") Signed-off-by: Harry Hsu --- kernel/livepatch/transition.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/kernel/livepatch/transition.c b/kernel/livepatch/transition.c index 2351a19ac2a9..8d6e3a58101f 100644 --- a/kernel/livepatch/transition.c +++ b/kernel/livepatch/transition.c @@ -223,7 +223,7 @@ static int klp_check_stack_func(struct klp_func *func, unsigned long *entries, */ ops = klp_find_ops(func->old_func); - if (list_is_singular(&ops->func_stack)) { + if (list_is_last(&func->stack_node, &ops->func_stack)) { /* original function */ func_addr = (unsigned long)func->old_func; func_size = func->old_size; -- 2.43.0