Recreate RHEL 6.12.0-211.22.1 from CS10/upstream backports
Add the RHEL 211.21.1..211.22.1 backports (1288-1351) from centos-stream-10 and upstream stable, on top of 211.20.1. Bump pkgrelease and specrelease to 211.22.1. (The redhat/ automotive rebuild-changelog tooling change is omitted: it patches redhat/scripts not present in this build base and does not affect the kernel.)
This commit is contained in:
parent
4223cf37dd
commit
0eab958d1f
@ -0,0 +1,90 @@
|
||||
From 3453882f36c40d2339267093676585a89808a73d Mon Sep 17 00:00:00 2001
|
||||
From: Xiang Mei <xmei5@asu.edu>
|
||||
Date: Thu, 26 Mar 2026 00:55:53 -0700
|
||||
Subject: [PATCH] net: bonding: fix use-after-free in bond_xmit_broadcast()
|
||||
|
||||
commit 2884bf72fb8f03409e423397319205de48adca16 upstream.
|
||||
|
||||
bond_xmit_broadcast() reuses the original skb for the last slave
|
||||
(determined by bond_is_last_slave()) and clones it for others.
|
||||
Concurrent slave enslave/release can mutate the slave list during
|
||||
RCU-protected iteration, changing which slave is "last" mid-loop.
|
||||
This causes the original skb to be double-consumed (double-freed).
|
||||
|
||||
Replace the racy bond_is_last_slave() check with a simple index
|
||||
comparison (i + 1 == slaves_count) against the pre-snapshot slave
|
||||
count taken via READ_ONCE() before the loop. This preserves the
|
||||
zero-copy optimization for the last slave while making the "last"
|
||||
determination stable against concurrent list mutations.
|
||||
|
||||
The UAF can trigger the following crash:
|
||||
|
||||
==================================================================
|
||||
BUG: KASAN: slab-use-after-free in skb_clone
|
||||
Read of size 8 at addr ffff888100ef8d40 by task exploit/147
|
||||
|
||||
CPU: 1 UID: 0 PID: 147 Comm: exploit Not tainted 7.0.0-rc3+ #4 PREEMPTLAZY
|
||||
Call Trace:
|
||||
<TASK>
|
||||
dump_stack_lvl (lib/dump_stack.c:123)
|
||||
print_report (mm/kasan/report.c:379 mm/kasan/report.c:482)
|
||||
kasan_report (mm/kasan/report.c:597)
|
||||
skb_clone (include/linux/skbuff.h:1724 include/linux/skbuff.h:1792 include/linux/skbuff.h:3396 net/core/skbuff.c:2108)
|
||||
bond_xmit_broadcast (drivers/net/bonding/bond_main.c:5334)
|
||||
bond_start_xmit (drivers/net/bonding/bond_main.c:5567 drivers/net/bonding/bond_main.c:5593)
|
||||
dev_hard_start_xmit (include/linux/netdevice.h:5325 include/linux/netdevice.h:5334 net/core/dev.c:3871 net/core/dev.c:3887)
|
||||
__dev_queue_xmit (include/linux/netdevice.h:3601 net/core/dev.c:4838)
|
||||
ip6_finish_output2 (include/net/neighbour.h:540 include/net/neighbour.h:554 net/ipv6/ip6_output.c:136)
|
||||
ip6_finish_output (net/ipv6/ip6_output.c:208 net/ipv6/ip6_output.c:219)
|
||||
ip6_output (net/ipv6/ip6_output.c:250)
|
||||
ip6_send_skb (net/ipv6/ip6_output.c:1985)
|
||||
udp_v6_send_skb (net/ipv6/udp.c:1442)
|
||||
udpv6_sendmsg (net/ipv6/udp.c:1733)
|
||||
__sys_sendto (net/socket.c:730 net/socket.c:742 net/socket.c:2206)
|
||||
__x64_sys_sendto (net/socket.c:2209)
|
||||
do_syscall_64 (arch/x86/entry/syscall_64.c:63 arch/x86/entry/syscall_64.c:94)
|
||||
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:130)
|
||||
</TASK>
|
||||
|
||||
Allocated by task 147:
|
||||
|
||||
Freed by task 147:
|
||||
|
||||
The buggy address belongs to the object at ffff888100ef8c80
|
||||
which belongs to the cache skbuff_head_cache of size 224
|
||||
The buggy address is located 192 bytes inside of
|
||||
freed 224-byte region [ffff888100ef8c80, ffff888100ef8d60)
|
||||
|
||||
Memory state around the buggy address:
|
||||
ffff888100ef8c00: fb fb fb fb fc fc fc fc fc fc fc fc fc fc fc fc
|
||||
ffff888100ef8c80: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
>ffff888100ef8d00: fb fb fb fb fb fb fb fb fb fb fb fb fc fc fc fc
|
||||
^
|
||||
ffff888100ef8d80: fc fc fc fc fc fc fc fc fa fb fb fb fb fb fb fb
|
||||
ffff888100ef8e00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
|
||||
==================================================================
|
||||
|
||||
Fixes: 4e5bd03ae346 ("net: bonding: fix bond_xmit_broadcast return value error bug")
|
||||
Reported-by: Weiming Shi <bestswngs@gmail.com>
|
||||
Signed-off-by: Xiang Mei <xmei5@asu.edu>
|
||||
Link: https://patch.msgid.link/20260326075553.3960562-1-xmei5@asu.edu
|
||||
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
|
||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
||||
Signed-off-by: Kevin Berry <kpberry@google.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
|
||||
|
||||
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
|
||||
index 294d00f..67fd0c4 100644
|
||||
--- a/drivers/net/bonding/bond_main.c
|
||||
+++ b/drivers/net/bonding/bond_main.c
|
||||
@@ -5401,7 +5401,7 @@ static netdev_tx_t bond_xmit_broadcast(struct sk_buff *skb,
|
||||
if (!(bond_slave_is_up(slave) && slave->link == BOND_LINK_UP))
|
||||
continue;
|
||||
|
||||
- if (bond_is_last_slave(bond, slave)) {
|
||||
+ if (i + 1 == slaves_count) {
|
||||
skb2 = skb;
|
||||
skb_used = true;
|
||||
} else {
|
||||
@ -0,0 +1,123 @@
|
||||
From ac9c3524e6b15adece8493a0db2444e83b3de591 Mon Sep 17 00:00:00 2001
|
||||
From: Mete Durlu <mdurlu@redhat.com>
|
||||
Date: Fri, 20 Mar 2026 15:05:43 +0100
|
||||
Subject: [PATCH] s390/pci: Avoid deadlock between PCI error recovery and mlx5
|
||||
crdump
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-157932
|
||||
|
||||
commit 0fd20f65df6aa430454a0deed8f43efa91c54835
|
||||
Author: Gerd Bayer <gbayer@linux.ibm.com>
|
||||
Date: Thu Oct 16 11:27:03 2025 +0200
|
||||
|
||||
s390/pci: Avoid deadlock between PCI error recovery and mlx5 crdump
|
||||
|
||||
Do not block PCI config accesses through pci_cfg_access_lock() when
|
||||
executing the s390 variant of PCI error recovery: Acquire just
|
||||
device_lock() instead of pci_dev_lock() as powerpc's EEH and
|
||||
generig PCI AER processing do.
|
||||
|
||||
During error recovery testing a pair of tasks was reported to be hung:
|
||||
|
||||
mlx5_core 0000:00:00.1: mlx5_health_try_recover:338:(pid 5553): health recovery flow aborted, PCI reads still not working
|
||||
INFO: task kmcheck:72 blocked for more than 122 seconds.
|
||||
Not tainted 5.14.0-570.12.1.bringup7.el9.s390x #1
|
||||
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
|
||||
task:kmcheck state:D stack:0 pid:72 tgid:72 ppid:2 flags:0x00000000
|
||||
Call Trace:
|
||||
[<000000065256f030>] __schedule+0x2a0/0x590
|
||||
[<000000065256f356>] schedule+0x36/0xe0
|
||||
[<000000065256f572>] schedule_preempt_disabled+0x22/0x30
|
||||
[<0000000652570a94>] __mutex_lock.constprop.0+0x484/0x8a8
|
||||
[<000003ff800673a4>] mlx5_unload_one+0x34/0x58 [mlx5_core]
|
||||
[<000003ff8006745c>] mlx5_pci_err_detected+0x94/0x140 [mlx5_core]
|
||||
[<0000000652556c5a>] zpci_event_attempt_error_recovery+0xf2/0x398
|
||||
[<0000000651b9184a>] __zpci_event_error+0x23a/0x2c0
|
||||
INFO: task kworker/u1664:6:1514 blocked for more than 122 seconds.
|
||||
Not tainted 5.14.0-570.12.1.bringup7.el9.s390x #1
|
||||
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
|
||||
task:kworker/u1664:6 state:D stack:0 pid:1514 tgid:1514 ppid:2 flags:0x00000000
|
||||
Workqueue: mlx5_health0000:00:00.0 mlx5_fw_fatal_reporter_err_work [mlx5_core]
|
||||
Call Trace:
|
||||
[<000000065256f030>] __schedule+0x2a0/0x590
|
||||
[<000000065256f356>] schedule+0x36/0xe0
|
||||
[<0000000652172e28>] pci_wait_cfg+0x80/0xe8
|
||||
[<0000000652172f94>] pci_cfg_access_lock+0x74/0x88
|
||||
[<000003ff800916b6>] mlx5_vsc_gw_lock+0x36/0x178 [mlx5_core]
|
||||
[<000003ff80098824>] mlx5_crdump_collect+0x34/0x1c8 [mlx5_core]
|
||||
[<000003ff80074b62>] mlx5_fw_fatal_reporter_dump+0x6a/0xe8 [mlx5_core]
|
||||
[<0000000652512242>] devlink_health_do_dump.part.0+0x82/0x168
|
||||
[<0000000652513212>] devlink_health_report+0x19a/0x230
|
||||
[<000003ff80075a12>] mlx5_fw_fatal_reporter_err_work+0xba/0x1b0 [mlx5_core]
|
||||
|
||||
No kernel log of the exact same error with an upstream kernel is
|
||||
available - but the very same deadlock situation can be constructed there,
|
||||
too:
|
||||
|
||||
- task: kmcheck
|
||||
mlx5_unload_one() tries to acquire devlink lock while the PCI error
|
||||
recovery code has set pdev->block_cfg_access by way of
|
||||
pci_cfg_access_lock()
|
||||
- task: kworker
|
||||
mlx5_crdump_collect() tries to set block_cfg_access through
|
||||
pci_cfg_access_lock() while devlink_health_report() had acquired
|
||||
the devlink lock.
|
||||
|
||||
A similar deadlock situation can be reproduced by requesting a
|
||||
crdump with
|
||||
> devlink health dump show pci/<BDF> reporter fw_fatal
|
||||
|
||||
while PCI error recovery is executed on the same <BDF> physical function
|
||||
by mlx5_core's pci_error_handlers. On s390 this can be injected with
|
||||
> zpcictl --reset-fw <BDF>
|
||||
|
||||
Tests with this patch failed to reproduce that second deadlock situation,
|
||||
the devlink command is rejected with "kernel answers: Permission denied" -
|
||||
and we get a kernel log message of:
|
||||
|
||||
mlx5_core 1ed0:00:00.1: mlx5_crdump_collect:50:(pid 254382): crdump: failed to lock vsc gw err -5
|
||||
|
||||
because the config read of VSC_SEMAPHORE is rejected by the underlying
|
||||
hardware.
|
||||
|
||||
Two prior attempts to address this issue have been discussed and
|
||||
ultimately rejected [see link], with the primary argument that s390's
|
||||
implementation of PCI error recovery is imposing restrictions that
|
||||
neither powerpc's EEH nor PCI AER handling need. Tests show that PCI
|
||||
error recovery on s390 is running to completion even without blocking
|
||||
access to PCI config space.
|
||||
|
||||
Link: https://lore.kernel.org/all/20251007144826.2825134-1-gbayer@linux.ibm.com/
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 4cdf2f4e24ff ("s390/pci: implement minimal PCI error recovery")
|
||||
Reviewed-by: Niklas Schnelle <schnelle@linux.ibm.com>
|
||||
Signed-off-by: Gerd Bayer <gbayer@linux.ibm.com>
|
||||
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
|
||||
|
||||
Signed-off-by: Mete Durlu <mdurlu@redhat.com>
|
||||
|
||||
diff --git a/arch/s390/pci/pci_event.c b/arch/s390/pci/pci_event.c
|
||||
index d930416d4c90..da0de34d2e5c 100644
|
||||
--- a/arch/s390/pci/pci_event.c
|
||||
+++ b/arch/s390/pci/pci_event.c
|
||||
@@ -187,7 +187,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
|
||||
* is unbound or probed and that userspace can't access its
|
||||
* configuration space while we perform recovery.
|
||||
*/
|
||||
- pci_dev_lock(pdev);
|
||||
+ device_lock(&pdev->dev);
|
||||
if (pdev->error_state == pci_channel_io_perm_failure) {
|
||||
ers_res = PCI_ERS_RESULT_DISCONNECT;
|
||||
goto out_unlock;
|
||||
@@ -254,7 +254,7 @@ static pci_ers_result_t zpci_event_attempt_error_recovery(struct pci_dev *pdev)
|
||||
if (driver->err_handler->resume)
|
||||
driver->err_handler->resume(pdev);
|
||||
out_unlock:
|
||||
- pci_dev_unlock(pdev);
|
||||
+ device_unlock(&pdev->dev);
|
||||
zpci_report_status(zdev, "recovery", status_str);
|
||||
|
||||
return ers_res;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,138 @@
|
||||
From 9837d44c3a8c7908fca4a3e4ef2e753b43b2e7da Mon Sep 17 00:00:00 2001
|
||||
From: Michal Schmidt <mschmidt@redhat.com>
|
||||
Date: Mon, 27 Apr 2026 17:18:26 +0200
|
||||
Subject: [PATCH] ice: fix stats array overflow when VF requests more queues
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-163186
|
||||
|
||||
Upstream status: Posted: https://lore.kernel.org/netdev/20260427151827.43342-1-mschmidt@redhat.com/
|
||||
|
||||
When a VF increases its queue count via VIRTCHNL_OP_REQUEST_QUEUES,
|
||||
ice_vc_request_qs_msg() sets vf->num_req_qs and triggers a VF reset.
|
||||
The reset calls ice_vf_reconfig_vsi(), which does ice_vsi_decfg()
|
||||
followed by ice_vsi_cfg(). ice_vsi_decfg() does not free the per-ring
|
||||
stats arrays. Inside ice_vsi_cfg_def(), ice_vsi_set_num_qs() updates
|
||||
alloc_txq/alloc_rxq to the new larger value, but
|
||||
ice_vsi_alloc_stat_arrays() returns early because the stats already
|
||||
exist. ice_vsi_alloc_ring_stats() then iterates using the new larger
|
||||
alloc_txq and writes beyond the bounds of the old, smaller
|
||||
tx_ring_stats/rx_ring_stats pointer arrays, corrupting adjacent SLUB
|
||||
metadata.
|
||||
|
||||
KASAN detects the bug:
|
||||
==================================================================
|
||||
BUG: KASAN: slab-out-of-bounds in ice_vsi_alloc_ring_stats+0x385/0x4a0 [ice]
|
||||
Read of size 8 at addr ffff88810affea60 by task kworker/u131:7/221
|
||||
|
||||
CPU: 24 UID: 0 PID: 221 Comm: kworker/u131:7 Not tainted 7.1.0-rc1+ #1 PREEMPT(lazy)
|
||||
...
|
||||
Workqueue: ice ice_service_task [ice]
|
||||
Call Trace:
|
||||
<TASK>
|
||||
...
|
||||
kasan_report+0xd7/0x120
|
||||
ice_vsi_alloc_ring_stats+0x385/0x4a0 [ice]
|
||||
ice_vsi_cfg_def+0x12e2/0x2060 [ice]
|
||||
ice_vsi_cfg+0xb5/0x3c0 [ice]
|
||||
ice_reset_vf+0x858/0xf80 [ice]
|
||||
ice_vc_request_qs_msg+0x1da/0x290 [ice]
|
||||
ice_vc_process_vf_msg+0xb15/0x1430 [ice]
|
||||
__ice_clean_ctrlq+0x70d/0x9d0 [ice]
|
||||
ice_service_task+0x840/0xf20 [ice]
|
||||
process_one_work+0x690/0xff0
|
||||
worker_thread+0x4d9/0xd20
|
||||
kthread+0x322/0x410
|
||||
ret_from_fork+0x332/0x660
|
||||
ret_from_fork_asm+0x1a/0x30
|
||||
</TASK>
|
||||
|
||||
Allocated by task 2439:
|
||||
kasan_save_stack+0x1c/0x40
|
||||
kasan_save_track+0x10/0x30
|
||||
__kasan_kmalloc+0x96/0xb0
|
||||
__kmalloc_noprof+0x1d8/0x580
|
||||
ice_vsi_cfg_def+0x115c/0x2060 [ice]
|
||||
ice_vsi_cfg+0xb5/0x3c0 [ice]
|
||||
ice_vsi_setup+0x180/0x320 [ice]
|
||||
ice_start_vfs+0x1f3/0x590 [ice]
|
||||
ice_ena_vfs+0x66d/0x798 [ice]
|
||||
ice_sriov_configure.cold+0xe4/0x121 [ice]
|
||||
sriov_numvfs_store+0x279/0x480
|
||||
kernfs_fop_write_iter+0x331/0x4f0
|
||||
vfs_write+0x4c4/0xe40
|
||||
ksys_write+0x10c/0x240
|
||||
do_syscall_64+0xd9/0x650
|
||||
entry_SYSCALL_64_after_hwframe+0x76/0x7e
|
||||
|
||||
The buggy address belongs to the object at ffff88810affea40
|
||||
which belongs to the cache kmalloc-32 of size 32
|
||||
The buggy address is located 0 bytes to the right of
|
||||
allocated 32-byte region [ffff88810affea40, ffff88810affea60)
|
||||
...
|
||||
==================================================================
|
||||
|
||||
ice_vsi_rebuild() handles this correctly by calling
|
||||
ice_vsi_realloc_stat_arrays() before reconfiguration, but
|
||||
ice_vf_reconfig_vsi() was missing this call.
|
||||
|
||||
Fix by calling ice_vsi_realloc_stat_arrays() in ice_vf_reconfig_vsi()
|
||||
before ice_vsi_decfg(), mirroring the ice_vsi_rebuild() pattern. Set
|
||||
vsi->req_txq/req_rxq from vf->num_req_qs so the realloc function knows
|
||||
the target array size.
|
||||
|
||||
See the linked RHEL Jira item for a reproducer.
|
||||
|
||||
Fixes: 2a2cb4c6c181 ("ice: replace ice_vf_recreate_vsi() with ice_vf_reconfig_vsi()")
|
||||
Closes: https://redhat.atlassian.net/browse/RHEL-164321
|
||||
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
|
||||
Assisted-by: Claude:claude-opus-4-6 semcode
|
||||
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
|
||||
Reviewed-by: Simon Horman <horms@kernel.org>
|
||||
Reviewed-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
|
||||
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.c b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
index 26496eaed981..7bc5a7009cbb 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.c
|
||||
@@ -3017,7 +3017,7 @@ ice_vsi_rebuild_set_coalesce(struct ice_vsi *vsi,
|
||||
* ice_vsi_realloc_stat_arrays - Frees unused stat structures or alloc new ones
|
||||
* @vsi: VSI pointer
|
||||
*/
|
||||
-static int
|
||||
+int
|
||||
ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi)
|
||||
{
|
||||
u16 req_txq = vsi->req_txq ? vsi->req_txq : vsi->alloc_txq;
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_lib.h b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
index 2cb1eb98b9da..fce6f633f506 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_lib.h
|
||||
@@ -66,6 +66,7 @@ int ice_ena_vsi(struct ice_vsi *vsi, bool locked);
|
||||
void ice_vsi_decfg(struct ice_vsi *vsi);
|
||||
void ice_dis_vsi(struct ice_vsi *vsi, bool locked);
|
||||
|
||||
+int ice_vsi_realloc_stat_arrays(struct ice_vsi *vsi);
|
||||
int ice_vsi_rebuild(struct ice_vsi *vsi, u32 vsi_flags);
|
||||
int ice_vsi_cfg(struct ice_vsi *vsi);
|
||||
struct ice_vsi *ice_vsi_alloc(struct ice_pf *pf);
|
||||
diff --git a/drivers/net/ethernet/intel/ice/ice_vf_lib.c b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
index de9e81ccee66..fd71dd10eb38 100644
|
||||
--- a/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
+++ b/drivers/net/ethernet/intel/ice/ice_vf_lib.c
|
||||
@@ -268,6 +268,13 @@ static int ice_vf_reconfig_vsi(struct ice_vf *vf)
|
||||
|
||||
vsi->flags = ICE_VSI_FLAG_NO_INIT;
|
||||
|
||||
+ vsi->req_txq = vf->num_req_qs;
|
||||
+ vsi->req_rxq = vf->num_req_qs;
|
||||
+
|
||||
+ err = ice_vsi_realloc_stat_arrays(vsi);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
+
|
||||
ice_vsi_decfg(vsi);
|
||||
ice_fltr_remove_all(vsi);
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
57
1291-s390-dasd-fix-gendisk-parent-after-copy-pair-swap.patch
Normal file
57
1291-s390-dasd-fix-gendisk-parent-after-copy-pair-swap.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 8ac29c454e865adf7b65a4f83d28177e0ecb1dca Mon Sep 17 00:00:00 2001
|
||||
From: Ming Lei <ming.lei@redhat.com>
|
||||
Date: Wed, 26 Nov 2025 17:06:31 +0100
|
||||
Subject: [PATCH] s390/dasd: Fix gendisk parent after copy pair swap
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-144763
|
||||
|
||||
commit c943bfc6afb8d0e781b9b7406f36caa8bbf95cb9
|
||||
Author: Stefan Haberland <sth@linux.ibm.com>
|
||||
Date: Wed Nov 26 17:06:31 2025 +0100
|
||||
|
||||
s390/dasd: Fix gendisk parent after copy pair swap
|
||||
|
||||
After a copy pair swap the block device's "device" symlink points to
|
||||
the secondary CCW device, but the gendisk's parent remained the
|
||||
primary, leaving /sys/block/<dasdx> under the wrong parent.
|
||||
|
||||
Move the gendisk to the secondary's device with device_move(), keeping
|
||||
the sysfs topology consistent after the swap.
|
||||
|
||||
Fixes: 413862caad6f ("s390/dasd: add copy pair swap capability")
|
||||
Cc: stable@vger.kernel.org #6.1
|
||||
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
|
||||
Signed-off-by: Ming Lei <ming.lei@redhat.com>
|
||||
|
||||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
|
||||
index 1ebe589b5185..78fef8959c78 100644
|
||||
--- a/drivers/s390/block/dasd_eckd.c
|
||||
+++ b/drivers/s390/block/dasd_eckd.c
|
||||
@@ -6149,6 +6149,7 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid
|
||||
struct dasd_copy_relation *copy;
|
||||
struct dasd_block *block;
|
||||
struct gendisk *gdp;
|
||||
+ int rc;
|
||||
|
||||
copy = device->copy;
|
||||
if (!copy)
|
||||
@@ -6183,6 +6184,13 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid
|
||||
/* swap blocklayer device link */
|
||||
gdp = block->gdp;
|
||||
dasd_add_link_to_gendisk(gdp, secondary);
|
||||
+ rc = device_move(disk_to_dev(gdp), &secondary->cdev->dev, DPM_ORDER_NONE);
|
||||
+ if (rc) {
|
||||
+ dev_err(&primary->cdev->dev,
|
||||
+ "copy_pair_swap: moving blockdevice parent %s->%s failed (%d)\n",
|
||||
+ dev_name(&primary->cdev->dev),
|
||||
+ dev_name(&secondary->cdev->dev), rc);
|
||||
+ }
|
||||
|
||||
/* re-enable device */
|
||||
dasd_device_remove_stop_bits(primary, DASD_STOPPED_PPRC);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
54
1292-s390-dasd-move-quiesce-state-with-pprc-swap.patch
Normal file
54
1292-s390-dasd-move-quiesce-state-with-pprc-swap.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 98d247e4eac9e5a06678190715d9f9d86902aa9c Mon Sep 17 00:00:00 2001
|
||||
From: Mete Durlu <mdurlu@redhat.com>
|
||||
Date: Fri, 27 Mar 2026 13:20:49 +0100
|
||||
Subject: [PATCH] s390/dasd: Move quiesce state with pprc swap
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-161531
|
||||
|
||||
commit 40e9cd4ae8ec43b107ed2bff422a8fa39dcf4e4b
|
||||
Author: Stefan Haberland <sth@linux.ibm.com>
|
||||
Date: Tue Mar 10 15:23:29 2026 +0100
|
||||
|
||||
s390/dasd: Move quiesce state with pprc swap
|
||||
|
||||
Quiesce and resume is a mechanism to suspend operations on DASD devices.
|
||||
In the context of a controlled copy pair swap operation, the quiesce
|
||||
operation is usually issued before the actual swap and a resume
|
||||
afterwards.
|
||||
|
||||
During the swap operation, the underlying device is exchanged. Therefore,
|
||||
the quiesce flag must be moved to the secondary device to ensure a
|
||||
consistent quiesce state after the swap.
|
||||
|
||||
The secondary device itself cannot be suspended separately because there
|
||||
is no separate block device representation for it.
|
||||
|
||||
Fixes: 413862caad6f ("s390/dasd: add copy pair swap capability")
|
||||
Cc: stable@vger.kernel.org #6.1
|
||||
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||||
Link: https://patch.msgid.link/20260310142330.4080106-2-sth@linux.ibm.com
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
|
||||
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||||
Signed-off-by: Mete Durlu <mdurlu@redhat.com>
|
||||
|
||||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
|
||||
index 78fef8959c78..c6d825109f53 100644
|
||||
--- a/drivers/s390/block/dasd_eckd.c
|
||||
+++ b/drivers/s390/block/dasd_eckd.c
|
||||
@@ -6192,6 +6192,11 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid
|
||||
dev_name(&secondary->cdev->dev), rc);
|
||||
}
|
||||
|
||||
+ if (primary->stopped & DASD_STOPPED_QUIESCE) {
|
||||
+ dasd_device_set_stop_bits(secondary, DASD_STOPPED_QUIESCE);
|
||||
+ dasd_device_remove_stop_bits(primary, DASD_STOPPED_QUIESCE);
|
||||
+ }
|
||||
+
|
||||
/* re-enable device */
|
||||
dasd_device_remove_stop_bits(primary, DASD_STOPPED_PPRC);
|
||||
dasd_device_remove_stop_bits(secondary, DASD_STOPPED_PPRC);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,83 @@
|
||||
From 2435d419304a1e5bfc93947d3c6a7902b49aadcc Mon Sep 17 00:00:00 2001
|
||||
From: Mete Durlu <mdurlu@redhat.com>
|
||||
Date: Fri, 27 Mar 2026 13:20:52 +0100
|
||||
Subject: [PATCH] s390/dasd: Copy detected format information to secondary
|
||||
device
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-161531
|
||||
|
||||
commit 4c527c7e030672efd788d0806d7a68972a7ba3c1
|
||||
Author: Stefan Haberland <sth@linux.ibm.com>
|
||||
Date: Tue Mar 10 15:23:30 2026 +0100
|
||||
|
||||
s390/dasd: Copy detected format information to secondary device
|
||||
|
||||
During online processing for a DASD device an IO operation is started to
|
||||
determine the format of the device. CDL format contains specifically
|
||||
sized blocks at the beginning of the disk.
|
||||
|
||||
For a PPRC secondary device no real IO operation is possible therefore
|
||||
this IO request can not be started and this step is skipped for online
|
||||
processing of secondary devices. This is generally fine since the
|
||||
secondary is a copy of the primary device.
|
||||
|
||||
In case of an additional partition detection that is run after a swap
|
||||
operation the format information is needed to properly drive partition
|
||||
detection IO.
|
||||
|
||||
Currently the information is not passed leading to IO errors during
|
||||
partition detection and a wrongly detected partition table which in turn
|
||||
might lead to data corruption on the disk with the wrong partition table.
|
||||
|
||||
Fix by passing the format information from primary to secondary device.
|
||||
|
||||
Fixes: 413862caad6f ("s390/dasd: add copy pair swap capability")
|
||||
Cc: stable@vger.kernel.org #6.1
|
||||
Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com>
|
||||
Acked-by: Eduard Shishkin <edward6@linux.ibm.com>
|
||||
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||||
Link: https://patch.msgid.link/20260310142330.4080106-3-sth@linux.ibm.com
|
||||
Signed-off-by: Jens Axboe <axboe@kernel.dk>
|
||||
|
||||
Signed-off-by: Stefan Haberland <sth@linux.ibm.com>
|
||||
Signed-off-by: Mete Durlu <mdurlu@redhat.com>
|
||||
|
||||
diff --git a/drivers/s390/block/dasd_eckd.c b/drivers/s390/block/dasd_eckd.c
|
||||
index c6d825109f53..0d874d92a099 100644
|
||||
--- a/drivers/s390/block/dasd_eckd.c
|
||||
+++ b/drivers/s390/block/dasd_eckd.c
|
||||
@@ -6145,6 +6145,7 @@ static void copy_pair_set_active(struct dasd_copy_relation *copy, char *new_busi
|
||||
static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid,
|
||||
char *sec_busid)
|
||||
{
|
||||
+ struct dasd_eckd_private *prim_priv, *sec_priv;
|
||||
struct dasd_device *primary, *secondary;
|
||||
struct dasd_copy_relation *copy;
|
||||
struct dasd_block *block;
|
||||
@@ -6165,6 +6166,9 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid
|
||||
if (!secondary)
|
||||
return DASD_COPYPAIRSWAP_SECONDARY;
|
||||
|
||||
+ prim_priv = primary->private;
|
||||
+ sec_priv = secondary->private;
|
||||
+
|
||||
/*
|
||||
* usually the device should be quiesced for swap
|
||||
* for paranoia stop device and requeue requests again
|
||||
@@ -6197,6 +6201,13 @@ static int dasd_eckd_copy_pair_swap(struct dasd_device *device, char *prim_busid
|
||||
dasd_device_remove_stop_bits(primary, DASD_STOPPED_QUIESCE);
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * The secondary device never got through format detection, but since it
|
||||
+ * is a copy of the primary device, the format is exactly the same;
|
||||
+ * therefore, the detected layout can simply be copied.
|
||||
+ */
|
||||
+ sec_priv->uses_cdl = prim_priv->uses_cdl;
|
||||
+
|
||||
/* re-enable device */
|
||||
dasd_device_remove_stop_bits(primary, DASD_STOPPED_PPRC);
|
||||
dasd_device_remove_stop_bits(secondary, DASD_STOPPED_PPRC);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
55
1294-nouveau-gsp-drop-warn-on-in-acpi-probes.patch
Normal file
55
1294-nouveau-gsp-drop-warn-on-in-acpi-probes.patch
Normal file
@ -0,0 +1,55 @@
|
||||
From 9478c166c46934160135e197b049b5a05753f2ad Mon Sep 17 00:00:00 2001
|
||||
From: Dave Airlie <airlied@redhat.com>
|
||||
Date: Thu, 21 Nov 2024 11:46:01 +1000
|
||||
Subject: [PATCH] nouveau/gsp: drop WARN_ON in ACPI probes
|
||||
|
||||
These WARN_ONs seem to trigger a lot, and we don't seem to have a
|
||||
plan to fix them, so just drop them, as they are most likely
|
||||
harmless.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 176fdcbddfd2 ("drm/nouveau/gsp/r535: add support for booting GSP-RM")
|
||||
Signed-off-by: Dave Airlie <airlied@redhat.com>
|
||||
Link: https://patch.msgid.link/20241121014601.229391-1-airlied@gmail.com
|
||||
Signed-off-by: Danilo Krummrich <dakr@kernel.org>
|
||||
|
||||
diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
|
||||
index 7fb13434c051..a575a8dbf727 100644
|
||||
--- a/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
|
||||
+++ b/drivers/gpu/drm/nouveau/nvkm/subdev/gsp/rm/r535/gsp.c
|
||||
@@ -737,8 +737,8 @@ r535_gsp_acpi_caps(acpi_handle handle, CAPS_METHOD_DATA *caps)
|
||||
if (!obj)
|
||||
goto done;
|
||||
|
||||
- if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
- WARN_ON(obj->buffer.length != 4))
|
||||
+ if (obj->type != ACPI_TYPE_BUFFER ||
|
||||
+ obj->buffer.length != 4)
|
||||
goto done;
|
||||
|
||||
caps->status = 0;
|
||||
@@ -773,8 +773,8 @@ r535_gsp_acpi_jt(acpi_handle handle, JT_METHOD_DATA *jt)
|
||||
if (!obj)
|
||||
goto done;
|
||||
|
||||
- if (WARN_ON(obj->type != ACPI_TYPE_BUFFER) ||
|
||||
- WARN_ON(obj->buffer.length != 4))
|
||||
+ if (obj->type != ACPI_TYPE_BUFFER ||
|
||||
+ obj->buffer.length != 4)
|
||||
goto done;
|
||||
|
||||
jt->status = 0;
|
||||
@@ -861,8 +861,8 @@ r535_gsp_acpi_dod(acpi_handle handle, DOD_METHOD_DATA *dod)
|
||||
|
||||
_DOD = output.pointer;
|
||||
|
||||
- if (WARN_ON(_DOD->type != ACPI_TYPE_PACKAGE) ||
|
||||
- WARN_ON(_DOD->package.count > ARRAY_SIZE(dod->acpiIdList)))
|
||||
+ if (_DOD->type != ACPI_TYPE_PACKAGE ||
|
||||
+ _DOD->package.count > ARRAY_SIZE(dod->acpiIdList))
|
||||
return;
|
||||
|
||||
for (int i = 0; i < _DOD->package.count; i++) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
77
1295-can-raw-fix-ro-uniq-use-after-free-in-raw-rcv.patch
Normal file
77
1295-can-raw-fix-ro-uniq-use-after-free-in-raw-rcv.patch
Normal file
@ -0,0 +1,77 @@
|
||||
From c9a44a91015ff6116ef4dfb6e2c752e5366b2d32 Mon Sep 17 00:00:00 2001
|
||||
From: Davide Caratti <dcaratti@redhat.com>
|
||||
Date: Mon, 27 Apr 2026 12:58:46 +0200
|
||||
Subject: [PATCH] can: raw: fix ro->uniq use-after-free in raw_rcv()
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-170766
|
||||
CVE: CVE-2026-31532
|
||||
Upstream Status: net-next.git commit a535a9217ca3f2fccedaafb2fddb4c48f27d36dc
|
||||
|
||||
commit a535a9217ca3f2fccedaafb2fddb4c48f27d36dc
|
||||
Author: Samuel Page <sam@bynar.io>
|
||||
Date: Wed Apr 8 15:30:13 2026 +0100
|
||||
|
||||
can: raw: fix ro->uniq use-after-free in raw_rcv()
|
||||
|
||||
raw_release() unregisters raw CAN receive filters via can_rx_unregister(),
|
||||
but receiver deletion is deferred with call_rcu(). This leaves a window
|
||||
where raw_rcv() may still be running in an RCU read-side critical section
|
||||
after raw_release() frees ro->uniq, leading to a use-after-free of the
|
||||
percpu uniq storage.
|
||||
|
||||
Move free_percpu(ro->uniq) out of raw_release() and into a raw-specific
|
||||
socket destructor. can_rx_unregister() takes an extra reference to the
|
||||
socket and only drops it from the RCU callback, so freeing uniq from
|
||||
sk_destruct ensures the percpu area is not released until the relevant
|
||||
callbacks have drained.
|
||||
|
||||
Fixes: 514ac99c64b2 ("can: fix multiple delivery of a single CAN frame for overlapping CAN filters")
|
||||
Cc: stable@vger.kernel.org # v4.1+
|
||||
Assisted-by: Bynario AI
|
||||
Signed-off-by: Samuel Page <sam@bynar.io>
|
||||
Link: https://patch.msgid.link/26ec626d-cae7-4418-9782-7198864d070c@bynar.io
|
||||
Acked-by: Oliver Hartkopp <socketcan@hartkopp.net>
|
||||
[mkl: applied manually]
|
||||
Signed-off-by: Marc Kleine-Budde <mkl@pengutronix.de>
|
||||
|
||||
Signed-off-by: Davide Caratti <dcaratti@redhat.com>
|
||||
|
||||
diff --git a/net/can/raw.c b/net/can/raw.c
|
||||
index 2aab0398e444..c7e392fad11a 100644
|
||||
--- a/net/can/raw.c
|
||||
+++ b/net/can/raw.c
|
||||
@@ -360,6 +360,14 @@ static int raw_notifier(struct notifier_block *nb, unsigned long msg,
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
+static void raw_sock_destruct(struct sock *sk)
|
||||
+{
|
||||
+ struct raw_sock *ro = raw_sk(sk);
|
||||
+
|
||||
+ free_percpu(ro->uniq);
|
||||
+ can_sock_destruct(sk);
|
||||
+}
|
||||
+
|
||||
static int raw_init(struct sock *sk)
|
||||
{
|
||||
struct raw_sock *ro = raw_sk(sk);
|
||||
@@ -386,6 +394,8 @@ static int raw_init(struct sock *sk)
|
||||
if (unlikely(!ro->uniq))
|
||||
return -ENOMEM;
|
||||
|
||||
+ sk->sk_destruct = raw_sock_destruct;
|
||||
+
|
||||
/* set notifier */
|
||||
spin_lock(&raw_notifier_lock);
|
||||
list_add_tail(&ro->notifier, &raw_notifier_list);
|
||||
@@ -433,7 +443,6 @@ static int raw_release(struct socket *sock)
|
||||
ro->bound = 0;
|
||||
ro->dev = NULL;
|
||||
ro->count = 0;
|
||||
- free_percpu(ro->uniq);
|
||||
|
||||
sock_orphan(sk);
|
||||
sock->sk = NULL;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From ce3e488188bb7c00b8ccdba07c6ccfb98d7384a2 Mon Sep 17 00:00:00 2001
|
||||
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
Date: Tue, 28 Apr 2026 18:31:31 +0000
|
||||
Subject: [PATCH] erofs: add GFP_NOIO in the bio completion if needed
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-171687
|
||||
CVE: CVE-2026-31467
|
||||
|
||||
commit c23df30915f83e7257c8625b690a1cece94142a0
|
||||
Author: Jiucheng Xu <jiucheng.xu@amlogic.com>
|
||||
Date: Wed Mar 11 17:11:31 2026 +0800
|
||||
|
||||
erofs: add GFP_NOIO in the bio completion if needed
|
||||
|
||||
The bio completion path in the process context (e.g. dm-verity)
|
||||
will directly call into decompression rather than trigger another
|
||||
workqueue context for minimal scheduling latencies, which can
|
||||
then call vm_map_ram() with GFP_KERNEL.
|
||||
|
||||
Due to insufficient memory, vm_map_ram() may generate memory
|
||||
swapping I/O, which can cause submit_bio_wait to deadlock
|
||||
in some scenarios.
|
||||
|
||||
Trimmed down the call stack, as follows:
|
||||
|
||||
f2fs_submit_read_io
|
||||
submit_bio //bio_list is initialized.
|
||||
mmc_blk_mq_recovery
|
||||
z_erofs_endio
|
||||
vm_map_ram
|
||||
__pte_alloc_kernel
|
||||
__alloc_pages_direct_reclaim
|
||||
shrink_folio_list
|
||||
__swap_writepage
|
||||
submit_bio_wait //bio_list is non-NULL, hang!!!
|
||||
|
||||
Use memalloc_noio_{save,restore}() to wrap up this path.
|
||||
|
||||
Reviewed-by: Gao Xiang <hsiangkao@linux.alibaba.com>
|
||||
Signed-off-by: Jiucheng Xu <jiucheng.xu@amlogic.com>
|
||||
Reviewed-by: Chao Yu <chao@kernel.org>
|
||||
Signed-off-by: Gao Xiang <hsiangkao@linux.alibaba.com>
|
||||
|
||||
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
|
||||
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
|
||||
index db1f13663cd5..cfde72fcd548 100644
|
||||
--- a/fs/erofs/zdata.c
|
||||
+++ b/fs/erofs/zdata.c
|
||||
@@ -1337,6 +1337,7 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
|
||||
int bios)
|
||||
{
|
||||
struct erofs_sb_info *const sbi = EROFS_SB(io->sb);
|
||||
+ int gfp_flag;
|
||||
|
||||
/* wake up the caller thread for sync decompression */
|
||||
if (io->sync) {
|
||||
@@ -1370,7 +1371,9 @@ static void z_erofs_decompress_kickoff(struct z_erofs_decompressqueue *io,
|
||||
sbi->opt.sync_decompress = EROFS_SYNC_DECOMPRESS_FORCE_ON;
|
||||
return;
|
||||
}
|
||||
+ gfp_flag = memalloc_noio_save();
|
||||
z_erofs_decompressqueue_work(&io->u.work);
|
||||
+ memalloc_noio_restore(gfp_flag);
|
||||
}
|
||||
|
||||
static void z_erofs_fill_bio_vec(struct bio_vec *bvec,
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
90
1297-alsa-6fire-fix-use-after-free-on-disconnect.patch
Normal file
90
1297-alsa-6fire-fix-use-after-free-on-disconnect.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From ee288dfa7ea837c1ffe68fd01e54d422e02f0fc4 Mon Sep 17 00:00:00 2001
|
||||
From: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
Date: Mon, 4 May 2026 08:33:31 +0000
|
||||
Subject: [PATCH] ALSA: 6fire: fix use-after-free on disconnect
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-172974
|
||||
CVE: CVE-2026-31581
|
||||
|
||||
commit b9c826916fdce6419b94eb0cd8810fdac18c2386
|
||||
Author: Berk Cem Goksel <berkcgoksel@gmail.com>
|
||||
Date: Fri Apr 10 08:13:41 2026 +0300
|
||||
|
||||
ALSA: 6fire: fix use-after-free on disconnect
|
||||
|
||||
In usb6fire_chip_abort(), the chip struct is allocated as the card's
|
||||
private data (via snd_card_new with sizeof(struct sfire_chip)). When
|
||||
snd_card_free_when_closed() is called and no file handles are open, the
|
||||
card and embedded chip are freed synchronously. The subsequent
|
||||
chip->card = NULL write then hits freed slab memory.
|
||||
|
||||
Call trace:
|
||||
usb6fire_chip_abort sound/usb/6fire/chip.c:59 [inline]
|
||||
usb6fire_chip_disconnect+0x348/0x358 sound/usb/6fire/chip.c:182
|
||||
usb_unbind_interface+0x1a8/0x88c drivers/usb/core/driver.c:458
|
||||
...
|
||||
hub_event+0x1a04/0x4518 drivers/usb/core/hub.c:5953
|
||||
|
||||
Fix by moving the card lifecycle out of usb6fire_chip_abort() and into
|
||||
usb6fire_chip_disconnect(). The card pointer is saved in a local
|
||||
before any teardown, snd_card_disconnect() is called first to prevent
|
||||
new opens, URBs are aborted while chip is still valid, and
|
||||
snd_card_free_when_closed() is called last so chip is never accessed
|
||||
after the card may be freed.
|
||||
|
||||
Fixes: a0810c3d6dd2 ("ALSA: 6fire: Release resources at card release")
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: Andrey Konovalov <andreyknvl@gmail.com>
|
||||
Signed-off-by: Berk Cem Goksel <berkcgoksel@gmail.com>
|
||||
Link: https://patch.msgid.link/20260410051341.1069716-1-berkcgoksel@gmail.com
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
|
||||
Signed-off-by: CKI Backport Bot <cki-ci-bot+cki-gitlab-backport-bot@redhat.com>
|
||||
|
||||
diff --git a/sound/usb/6fire/chip.c b/sound/usb/6fire/chip.c
|
||||
index 5ff78814e687..874f6cd503ca 100644
|
||||
--- a/sound/usb/6fire/chip.c
|
||||
+++ b/sound/usb/6fire/chip.c
|
||||
@@ -53,11 +53,6 @@ static void usb6fire_chip_abort(struct sfire_chip *chip)
|
||||
usb6fire_comm_abort(chip);
|
||||
if (chip->control)
|
||||
usb6fire_control_abort(chip);
|
||||
- if (chip->card) {
|
||||
- snd_card_disconnect(chip->card);
|
||||
- snd_card_free_when_closed(chip->card);
|
||||
- chip->card = NULL;
|
||||
- }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -168,6 +163,7 @@ static int usb6fire_chip_probe(struct usb_interface *intf,
|
||||
static void usb6fire_chip_disconnect(struct usb_interface *intf)
|
||||
{
|
||||
struct sfire_chip *chip;
|
||||
+ struct snd_card *card;
|
||||
|
||||
chip = usb_get_intfdata(intf);
|
||||
if (chip) { /* if !chip, fw upload has been performed */
|
||||
@@ -178,8 +174,19 @@ static void usb6fire_chip_disconnect(struct usb_interface *intf)
|
||||
chips[chip->regidx] = NULL;
|
||||
}
|
||||
|
||||
+ /*
|
||||
+ * Save card pointer before teardown.
|
||||
+ * snd_card_free_when_closed() may free card (and
|
||||
+ * the embedded chip) immediately, so it must be
|
||||
+ * called last and chip must not be accessed after.
|
||||
+ */
|
||||
+ card = chip->card;
|
||||
chip->shutdown = true;
|
||||
+ if (card)
|
||||
+ snd_card_disconnect(card);
|
||||
usb6fire_chip_abort(chip);
|
||||
+ if (card)
|
||||
+ snd_card_free_when_closed(card);
|
||||
}
|
||||
}
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
54
1298-ip6-tunnel-clear-skb2-cb-in-ip4ip6-err.patch
Normal file
54
1298-ip6-tunnel-clear-skb2-cb-in-ip4ip6-err.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 1063515ce15ff31065c4e7f8265f4c2fd3c54876 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Thu, 26 Mar 2026 15:51:38 +0000
|
||||
Subject: [PATCH] ip6_tunnel: clear skb2->cb[] in ip4ip6_err()
|
||||
|
||||
[ Upstream commit 2edfa31769a4add828a7e604b21cb82aaaa05925 ]
|
||||
|
||||
Oskar Kjos reported the following problem.
|
||||
|
||||
ip4ip6_err() calls icmp_send() on a cloned skb whose cb[] was written
|
||||
by the IPv6 receive path as struct inet6_skb_parm. icmp_send() passes
|
||||
IPCB(skb2) to __ip_options_echo(), which interprets that cb[] region
|
||||
as struct inet_skb_parm (IPv4). The layouts differ: inet6_skb_parm.nhoff
|
||||
at offset 14 overlaps inet_skb_parm.opt.rr, producing a non-zero rr
|
||||
value. __ip_options_echo() then reads optlen from attacker-controlled
|
||||
packet data at sptr[rr+1] and copies that many bytes into dopt->__data,
|
||||
a fixed 40-byte stack buffer (IP_OPTIONS_DATA_FIXED_SIZE).
|
||||
|
||||
To fix this we clear skb2->cb[], as suggested by Oskar Kjos.
|
||||
|
||||
Also add minimal IPv4 header validation (version == 4, ihl >= 5).
|
||||
|
||||
Fixes: c4d3efafcc93 ("[IPV6] IP6TUNNEL: Add support to IPv4 over IPv6 tunnel.")
|
||||
Reported-by: Oskar Kjos <oskar.kjos@hotmail.com>
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
|
||||
Link: https://patch.msgid.link/20260326155138.2429480-1-edumazet@google.com
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Sasha Levin <sashal@kernel.org>
|
||||
|
||||
diff --git a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
|
||||
index 9f1b66bb513c..f0a8350eb52e 100644
|
||||
--- a/net/ipv6/ip6_tunnel.c
|
||||
+++ b/net/ipv6/ip6_tunnel.c
|
||||
@@ -601,11 +601,16 @@ ip4ip6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
|
||||
if (!skb2)
|
||||
return 0;
|
||||
|
||||
+ /* Remove debris left by IPv6 stack. */
|
||||
+ memset(IPCB(skb2), 0, sizeof(*IPCB(skb2)));
|
||||
+
|
||||
skb_dst_drop(skb2);
|
||||
|
||||
skb_pull(skb2, offset);
|
||||
skb_reset_network_header(skb2);
|
||||
eiph = ip_hdr(skb2);
|
||||
+ if (eiph->version != 4 || eiph->ihl < 5)
|
||||
+ goto out;
|
||||
|
||||
/* Try to guess incoming interface */
|
||||
rt = ip_route_output_ports(dev_net(skb->dev), &fl4, NULL, eiph->saddr,
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,79 @@
|
||||
From 4babc2d9fda2df43823b85d08a0180b68f1b0854 Mon Sep 17 00:00:00 2001
|
||||
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Date: Tue, 21 Apr 2026 15:16:33 +0200
|
||||
Subject: [PATCH] ipv6: rpl: reserve mac_len headroom when recompressed SRH
|
||||
grows
|
||||
|
||||
commit 9e6bf146b55999a095bb14f73a843942456d1adc upstream.
|
||||
|
||||
ipv6_rpl_srh_rcv() decompresses an RFC 6554 Source Routing Header, swaps
|
||||
the next segment into ipv6_hdr->daddr, recompresses, then pulls the old
|
||||
header and pushes the new one plus the IPv6 header back. The
|
||||
recompressed header can be larger than the received one when the swap
|
||||
reduces the common-prefix length the segments share with daddr (CmprI=0,
|
||||
CmprE>0, seg[0][0] != daddr[0] gives the maximum +8 bytes).
|
||||
|
||||
pskb_expand_head() was gated on segments_left == 0, so on earlier
|
||||
segments the push consumed unchecked headroom. Once skb_push() leaves
|
||||
fewer than skb->mac_len bytes in front of data,
|
||||
skb_mac_header_rebuild()'s call to:
|
||||
|
||||
skb_set_mac_header(skb, -skb->mac_len);
|
||||
|
||||
will store (data - head) - mac_len into the u16 mac_header field, which
|
||||
wraps to ~65530, and the following memmove() writes mac_len bytes ~64KiB
|
||||
past skb->head.
|
||||
|
||||
A single AF_INET6/SOCK_RAW/IPV6_HDRINCL packet over lo with a two
|
||||
segment type-3 SRH (CmprI=0, CmprE=15) reaches headroom 8 after one
|
||||
pass; KASAN reports a 14-byte OOB write in ipv6_rthdr_rcv.
|
||||
|
||||
Fix this by expanding the head whenever the remaining room is less than
|
||||
the push size plus mac_len, and request that much extra so the rebuilt
|
||||
MAC header fits afterwards.
|
||||
|
||||
Fixes: 8610c7c6e3bd ("net: ipv6: add support for rpl sr exthdr")
|
||||
Cc: stable <stable@kernel.org>
|
||||
Reported-by: Anthropic
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Link: https://patch.msgid.link/2026042133-gout-unvented-1bd9@gregkh
|
||||
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
|
||||
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
|
||||
index 8a30dd83cf0b..d09ae48030b3 100644
|
||||
--- a/net/ipv6/exthdrs.c
|
||||
+++ b/net/ipv6/exthdrs.c
|
||||
@@ -491,6 +491,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
|
||||
struct net *net = dev_net(skb->dev);
|
||||
struct inet6_dev *idev;
|
||||
struct ipv6hdr *oldhdr;
|
||||
+ unsigned int chdr_len;
|
||||
unsigned char *buf;
|
||||
int accept_rpl_seg;
|
||||
int i, err;
|
||||
@@ -594,8 +595,10 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
|
||||
skb_pull(skb, ((hdr->hdrlen + 1) << 3));
|
||||
skb_postpull_rcsum(skb, oldhdr,
|
||||
sizeof(struct ipv6hdr) + ((hdr->hdrlen + 1) << 3));
|
||||
- if (unlikely(!hdr->segments_left)) {
|
||||
- if (pskb_expand_head(skb, sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3), 0,
|
||||
+ chdr_len = sizeof(struct ipv6hdr) + ((chdr->hdrlen + 1) << 3);
|
||||
+ if (unlikely(!hdr->segments_left ||
|
||||
+ skb_headroom(skb) < chdr_len + skb->mac_len)) {
|
||||
+ if (pskb_expand_head(skb, chdr_len + skb->mac_len, 0,
|
||||
GFP_ATOMIC)) {
|
||||
__IP6_INC_STATS(net, ip6_dst_idev(skb_dst(skb)), IPSTATS_MIB_OUTDISCARDS);
|
||||
kfree_skb(skb);
|
||||
@@ -605,7 +608,7 @@ static int ipv6_rpl_srh_rcv(struct sk_buff *skb)
|
||||
|
||||
oldhdr = ipv6_hdr(skb);
|
||||
}
|
||||
- skb_push(skb, ((chdr->hdrlen + 1) << 3) + sizeof(struct ipv6hdr));
|
||||
+ skb_push(skb, chdr_len);
|
||||
skb_reset_network_header(skb);
|
||||
skb_mac_header_rebuild(skb);
|
||||
skb_set_transport_header(skb, sizeof(struct ipv6hdr));
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
119
1300-fs-constify-file-ptr-in-backing-file-accessor-helpers.patch
Normal file
119
1300-fs-constify-file-ptr-in-backing-file-accessor-helpers.patch
Normal file
@ -0,0 +1,119 @@
|
||||
From 95ceb7510d751e76b068573ecbb2030cbd73852b Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 11:09:13 +0200
|
||||
Subject: [PATCH] fs: constify file ptr in backing_file accessor helpers
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
|
||||
commit 4e301d858af17ae2ce56886296e5458c5a08219a
|
||||
Author: Amir Goldstein <amir73il@gmail.com>
|
||||
Date: Sat Jun 7 13:53:03 2025 +0200
|
||||
|
||||
fs: constify file ptr in backing_file accessor helpers
|
||||
|
||||
Add internal helper backing_file_set_user_path() for the only
|
||||
two cases that need to modify backing_file fields.
|
||||
|
||||
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
|
||||
Link: https://lore.kernel.org/20250607115304.2521155-2-amir73il@gmail.com
|
||||
Signed-off-by: Christian Brauner <brauner@kernel.org>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/fs/backing-file.c b/fs/backing-file.c
|
||||
index 09a9be945d45..892361c31c3d 100644
|
||||
--- a/fs/backing-file.c
|
||||
+++ b/fs/backing-file.c
|
||||
@@ -41,7 +41,7 @@ struct file *backing_file_open(const struct path *user_path, int flags,
|
||||
return f;
|
||||
|
||||
path_get(user_path);
|
||||
- *backing_file_user_path(f) = *user_path;
|
||||
+ backing_file_set_user_path(f, user_path);
|
||||
error = vfs_open(real_path, f);
|
||||
if (error) {
|
||||
fput(f);
|
||||
@@ -65,7 +65,7 @@ struct file *backing_tmpfile_open(const struct path *user_path, int flags,
|
||||
return f;
|
||||
|
||||
path_get(user_path);
|
||||
- *backing_file_user_path(f) = *user_path;
|
||||
+ backing_file_set_user_path(f, user_path);
|
||||
error = vfs_tmpfile(real_idmap, real_parentpath, f, mode);
|
||||
if (error) {
|
||||
fput(f);
|
||||
diff --git a/fs/file_table.c b/fs/file_table.c
|
||||
index 15a3593c6ece..9979efb9a380 100644
|
||||
--- a/fs/file_table.c
|
||||
+++ b/fs/file_table.c
|
||||
@@ -53,17 +53,20 @@ struct backing_file {
|
||||
};
|
||||
};
|
||||
|
||||
-static inline struct backing_file *backing_file(struct file *f)
|
||||
-{
|
||||
- return container_of(f, struct backing_file, file);
|
||||
-}
|
||||
+#define backing_file(f) container_of(f, struct backing_file, file)
|
||||
|
||||
-struct path *backing_file_user_path(struct file *f)
|
||||
+struct path *backing_file_user_path(const struct file *f)
|
||||
{
|
||||
return &backing_file(f)->user_path;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(backing_file_user_path);
|
||||
|
||||
+void backing_file_set_user_path(struct file *f, const struct path *path)
|
||||
+{
|
||||
+ backing_file(f)->user_path = *path;
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(backing_file_set_user_path);
|
||||
+
|
||||
static inline void file_free(struct file *f)
|
||||
{
|
||||
security_file_free(f);
|
||||
diff --git a/fs/internal.h b/fs/internal.h
|
||||
index dd13dfde4adb..67e2e164c647 100644
|
||||
--- a/fs/internal.h
|
||||
+++ b/fs/internal.h
|
||||
@@ -100,6 +100,7 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
|
||||
struct file *alloc_empty_file(int flags, const struct cred *cred);
|
||||
struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred);
|
||||
struct file *alloc_empty_backing_file(int flags, const struct cred *cred);
|
||||
+void backing_file_set_user_path(struct file *f, const struct path *path);
|
||||
|
||||
static inline void file_put_write_access(struct file *file)
|
||||
{
|
||||
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
||||
index 83ddabaa0ac3..04309befc557 100644
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -2793,7 +2793,7 @@ struct file *dentry_open(const struct path *path, int flags,
|
||||
const struct cred *creds);
|
||||
struct file *dentry_create(const struct path *path, int flags, umode_t mode,
|
||||
const struct cred *cred);
|
||||
-struct path *backing_file_user_path(struct file *f);
|
||||
+struct path *backing_file_user_path(const struct file *f);
|
||||
|
||||
/*
|
||||
* When mmapping a file on a stackable filesystem (e.g., overlayfs), the file
|
||||
@@ -2805,14 +2805,14 @@ struct path *backing_file_user_path(struct file *f);
|
||||
* by fstat() on that same fd.
|
||||
*/
|
||||
/* Get the path to display in /proc/<pid>/maps */
|
||||
-static inline const struct path *file_user_path(struct file *f)
|
||||
+static inline const struct path *file_user_path(const struct file *f)
|
||||
{
|
||||
if (unlikely(f->f_mode & FMODE_BACKING))
|
||||
return backing_file_user_path(f);
|
||||
return &f->f_path;
|
||||
}
|
||||
/* Get the inode whose inode number to display in /proc/<pid>/maps */
|
||||
-static inline const struct inode *file_user_inode(struct file *f)
|
||||
+static inline const struct inode *file_user_inode(const struct file *f)
|
||||
{
|
||||
if (unlikely(f->f_mode & FMODE_BACKING))
|
||||
return d_inode(backing_file_user_path(f)->dentry);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
122
1301-lsm-split-the-notifier-code-out-into-lsm-notifier-c.patch
Normal file
122
1301-lsm-split-the-notifier-code-out-into-lsm-notifier-c.patch
Normal file
@ -0,0 +1,122 @@
|
||||
From 6a5de58e1181a41f95ac002a27d95f1dbf5933c9 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Fri, 29 May 2026 17:24:58 +0200
|
||||
Subject: [PATCH] lsm: split the notifier code out into lsm_notifier.c
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit a5e7c17c810052e94dae36f1a976a052f4490458
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Mon Feb 10 19:20:58 2025 -0500
|
||||
|
||||
lsm: split the notifier code out into lsm_notifier.c
|
||||
|
||||
In an effort to decompose security/security.c somewhat to make it less
|
||||
twisted and unwieldy, pull out the LSM notifier code into a new file
|
||||
as it is fairly well self-contained.
|
||||
|
||||
No code changes.
|
||||
|
||||
Reviewed-by: Kees Cook <kees@kernel.org>
|
||||
Reviewed-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/Makefile b/security/Makefile
|
||||
index cc0982214b84..c7a3f1cb2fd5 100644
|
||||
--- a/security/Makefile
|
||||
+++ b/security/Makefile
|
||||
@@ -11,7 +11,7 @@ obj-$(CONFIG_SECURITY) += lsm_syscalls.o
|
||||
obj-$(CONFIG_MMU) += min_addr.o
|
||||
|
||||
# Object file lists
|
||||
-obj-$(CONFIG_SECURITY) += security.o
|
||||
+obj-$(CONFIG_SECURITY) += security.o lsm_notifier.o
|
||||
obj-$(CONFIG_SECURITYFS) += inode.o
|
||||
obj-$(CONFIG_SECURITY_SELINUX) += selinux/
|
||||
obj-$(CONFIG_SECURITY_SMACK) += smack/
|
||||
diff --git a/security/lsm_notifier.c b/security/lsm_notifier.c
|
||||
new file mode 100644
|
||||
index 000000000000..c92fad5d57d4
|
||||
--- /dev/null
|
||||
+++ b/security/lsm_notifier.c
|
||||
@@ -0,0 +1,31 @@
|
||||
+// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
+/*
|
||||
+ * LSM notifier functions
|
||||
+ *
|
||||
+ */
|
||||
+
|
||||
+#include <linux/notifier.h>
|
||||
+#include <linux/security.h>
|
||||
+
|
||||
+static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
|
||||
+
|
||||
+int call_blocking_lsm_notifier(enum lsm_event event, void *data)
|
||||
+{
|
||||
+ return blocking_notifier_call_chain(&blocking_lsm_notifier_chain,
|
||||
+ event, data);
|
||||
+}
|
||||
+EXPORT_SYMBOL(call_blocking_lsm_notifier);
|
||||
+
|
||||
+int register_blocking_lsm_notifier(struct notifier_block *nb)
|
||||
+{
|
||||
+ return blocking_notifier_chain_register(&blocking_lsm_notifier_chain,
|
||||
+ nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL(register_blocking_lsm_notifier);
|
||||
+
|
||||
+int unregister_blocking_lsm_notifier(struct notifier_block *nb)
|
||||
+{
|
||||
+ return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain,
|
||||
+ nb);
|
||||
+}
|
||||
+EXPORT_SYMBOL(unregister_blocking_lsm_notifier);
|
||||
diff --git a/security/security.c b/security/security.c
|
||||
index 4535ba7d0208..9a5f9a2f8ff3 100644
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -91,8 +91,6 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
|
||||
[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
|
||||
};
|
||||
|
||||
-static BLOCKING_NOTIFIER_HEAD(blocking_lsm_notifier_chain);
|
||||
-
|
||||
static struct kmem_cache *lsm_file_cache;
|
||||
static struct kmem_cache *lsm_inode_cache;
|
||||
|
||||
@@ -649,27 +647,6 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
||||
}
|
||||
}
|
||||
|
||||
-int call_blocking_lsm_notifier(enum lsm_event event, void *data)
|
||||
-{
|
||||
- return blocking_notifier_call_chain(&blocking_lsm_notifier_chain,
|
||||
- event, data);
|
||||
-}
|
||||
-EXPORT_SYMBOL(call_blocking_lsm_notifier);
|
||||
-
|
||||
-int register_blocking_lsm_notifier(struct notifier_block *nb)
|
||||
-{
|
||||
- return blocking_notifier_chain_register(&blocking_lsm_notifier_chain,
|
||||
- nb);
|
||||
-}
|
||||
-EXPORT_SYMBOL(register_blocking_lsm_notifier);
|
||||
-
|
||||
-int unregister_blocking_lsm_notifier(struct notifier_block *nb)
|
||||
-{
|
||||
- return blocking_notifier_chain_unregister(&blocking_lsm_notifier_chain,
|
||||
- nb);
|
||||
-}
|
||||
-EXPORT_SYMBOL(unregister_blocking_lsm_notifier);
|
||||
-
|
||||
/**
|
||||
* lsm_blob_alloc - allocate a composite blob
|
||||
* @dest: the destination for the blob
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
1301
1302-lsm-split-the-init-code-out-into-lsm-init-c.patch
Normal file
1301
1302-lsm-split-the-init-code-out-into-lsm-init-c.patch
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,167 @@
|
||||
From 204c54d19e2c1e71bf75a49bb07d965bee634401 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Fri, 29 May 2026 17:43:36 +0200
|
||||
Subject: [PATCH] lsm: consolidate lsm_allowed() and prepare_lsm() into
|
||||
lsm_prepare()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- conflict due to 5816bf4273ed ("lsm,selinux: Add LSM blob support for
|
||||
BPF objects"), which is not backported
|
||||
|
||||
commit e02578561d47567be26e603c6d27c10a5aa4c2c4
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Tue Feb 11 12:19:47 2025 -0500
|
||||
|
||||
lsm: consolidate lsm_allowed() and prepare_lsm() into lsm_prepare()
|
||||
|
||||
Simplify and consolidate the lsm_allowed() and prepare_lsm() functions
|
||||
into a new function, lsm_prepare().
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index aa64e3437d25..719835ec8f0a 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -123,22 +123,6 @@ static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
|
||||
is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
-/* Is an LSM allowed to be initialized? */
|
||||
-static bool __init lsm_allowed(struct lsm_info *lsm)
|
||||
-{
|
||||
- /* Skip if the LSM is disabled. */
|
||||
- if (!is_enabled(lsm))
|
||||
- return false;
|
||||
-
|
||||
- /* Not allowed if another exclusive LSM already initialized. */
|
||||
- if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) {
|
||||
- init_debug("exclusive disabled: %s\n", lsm->name);
|
||||
- return false;
|
||||
- }
|
||||
-
|
||||
- return true;
|
||||
-}
|
||||
-
|
||||
static void __init lsm_set_blob_size(int *need, int *lbs)
|
||||
{
|
||||
int offset;
|
||||
@@ -151,51 +135,50 @@ static void __init lsm_set_blob_size(int *need, int *lbs)
|
||||
*need = offset;
|
||||
}
|
||||
|
||||
-static void __init lsm_set_blob_sizes(struct lsm_blob_sizes *needed)
|
||||
+/**
|
||||
+ * lsm_prepare - Prepare the LSM framework for a new LSM
|
||||
+ * @lsm: LSM definition
|
||||
+ */
|
||||
+static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
{
|
||||
- if (!needed)
|
||||
+ struct lsm_blob_sizes *blobs;
|
||||
+
|
||||
+ if (!is_enabled(lsm)) {
|
||||
+ set_enabled(lsm, false);
|
||||
return;
|
||||
+ } else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) {
|
||||
+ init_debug("exclusive disabled: %s\n", lsm->name);
|
||||
+ set_enabled(lsm, false);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- lsm_set_blob_size(&needed->lbs_cred, &blob_sizes.lbs_cred);
|
||||
- lsm_set_blob_size(&needed->lbs_file, &blob_sizes.lbs_file);
|
||||
- lsm_set_blob_size(&needed->lbs_ib, &blob_sizes.lbs_ib);
|
||||
- /*
|
||||
- * The inode blob gets an rcu_head in addition to
|
||||
- * what the modules might need.
|
||||
- */
|
||||
- if (needed->lbs_inode && blob_sizes.lbs_inode == 0)
|
||||
+ /* Mark the LSM as enabled. */
|
||||
+ set_enabled(lsm, true);
|
||||
+ if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
|
||||
+ init_debug("exclusive chosen: %s\n", lsm->name);
|
||||
+ exclusive = lsm;
|
||||
+ }
|
||||
+
|
||||
+ /* Register the LSM blob sizes. */
|
||||
+ blobs = lsm->blobs;
|
||||
+ lsm_set_blob_size(&blobs->lbs_cred, &blob_sizes.lbs_cred);
|
||||
+ lsm_set_blob_size(&blobs->lbs_file, &blob_sizes.lbs_file);
|
||||
+ lsm_set_blob_size(&blobs->lbs_ib, &blob_sizes.lbs_ib);
|
||||
+ /* inode blob gets an rcu_head in addition to LSM blobs. */
|
||||
+ if (blobs->lbs_inode && blob_sizes.lbs_inode == 0)
|
||||
blob_sizes.lbs_inode = sizeof(struct rcu_head);
|
||||
- lsm_set_blob_size(&needed->lbs_inode, &blob_sizes.lbs_inode);
|
||||
- lsm_set_blob_size(&needed->lbs_ipc, &blob_sizes.lbs_ipc);
|
||||
- lsm_set_blob_size(&needed->lbs_key, &blob_sizes.lbs_key);
|
||||
- lsm_set_blob_size(&needed->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
|
||||
- lsm_set_blob_size(&needed->lbs_perf_event, &blob_sizes.lbs_perf_event);
|
||||
- lsm_set_blob_size(&needed->lbs_sock, &blob_sizes.lbs_sock);
|
||||
- lsm_set_blob_size(&needed->lbs_superblock, &blob_sizes.lbs_superblock);
|
||||
- lsm_set_blob_size(&needed->lbs_task, &blob_sizes.lbs_task);
|
||||
- lsm_set_blob_size(&needed->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
|
||||
- lsm_set_blob_size(&needed->lbs_xattr_count,
|
||||
+ lsm_set_blob_size(&blobs->lbs_inode, &blob_sizes.lbs_inode);
|
||||
+ lsm_set_blob_size(&blobs->lbs_ipc, &blob_sizes.lbs_ipc);
|
||||
+ lsm_set_blob_size(&blobs->lbs_key, &blob_sizes.lbs_key);
|
||||
+ lsm_set_blob_size(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
|
||||
+ lsm_set_blob_size(&blobs->lbs_perf_event, &blob_sizes.lbs_perf_event);
|
||||
+ lsm_set_blob_size(&blobs->lbs_sock, &blob_sizes.lbs_sock);
|
||||
+ lsm_set_blob_size(&blobs->lbs_superblock, &blob_sizes.lbs_superblock);
|
||||
+ lsm_set_blob_size(&blobs->lbs_task, &blob_sizes.lbs_task);
|
||||
+ lsm_set_blob_size(&blobs->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
|
||||
+ lsm_set_blob_size(&blobs->lbs_xattr_count,
|
||||
&blob_sizes.lbs_xattr_count);
|
||||
- lsm_set_blob_size(&needed->lbs_bdev, &blob_sizes.lbs_bdev);
|
||||
-}
|
||||
-
|
||||
-/* Prepare LSM for initialization. */
|
||||
-static void __init prepare_lsm(struct lsm_info *lsm)
|
||||
-{
|
||||
- int enabled = lsm_allowed(lsm);
|
||||
-
|
||||
- /* Record enablement (to handle any following exclusive LSMs). */
|
||||
- set_enabled(lsm, enabled);
|
||||
-
|
||||
- /* If enabled, do pre-initialization work. */
|
||||
- if (enabled) {
|
||||
- if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
|
||||
- exclusive = lsm;
|
||||
- init_debug("exclusive chosen: %s\n", lsm->name);
|
||||
- }
|
||||
-
|
||||
- lsm_set_blob_sizes(lsm->blobs);
|
||||
- }
|
||||
+ lsm_set_blob_size(&blobs->lbs_bdev, &blob_sizes.lbs_bdev);
|
||||
}
|
||||
|
||||
/* Initialize a given LSM, if it is enabled. */
|
||||
@@ -358,7 +341,7 @@ static void __init ordered_lsm_init(void)
|
||||
ordered_lsm_parse(builtin_lsm_order, "builtin");
|
||||
|
||||
for (lsm = ordered_lsms; *lsm; lsm++)
|
||||
- prepare_lsm(*lsm);
|
||||
+ lsm_prepare(*lsm);
|
||||
|
||||
report_lsm_order();
|
||||
|
||||
@@ -503,7 +486,7 @@ int __init early_security_init(void)
|
||||
for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
|
||||
if (!lsm->enabled)
|
||||
lsm->enabled = &lsm_enabled_true;
|
||||
- prepare_lsm(lsm);
|
||||
+ lsm_prepare(lsm);
|
||||
initialize_lsm(lsm);
|
||||
}
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,172 @@
|
||||
From 92ed776aa54bac14d013ad9b08ad44b7ed8af0ea Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Fri, 29 May 2026 18:31:38 +0200
|
||||
Subject: [PATCH] lsm: introduce looping macros for the initialization code
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 37f788f65528611f4482e2135d11ca34afb25828
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Apr 9 17:59:42 2025 -0400
|
||||
|
||||
lsm: introduce looping macros for the initialization code
|
||||
|
||||
There are three common for loop patterns in the LSM initialization code
|
||||
to loop through the ordered LSM list and the registered "early" LSMs.
|
||||
This patch implements these loop patterns as macros to help simplify the
|
||||
code and reduce the chance for errors.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 719835ec8f0a..2424975ca0eb 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -32,6 +32,15 @@ static __initdata bool debug;
|
||||
pr_info(__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
+#define lsm_order_for_each(iter) \
|
||||
+ for ((iter) = ordered_lsms; *(iter); (iter)++)
|
||||
+#define lsm_for_each_raw(iter) \
|
||||
+ for ((iter) = __start_lsm_info; \
|
||||
+ (iter) < __end_lsm_info; (iter)++)
|
||||
+#define lsm_early_for_each_raw(iter) \
|
||||
+ for ((iter) = __start_early_lsm_info; \
|
||||
+ (iter) < __end_early_lsm_info; (iter)++)
|
||||
+
|
||||
static int lsm_append(const char *new, char **result);
|
||||
|
||||
/* Save user chosen LSM */
|
||||
@@ -96,9 +105,10 @@ static bool __init exists_ordered_lsm(struct lsm_info *lsm)
|
||||
{
|
||||
struct lsm_info **check;
|
||||
|
||||
- for (check = ordered_lsms; *check; check++)
|
||||
+ lsm_order_for_each(check) {
|
||||
if (*check == lsm)
|
||||
return true;
|
||||
+ }
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -206,7 +216,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
char *sep, *name, *next;
|
||||
|
||||
/* LSM_ORDER_FIRST is always first. */
|
||||
- for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
if (lsm->order == LSM_ORDER_FIRST)
|
||||
append_ordered_lsm(lsm, " first");
|
||||
}
|
||||
@@ -221,8 +231,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
* if the selected one was separately disabled: disable
|
||||
* all non-matching Legacy Major LSMs.
|
||||
*/
|
||||
- for (major = __start_lsm_info; major < __end_lsm_info;
|
||||
- major++) {
|
||||
+ lsm_for_each_raw(major) {
|
||||
if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
strcmp(major->name, chosen_major_lsm) != 0) {
|
||||
set_enabled(major, false);
|
||||
@@ -238,7 +247,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
while ((name = strsep(&next, ",")) != NULL) {
|
||||
bool found = false;
|
||||
|
||||
- for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
if (strcmp(lsm->name, name) == 0) {
|
||||
if (lsm->order == LSM_ORDER_MUTABLE)
|
||||
append_ordered_lsm(lsm, origin);
|
||||
@@ -253,7 +262,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
|
||||
/* Process "security=", if given. */
|
||||
if (chosen_major_lsm) {
|
||||
- for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
if (exists_ordered_lsm(lsm))
|
||||
continue;
|
||||
if (strcmp(lsm->name, chosen_major_lsm) == 0)
|
||||
@@ -262,13 +271,13 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
}
|
||||
|
||||
/* LSM_ORDER_LAST is always last. */
|
||||
- for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
if (lsm->order == LSM_ORDER_LAST)
|
||||
append_ordered_lsm(lsm, " last");
|
||||
}
|
||||
|
||||
/* Disable all LSMs not in the ordered list. */
|
||||
- for (lsm = __start_lsm_info; lsm < __end_lsm_info; lsm++) {
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
if (exists_ordered_lsm(lsm))
|
||||
continue;
|
||||
set_enabled(lsm, false);
|
||||
@@ -287,13 +296,14 @@ static void __init report_lsm_order(void)
|
||||
pr_info("initializing lsm=");
|
||||
|
||||
/* Report each enabled LSM name, comma separated. */
|
||||
- for (early = __start_early_lsm_info;
|
||||
- early < __end_early_lsm_info; early++)
|
||||
+ lsm_early_for_each_raw(early) {
|
||||
if (is_enabled(early))
|
||||
pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
|
||||
- for (lsm = ordered_lsms; *lsm; lsm++)
|
||||
+ }
|
||||
+ lsm_order_for_each(lsm) {
|
||||
if (is_enabled(*lsm))
|
||||
pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name);
|
||||
+ }
|
||||
|
||||
pr_cont("\n");
|
||||
}
|
||||
@@ -340,8 +350,9 @@ static void __init ordered_lsm_init(void)
|
||||
} else
|
||||
ordered_lsm_parse(builtin_lsm_order, "builtin");
|
||||
|
||||
- for (lsm = ordered_lsms; *lsm; lsm++)
|
||||
+ lsm_order_for_each(lsm) {
|
||||
lsm_prepare(*lsm);
|
||||
+ }
|
||||
|
||||
report_lsm_order();
|
||||
|
||||
@@ -376,8 +387,9 @@ static void __init ordered_lsm_init(void)
|
||||
|
||||
lsm_early_cred((struct cred *) current->cred);
|
||||
lsm_early_task(current);
|
||||
- for (lsm = ordered_lsms; *lsm; lsm++)
|
||||
+ lsm_order_for_each(lsm) {
|
||||
initialize_lsm(*lsm);
|
||||
+ }
|
||||
}
|
||||
|
||||
static bool match_last_lsm(const char *list, const char *lsm)
|
||||
@@ -483,7 +495,7 @@ int __init early_security_init(void)
|
||||
if (early_security_initialized)
|
||||
return 0;
|
||||
|
||||
- for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
|
||||
+ lsm_early_for_each_raw(lsm) {
|
||||
if (!lsm->enabled)
|
||||
lsm->enabled = &lsm_enabled_true;
|
||||
lsm_prepare(lsm);
|
||||
@@ -511,7 +523,7 @@ int __init security_init(void)
|
||||
* Append the names of the early LSM modules now that kmalloc() is
|
||||
* available
|
||||
*/
|
||||
- for (lsm = __start_early_lsm_info; lsm < __end_early_lsm_info; lsm++) {
|
||||
+ lsm_early_for_each_raw(lsm) {
|
||||
init_debug(" early started: %s (%s)\n", lsm->name,
|
||||
is_enabled(lsm) ? "enabled" : "disabled");
|
||||
if (lsm->enabled)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
86
1305-lsm-integrate-report-lsm-order-code-into-caller.patch
Normal file
86
1305-lsm-integrate-report-lsm-order-code-into-caller.patch
Normal file
@ -0,0 +1,86 @@
|
||||
From 4190f2549074d006122a76cdcb2a5b361d59d650 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:31 +0200
|
||||
Subject: [PATCH] lsm: integrate report_lsm_order() code into caller
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit cb1513db7a6ed82d22853608d78bbf72ad8c67c1
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Sat Jul 12 16:10:15 2025 -0400
|
||||
|
||||
lsm: integrate report_lsm_order() code into caller
|
||||
|
||||
With only one caller of report_lsm_order(), insert the function's code
|
||||
directly into the caller and ger rid of report_lsm_order().
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 2424975ca0eb..fc40d37c3321 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -288,26 +288,6 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
kfree(sep);
|
||||
}
|
||||
|
||||
-static void __init report_lsm_order(void)
|
||||
-{
|
||||
- struct lsm_info **lsm, *early;
|
||||
- int first = 0;
|
||||
-
|
||||
- pr_info("initializing lsm=");
|
||||
-
|
||||
- /* Report each enabled LSM name, comma separated. */
|
||||
- lsm_early_for_each_raw(early) {
|
||||
- if (is_enabled(early))
|
||||
- pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
|
||||
- }
|
||||
- lsm_order_for_each(lsm) {
|
||||
- if (is_enabled(*lsm))
|
||||
- pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name);
|
||||
- }
|
||||
-
|
||||
- pr_cont("\n");
|
||||
-}
|
||||
-
|
||||
/**
|
||||
* lsm_early_cred - during initialization allocate a composite cred blob
|
||||
* @cred: the cred that needs a blob
|
||||
@@ -338,7 +318,9 @@ static void __init lsm_early_task(struct task_struct *task)
|
||||
|
||||
static void __init ordered_lsm_init(void)
|
||||
{
|
||||
+ unsigned int first = 0;
|
||||
struct lsm_info **lsm;
|
||||
+ struct lsm_info *early;
|
||||
|
||||
if (chosen_lsm_order) {
|
||||
if (chosen_major_lsm) {
|
||||
@@ -354,7 +336,16 @@ static void __init ordered_lsm_init(void)
|
||||
lsm_prepare(*lsm);
|
||||
}
|
||||
|
||||
- report_lsm_order();
|
||||
+ pr_info("initializing lsm=");
|
||||
+ lsm_early_for_each_raw(early) {
|
||||
+ if (is_enabled(early))
|
||||
+ pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
|
||||
+ }
|
||||
+ lsm_order_for_each(lsm) {
|
||||
+ if (is_enabled(*lsm))
|
||||
+ pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name);
|
||||
+ }
|
||||
+ pr_cont("\n");
|
||||
|
||||
init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
|
||||
init_debug("file blob size = %d\n", blob_sizes.lbs_file);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,82 @@
|
||||
From 7a7bb4c213345231e80b7545d00bcee30e62fd94 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:32 +0200
|
||||
Subject: [PATCH] lsm: integrate lsm_early_cred() and lsm_early_task() into
|
||||
caller
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 92ed3500c9a91f43e094c9b8fb4bab9976565d74
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Sat Jul 12 16:27:39 2025 -0400
|
||||
|
||||
lsm: integrate lsm_early_cred() and lsm_early_task() into caller
|
||||
|
||||
With only one caller of lsm_early_cred() and lsm_early_task(), insert
|
||||
the functions' code directly into the caller and ger rid of the two
|
||||
functions.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index fc40d37c3321..19eac2b39f2b 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -288,34 +288,6 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
kfree(sep);
|
||||
}
|
||||
|
||||
-/**
|
||||
- * lsm_early_cred - during initialization allocate a composite cred blob
|
||||
- * @cred: the cred that needs a blob
|
||||
- *
|
||||
- * Allocate the cred blob for all the modules
|
||||
- */
|
||||
-static void __init lsm_early_cred(struct cred *cred)
|
||||
-{
|
||||
- int rc = lsm_cred_alloc(cred, GFP_KERNEL);
|
||||
-
|
||||
- if (rc)
|
||||
- panic("%s: Early cred alloc failed.\n", __func__);
|
||||
-}
|
||||
-
|
||||
-/**
|
||||
- * lsm_early_task - during initialization allocate a composite task blob
|
||||
- * @task: the task that needs a blob
|
||||
- *
|
||||
- * Allocate the task blob for all the modules
|
||||
- */
|
||||
-static void __init lsm_early_task(struct task_struct *task)
|
||||
-{
|
||||
- int rc = lsm_task_alloc(task);
|
||||
-
|
||||
- if (rc)
|
||||
- panic("%s: Early task alloc failed.\n", __func__);
|
||||
-}
|
||||
-
|
||||
static void __init ordered_lsm_init(void)
|
||||
{
|
||||
unsigned int first = 0;
|
||||
@@ -376,8 +348,11 @@ static void __init ordered_lsm_init(void)
|
||||
blob_sizes.lbs_inode, 0,
|
||||
SLAB_PANIC, NULL);
|
||||
|
||||
- lsm_early_cred((struct cred *) current->cred);
|
||||
- lsm_early_task(current);
|
||||
+ if (lsm_cred_alloc((struct cred __rcu *)current->cred, GFP_KERNEL))
|
||||
+ panic("%s: early cred alloc failed.\n", __func__);
|
||||
+ if (lsm_task_alloc(current))
|
||||
+ panic("%s: early task alloc failed.\n", __func__);
|
||||
+
|
||||
lsm_order_for_each(lsm) {
|
||||
initialize_lsm(*lsm);
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
63
1307-lsm-rename-ordered-lsm-init-to-lsm-init-ordered.patch
Normal file
63
1307-lsm-rename-ordered-lsm-init-to-lsm-init-ordered.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From c2e5c69d0c70768dc6cd10ab0a5704ebb2545967 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:32 +0200
|
||||
Subject: [PATCH] lsm: rename ordered_lsm_init() to lsm_init_ordered()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit faabedcd6e88ca1f65ef45d711d2e0c7288fd551
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Tue Feb 11 12:59:30 2025 -0500
|
||||
|
||||
lsm: rename ordered_lsm_init() to lsm_init_ordered()
|
||||
|
||||
The new name more closely fits the rest of the naming scheme in
|
||||
security/lsm_init.c. This patch also adds a trivial comment block to
|
||||
the top of the function.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 19eac2b39f2b..a590a785f724 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -288,7 +288,10 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
kfree(sep);
|
||||
}
|
||||
|
||||
-static void __init ordered_lsm_init(void)
|
||||
+/**
|
||||
+ * lsm_init_ordered - Initialize the ordered LSMs
|
||||
+ */
|
||||
+static void __init lsm_init_ordered(void)
|
||||
{
|
||||
unsigned int first = 0;
|
||||
struct lsm_info **lsm;
|
||||
@@ -336,9 +339,6 @@ static void __init ordered_lsm_init(void)
|
||||
init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
|
||||
init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
|
||||
|
||||
- /*
|
||||
- * Create any kmem_caches needed for blobs
|
||||
- */
|
||||
if (blob_sizes.lbs_file)
|
||||
lsm_file_cache = kmem_cache_create("lsm_file_cache",
|
||||
blob_sizes.lbs_file, 0,
|
||||
@@ -497,7 +497,7 @@ int __init security_init(void)
|
||||
}
|
||||
|
||||
/* Load LSMs in specified order. */
|
||||
- ordered_lsm_init();
|
||||
+ lsm_init_ordered();
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,363 @@
|
||||
From 369918c7a55af0dc1d94780d5fde14536636ace1 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:33 +0200
|
||||
Subject: [PATCH] lsm: replace the name field with a pointer to the lsm_id
|
||||
struct
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 9f9dc69e06ecbc61e7a50b823b82a78daf130dc0
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Feb 12 14:45:06 2025 -0500
|
||||
|
||||
lsm: replace the name field with a pointer to the lsm_id struct
|
||||
|
||||
Reduce the duplication between the lsm_id struct and the DEFINE_LSM()
|
||||
definition by linking the lsm_id struct directly into the individual
|
||||
LSM's DEFINE_LSM() instance.
|
||||
|
||||
Linking the lsm_id into the LSM definition also allows us to simplify
|
||||
the security_add_hooks() function by removing the code which populates
|
||||
the lsm_idlist[] array and moving it into the normal LSM startup code
|
||||
where the LSM list is parsed and the individual LSMs are enabled,
|
||||
making for a cleaner implementation with less overhead at boot.
|
||||
|
||||
Reviewed-by: Kees Cook <kees@kernel.org>
|
||||
Reviewed-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
|
||||
index eeb4bfd60b79..4cd17c9a229f 100644
|
||||
--- a/include/linux/lsm_hooks.h
|
||||
+++ b/include/linux/lsm_hooks.h
|
||||
@@ -149,7 +149,7 @@ enum lsm_order {
|
||||
};
|
||||
|
||||
struct lsm_info {
|
||||
- const char *name; /* Required. */
|
||||
+ const struct lsm_id *id;
|
||||
enum lsm_order order; /* Optional: default is LSM_ORDER_MUTABLE */
|
||||
unsigned long flags; /* Optional: flags describing LSM */
|
||||
int *enabled; /* Optional: controlled by CONFIG_LSM */
|
||||
diff --git a/security/apparmor/lsm.c b/security/apparmor/lsm.c
|
||||
index 248d68624b35..6b5742e60454 100644
|
||||
--- a/security/apparmor/lsm.c
|
||||
+++ b/security/apparmor/lsm.c
|
||||
@@ -2275,7 +2275,7 @@ static int __init apparmor_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(apparmor) = {
|
||||
- .name = "apparmor",
|
||||
+ .id = &apparmor_lsmid,
|
||||
.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
|
||||
.enabled = &apparmor_enabled,
|
||||
.blobs = &apparmor_blob_sizes,
|
||||
diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c
|
||||
index db759025abe1..40efde233f3a 100644
|
||||
--- a/security/bpf/hooks.c
|
||||
+++ b/security/bpf/hooks.c
|
||||
@@ -33,7 +33,7 @@ struct lsm_blob_sizes bpf_lsm_blob_sizes __ro_after_init = {
|
||||
};
|
||||
|
||||
DEFINE_LSM(bpf) = {
|
||||
- .name = "bpf",
|
||||
+ .id = &bpf_lsmid,
|
||||
.init = bpf_lsm_init,
|
||||
.blobs = &bpf_lsm_blob_sizes
|
||||
};
|
||||
diff --git a/security/commoncap.c b/security/commoncap.c
|
||||
index cefad323a0b1..7d0b5a58d4e1 100644
|
||||
--- a/security/commoncap.c
|
||||
+++ b/security/commoncap.c
|
||||
@@ -1470,7 +1470,7 @@ static int __init capability_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(capability) = {
|
||||
- .name = "capability",
|
||||
+ .id = &capability_lsmid,
|
||||
.order = LSM_ORDER_FIRST,
|
||||
.init = capability_init,
|
||||
};
|
||||
diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c
|
||||
index 377e57e9084f..bb0f8631195e 100644
|
||||
--- a/security/integrity/evm/evm_main.c
|
||||
+++ b/security/integrity/evm/evm_main.c
|
||||
@@ -1175,7 +1175,7 @@ struct lsm_blob_sizes evm_blob_sizes __ro_after_init = {
|
||||
};
|
||||
|
||||
DEFINE_LSM(evm) = {
|
||||
- .name = "evm",
|
||||
+ .id = &evm_lsmid,
|
||||
.init = init_evm_lsm,
|
||||
.order = LSM_ORDER_LAST,
|
||||
.blobs = &evm_blob_sizes,
|
||||
diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c
|
||||
index 66aa7bc8d76d..c60a9b1082d4 100644
|
||||
--- a/security/integrity/ima/ima_main.c
|
||||
+++ b/security/integrity/ima/ima_main.c
|
||||
@@ -1222,7 +1222,7 @@ struct lsm_blob_sizes ima_blob_sizes __ro_after_init = {
|
||||
};
|
||||
|
||||
DEFINE_LSM(ima) = {
|
||||
- .name = "ima",
|
||||
+ .id = &ima_lsmid,
|
||||
.init = init_ima_lsm,
|
||||
.order = LSM_ORDER_LAST,
|
||||
.blobs = &ima_blob_sizes,
|
||||
diff --git a/security/ipe/ipe.c b/security/ipe/ipe.c
|
||||
index 4317134cb0da..2426441181dc 100644
|
||||
--- a/security/ipe/ipe.c
|
||||
+++ b/security/ipe/ipe.c
|
||||
@@ -92,7 +92,7 @@ static int __init ipe_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(ipe) = {
|
||||
- .name = "ipe",
|
||||
+ .id = &ipe_lsmid,
|
||||
.init = ipe_init,
|
||||
.blobs = &ipe_blobs,
|
||||
};
|
||||
diff --git a/security/landlock/setup.c b/security/landlock/setup.c
|
||||
index 28519a45b11f..460c5b79d957 100644
|
||||
--- a/security/landlock/setup.c
|
||||
+++ b/security/landlock/setup.c
|
||||
@@ -43,7 +43,7 @@ static int __init landlock_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(LANDLOCK_NAME) = {
|
||||
- .name = LANDLOCK_NAME,
|
||||
+ .id = &landlock_lsmid,
|
||||
.init = landlock_init,
|
||||
.blobs = &landlock_blob_sizes,
|
||||
};
|
||||
diff --git a/security/loadpin/loadpin.c b/security/loadpin/loadpin.c
|
||||
index 02144ec39f43..92c9618e38ad 100644
|
||||
--- a/security/loadpin/loadpin.c
|
||||
+++ b/security/loadpin/loadpin.c
|
||||
@@ -271,7 +271,7 @@ static int __init loadpin_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(loadpin) = {
|
||||
- .name = "loadpin",
|
||||
+ .id = &loadpin_lsmid,
|
||||
.init = loadpin_init,
|
||||
};
|
||||
|
||||
diff --git a/security/lockdown/lockdown.c b/security/lockdown/lockdown.c
|
||||
index ddf496f7fca5..c27aaee60da3 100644
|
||||
--- a/security/lockdown/lockdown.c
|
||||
+++ b/security/lockdown/lockdown.c
|
||||
@@ -169,6 +169,6 @@ DEFINE_EARLY_LSM(lockdown) = {
|
||||
#else
|
||||
DEFINE_LSM(lockdown) = {
|
||||
#endif
|
||||
- .name = "lockdown",
|
||||
+ .id = &lockdown_lsmid,
|
||||
.init = lockdown_lsm_init,
|
||||
};
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index a590a785f724..e5faf6be44fb 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -127,9 +127,10 @@ static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
|
||||
/* Enable this LSM, if it is not already set. */
|
||||
if (!lsm->enabled)
|
||||
lsm->enabled = &lsm_enabled_true;
|
||||
- ordered_lsms[last_lsm++] = lsm;
|
||||
+ ordered_lsms[last_lsm] = lsm;
|
||||
+ lsm_idlist[last_lsm++] = lsm->id;
|
||||
|
||||
- init_debug("%s ordered: %s (%s)\n", from, lsm->name,
|
||||
+ init_debug("%s ordered: %s (%s)\n", from, lsm->id->name,
|
||||
is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
@@ -157,7 +158,7 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
set_enabled(lsm, false);
|
||||
return;
|
||||
} else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) {
|
||||
- init_debug("exclusive disabled: %s\n", lsm->name);
|
||||
+ init_debug("exclusive disabled: %s\n", lsm->id->name);
|
||||
set_enabled(lsm, false);
|
||||
return;
|
||||
}
|
||||
@@ -165,7 +166,7 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
/* Mark the LSM as enabled. */
|
||||
set_enabled(lsm, true);
|
||||
if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
|
||||
- init_debug("exclusive chosen: %s\n", lsm->name);
|
||||
+ init_debug("exclusive chosen: %s\n", lsm->id->name);
|
||||
exclusive = lsm;
|
||||
}
|
||||
|
||||
@@ -197,9 +198,9 @@ static void __init initialize_lsm(struct lsm_info *lsm)
|
||||
if (is_enabled(lsm)) {
|
||||
int ret;
|
||||
|
||||
- init_debug("initializing %s\n", lsm->name);
|
||||
+ init_debug("initializing %s\n", lsm->id->name);
|
||||
ret = lsm->init();
|
||||
- WARN(ret, "%s failed to initialize: %d\n", lsm->name, ret);
|
||||
+ WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -233,10 +234,10 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
*/
|
||||
lsm_for_each_raw(major) {
|
||||
if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
- strcmp(major->name, chosen_major_lsm) != 0) {
|
||||
+ strcmp(major->id->name, chosen_major_lsm) != 0) {
|
||||
set_enabled(major, false);
|
||||
init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
|
||||
- chosen_major_lsm, major->name);
|
||||
+ chosen_major_lsm, major->id->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -248,7 +249,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
bool found = false;
|
||||
|
||||
lsm_for_each_raw(lsm) {
|
||||
- if (strcmp(lsm->name, name) == 0) {
|
||||
+ if (strcmp(lsm->id->name, name) == 0) {
|
||||
if (lsm->order == LSM_ORDER_MUTABLE)
|
||||
append_ordered_lsm(lsm, origin);
|
||||
found = true;
|
||||
@@ -265,7 +266,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (exists_ordered_lsm(lsm))
|
||||
continue;
|
||||
- if (strcmp(lsm->name, chosen_major_lsm) == 0)
|
||||
+ if (strcmp(lsm->id->name, chosen_major_lsm) == 0)
|
||||
append_ordered_lsm(lsm, "security=");
|
||||
}
|
||||
}
|
||||
@@ -282,7 +283,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
continue;
|
||||
set_enabled(lsm, false);
|
||||
init_debug("%s skipped: %s (not in requested order)\n",
|
||||
- origin, lsm->name);
|
||||
+ origin, lsm->id->name);
|
||||
}
|
||||
|
||||
kfree(sep);
|
||||
@@ -314,11 +315,13 @@ static void __init lsm_init_ordered(void)
|
||||
pr_info("initializing lsm=");
|
||||
lsm_early_for_each_raw(early) {
|
||||
if (is_enabled(early))
|
||||
- pr_cont("%s%s", first++ == 0 ? "" : ",", early->name);
|
||||
+ pr_cont("%s%s",
|
||||
+ first++ == 0 ? "" : ",", early->id->name);
|
||||
}
|
||||
lsm_order_for_each(lsm) {
|
||||
if (is_enabled(*lsm))
|
||||
- pr_cont("%s%s", first++ == 0 ? "" : ",", (*lsm)->name);
|
||||
+ pr_cont("%s%s",
|
||||
+ first++ == 0 ? "" : ",", (*lsm)->id->name);
|
||||
}
|
||||
pr_cont("\n");
|
||||
|
||||
@@ -426,18 +429,6 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
||||
{
|
||||
int i;
|
||||
|
||||
- /*
|
||||
- * A security module may call security_add_hooks() more
|
||||
- * than once during initialization, and LSM initialization
|
||||
- * is serialized. Landlock is one such case.
|
||||
- * Look at the previous entry, if there is one, for duplication.
|
||||
- */
|
||||
- if (lsm_active_cnt == 0 || lsm_idlist[lsm_active_cnt - 1] != lsmid) {
|
||||
- if (lsm_active_cnt >= MAX_LSM_COUNT)
|
||||
- panic("%s Too many LSMs registered.\n", __func__);
|
||||
- lsm_idlist[lsm_active_cnt++] = lsmid;
|
||||
- }
|
||||
-
|
||||
for (i = 0; i < count; i++) {
|
||||
hooks[i].lsmid = lsmid;
|
||||
lsm_static_call_init(&hooks[i]);
|
||||
@@ -490,10 +481,10 @@ int __init security_init(void)
|
||||
* available
|
||||
*/
|
||||
lsm_early_for_each_raw(lsm) {
|
||||
- init_debug(" early started: %s (%s)\n", lsm->name,
|
||||
+ init_debug(" early started: %s (%s)\n", lsm->id->name,
|
||||
is_enabled(lsm) ? "enabled" : "disabled");
|
||||
if (lsm->enabled)
|
||||
- lsm_append(lsm->name, &lsm_names);
|
||||
+ lsm_append(lsm->id->name, &lsm_names);
|
||||
}
|
||||
|
||||
/* Load LSMs in specified order. */
|
||||
diff --git a/security/safesetid/lsm.c b/security/safesetid/lsm.c
|
||||
index 1ba564f097f5..9a7c68d4e642 100644
|
||||
--- a/security/safesetid/lsm.c
|
||||
+++ b/security/safesetid/lsm.c
|
||||
@@ -287,6 +287,6 @@ static int __init safesetid_security_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(safesetid_security_init) = {
|
||||
+ .id = &safesetid_lsmid,
|
||||
.init = safesetid_security_init,
|
||||
- .name = "safesetid",
|
||||
};
|
||||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
|
||||
index 1bc947e2b0e7..a2323c6daafe 100644
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -7480,7 +7480,7 @@ void selinux_complete_init(void)
|
||||
/* SELinux requires early initialization in order to label
|
||||
all processes and objects when they are created. */
|
||||
DEFINE_LSM(selinux) = {
|
||||
- .name = "selinux",
|
||||
+ .id = &selinux_lsmid,
|
||||
.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
|
||||
.enabled = &selinux_enabled_boot,
|
||||
.blobs = &selinux_blob_sizes,
|
||||
diff --git a/security/smack/smack_lsm.c b/security/smack/smack_lsm.c
|
||||
index 7c8b06e974bb..43546723f600 100644
|
||||
--- a/security/smack/smack_lsm.c
|
||||
+++ b/security/smack/smack_lsm.c
|
||||
@@ -5318,7 +5318,7 @@ static __init int smack_init(void)
|
||||
* all processes and objects when they are created.
|
||||
*/
|
||||
DEFINE_LSM(smack) = {
|
||||
- .name = "smack",
|
||||
+ .id = &smack_lsmid,
|
||||
.flags = LSM_FLAG_LEGACY_MAJOR | LSM_FLAG_EXCLUSIVE,
|
||||
.blobs = &smack_blob_sizes,
|
||||
.init = smack_init,
|
||||
diff --git a/security/tomoyo/tomoyo.c b/security/tomoyo/tomoyo.c
|
||||
index fa08d78162bb..3c6964ea7ace 100644
|
||||
--- a/security/tomoyo/tomoyo.c
|
||||
+++ b/security/tomoyo/tomoyo.c
|
||||
@@ -615,7 +615,7 @@ static int __init tomoyo_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(tomoyo) = {
|
||||
- .name = "tomoyo",
|
||||
+ .id = &tomoyo_lsmid,
|
||||
.enabled = &tomoyo_enabled,
|
||||
.flags = LSM_FLAG_LEGACY_MAJOR,
|
||||
.blobs = &tomoyo_blob_sizes,
|
||||
diff --git a/security/yama/yama_lsm.c b/security/yama/yama_lsm.c
|
||||
index 54bd5f535ac1..f546176dd2fc 100644
|
||||
--- a/security/yama/yama_lsm.c
|
||||
+++ b/security/yama/yama_lsm.c
|
||||
@@ -483,6 +483,6 @@ static int __init yama_init(void)
|
||||
}
|
||||
|
||||
DEFINE_LSM(yama) = {
|
||||
- .name = "yama",
|
||||
+ .id = &yama_lsmid,
|
||||
.init = yama_init,
|
||||
};
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
226
1309-lsm-rename-the-lsm-order-variables-for-consistency.patch
Normal file
226
1309-lsm-rename-the-lsm-order-variables-for-consistency.patch
Normal file
@ -0,0 +1,226 @@
|
||||
From f212d5ad65c47cf954187a1d3ed14db6127b3727 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:33 +0200
|
||||
Subject: [PATCH] lsm: rename the lsm order variables for consistency
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 592b104f9b516b2c22cb23a2f4c34486fdb21bae
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Tue Feb 11 17:13:26 2025 -0500
|
||||
|
||||
lsm: rename the lsm order variables for consistency
|
||||
|
||||
Rename the builtin_lsm_order variable to lsm_order_builtin,
|
||||
chosen_lsm_order to lsm_order_cmdline, chosen_major_lsm to
|
||||
lsm_order_legacy, ordered_lsms[] to lsm_order[], and exclusive
|
||||
to lsm_exclusive.
|
||||
|
||||
This patch also renames the associated kernel command line parsing
|
||||
functions and adds some basic function comment blocks. The parsing
|
||||
function choose_major_lsm() was renamed to lsm_choose_security(),
|
||||
choose_lsm_order() to lsm_choose_lsm(), and enable_debug() to
|
||||
lsm_debug_enable().
|
||||
|
||||
Reviewed-by: Kees Cook <kees@kernel.org>
|
||||
Reviewed-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index e5faf6be44fb..171b2b047bdc 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -16,14 +16,14 @@ char *lsm_names;
|
||||
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
|
||||
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
|
||||
|
||||
-/* Boot-time LSM user choice */
|
||||
-static __initconst const char *const builtin_lsm_order = CONFIG_LSM;
|
||||
-static __initdata const char *chosen_lsm_order;
|
||||
-static __initdata const char *chosen_major_lsm;
|
||||
+/* Build and boot-time LSM ordering. */
|
||||
+static __initconst const char *const lsm_order_builtin = CONFIG_LSM;
|
||||
+static __initdata const char *lsm_order_cmdline;
|
||||
+static __initdata const char *lsm_order_legacy;
|
||||
|
||||
/* Ordered list of LSMs to initialize. */
|
||||
-static __initdata struct lsm_info *ordered_lsms[MAX_LSM_COUNT + 1];
|
||||
-static __initdata struct lsm_info *exclusive;
|
||||
+static __initdata struct lsm_info *lsm_order[MAX_LSM_COUNT + 1];
|
||||
+static __initdata struct lsm_info *lsm_exclusive;
|
||||
|
||||
static __initdata bool debug;
|
||||
#define init_debug(...) \
|
||||
@@ -33,7 +33,7 @@ static __initdata bool debug;
|
||||
} while (0)
|
||||
|
||||
#define lsm_order_for_each(iter) \
|
||||
- for ((iter) = ordered_lsms; *(iter); (iter)++)
|
||||
+ for ((iter) = lsm_order; *(iter); (iter)++)
|
||||
#define lsm_for_each_raw(iter) \
|
||||
for ((iter) = __start_lsm_info; \
|
||||
(iter) < __end_lsm_info; (iter)++)
|
||||
@@ -41,31 +41,41 @@ static __initdata bool debug;
|
||||
for ((iter) = __start_early_lsm_info; \
|
||||
(iter) < __end_early_lsm_info; (iter)++)
|
||||
|
||||
-static int lsm_append(const char *new, char **result);
|
||||
-
|
||||
-/* Save user chosen LSM */
|
||||
-static int __init choose_major_lsm(char *str)
|
||||
+/**
|
||||
+ * lsm_choose_security - Legacy "major" LSM selection
|
||||
+ * @str: kernel command line parameter
|
||||
+ */
|
||||
+static int __init lsm_choose_security(char *str)
|
||||
{
|
||||
- chosen_major_lsm = str;
|
||||
+ lsm_order_legacy = str;
|
||||
return 1;
|
||||
}
|
||||
-__setup("security=", choose_major_lsm);
|
||||
+__setup("security=", lsm_choose_security);
|
||||
|
||||
-/* Explicitly choose LSM initialization order. */
|
||||
-static int __init choose_lsm_order(char *str)
|
||||
+/**
|
||||
+ * lsm_choose_lsm - Modern LSM selection
|
||||
+ * @str: kernel command line parameter
|
||||
+ */
|
||||
+static int __init lsm_choose_lsm(char *str)
|
||||
{
|
||||
- chosen_lsm_order = str;
|
||||
+ lsm_order_cmdline = str;
|
||||
return 1;
|
||||
}
|
||||
-__setup("lsm=", choose_lsm_order);
|
||||
+__setup("lsm=", lsm_choose_lsm);
|
||||
|
||||
-/* Enable LSM order debugging. */
|
||||
-static int __init enable_debug(char *str)
|
||||
+/**
|
||||
+ * lsm_debug_enable - Enable LSM framework debugging
|
||||
+ * @str: kernel command line parameter
|
||||
+ *
|
||||
+ * Currently we only provide debug info during LSM initialization, but we may
|
||||
+ * want to expand this in the future.
|
||||
+ */
|
||||
+static int __init lsm_debug_enable(char *str)
|
||||
{
|
||||
debug = true;
|
||||
return 1;
|
||||
}
|
||||
-__setup("lsm.debug", enable_debug);
|
||||
+__setup("lsm.debug", lsm_debug_enable);
|
||||
|
||||
/* Mark an LSM's enabled flag. */
|
||||
static int lsm_enabled_true __initdata = 1;
|
||||
@@ -127,7 +137,7 @@ static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
|
||||
/* Enable this LSM, if it is not already set. */
|
||||
if (!lsm->enabled)
|
||||
lsm->enabled = &lsm_enabled_true;
|
||||
- ordered_lsms[last_lsm] = lsm;
|
||||
+ lsm_order[last_lsm] = lsm;
|
||||
lsm_idlist[last_lsm++] = lsm->id;
|
||||
|
||||
init_debug("%s ordered: %s (%s)\n", from, lsm->id->name,
|
||||
@@ -157,7 +167,7 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
if (!is_enabled(lsm)) {
|
||||
set_enabled(lsm, false);
|
||||
return;
|
||||
- } else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && exclusive) {
|
||||
+ } else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && lsm_exclusive) {
|
||||
init_debug("exclusive disabled: %s\n", lsm->id->name);
|
||||
set_enabled(lsm, false);
|
||||
return;
|
||||
@@ -165,9 +175,9 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
|
||||
/* Mark the LSM as enabled. */
|
||||
set_enabled(lsm, true);
|
||||
- if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !exclusive) {
|
||||
+ if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !lsm_exclusive) {
|
||||
init_debug("exclusive chosen: %s\n", lsm->id->name);
|
||||
- exclusive = lsm;
|
||||
+ lsm_exclusive = lsm;
|
||||
}
|
||||
|
||||
/* Register the LSM blob sizes. */
|
||||
@@ -223,7 +233,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
}
|
||||
|
||||
/* Process "security=", if given. */
|
||||
- if (chosen_major_lsm) {
|
||||
+ if (lsm_order_legacy) {
|
||||
struct lsm_info *major;
|
||||
|
||||
/*
|
||||
@@ -234,10 +244,10 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
*/
|
||||
lsm_for_each_raw(major) {
|
||||
if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
- strcmp(major->id->name, chosen_major_lsm) != 0) {
|
||||
+ strcmp(major->id->name, lsm_order_legacy) != 0) {
|
||||
set_enabled(major, false);
|
||||
init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
|
||||
- chosen_major_lsm, major->id->name);
|
||||
+ lsm_order_legacy, major->id->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -262,11 +272,11 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
}
|
||||
|
||||
/* Process "security=", if given. */
|
||||
- if (chosen_major_lsm) {
|
||||
+ if (lsm_order_legacy) {
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (exists_ordered_lsm(lsm))
|
||||
continue;
|
||||
- if (strcmp(lsm->id->name, chosen_major_lsm) == 0)
|
||||
+ if (strcmp(lsm->id->name, lsm_order_legacy) == 0)
|
||||
append_ordered_lsm(lsm, "security=");
|
||||
}
|
||||
}
|
||||
@@ -298,15 +308,15 @@ static void __init lsm_init_ordered(void)
|
||||
struct lsm_info **lsm;
|
||||
struct lsm_info *early;
|
||||
|
||||
- if (chosen_lsm_order) {
|
||||
- if (chosen_major_lsm) {
|
||||
+ if (lsm_order_cmdline) {
|
||||
+ if (lsm_order_legacy) {
|
||||
pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
|
||||
- chosen_major_lsm, chosen_lsm_order);
|
||||
- chosen_major_lsm = NULL;
|
||||
+ lsm_order_legacy, lsm_order_cmdline);
|
||||
+ lsm_order_legacy = NULL;
|
||||
}
|
||||
- ordered_lsm_parse(chosen_lsm_order, "cmdline");
|
||||
+ ordered_lsm_parse(lsm_order_cmdline, "cmdline");
|
||||
} else
|
||||
- ordered_lsm_parse(builtin_lsm_order, "builtin");
|
||||
+ ordered_lsm_parse(lsm_order_builtin, "builtin");
|
||||
|
||||
lsm_order_for_each(lsm) {
|
||||
lsm_prepare(*lsm);
|
||||
@@ -472,9 +482,9 @@ int __init security_init(void)
|
||||
{
|
||||
struct lsm_info *lsm;
|
||||
|
||||
- init_debug("legacy security=%s\n", chosen_major_lsm ? : " *unspecified*");
|
||||
- init_debug(" CONFIG_LSM=%s\n", builtin_lsm_order);
|
||||
- init_debug("boot arg lsm=%s\n", chosen_lsm_order ? : " *unspecified*");
|
||||
+ init_debug("legacy security=%s\n", lsm_order_legacy ? : " *unspecified*");
|
||||
+ init_debug(" CONFIG_LSM=%s\n", lsm_order_builtin);
|
||||
+ init_debug("boot arg lsm=%s\n", lsm_order_cmdline ? : " *unspecified*");
|
||||
|
||||
/*
|
||||
* Append the names of the early LSM modules now that kmalloc() is
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
102
1310-lsm-rework-lsm-active-cnt-and-lsm-idlist.patch
Normal file
102
1310-lsm-rework-lsm-active-cnt-and-lsm-idlist.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From c4c061449d1ae617402680b00ab006b1e0ee2c2c Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:34 +0200
|
||||
Subject: [PATCH] lsm: rework lsm_active_cnt and lsm_idlist[]
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 250898ca335f337bc032a9693dc0a30a1cb85825
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Feb 12 15:36:51 2025 -0500
|
||||
|
||||
lsm: rework lsm_active_cnt and lsm_idlist[]
|
||||
|
||||
Move the LSM active count and lsm_id list declarations out of a header
|
||||
that is visible across the kernel and into a header that is limited to
|
||||
the LSM framework. This not only helps keep the include/linux headers
|
||||
smaller and cleaner, it helps prevent misuse of these variables.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/include/linux/security.h b/include/linux/security.h
|
||||
index 3254f74457f7..2db88ddbe9a9 100644
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -167,8 +167,6 @@ struct lsm_prop {
|
||||
};
|
||||
|
||||
extern const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX+1];
|
||||
-extern u32 lsm_active_cnt;
|
||||
-extern const struct lsm_id *lsm_idlist[];
|
||||
|
||||
/* These functions are in security/commoncap.c */
|
||||
extern int cap_capable(const struct cred *cred, struct user_namespace *ns,
|
||||
diff --git a/security/lsm.h b/security/lsm.h
|
||||
index 0e1731bad4a7..dbe755c45e57 100644
|
||||
--- a/security/lsm.h
|
||||
+++ b/security/lsm.h
|
||||
@@ -7,6 +7,11 @@
|
||||
#define _LSM_H_
|
||||
|
||||
#include <linux/lsm_hooks.h>
|
||||
+#include <linux/lsm_count.h>
|
||||
+
|
||||
+/* List of configured LSMs */
|
||||
+extern unsigned int lsm_active_cnt;
|
||||
+extern const struct lsm_id *lsm_idlist[];
|
||||
|
||||
/* LSM blob configuration */
|
||||
extern struct lsm_blob_sizes blob_sizes;
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 171b2b047bdc..e7afc74caa2b 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -214,12 +214,6 @@ static void __init initialize_lsm(struct lsm_info *lsm)
|
||||
}
|
||||
}
|
||||
|
||||
-/*
|
||||
- * Current index to use while initializing the lsm id list.
|
||||
- */
|
||||
-u32 lsm_active_cnt __ro_after_init;
|
||||
-const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
|
||||
-
|
||||
/* Populate ordered LSMs list from comma-separated LSM name list. */
|
||||
static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
{
|
||||
diff --git a/security/lsm_syscalls.c b/security/lsm_syscalls.c
|
||||
index 8440948a690c..5648b1f0ce9c 100644
|
||||
--- a/security/lsm_syscalls.c
|
||||
+++ b/security/lsm_syscalls.c
|
||||
@@ -17,6 +17,8 @@
|
||||
#include <linux/lsm_hooks.h>
|
||||
#include <uapi/linux/lsm.h>
|
||||
|
||||
+#include "lsm.h"
|
||||
+
|
||||
/**
|
||||
* lsm_name_to_attr - map an LSM attribute name to its ID
|
||||
* @name: name of the attribute
|
||||
diff --git a/security/security.c b/security/security.c
|
||||
index 6040891f4588..6f20f44c8d13 100644
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -74,6 +74,9 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
|
||||
[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
|
||||
};
|
||||
|
||||
+unsigned int lsm_active_cnt __ro_after_init;
|
||||
+const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
|
||||
+
|
||||
struct lsm_blob_sizes blob_sizes;
|
||||
|
||||
struct kmem_cache *lsm_file_cache;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
184
1311-lsm-get-rid-of-the-lsm-names-list-and-do-some-cleanup.patch
Normal file
184
1311-lsm-get-rid-of-the-lsm-names-list-and-do-some-cleanup.patch
Normal file
@ -0,0 +1,184 @@
|
||||
From e84cf2768df37393453e8bb645555e360761056c Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:20:34 +0200
|
||||
Subject: [PATCH] lsm: get rid of the lsm_names list and do some cleanup
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 935d508d4d7ab9d19c603bd7eb2937249551d507
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Thu Feb 13 17:34:12 2025 -0500
|
||||
|
||||
lsm: get rid of the lsm_names list and do some cleanup
|
||||
|
||||
The LSM currently has a lot of code to maintain a list of the currently
|
||||
active LSMs in a human readable string, with the only user being the
|
||||
"/sys/kernel/security/lsm" code. Let's drop all of that code and
|
||||
generate the string on first use and then cache it for subsequent use.
|
||||
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
|
||||
index 4cd17c9a229f..bc477fb20d02 100644
|
||||
--- a/include/linux/lsm_hooks.h
|
||||
+++ b/include/linux/lsm_hooks.h
|
||||
@@ -169,7 +169,6 @@ struct lsm_info {
|
||||
|
||||
|
||||
/* DO NOT tamper with these variables outside of the LSM framework */
|
||||
-extern char *lsm_names;
|
||||
extern struct lsm_static_calls_table static_calls_table __ro_after_init;
|
||||
|
||||
/**
|
||||
diff --git a/security/inode.c b/security/inode.c
|
||||
index da3ab44c8e57..6f3caab37ab2 100644
|
||||
--- a/security/inode.c
|
||||
+++ b/security/inode.c
|
||||
@@ -22,6 +22,8 @@
|
||||
#include <linux/lsm_hooks.h>
|
||||
#include <linux/magic.h>
|
||||
|
||||
+#include "lsm.h"
|
||||
+
|
||||
static struct vfsmount *mount;
|
||||
static int mount_count;
|
||||
|
||||
@@ -339,12 +341,49 @@ void securityfs_recursive_remove(struct dentry *dentry)
|
||||
EXPORT_SYMBOL_GPL(securityfs_recursive_remove);
|
||||
|
||||
#ifdef CONFIG_SECURITY
|
||||
+#include <linux/spinlock.h>
|
||||
+
|
||||
static struct dentry *lsm_dentry;
|
||||
+
|
||||
static ssize_t lsm_read(struct file *filp, char __user *buf, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
- return simple_read_from_buffer(buf, count, ppos, lsm_names,
|
||||
- strlen(lsm_names));
|
||||
+ int i;
|
||||
+ static char *str;
|
||||
+ static size_t len;
|
||||
+ static DEFINE_SPINLOCK(lock);
|
||||
+
|
||||
+ /* NOTE: we never free or modify the string once it is set */
|
||||
+
|
||||
+ if (unlikely(!str || !len)) {
|
||||
+ char *str_tmp;
|
||||
+ size_t len_tmp = 0;
|
||||
+
|
||||
+ for (i = 0; i < lsm_active_cnt; i++)
|
||||
+ /* the '+ 1' accounts for either a comma or a NUL */
|
||||
+ len_tmp += strlen(lsm_idlist[i]->name) + 1;
|
||||
+
|
||||
+ str_tmp = kmalloc(len_tmp, GFP_KERNEL);
|
||||
+ if (!str_tmp)
|
||||
+ return -ENOMEM;
|
||||
+ str_tmp[0] = '\0';
|
||||
+
|
||||
+ for (i = 0; i < lsm_active_cnt; i++) {
|
||||
+ if (i > 0)
|
||||
+ strcat(str_tmp, ",");
|
||||
+ strcat(str_tmp, lsm_idlist[i]->name);
|
||||
+ }
|
||||
+
|
||||
+ spin_lock(&lock);
|
||||
+ if (!str) {
|
||||
+ str = str_tmp;
|
||||
+ len = len_tmp - 1;
|
||||
+ } else
|
||||
+ kfree(str_tmp);
|
||||
+ spin_unlock(&lock);
|
||||
+ }
|
||||
+
|
||||
+ return simple_read_from_buffer(buf, count, ppos, str, len);
|
||||
}
|
||||
|
||||
static const struct file_operations lsm_ops = {
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index e7afc74caa2b..7c244a309a35 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -10,8 +10,6 @@
|
||||
|
||||
#include "lsm.h"
|
||||
|
||||
-char *lsm_names;
|
||||
-
|
||||
/* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */
|
||||
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
|
||||
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
|
||||
@@ -365,42 +363,6 @@ static void __init lsm_init_ordered(void)
|
||||
}
|
||||
}
|
||||
|
||||
-static bool match_last_lsm(const char *list, const char *lsm)
|
||||
-{
|
||||
- const char *last;
|
||||
-
|
||||
- if (WARN_ON(!list || !lsm))
|
||||
- return false;
|
||||
- last = strrchr(list, ',');
|
||||
- if (last)
|
||||
- /* Pass the comma, strcmp() will check for '\0' */
|
||||
- last++;
|
||||
- else
|
||||
- last = list;
|
||||
- return !strcmp(last, lsm);
|
||||
-}
|
||||
-
|
||||
-static int lsm_append(const char *new, char **result)
|
||||
-{
|
||||
- char *cp;
|
||||
-
|
||||
- if (*result == NULL) {
|
||||
- *result = kstrdup(new, GFP_KERNEL);
|
||||
- if (*result == NULL)
|
||||
- return -ENOMEM;
|
||||
- } else {
|
||||
- /* Check if it is the last registered name */
|
||||
- if (match_last_lsm(*result, new))
|
||||
- return 0;
|
||||
- cp = kasprintf(GFP_KERNEL, "%s,%s", *result, new);
|
||||
- if (cp == NULL)
|
||||
- return -ENOMEM;
|
||||
- kfree(*result);
|
||||
- *result = cp;
|
||||
- }
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
{
|
||||
struct lsm_static_call *scall = hl->scalls;
|
||||
@@ -437,15 +399,6 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
||||
hooks[i].lsmid = lsmid;
|
||||
lsm_static_call_init(&hooks[i]);
|
||||
}
|
||||
-
|
||||
- /*
|
||||
- * Don't try to append during early_security_init(), we'll come back
|
||||
- * and fix this up afterwards.
|
||||
- */
|
||||
- if (slab_is_available()) {
|
||||
- if (lsm_append(lsmid->name, &lsm_names) < 0)
|
||||
- panic("%s - Cannot get early memory.\n", __func__);
|
||||
- }
|
||||
}
|
||||
|
||||
int __init early_security_init(void)
|
||||
@@ -487,8 +440,6 @@ int __init security_init(void)
|
||||
lsm_early_for_each_raw(lsm) {
|
||||
init_debug(" early started: %s (%s)\n", lsm->id->name,
|
||||
is_enabled(lsm) ? "enabled" : "disabled");
|
||||
- if (lsm->enabled)
|
||||
- lsm_append(lsm->id->name, &lsm_names);
|
||||
}
|
||||
|
||||
/* Load LSMs in specified order. */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,179 @@
|
||||
From d52cc6c688625151f1b39aa7b2b5c532b47a2211 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:26:49 +0200
|
||||
Subject: [PATCH] lsm: rework the LSM enable/disable setter/getter functions
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 2d67172612fd9df2c4d08533515ef483cb526dd9
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Thu Apr 10 22:04:26 2025 -0400
|
||||
|
||||
lsm: rework the LSM enable/disable setter/getter functions
|
||||
|
||||
In addition to style changes, rename set_enabled() to lsm_enabled_set()
|
||||
and is_enabled() to lsm_is_enabled() to better fit within the LSM
|
||||
initialization code.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 7c244a309a35..9929d1a61634 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -10,6 +10,10 @@
|
||||
|
||||
#include "lsm.h"
|
||||
|
||||
+/* LSM enabled constants. */
|
||||
+static __initdata int lsm_enabled_true = 1;
|
||||
+static __initdata int lsm_enabled_false = 0;
|
||||
+
|
||||
/* Pointers to LSM sections defined in include/asm-generic/vmlinux.lds.h */
|
||||
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
|
||||
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
|
||||
@@ -75,37 +79,33 @@ static int __init lsm_debug_enable(char *str)
|
||||
}
|
||||
__setup("lsm.debug", lsm_debug_enable);
|
||||
|
||||
-/* Mark an LSM's enabled flag. */
|
||||
-static int lsm_enabled_true __initdata = 1;
|
||||
-static int lsm_enabled_false __initdata = 0;
|
||||
-static void __init set_enabled(struct lsm_info *lsm, bool enabled)
|
||||
+/**
|
||||
+ * lsm_enabled_set - Mark a LSM as enabled
|
||||
+ * @lsm: LSM definition
|
||||
+ * @enabled: enabled flag
|
||||
+ */
|
||||
+static void __init lsm_enabled_set(struct lsm_info *lsm, bool enabled)
|
||||
{
|
||||
/*
|
||||
* When an LSM hasn't configured an enable variable, we can use
|
||||
* a hard-coded location for storing the default enabled state.
|
||||
*/
|
||||
- if (!lsm->enabled) {
|
||||
- if (enabled)
|
||||
- lsm->enabled = &lsm_enabled_true;
|
||||
- else
|
||||
- lsm->enabled = &lsm_enabled_false;
|
||||
- } else if (lsm->enabled == &lsm_enabled_true) {
|
||||
- if (!enabled)
|
||||
- lsm->enabled = &lsm_enabled_false;
|
||||
- } else if (lsm->enabled == &lsm_enabled_false) {
|
||||
- if (enabled)
|
||||
- lsm->enabled = &lsm_enabled_true;
|
||||
+ if (!lsm->enabled ||
|
||||
+ lsm->enabled == &lsm_enabled_true ||
|
||||
+ lsm->enabled == &lsm_enabled_false) {
|
||||
+ lsm->enabled = enabled ? &lsm_enabled_true : &lsm_enabled_false;
|
||||
} else {
|
||||
*lsm->enabled = enabled;
|
||||
}
|
||||
}
|
||||
|
||||
-static inline bool is_enabled(struct lsm_info *lsm)
|
||||
+/**
|
||||
+ * lsm_is_enabled - Determine if a LSM is enabled
|
||||
+ * @lsm: LSM definition
|
||||
+ */
|
||||
+static inline bool lsm_is_enabled(struct lsm_info *lsm)
|
||||
{
|
||||
- if (!lsm->enabled)
|
||||
- return false;
|
||||
-
|
||||
- return *lsm->enabled;
|
||||
+ return (lsm->enabled ? *lsm->enabled : false);
|
||||
}
|
||||
|
||||
/* Is an LSM already listed in the ordered LSMs list? */
|
||||
@@ -139,7 +139,7 @@ static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
|
||||
lsm_idlist[last_lsm++] = lsm->id;
|
||||
|
||||
init_debug("%s ordered: %s (%s)\n", from, lsm->id->name,
|
||||
- is_enabled(lsm) ? "enabled" : "disabled");
|
||||
+ lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
static void __init lsm_set_blob_size(int *need, int *lbs)
|
||||
@@ -162,17 +162,17 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
{
|
||||
struct lsm_blob_sizes *blobs;
|
||||
|
||||
- if (!is_enabled(lsm)) {
|
||||
- set_enabled(lsm, false);
|
||||
+ if (!lsm_is_enabled(lsm)) {
|
||||
+ lsm_enabled_set(lsm, false);
|
||||
return;
|
||||
} else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && lsm_exclusive) {
|
||||
init_debug("exclusive disabled: %s\n", lsm->id->name);
|
||||
- set_enabled(lsm, false);
|
||||
+ lsm_enabled_set(lsm, false);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Mark the LSM as enabled. */
|
||||
- set_enabled(lsm, true);
|
||||
+ lsm_enabled_set(lsm, true);
|
||||
if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !lsm_exclusive) {
|
||||
init_debug("exclusive chosen: %s\n", lsm->id->name);
|
||||
lsm_exclusive = lsm;
|
||||
@@ -203,7 +203,7 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
/* Initialize a given LSM, if it is enabled. */
|
||||
static void __init initialize_lsm(struct lsm_info *lsm)
|
||||
{
|
||||
- if (is_enabled(lsm)) {
|
||||
+ if (lsm_is_enabled(lsm)) {
|
||||
int ret;
|
||||
|
||||
init_debug("initializing %s\n", lsm->id->name);
|
||||
@@ -237,7 +237,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
lsm_for_each_raw(major) {
|
||||
if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
strcmp(major->id->name, lsm_order_legacy) != 0) {
|
||||
- set_enabled(major, false);
|
||||
+ lsm_enabled_set(major, false);
|
||||
init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
|
||||
lsm_order_legacy, major->id->name);
|
||||
}
|
||||
@@ -283,7 +283,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (exists_ordered_lsm(lsm))
|
||||
continue;
|
||||
- set_enabled(lsm, false);
|
||||
+ lsm_enabled_set(lsm, false);
|
||||
init_debug("%s skipped: %s (not in requested order)\n",
|
||||
origin, lsm->id->name);
|
||||
}
|
||||
@@ -316,12 +316,12 @@ static void __init lsm_init_ordered(void)
|
||||
|
||||
pr_info("initializing lsm=");
|
||||
lsm_early_for_each_raw(early) {
|
||||
- if (is_enabled(early))
|
||||
+ if (lsm_is_enabled(early))
|
||||
pr_cont("%s%s",
|
||||
first++ == 0 ? "" : ",", early->id->name);
|
||||
}
|
||||
lsm_order_for_each(lsm) {
|
||||
- if (is_enabled(*lsm))
|
||||
+ if (lsm_is_enabled(*lsm))
|
||||
pr_cont("%s%s",
|
||||
first++ == 0 ? "" : ",", (*lsm)->id->name);
|
||||
}
|
||||
@@ -439,7 +439,7 @@ int __init security_init(void)
|
||||
*/
|
||||
lsm_early_for_each_raw(lsm) {
|
||||
init_debug(" early started: %s (%s)\n", lsm->id->name,
|
||||
- is_enabled(lsm) ? "enabled" : "disabled");
|
||||
+ lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
/* Load LSMs in specified order. */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
71
1313-lsm-rename-exists-ordered-lsm-to-lsm-order-exists.patch
Normal file
71
1313-lsm-rename-exists-ordered-lsm-to-lsm-order-exists.patch
Normal file
@ -0,0 +1,71 @@
|
||||
From f5d2029482544f20f0ef5652593a120262b8a96e Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:26:50 +0200
|
||||
Subject: [PATCH] lsm: rename exists_ordered_lsm() to lsm_order_exists()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit a748372a282ae1e23d5d4b14a3e190c28764cfd2
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Sun Jul 13 17:37:56 2025 -0400
|
||||
|
||||
lsm: rename exists_ordered_lsm() to lsm_order_exists()
|
||||
|
||||
Also add a header comment block to the function.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 9929d1a61634..bee12c553820 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -108,8 +108,11 @@ static inline bool lsm_is_enabled(struct lsm_info *lsm)
|
||||
return (lsm->enabled ? *lsm->enabled : false);
|
||||
}
|
||||
|
||||
-/* Is an LSM already listed in the ordered LSMs list? */
|
||||
-static bool __init exists_ordered_lsm(struct lsm_info *lsm)
|
||||
+/**
|
||||
+ * lsm_order_exists - Determine if a LSM exists in the ordered list
|
||||
+ * @lsm: LSM definition
|
||||
+ */
|
||||
+static bool __init lsm_order_exists(struct lsm_info *lsm)
|
||||
{
|
||||
struct lsm_info **check;
|
||||
|
||||
@@ -126,7 +129,7 @@ static int last_lsm __initdata;
|
||||
static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
|
||||
{
|
||||
/* Ignore duplicate selections. */
|
||||
- if (exists_ordered_lsm(lsm))
|
||||
+ if (lsm_order_exists(lsm))
|
||||
return;
|
||||
|
||||
if (WARN(last_lsm == MAX_LSM_COUNT, "%s: out of LSM static calls!?\n", from))
|
||||
@@ -266,7 +269,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
/* Process "security=", if given. */
|
||||
if (lsm_order_legacy) {
|
||||
lsm_for_each_raw(lsm) {
|
||||
- if (exists_ordered_lsm(lsm))
|
||||
+ if (lsm_order_exists(lsm))
|
||||
continue;
|
||||
if (strcmp(lsm->id->name, lsm_order_legacy) == 0)
|
||||
append_ordered_lsm(lsm, "security=");
|
||||
@@ -281,7 +284,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
|
||||
/* Disable all LSMs not in the ordered list. */
|
||||
lsm_for_each_raw(lsm) {
|
||||
- if (exists_ordered_lsm(lsm))
|
||||
+ if (lsm_order_exists(lsm))
|
||||
continue;
|
||||
lsm_enabled_set(lsm, false);
|
||||
init_debug("%s skipped: %s (not in requested order)\n",
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,170 @@
|
||||
From 2fad39b00bffc92249f43dfa2db89c89b640bcc2 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:26:50 +0200
|
||||
Subject: [PATCH] lsm: rename/rework append_ordered_lsm() into
|
||||
lsm_order_append()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 24a9c58978ee368cbd796a03cb6e8ade6e0b6f5f
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Jul 16 15:04:10 2025 -0400
|
||||
|
||||
lsm: rename/rework append_ordered_lsm() into lsm_order_append()
|
||||
|
||||
Rename append_ordered_lsm() to lsm_order_append() to better match
|
||||
convention and do some rework. The rework includes moving the
|
||||
LSM_FLAG_EXCLUSIVE logic from lsm_prepare() to lsm_order_append()
|
||||
in order to consolidate the individual LSM append/activation code,
|
||||
and adding logic to skip appending explicitly disabled LSMs to the
|
||||
active LSM list.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index bee12c553820..30ed62311565 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -124,24 +124,48 @@ static bool __init lsm_order_exists(struct lsm_info *lsm)
|
||||
return false;
|
||||
}
|
||||
|
||||
-/* Append an LSM to the list of ordered LSMs to initialize. */
|
||||
-static int last_lsm __initdata;
|
||||
-static void __init append_ordered_lsm(struct lsm_info *lsm, const char *from)
|
||||
+/**
|
||||
+ * lsm_order_append - Append a LSM to the ordered list
|
||||
+ * @lsm: LSM definition
|
||||
+ * @src: source of the addition
|
||||
+ *
|
||||
+ * Append @lsm to the enabled LSM array after ensuring that it hasn't been
|
||||
+ * explicitly disabled, is a duplicate entry, or would run afoul of the
|
||||
+ * LSM_FLAG_EXCLUSIVE logic.
|
||||
+ */
|
||||
+static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
|
||||
{
|
||||
/* Ignore duplicate selections. */
|
||||
if (lsm_order_exists(lsm))
|
||||
return;
|
||||
|
||||
- if (WARN(last_lsm == MAX_LSM_COUNT, "%s: out of LSM static calls!?\n", from))
|
||||
- return;
|
||||
+ /* Skip explicitly disabled LSMs. */
|
||||
+ if (lsm->enabled && !lsm_is_enabled(lsm))
|
||||
+ goto out;
|
||||
|
||||
- /* Enable this LSM, if it is not already set. */
|
||||
- if (!lsm->enabled)
|
||||
- lsm->enabled = &lsm_enabled_true;
|
||||
- lsm_order[last_lsm] = lsm;
|
||||
- lsm_idlist[last_lsm++] = lsm->id;
|
||||
+ if (WARN(lsm_active_cnt == MAX_LSM_COUNT,
|
||||
+ "%s: out of LSM static calls!?\n", src)) {
|
||||
+ lsm_enabled_set(lsm, false);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (lsm->flags & LSM_FLAG_EXCLUSIVE) {
|
||||
+ if (lsm_exclusive) {
|
||||
+ init_debug("exclusive disabled: %s\n", lsm->id->name);
|
||||
+ lsm_enabled_set(lsm, false);
|
||||
+ goto out;
|
||||
+ } else {
|
||||
+ init_debug("exclusive chosen: %s\n", lsm->id->name);
|
||||
+ lsm_exclusive = lsm;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- init_debug("%s ordered: %s (%s)\n", from, lsm->id->name,
|
||||
+ lsm_enabled_set(lsm, true);
|
||||
+ lsm_order[lsm_active_cnt] = lsm;
|
||||
+ lsm_idlist[lsm_active_cnt++] = lsm->id;
|
||||
+
|
||||
+out:
|
||||
+ init_debug("%s ordered: %s (%s)\n", src, lsm->id->name,
|
||||
lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
@@ -163,26 +187,12 @@ static void __init lsm_set_blob_size(int *need, int *lbs)
|
||||
*/
|
||||
static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
{
|
||||
- struct lsm_blob_sizes *blobs;
|
||||
+ struct lsm_blob_sizes *blobs = lsm->blobs;
|
||||
|
||||
- if (!lsm_is_enabled(lsm)) {
|
||||
- lsm_enabled_set(lsm, false);
|
||||
- return;
|
||||
- } else if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && lsm_exclusive) {
|
||||
- init_debug("exclusive disabled: %s\n", lsm->id->name);
|
||||
- lsm_enabled_set(lsm, false);
|
||||
+ if (!blobs)
|
||||
return;
|
||||
- }
|
||||
-
|
||||
- /* Mark the LSM as enabled. */
|
||||
- lsm_enabled_set(lsm, true);
|
||||
- if ((lsm->flags & LSM_FLAG_EXCLUSIVE) && !lsm_exclusive) {
|
||||
- init_debug("exclusive chosen: %s\n", lsm->id->name);
|
||||
- lsm_exclusive = lsm;
|
||||
- }
|
||||
|
||||
/* Register the LSM blob sizes. */
|
||||
- blobs = lsm->blobs;
|
||||
lsm_set_blob_size(&blobs->lbs_cred, &blob_sizes.lbs_cred);
|
||||
lsm_set_blob_size(&blobs->lbs_file, &blob_sizes.lbs_file);
|
||||
lsm_set_blob_size(&blobs->lbs_ib, &blob_sizes.lbs_ib);
|
||||
@@ -224,7 +234,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
/* LSM_ORDER_FIRST is always first. */
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (lsm->order == LSM_ORDER_FIRST)
|
||||
- append_ordered_lsm(lsm, " first");
|
||||
+ lsm_order_append(lsm, " first");
|
||||
}
|
||||
|
||||
/* Process "security=", if given. */
|
||||
@@ -256,7 +266,7 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (strcmp(lsm->id->name, name) == 0) {
|
||||
if (lsm->order == LSM_ORDER_MUTABLE)
|
||||
- append_ordered_lsm(lsm, origin);
|
||||
+ lsm_order_append(lsm, origin);
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
@@ -272,14 +282,14 @@ static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
if (lsm_order_exists(lsm))
|
||||
continue;
|
||||
if (strcmp(lsm->id->name, lsm_order_legacy) == 0)
|
||||
- append_ordered_lsm(lsm, "security=");
|
||||
+ lsm_order_append(lsm, "security=");
|
||||
}
|
||||
}
|
||||
|
||||
/* LSM_ORDER_LAST is always last. */
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (lsm->order == LSM_ORDER_LAST)
|
||||
- append_ordered_lsm(lsm, " last");
|
||||
+ lsm_order_append(lsm, " last");
|
||||
}
|
||||
|
||||
/* Disable all LSMs not in the ordered list. */
|
||||
@@ -413,8 +423,8 @@ int __init early_security_init(void)
|
||||
return 0;
|
||||
|
||||
lsm_early_for_each_raw(lsm) {
|
||||
- if (!lsm->enabled)
|
||||
- lsm->enabled = &lsm_enabled_true;
|
||||
+ lsm_enabled_set(lsm, true);
|
||||
+ lsm_order_append(lsm, "early");
|
||||
lsm_prepare(lsm);
|
||||
initialize_lsm(lsm);
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,166 @@
|
||||
From 9a0e65bba0a4f8b08943349600337bc08612db41 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:26:51 +0200
|
||||
Subject: [PATCH] lsm: rename/rework ordered_lsm_parse() to lsm_order_parse()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 752db06571816a3870b17814882425318b5ec0ef
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Sun Jul 13 17:51:12 2025 -0400
|
||||
|
||||
lsm: rename/rework ordered_lsm_parse() to lsm_order_parse()
|
||||
|
||||
Rename ordered_lsm_parse() to lsm_order_parse() for the sake of
|
||||
consistency with the other LSM initialization routines, and also
|
||||
do some minor rework of the function. Aside from some minor style
|
||||
decisions, the majority of the rework involved shuffling the order
|
||||
of the LSM_FLAG_LEGACY and LSM_ORDER_FIRST code so that the
|
||||
LSM_FLAG_LEGACY checks are handled first; it is important to note
|
||||
that this doesn't affect the order in which the LSMs are registered.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 30ed62311565..d159981ad0a2 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -225,83 +225,75 @@ static void __init initialize_lsm(struct lsm_info *lsm)
|
||||
}
|
||||
}
|
||||
|
||||
-/* Populate ordered LSMs list from comma-separated LSM name list. */
|
||||
-static void __init ordered_lsm_parse(const char *order, const char *origin)
|
||||
+/**
|
||||
+ * lsm_order_parse - Parse the comma delimited LSM list
|
||||
+ * @list: LSM list
|
||||
+ * @src: source of the list
|
||||
+ */
|
||||
+static void __init lsm_order_parse(const char *list, const char *src)
|
||||
{
|
||||
struct lsm_info *lsm;
|
||||
char *sep, *name, *next;
|
||||
|
||||
- /* LSM_ORDER_FIRST is always first. */
|
||||
- lsm_for_each_raw(lsm) {
|
||||
- if (lsm->order == LSM_ORDER_FIRST)
|
||||
- lsm_order_append(lsm, " first");
|
||||
- }
|
||||
-
|
||||
- /* Process "security=", if given. */
|
||||
+ /* Handle any Legacy LSM exclusions if one was specified. */
|
||||
if (lsm_order_legacy) {
|
||||
- struct lsm_info *major;
|
||||
-
|
||||
/*
|
||||
- * To match the original "security=" behavior, this
|
||||
- * explicitly does NOT fallback to another Legacy Major
|
||||
- * if the selected one was separately disabled: disable
|
||||
- * all non-matching Legacy Major LSMs.
|
||||
+ * To match the original "security=" behavior, this explicitly
|
||||
+ * does NOT fallback to another Legacy Major if the selected
|
||||
+ * one was separately disabled: disable all non-matching
|
||||
+ * Legacy Major LSMs.
|
||||
*/
|
||||
- lsm_for_each_raw(major) {
|
||||
- if ((major->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
- strcmp(major->id->name, lsm_order_legacy) != 0) {
|
||||
- lsm_enabled_set(major, false);
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
+ if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
+ strcmp(lsm->id->name, lsm_order_legacy)) {
|
||||
+ lsm_enabled_set(lsm, false);
|
||||
init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
|
||||
- lsm_order_legacy, major->id->name);
|
||||
+ lsm_order_legacy, lsm->id->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- sep = kstrdup(order, GFP_KERNEL);
|
||||
+ /* LSM_ORDER_FIRST */
|
||||
+ lsm_for_each_raw(lsm) {
|
||||
+ if (lsm->order == LSM_ORDER_FIRST)
|
||||
+ lsm_order_append(lsm, "first");
|
||||
+ }
|
||||
+
|
||||
+ /* Normal or "mutable" LSMs */
|
||||
+ sep = kstrdup(list, GFP_KERNEL);
|
||||
next = sep;
|
||||
/* Walk the list, looking for matching LSMs. */
|
||||
while ((name = strsep(&next, ",")) != NULL) {
|
||||
- bool found = false;
|
||||
-
|
||||
lsm_for_each_raw(lsm) {
|
||||
- if (strcmp(lsm->id->name, name) == 0) {
|
||||
- if (lsm->order == LSM_ORDER_MUTABLE)
|
||||
- lsm_order_append(lsm, origin);
|
||||
- found = true;
|
||||
- }
|
||||
+ if (!strcmp(lsm->id->name, name) &&
|
||||
+ lsm->order == LSM_ORDER_MUTABLE)
|
||||
+ lsm_order_append(lsm, src);
|
||||
}
|
||||
-
|
||||
- if (!found)
|
||||
- init_debug("%s ignored: %s (not built into kernel)\n",
|
||||
- origin, name);
|
||||
}
|
||||
+ kfree(sep);
|
||||
|
||||
- /* Process "security=", if given. */
|
||||
+ /* Legacy LSM if specified. */
|
||||
if (lsm_order_legacy) {
|
||||
lsm_for_each_raw(lsm) {
|
||||
- if (lsm_order_exists(lsm))
|
||||
- continue;
|
||||
- if (strcmp(lsm->id->name, lsm_order_legacy) == 0)
|
||||
- lsm_order_append(lsm, "security=");
|
||||
+ if (!strcmp(lsm->id->name, lsm_order_legacy))
|
||||
+ lsm_order_append(lsm, src);
|
||||
}
|
||||
}
|
||||
|
||||
- /* LSM_ORDER_LAST is always last. */
|
||||
+ /* LSM_ORDER_LAST */
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (lsm->order == LSM_ORDER_LAST)
|
||||
- lsm_order_append(lsm, " last");
|
||||
+ lsm_order_append(lsm, "last");
|
||||
}
|
||||
|
||||
- /* Disable all LSMs not in the ordered list. */
|
||||
+ /* Disable all LSMs not previously enabled. */
|
||||
lsm_for_each_raw(lsm) {
|
||||
if (lsm_order_exists(lsm))
|
||||
continue;
|
||||
lsm_enabled_set(lsm, false);
|
||||
init_debug("%s skipped: %s (not in requested order)\n",
|
||||
- origin, lsm->id->name);
|
||||
+ src, lsm->id->name);
|
||||
}
|
||||
-
|
||||
- kfree(sep);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -319,9 +311,9 @@ static void __init lsm_init_ordered(void)
|
||||
lsm_order_legacy, lsm_order_cmdline);
|
||||
lsm_order_legacy = NULL;
|
||||
}
|
||||
- ordered_lsm_parse(lsm_order_cmdline, "cmdline");
|
||||
+ lsm_order_parse(lsm_order_cmdline, "cmdline");
|
||||
} else
|
||||
- ordered_lsm_parse(lsm_order_builtin, "builtin");
|
||||
+ lsm_order_parse(lsm_order_builtin, "builtin");
|
||||
|
||||
lsm_order_for_each(lsm) {
|
||||
lsm_prepare(*lsm);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
148
1316-lsm-cleanup-the-lsm-blob-size-code.patch
Normal file
148
1316-lsm-cleanup-the-lsm-blob-size-code.patch
Normal file
@ -0,0 +1,148 @@
|
||||
From 7cbba38d94b554ea452c90264ea4f7b03ef18498 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Fri, 29 May 2026 18:37:27 +0200
|
||||
Subject: [PATCH] lsm: cleanup the LSM blob size code
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- conflict due to 5816bf4273ed ("lsm,selinux: Add LSM blob support for
|
||||
BPF objects"), which is not backported
|
||||
|
||||
commit 291271e691740003021cf5b48fa7cf7e3371eaa7
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Tue Feb 11 17:49:11 2025 -0500
|
||||
|
||||
lsm: cleanup the LSM blob size code
|
||||
|
||||
Convert the lsm_blob_size fields to unsigned integers as there is no
|
||||
current need for them to be negative, change "lsm_set_blob_size()" to
|
||||
"lsm_blob_size_update()" to better reflect reality, and perform some
|
||||
other minor cleanups to the associated code.
|
||||
|
||||
Reviewed-by: Kees Cook <kees@kernel.org>
|
||||
Reviewed-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
|
||||
index bc477fb20d02..a7ecb0791a0f 100644
|
||||
--- a/include/linux/lsm_hooks.h
|
||||
+++ b/include/linux/lsm_hooks.h
|
||||
@@ -102,20 +102,20 @@ struct security_hook_list {
|
||||
* Security blob size or offset data.
|
||||
*/
|
||||
struct lsm_blob_sizes {
|
||||
- int lbs_cred;
|
||||
- int lbs_file;
|
||||
- int lbs_ib;
|
||||
- int lbs_inode;
|
||||
- int lbs_sock;
|
||||
- int lbs_superblock;
|
||||
- int lbs_ipc;
|
||||
- int lbs_key;
|
||||
- int lbs_msg_msg;
|
||||
- int lbs_perf_event;
|
||||
- int lbs_task;
|
||||
- int lbs_xattr_count; /* number of xattr slots in new_xattrs array */
|
||||
- int lbs_tun_dev;
|
||||
- int lbs_bdev;
|
||||
+ unsigned int lbs_cred;
|
||||
+ unsigned int lbs_file;
|
||||
+ unsigned int lbs_ib;
|
||||
+ unsigned int lbs_inode;
|
||||
+ unsigned int lbs_sock;
|
||||
+ unsigned int lbs_superblock;
|
||||
+ unsigned int lbs_ipc;
|
||||
+ unsigned int lbs_key;
|
||||
+ unsigned int lbs_msg_msg;
|
||||
+ unsigned int lbs_perf_event;
|
||||
+ unsigned int lbs_task;
|
||||
+ unsigned int lbs_xattr_count; /* num xattr slots in new_xattrs array */
|
||||
+ unsigned int lbs_tun_dev;
|
||||
+ unsigned int lbs_bdev;
|
||||
};
|
||||
|
||||
/*
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index d159981ad0a2..bc9191b53305 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -169,16 +169,22 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
|
||||
lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
-static void __init lsm_set_blob_size(int *need, int *lbs)
|
||||
+/**
|
||||
+ * lsm_blob_size_update - Update the LSM blob size and offset information
|
||||
+ * @sz_req: the requested additional blob size
|
||||
+ * @sz_cur: the existing blob size
|
||||
+ */
|
||||
+static void __init lsm_blob_size_update(unsigned int *sz_req,
|
||||
+ unsigned int *sz_cur)
|
||||
{
|
||||
- int offset;
|
||||
+ unsigned int offset;
|
||||
|
||||
- if (*need <= 0)
|
||||
+ if (*sz_req == 0)
|
||||
return;
|
||||
|
||||
- offset = ALIGN(*lbs, sizeof(void *));
|
||||
- *lbs = offset + *need;
|
||||
- *need = offset;
|
||||
+ offset = ALIGN(*sz_cur, sizeof(void *));
|
||||
+ *sz_cur = offset + *sz_req;
|
||||
+ *sz_req = offset;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -193,24 +199,27 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
return;
|
||||
|
||||
/* Register the LSM blob sizes. */
|
||||
- lsm_set_blob_size(&blobs->lbs_cred, &blob_sizes.lbs_cred);
|
||||
- lsm_set_blob_size(&blobs->lbs_file, &blob_sizes.lbs_file);
|
||||
- lsm_set_blob_size(&blobs->lbs_ib, &blob_sizes.lbs_ib);
|
||||
+ blobs = lsm->blobs;
|
||||
+ lsm_blob_size_update(&blobs->lbs_cred, &blob_sizes.lbs_cred);
|
||||
+ lsm_blob_size_update(&blobs->lbs_file, &blob_sizes.lbs_file);
|
||||
+ lsm_blob_size_update(&blobs->lbs_ib, &blob_sizes.lbs_ib);
|
||||
/* inode blob gets an rcu_head in addition to LSM blobs. */
|
||||
if (blobs->lbs_inode && blob_sizes.lbs_inode == 0)
|
||||
blob_sizes.lbs_inode = sizeof(struct rcu_head);
|
||||
- lsm_set_blob_size(&blobs->lbs_inode, &blob_sizes.lbs_inode);
|
||||
- lsm_set_blob_size(&blobs->lbs_ipc, &blob_sizes.lbs_ipc);
|
||||
- lsm_set_blob_size(&blobs->lbs_key, &blob_sizes.lbs_key);
|
||||
- lsm_set_blob_size(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
|
||||
- lsm_set_blob_size(&blobs->lbs_perf_event, &blob_sizes.lbs_perf_event);
|
||||
- lsm_set_blob_size(&blobs->lbs_sock, &blob_sizes.lbs_sock);
|
||||
- lsm_set_blob_size(&blobs->lbs_superblock, &blob_sizes.lbs_superblock);
|
||||
- lsm_set_blob_size(&blobs->lbs_task, &blob_sizes.lbs_task);
|
||||
- lsm_set_blob_size(&blobs->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
|
||||
- lsm_set_blob_size(&blobs->lbs_xattr_count,
|
||||
- &blob_sizes.lbs_xattr_count);
|
||||
- lsm_set_blob_size(&blobs->lbs_bdev, &blob_sizes.lbs_bdev);
|
||||
+ lsm_blob_size_update(&blobs->lbs_inode, &blob_sizes.lbs_inode);
|
||||
+ lsm_blob_size_update(&blobs->lbs_ipc, &blob_sizes.lbs_ipc);
|
||||
+ lsm_blob_size_update(&blobs->lbs_key, &blob_sizes.lbs_key);
|
||||
+ lsm_blob_size_update(&blobs->lbs_msg_msg, &blob_sizes.lbs_msg_msg);
|
||||
+ lsm_blob_size_update(&blobs->lbs_perf_event,
|
||||
+ &blob_sizes.lbs_perf_event);
|
||||
+ lsm_blob_size_update(&blobs->lbs_sock, &blob_sizes.lbs_sock);
|
||||
+ lsm_blob_size_update(&blobs->lbs_superblock,
|
||||
+ &blob_sizes.lbs_superblock);
|
||||
+ lsm_blob_size_update(&blobs->lbs_task, &blob_sizes.lbs_task);
|
||||
+ lsm_blob_size_update(&blobs->lbs_tun_dev, &blob_sizes.lbs_tun_dev);
|
||||
+ lsm_blob_size_update(&blobs->lbs_xattr_count,
|
||||
+ &blob_sizes.lbs_xattr_count);
|
||||
+ lsm_blob_size_update(&blobs->lbs_bdev, &blob_sizes.lbs_bdev);
|
||||
}
|
||||
|
||||
/* Initialize a given LSM, if it is enabled. */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,88 @@
|
||||
From 800c1228fa046d32687562f80731aa1cda374657 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:28:42 +0200
|
||||
Subject: [PATCH] lsm: cleanup initialize_lsm() and rename to lsm_init_single()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 27be5600fe852c52d5b70f4ac9406879b39c864e
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Tue Feb 11 18:24:04 2025 -0500
|
||||
|
||||
lsm: cleanup initialize_lsm() and rename to lsm_init_single()
|
||||
|
||||
Rename initialize_lsm() to be more consistent with the rest of the LSM
|
||||
initialization changes and rework the function itself to better fit
|
||||
with the "exit on fail" coding pattern.
|
||||
|
||||
Reviewed-by: Kees Cook <kees@kernel.org>
|
||||
Reviewed-by: John Johansen <john.johansen@canonical.com>
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index bc9191b53305..8cf53a48f37c 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -169,6 +169,7 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
|
||||
lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
+
|
||||
/**
|
||||
* lsm_blob_size_update - Update the LSM blob size and offset information
|
||||
* @sz_req: the requested additional blob size
|
||||
@@ -222,16 +223,20 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
lsm_blob_size_update(&blobs->lbs_bdev, &blob_sizes.lbs_bdev);
|
||||
}
|
||||
|
||||
-/* Initialize a given LSM, if it is enabled. */
|
||||
-static void __init initialize_lsm(struct lsm_info *lsm)
|
||||
+/**
|
||||
+ * lsm_init_single - Initialize a given LSM
|
||||
+ * @lsm: LSM definition
|
||||
+ */
|
||||
+static void __init lsm_init_single(struct lsm_info *lsm)
|
||||
{
|
||||
- if (lsm_is_enabled(lsm)) {
|
||||
- int ret;
|
||||
+ int ret;
|
||||
|
||||
- init_debug("initializing %s\n", lsm->id->name);
|
||||
- ret = lsm->init();
|
||||
- WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
|
||||
- }
|
||||
+ if (!lsm_is_enabled(lsm))
|
||||
+ return;
|
||||
+
|
||||
+ init_debug("initializing %s\n", lsm->id->name);
|
||||
+ ret = lsm->init();
|
||||
+ WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -373,7 +378,7 @@ static void __init lsm_init_ordered(void)
|
||||
panic("%s: early task alloc failed.\n", __func__);
|
||||
|
||||
lsm_order_for_each(lsm) {
|
||||
- initialize_lsm(*lsm);
|
||||
+ lsm_init_single(*lsm);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -427,7 +432,7 @@ int __init early_security_init(void)
|
||||
lsm_enabled_set(lsm, true);
|
||||
lsm_order_append(lsm, "early");
|
||||
lsm_prepare(lsm);
|
||||
- initialize_lsm(lsm);
|
||||
+ lsm_init_single(lsm);
|
||||
}
|
||||
|
||||
early_security_initialized = true;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
236
1318-lsm-fold-lsm-init-ordered-into-security-init.patch
Normal file
236
1318-lsm-fold-lsm-init-ordered-into-security-init.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From 4b0683928d38d0fd4d8ce409bb75adfb669b9eb7 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:28:42 +0200
|
||||
Subject: [PATCH] lsm: fold lsm_init_ordered() into security_init()
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- conflict due to 5816bf4273ed ("lsm,selinux: Add LSM blob support for
|
||||
BPF objects"), which is not backported
|
||||
|
||||
commit 45a41d1394aa2ed0305f0560f93bb87be7192481
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Feb 12 18:10:37 2025 -0500
|
||||
|
||||
lsm: fold lsm_init_ordered() into security_init()
|
||||
|
||||
With only security_init() calling lsm_init_ordered, it makes little
|
||||
sense to keep lsm_init_ordered() as a standalone function. Fold
|
||||
lsm_init_ordered() into security_init().
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 8cf53a48f37c..560ce78f3493 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -18,6 +18,9 @@ static __initdata int lsm_enabled_false = 0;
|
||||
extern struct lsm_info __start_lsm_info[], __end_lsm_info[];
|
||||
extern struct lsm_info __start_early_lsm_info[], __end_early_lsm_info[];
|
||||
|
||||
+/* Number of "early" LSMs */
|
||||
+static __initdata unsigned int lsm_count_early;
|
||||
+
|
||||
/* Build and boot-time LSM ordering. */
|
||||
static __initconst const char *const lsm_order_builtin = CONFIG_LSM;
|
||||
static __initdata const char *lsm_order_cmdline;
|
||||
@@ -169,7 +172,6 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
|
||||
lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
}
|
||||
|
||||
-
|
||||
/**
|
||||
* lsm_blob_size_update - Update the LSM blob size and offset information
|
||||
* @sz_req: the requested additional blob size
|
||||
@@ -310,78 +312,6 @@ static void __init lsm_order_parse(const char *list, const char *src)
|
||||
}
|
||||
}
|
||||
|
||||
-/**
|
||||
- * lsm_init_ordered - Initialize the ordered LSMs
|
||||
- */
|
||||
-static void __init lsm_init_ordered(void)
|
||||
-{
|
||||
- unsigned int first = 0;
|
||||
- struct lsm_info **lsm;
|
||||
- struct lsm_info *early;
|
||||
-
|
||||
- if (lsm_order_cmdline) {
|
||||
- if (lsm_order_legacy) {
|
||||
- pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
|
||||
- lsm_order_legacy, lsm_order_cmdline);
|
||||
- lsm_order_legacy = NULL;
|
||||
- }
|
||||
- lsm_order_parse(lsm_order_cmdline, "cmdline");
|
||||
- } else
|
||||
- lsm_order_parse(lsm_order_builtin, "builtin");
|
||||
-
|
||||
- lsm_order_for_each(lsm) {
|
||||
- lsm_prepare(*lsm);
|
||||
- }
|
||||
-
|
||||
- pr_info("initializing lsm=");
|
||||
- lsm_early_for_each_raw(early) {
|
||||
- if (lsm_is_enabled(early))
|
||||
- pr_cont("%s%s",
|
||||
- first++ == 0 ? "" : ",", early->id->name);
|
||||
- }
|
||||
- lsm_order_for_each(lsm) {
|
||||
- if (lsm_is_enabled(*lsm))
|
||||
- pr_cont("%s%s",
|
||||
- first++ == 0 ? "" : ",", (*lsm)->id->name);
|
||||
- }
|
||||
- pr_cont("\n");
|
||||
-
|
||||
- init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
|
||||
- init_debug("file blob size = %d\n", blob_sizes.lbs_file);
|
||||
- init_debug("ib blob size = %d\n", blob_sizes.lbs_ib);
|
||||
- init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
|
||||
- init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
|
||||
-#ifdef CONFIG_KEYS
|
||||
- init_debug("key blob size = %d\n", blob_sizes.lbs_key);
|
||||
-#endif /* CONFIG_KEYS */
|
||||
- init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
|
||||
- init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
|
||||
- init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
|
||||
- init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
|
||||
- init_debug("task blob size = %d\n", blob_sizes.lbs_task);
|
||||
- init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
|
||||
- init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
|
||||
- init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
|
||||
-
|
||||
- if (blob_sizes.lbs_file)
|
||||
- lsm_file_cache = kmem_cache_create("lsm_file_cache",
|
||||
- blob_sizes.lbs_file, 0,
|
||||
- SLAB_PANIC, NULL);
|
||||
- if (blob_sizes.lbs_inode)
|
||||
- lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
|
||||
- blob_sizes.lbs_inode, 0,
|
||||
- SLAB_PANIC, NULL);
|
||||
-
|
||||
- if (lsm_cred_alloc((struct cred __rcu *)current->cred, GFP_KERNEL))
|
||||
- panic("%s: early cred alloc failed.\n", __func__);
|
||||
- if (lsm_task_alloc(current))
|
||||
- panic("%s: early task alloc failed.\n", __func__);
|
||||
-
|
||||
- lsm_order_for_each(lsm) {
|
||||
- lsm_init_single(*lsm);
|
||||
- }
|
||||
-}
|
||||
-
|
||||
static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
{
|
||||
struct lsm_static_call *scall = hl->scalls;
|
||||
@@ -433,6 +363,7 @@ int __init early_security_init(void)
|
||||
lsm_order_append(lsm, "early");
|
||||
lsm_prepare(lsm);
|
||||
lsm_init_single(lsm);
|
||||
+ lsm_count_early++;
|
||||
}
|
||||
|
||||
early_security_initialized = true;
|
||||
@@ -440,29 +371,85 @@ int __init early_security_init(void)
|
||||
}
|
||||
|
||||
/**
|
||||
- * security_init - initializes the security framework
|
||||
+ * security_init - Initializes the LSM framework
|
||||
*
|
||||
* This should be called early in the kernel initialization sequence.
|
||||
*/
|
||||
int __init security_init(void)
|
||||
{
|
||||
- struct lsm_info *lsm;
|
||||
+ unsigned int cnt;
|
||||
+ struct lsm_info **lsm;
|
||||
+ struct lsm_info *early;
|
||||
+ unsigned int first = 0;
|
||||
|
||||
init_debug("legacy security=%s\n", lsm_order_legacy ? : " *unspecified*");
|
||||
init_debug(" CONFIG_LSM=%s\n", lsm_order_builtin);
|
||||
init_debug("boot arg lsm=%s\n", lsm_order_cmdline ? : " *unspecified*");
|
||||
|
||||
- /*
|
||||
- * Append the names of the early LSM modules now that kmalloc() is
|
||||
- * available
|
||||
- */
|
||||
- lsm_early_for_each_raw(lsm) {
|
||||
- init_debug(" early started: %s (%s)\n", lsm->id->name,
|
||||
- lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
+ if (lsm_order_cmdline) {
|
||||
+ if (lsm_order_legacy) {
|
||||
+ pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
|
||||
+ lsm_order_legacy, lsm_order_cmdline);
|
||||
+ lsm_order_legacy = NULL;
|
||||
+ }
|
||||
+ lsm_order_parse(lsm_order_cmdline, "cmdline");
|
||||
+ } else
|
||||
+ lsm_order_parse(lsm_order_builtin, "builtin");
|
||||
+
|
||||
+ lsm_order_for_each(lsm)
|
||||
+ lsm_prepare(*lsm);
|
||||
+
|
||||
+ pr_info("initializing lsm=");
|
||||
+ lsm_early_for_each_raw(early) {
|
||||
+ if (lsm_is_enabled(early))
|
||||
+ pr_cont("%s%s",
|
||||
+ first++ == 0 ? "" : ",", early->id->name);
|
||||
+ }
|
||||
+ lsm_order_for_each(lsm) {
|
||||
+ if (lsm_is_enabled(*lsm))
|
||||
+ pr_cont("%s%s",
|
||||
+ first++ == 0 ? "" : ",", (*lsm)->id->name);
|
||||
}
|
||||
+ pr_cont("\n");
|
||||
+
|
||||
+ init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
|
||||
+ init_debug("file blob size = %d\n", blob_sizes.lbs_file);
|
||||
+ init_debug("ib blob size = %d\n", blob_sizes.lbs_ib);
|
||||
+ init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
|
||||
+ init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
|
||||
+#ifdef CONFIG_KEYS
|
||||
+ init_debug("key blob size = %d\n", blob_sizes.lbs_key);
|
||||
+#endif /* CONFIG_KEYS */
|
||||
+ init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
|
||||
+ init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
|
||||
+ init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
|
||||
+ init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
|
||||
+ init_debug("task blob size = %d\n", blob_sizes.lbs_task);
|
||||
+ init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
|
||||
+ init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
|
||||
+ init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
|
||||
+
|
||||
+ if (blob_sizes.lbs_file)
|
||||
+ lsm_file_cache = kmem_cache_create("lsm_file_cache",
|
||||
+ blob_sizes.lbs_file, 0,
|
||||
+ SLAB_PANIC, NULL);
|
||||
+ if (blob_sizes.lbs_inode)
|
||||
+ lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
|
||||
+ blob_sizes.lbs_inode, 0,
|
||||
+ SLAB_PANIC, NULL);
|
||||
|
||||
- /* Load LSMs in specified order. */
|
||||
- lsm_init_ordered();
|
||||
+ if (lsm_cred_alloc((struct cred __rcu *)current->cred, GFP_KERNEL))
|
||||
+ panic("%s: early cred alloc failed.\n", __func__);
|
||||
+ if (lsm_task_alloc(current))
|
||||
+ panic("%s: early task alloc failed.\n", __func__);
|
||||
+
|
||||
+ cnt = 0;
|
||||
+ lsm_order_for_each(lsm) {
|
||||
+ /* skip the "early" LSMs as they have already been setup */
|
||||
+ if (cnt++ < lsm_count_early)
|
||||
+ continue;
|
||||
+ lsm_init_single(*lsm);
|
||||
+ }
|
||||
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 5a8181960a7f242505b8b6782253a87545aec9d3 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:28:43 +0200
|
||||
Subject: [PATCH] lsm: add/tweak function header comment blocks in lsm_init.c
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
|
||||
commit 450705334f698990804b470437f3014cee979486
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Feb 12 18:17:03 2025 -0500
|
||||
|
||||
lsm: add/tweak function header comment blocks in lsm_init.c
|
||||
|
||||
Add function header comments for lsm_static_call_init() and
|
||||
early_security_init(), tweak the existing comment block for
|
||||
security_add_hooks().
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index 560ce78f3493..a7eeeca2cb67 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -312,6 +312,10 @@ static void __init lsm_order_parse(const char *list, const char *src)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * lsm_static_call_init - Initialize a LSM's static calls
|
||||
+ * @hl: LSM hook list
|
||||
+ */
|
||||
static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
{
|
||||
struct lsm_static_call *scall = hl->scalls;
|
||||
@@ -332,12 +336,12 @@ static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
}
|
||||
|
||||
/**
|
||||
- * security_add_hooks - Add a modules hooks to the hook lists.
|
||||
- * @hooks: the hooks to add
|
||||
- * @count: the number of hooks to add
|
||||
- * @lsmid: the identification information for the security module
|
||||
+ * security_add_hooks - Add a LSM's hooks to the LSM framework's hook lists
|
||||
+ * @hooks: LSM hooks to add
|
||||
+ * @count: number of hooks to add
|
||||
+ * @lsmid: identification information for the LSM
|
||||
*
|
||||
- * Each LSM has to register its hooks with the infrastructure.
|
||||
+ * Each LSM has to register its hooks with the LSM framework.
|
||||
*/
|
||||
void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
||||
const struct lsm_id *lsmid)
|
||||
@@ -350,6 +354,9 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * early_security_init - Initialize the early LSMs
|
||||
+ */
|
||||
int __init early_security_init(void)
|
||||
{
|
||||
struct lsm_info *lsm;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,299 @@
|
||||
From 455eabf0b6cf32582a8f485f2628a4e0a90fe398 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 10:30:41 +0200
|
||||
Subject: [PATCH] lsm: cleanup the debug and console output in lsm_init.c
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- conflict due to 5816bf4273ed ("lsm,selinux: Add LSM blob support for
|
||||
BPF objects"), which is not backported
|
||||
|
||||
commit 5137e583ba2635b82667dc63cb35305750420411
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Wed Feb 12 18:20:01 2025 -0500
|
||||
|
||||
lsm: cleanup the debug and console output in lsm_init.c
|
||||
|
||||
Move away from an init specific init_debug() macro to a more general
|
||||
lsm_pr()/lsm_pr_cont()/lsm_pr_dbg() set of macros that are available
|
||||
both before and after init. In the process we do a number of minor
|
||||
changes to improve the LSM initialization output and cleanup the code
|
||||
somewhat.
|
||||
|
||||
Reviewed-by: Casey Schaufler <casey@schaufler-ca.com>
|
||||
Reviewed-by: John Johansen <john.johhansen@canonical.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/lsm.h b/security/lsm.h
|
||||
index dbe755c45e57..8dc267977ae0 100644
|
||||
--- a/security/lsm.h
|
||||
+++ b/security/lsm.h
|
||||
@@ -6,9 +6,20 @@
|
||||
#ifndef _LSM_H_
|
||||
#define _LSM_H_
|
||||
|
||||
+#include <linux/printk.h>
|
||||
#include <linux/lsm_hooks.h>
|
||||
#include <linux/lsm_count.h>
|
||||
|
||||
+/* LSM debugging */
|
||||
+extern bool lsm_debug;
|
||||
+#define lsm_pr(...) pr_info(__VA_ARGS__)
|
||||
+#define lsm_pr_cont(...) pr_cont(__VA_ARGS__)
|
||||
+#define lsm_pr_dbg(...) \
|
||||
+ do { \
|
||||
+ if (lsm_debug) \
|
||||
+ pr_info(__VA_ARGS__); \
|
||||
+ } while (0)
|
||||
+
|
||||
/* List of configured LSMs */
|
||||
extern unsigned int lsm_active_cnt;
|
||||
extern const struct lsm_id *lsm_idlist[];
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index a7eeeca2cb67..bef21da72c16 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -30,13 +30,6 @@ static __initdata const char *lsm_order_legacy;
|
||||
static __initdata struct lsm_info *lsm_order[MAX_LSM_COUNT + 1];
|
||||
static __initdata struct lsm_info *lsm_exclusive;
|
||||
|
||||
-static __initdata bool debug;
|
||||
-#define init_debug(...) \
|
||||
- do { \
|
||||
- if (debug) \
|
||||
- pr_info(__VA_ARGS__); \
|
||||
- } while (0)
|
||||
-
|
||||
#define lsm_order_for_each(iter) \
|
||||
for ((iter) = lsm_order; *(iter); (iter)++)
|
||||
#define lsm_for_each_raw(iter) \
|
||||
@@ -77,7 +70,7 @@ __setup("lsm=", lsm_choose_lsm);
|
||||
*/
|
||||
static int __init lsm_debug_enable(char *str)
|
||||
{
|
||||
- debug = true;
|
||||
+ lsm_debug = true;
|
||||
return 1;
|
||||
}
|
||||
__setup("lsm.debug", lsm_debug_enable);
|
||||
@@ -143,22 +136,28 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
|
||||
return;
|
||||
|
||||
/* Skip explicitly disabled LSMs. */
|
||||
- if (lsm->enabled && !lsm_is_enabled(lsm))
|
||||
- goto out;
|
||||
+ if (lsm->enabled && !lsm_is_enabled(lsm)) {
|
||||
+ lsm_pr_dbg("skip previously disabled LSM %s:%s\n",
|
||||
+ src, lsm->id->name);
|
||||
+ return;
|
||||
+ }
|
||||
|
||||
- if (WARN(lsm_active_cnt == MAX_LSM_COUNT,
|
||||
- "%s: out of LSM static calls!?\n", src)) {
|
||||
+ if (lsm_active_cnt == MAX_LSM_COUNT) {
|
||||
+ pr_warn("exceeded maximum LSM count on %s:%s\n",
|
||||
+ src, lsm->id->name);
|
||||
lsm_enabled_set(lsm, false);
|
||||
- goto out;
|
||||
+ return;
|
||||
}
|
||||
|
||||
if (lsm->flags & LSM_FLAG_EXCLUSIVE) {
|
||||
if (lsm_exclusive) {
|
||||
- init_debug("exclusive disabled: %s\n", lsm->id->name);
|
||||
+ lsm_pr_dbg("skip exclusive LSM conflict %s:%s\n",
|
||||
+ src, lsm->id->name);
|
||||
lsm_enabled_set(lsm, false);
|
||||
- goto out;
|
||||
+ return;
|
||||
} else {
|
||||
- init_debug("exclusive chosen: %s\n", lsm->id->name);
|
||||
+ lsm_pr_dbg("select exclusive LSM %s:%s\n",
|
||||
+ src, lsm->id->name);
|
||||
lsm_exclusive = lsm;
|
||||
}
|
||||
}
|
||||
@@ -167,9 +166,7 @@ static void __init lsm_order_append(struct lsm_info *lsm, const char *src)
|
||||
lsm_order[lsm_active_cnt] = lsm;
|
||||
lsm_idlist[lsm_active_cnt++] = lsm->id;
|
||||
|
||||
-out:
|
||||
- init_debug("%s ordered: %s (%s)\n", src, lsm->id->name,
|
||||
- lsm_is_enabled(lsm) ? "enabled" : "disabled");
|
||||
+ lsm_pr_dbg("enabling LSM %s:%s\n", src, lsm->id->name);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -236,7 +233,7 @@ static void __init lsm_init_single(struct lsm_info *lsm)
|
||||
if (!lsm_is_enabled(lsm))
|
||||
return;
|
||||
|
||||
- init_debug("initializing %s\n", lsm->id->name);
|
||||
+ lsm_pr_dbg("initializing %s\n", lsm->id->name);
|
||||
ret = lsm->init();
|
||||
WARN(ret, "%s failed to initialize: %d\n", lsm->id->name, ret);
|
||||
}
|
||||
@@ -263,8 +260,8 @@ static void __init lsm_order_parse(const char *list, const char *src)
|
||||
if ((lsm->flags & LSM_FLAG_LEGACY_MAJOR) &&
|
||||
strcmp(lsm->id->name, lsm_order_legacy)) {
|
||||
lsm_enabled_set(lsm, false);
|
||||
- init_debug("security=%s disabled: %s (only one legacy major LSM)\n",
|
||||
- lsm_order_legacy, lsm->id->name);
|
||||
+ lsm_pr_dbg("skip legacy LSM conflict %s:%s\n",
|
||||
+ src, lsm->id->name);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -307,8 +304,7 @@ static void __init lsm_order_parse(const char *list, const char *src)
|
||||
if (lsm_order_exists(lsm))
|
||||
continue;
|
||||
lsm_enabled_set(lsm, false);
|
||||
- init_debug("%s skipped: %s (not in requested order)\n",
|
||||
- src, lsm->id->name);
|
||||
+ lsm_pr_dbg("skip disabled LSM %s:%s\n", src, lsm->id->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,7 +312,7 @@ static void __init lsm_order_parse(const char *list, const char *src)
|
||||
* lsm_static_call_init - Initialize a LSM's static calls
|
||||
* @hl: LSM hook list
|
||||
*/
|
||||
-static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
+static int __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
{
|
||||
struct lsm_static_call *scall = hl->scalls;
|
||||
int i;
|
||||
@@ -328,11 +324,12 @@ static void __init lsm_static_call_init(struct security_hook_list *hl)
|
||||
hl->hook.lsm_func_addr);
|
||||
scall->hl = hl;
|
||||
static_branch_enable(scall->active);
|
||||
- return;
|
||||
+ return 0;
|
||||
}
|
||||
scall++;
|
||||
}
|
||||
- panic("%s - Ran out of static slots.\n", __func__);
|
||||
+
|
||||
+ return -ENOSPC;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -350,7 +347,9 @@ void __init security_add_hooks(struct security_hook_list *hooks, int count,
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
hooks[i].lsmid = lsmid;
|
||||
- lsm_static_call_init(&hooks[i]);
|
||||
+ if (lsm_static_call_init(&hooks[i]))
|
||||
+ panic("exhausted LSM callback slots with LSM %s\n",
|
||||
+ lsmid->name);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -386,19 +385,16 @@ int __init security_init(void)
|
||||
{
|
||||
unsigned int cnt;
|
||||
struct lsm_info **lsm;
|
||||
- struct lsm_info *early;
|
||||
- unsigned int first = 0;
|
||||
|
||||
- init_debug("legacy security=%s\n", lsm_order_legacy ? : " *unspecified*");
|
||||
- init_debug(" CONFIG_LSM=%s\n", lsm_order_builtin);
|
||||
- init_debug("boot arg lsm=%s\n", lsm_order_cmdline ? : " *unspecified*");
|
||||
+ if (lsm_debug) {
|
||||
+ lsm_pr("built-in LSM list: %s\n", lsm_order_builtin);
|
||||
+ lsm_pr("legacy LSM parameter: %s\n", lsm_order_legacy);
|
||||
+ lsm_pr("boot LSM parameter: %s\n", lsm_order_cmdline);
|
||||
+ }
|
||||
|
||||
if (lsm_order_cmdline) {
|
||||
- if (lsm_order_legacy) {
|
||||
- pr_warn("security=%s is ignored because it is superseded by lsm=%s\n",
|
||||
- lsm_order_legacy, lsm_order_cmdline);
|
||||
+ if (lsm_order_legacy)
|
||||
lsm_order_legacy = NULL;
|
||||
- }
|
||||
lsm_order_parse(lsm_order_cmdline, "cmdline");
|
||||
} else
|
||||
lsm_order_parse(lsm_order_builtin, "builtin");
|
||||
@@ -406,35 +402,22 @@ int __init security_init(void)
|
||||
lsm_order_for_each(lsm)
|
||||
lsm_prepare(*lsm);
|
||||
|
||||
- pr_info("initializing lsm=");
|
||||
- lsm_early_for_each_raw(early) {
|
||||
- if (lsm_is_enabled(early))
|
||||
- pr_cont("%s%s",
|
||||
- first++ == 0 ? "" : ",", early->id->name);
|
||||
- }
|
||||
- lsm_order_for_each(lsm) {
|
||||
- if (lsm_is_enabled(*lsm))
|
||||
- pr_cont("%s%s",
|
||||
- first++ == 0 ? "" : ",", (*lsm)->id->name);
|
||||
+ if (lsm_debug) {
|
||||
+ lsm_pr("blob(cred) size %d\n", blob_sizes.lbs_cred);
|
||||
+ lsm_pr("blob(file) size %d\n", blob_sizes.lbs_file);
|
||||
+ lsm_pr("blob(ib) size %d\n", blob_sizes.lbs_ib);
|
||||
+ lsm_pr("blob(inode) size %d\n", blob_sizes.lbs_inode);
|
||||
+ lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
|
||||
+ lsm_pr("blob(key) size %d\n", blob_sizes.lbs_key);
|
||||
+ lsm_pr("blob(msg_msg)_size %d\n", blob_sizes.lbs_msg_msg);
|
||||
+ lsm_pr("blob(sock) size %d\n", blob_sizes.lbs_sock);
|
||||
+ lsm_pr("blob(superblock) size %d\n", blob_sizes.lbs_superblock);
|
||||
+ lsm_pr("blob(perf_event) size %d\n", blob_sizes.lbs_perf_event);
|
||||
+ lsm_pr("blob(task) size %d\n", blob_sizes.lbs_task);
|
||||
+ lsm_pr("blob(tun_dev) size %d\n", blob_sizes.lbs_tun_dev);
|
||||
+ lsm_pr("blob(xattr) count %d\n", blob_sizes.lbs_xattr_count);
|
||||
+ lsm_pr("blob(bdev) size %d\n", blob_sizes.lbs_bdev);
|
||||
}
|
||||
- pr_cont("\n");
|
||||
-
|
||||
- init_debug("cred blob size = %d\n", blob_sizes.lbs_cred);
|
||||
- init_debug("file blob size = %d\n", blob_sizes.lbs_file);
|
||||
- init_debug("ib blob size = %d\n", blob_sizes.lbs_ib);
|
||||
- init_debug("inode blob size = %d\n", blob_sizes.lbs_inode);
|
||||
- init_debug("ipc blob size = %d\n", blob_sizes.lbs_ipc);
|
||||
-#ifdef CONFIG_KEYS
|
||||
- init_debug("key blob size = %d\n", blob_sizes.lbs_key);
|
||||
-#endif /* CONFIG_KEYS */
|
||||
- init_debug("msg_msg blob size = %d\n", blob_sizes.lbs_msg_msg);
|
||||
- init_debug("sock blob size = %d\n", blob_sizes.lbs_sock);
|
||||
- init_debug("superblock blob size = %d\n", blob_sizes.lbs_superblock);
|
||||
- init_debug("perf event blob size = %d\n", blob_sizes.lbs_perf_event);
|
||||
- init_debug("task blob size = %d\n", blob_sizes.lbs_task);
|
||||
- init_debug("tun device blob size = %d\n", blob_sizes.lbs_tun_dev);
|
||||
- init_debug("xattr slots = %d\n", blob_sizes.lbs_xattr_count);
|
||||
- init_debug("bdev blob size = %d\n", blob_sizes.lbs_bdev);
|
||||
|
||||
if (blob_sizes.lbs_file)
|
||||
lsm_file_cache = kmem_cache_create("lsm_file_cache",
|
||||
@@ -446,9 +429,9 @@ int __init security_init(void)
|
||||
SLAB_PANIC, NULL);
|
||||
|
||||
if (lsm_cred_alloc((struct cred __rcu *)current->cred, GFP_KERNEL))
|
||||
- panic("%s: early cred alloc failed.\n", __func__);
|
||||
+ panic("early LSM cred alloc failed\n");
|
||||
if (lsm_task_alloc(current))
|
||||
- panic("%s: early task alloc failed.\n", __func__);
|
||||
+ panic("early LSM task alloc failed\n");
|
||||
|
||||
cnt = 0;
|
||||
lsm_order_for_each(lsm) {
|
||||
diff --git a/security/security.c b/security/security.c
|
||||
index 6f20f44c8d13..56c48725e334 100644
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -74,6 +74,8 @@ const char *const lockdown_reasons[LOCKDOWN_CONFIDENTIALITY_MAX + 1] = {
|
||||
[LOCKDOWN_CONFIDENTIALITY_MAX] = "confidentiality",
|
||||
};
|
||||
|
||||
+bool lsm_debug __ro_after_init;
|
||||
+
|
||||
unsigned int lsm_active_cnt __ro_after_init;
|
||||
const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
88
1321-fs-prepare-for-adding-lsm-blob-to-backing-file.patch
Normal file
88
1321-fs-prepare-for-adding-lsm-blob-to-backing-file.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From 1367930b371086acec799dd7062ce70dae049608 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 10:09:51 +0200
|
||||
Subject: [PATCH] fs: prepare for adding LSM blob to backing_file
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- fs/file_table.c: trivial context fuzz
|
||||
|
||||
commit 880bd496ec72a6dcb00cb70c430ef752ba242ae7
|
||||
Author: Amir Goldstein <amir73il@gmail.com>
|
||||
Date: Mon Mar 30 10:27:51 2026 +0200
|
||||
|
||||
fs: prepare for adding LSM blob to backing_file
|
||||
|
||||
In preparation to adding LSM blob to backing_file struct, factor out
|
||||
helpers init_backing_file() and backing_file_free().
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: linux-fsdevel@vger.kernel.org
|
||||
Cc: linux-unionfs@vger.kernel.org
|
||||
Cc: linux-erofs@lists.ozlabs.org
|
||||
Signed-off-by: Amir Goldstein <amir73il@gmail.com>
|
||||
Reviewed-by: Serge Hallyn <serge@hallyn.com>
|
||||
[PM: use the term "LSM blob", fix comment style to match file]
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/fs/file_table.c b/fs/file_table.c
|
||||
index 9979efb9a380..4b4d50a1d9da 100644
|
||||
--- a/fs/file_table.c
|
||||
+++ b/fs/file_table.c
|
||||
@@ -67,6 +67,12 @@ void backing_file_set_user_path(struct file *f, const struct path *path)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(backing_file_set_user_path);
|
||||
|
||||
+static inline void backing_file_free(struct backing_file *ff)
|
||||
+{
|
||||
+ path_put(&ff->user_path);
|
||||
+ kmem_cache_free(bfilp_cachep, ff);
|
||||
+}
|
||||
+
|
||||
static inline void file_free(struct file *f)
|
||||
{
|
||||
security_file_free(f);
|
||||
@@ -74,8 +80,7 @@ static inline void file_free(struct file *f)
|
||||
percpu_counter_dec(&nr_files);
|
||||
put_cred(f->f_cred);
|
||||
if (unlikely(f->f_mode & FMODE_BACKING)) {
|
||||
- path_put(backing_file_user_path(f));
|
||||
- kmem_cache_free(bfilp_cachep, backing_file(f));
|
||||
+ backing_file_free(backing_file(f));
|
||||
} else {
|
||||
kmem_cache_free(filp_cachep, f);
|
||||
}
|
||||
@@ -278,6 +283,12 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred)
|
||||
return f;
|
||||
}
|
||||
|
||||
+static int init_backing_file(struct backing_file *ff)
|
||||
+{
|
||||
+ memset(&ff->user_path, 0, sizeof(ff->user_path));
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Variant of alloc_empty_file() that allocates a backing_file container
|
||||
* and doesn't check and modify nr_files.
|
||||
@@ -300,7 +311,14 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
|
||||
return ERR_PTR(error);
|
||||
}
|
||||
|
||||
+ /* The f_mode flags must be set before fput(). */
|
||||
ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT;
|
||||
+ error = init_backing_file(ff);
|
||||
+ if (unlikely(error)) {
|
||||
+ fput(&ff->file);
|
||||
+ return ERR_PTR(error);
|
||||
+ }
|
||||
+
|
||||
return &ff->file;
|
||||
}
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
569
1322-lsm-add-backing-file-lsm-hooks.patch
Normal file
569
1322-lsm-add-backing-file-lsm-hooks.patch
Normal file
@ -0,0 +1,569 @@
|
||||
From c2685f8b7b4392f68d8492a331de2f544cc80a8b Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 10:36:28 +0200
|
||||
Subject: [PATCH] lsm: add backing_file LSM hooks
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- fs/backing-file.c: adjust backing_file_mmap() to downstream state (missing
|
||||
scoped guards)
|
||||
- fs/erofs/ishare.c: hunk dropped, files not in RHEL10
|
||||
- fs/overlayfs/dir.c: adjust to different indentation
|
||||
- fs/overlayfs/file.c: adjust to different indentation
|
||||
|
||||
commit 6af36aeb147a06dea47c49859cd6ca5659aeb987
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Fri Dec 19 13:18:22 2025 -0500
|
||||
|
||||
lsm: add backing_file LSM hooks
|
||||
|
||||
Stacked filesystems such as overlayfs do not currently provide the
|
||||
necessary mechanisms for LSMs to properly enforce access controls on the
|
||||
mmap() and mprotect() operations. In order to resolve this gap, a LSM
|
||||
security blob is being added to the backing_file struct and the following
|
||||
new LSM hooks are being created:
|
||||
|
||||
security_backing_file_alloc()
|
||||
security_backing_file_free()
|
||||
security_mmap_backing_file()
|
||||
|
||||
The first two hooks are to manage the lifecycle of the LSM security blob
|
||||
in the backing_file struct, while the third provides a new mmap() access
|
||||
control point for the underlying backing file. It is also expected that
|
||||
LSMs will likely want to update their security_file_mprotect() callback
|
||||
to address issues with their mprotect() controls, but that does not
|
||||
require a change to the security_file_mprotect() LSM hook.
|
||||
|
||||
There are a three other small changes to support these new LSM hooks:
|
||||
* Pass the user file associated with a backing file down to
|
||||
alloc_empty_backing_file() so it can be included in the
|
||||
security_backing_file_alloc() hook.
|
||||
* Add getter and setter functions for the backing_file struct LSM blob
|
||||
as the backing_file struct remains private to fs/file_table.c.
|
||||
* Constify the file struct field in the LSM common_audit_data struct to
|
||||
better support LSMs that need to pass a const file struct pointer into
|
||||
the common LSM audit code.
|
||||
|
||||
Thanks to Arnd Bergmann for identifying the missing EXPORT_SYMBOL_GPL()
|
||||
and supplying a fixup.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Cc: linux-fsdevel@vger.kernel.org
|
||||
Cc: linux-unionfs@vger.kernel.org
|
||||
Cc: linux-erofs@lists.ozlabs.org
|
||||
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
|
||||
Reviewed-by: Serge Hallyn <serge@hallyn.com>
|
||||
Reviewed-by: Christian Brauner <brauner@kernel.org>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/fs/backing-file.c b/fs/backing-file.c
|
||||
index 892361c31c3d..bb7ecb0fc3ae 100644
|
||||
--- a/fs/backing-file.c
|
||||
+++ b/fs/backing-file.c
|
||||
@@ -12,6 +12,7 @@
|
||||
#include <linux/backing-file.h>
|
||||
#include <linux/splice.h>
|
||||
#include <linux/mm.h>
|
||||
+#include <linux/security.h>
|
||||
|
||||
#include "internal.h"
|
||||
|
||||
@@ -29,14 +30,15 @@
|
||||
* returned file into a container structure that also stores the stacked
|
||||
* file's path, which can be retrieved using backing_file_user_path().
|
||||
*/
|
||||
-struct file *backing_file_open(const struct path *user_path, int flags,
|
||||
+struct file *backing_file_open(const struct file *user_file, int flags,
|
||||
const struct path *real_path,
|
||||
const struct cred *cred)
|
||||
{
|
||||
+ const struct path *user_path = &user_file->f_path;
|
||||
struct file *f;
|
||||
int error;
|
||||
|
||||
- f = alloc_empty_backing_file(flags, cred);
|
||||
+ f = alloc_empty_backing_file(flags, cred, user_file);
|
||||
if (IS_ERR(f))
|
||||
return f;
|
||||
|
||||
@@ -52,15 +54,16 @@ struct file *backing_file_open(const struct path *user_path, int flags,
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(backing_file_open);
|
||||
|
||||
-struct file *backing_tmpfile_open(const struct path *user_path, int flags,
|
||||
+struct file *backing_tmpfile_open(const struct file *user_file, int flags,
|
||||
const struct path *real_parentpath,
|
||||
umode_t mode, const struct cred *cred)
|
||||
{
|
||||
struct mnt_idmap *real_idmap = mnt_idmap(real_parentpath->mnt);
|
||||
+ const struct path *user_path = &user_file->f_path;
|
||||
struct file *f;
|
||||
int error;
|
||||
|
||||
- f = alloc_empty_backing_file(flags, cred);
|
||||
+ f = alloc_empty_backing_file(flags, cred, user_file);
|
||||
if (IS_ERR(f))
|
||||
return f;
|
||||
|
||||
@@ -339,6 +342,11 @@ int backing_file_mmap(struct file *file, struct vm_area_struct *vma,
|
||||
vma_set_file(vma, file);
|
||||
|
||||
old_cred = override_creds(ctx->cred);
|
||||
+ ret = security_mmap_backing_file(vma, file, ctx->user_file);
|
||||
+ if (ret) {
|
||||
+ revert_creds(old_cred);
|
||||
+ return ret;
|
||||
+ }
|
||||
ret = call_mmap(vma->vm_file, vma);
|
||||
revert_creds(old_cred);
|
||||
|
||||
diff --git a/fs/file_table.c b/fs/file_table.c
|
||||
index 4b4d50a1d9da..0a7f25596d57 100644
|
||||
--- a/fs/file_table.c
|
||||
+++ b/fs/file_table.c
|
||||
@@ -51,6 +51,9 @@ struct backing_file {
|
||||
struct path user_path;
|
||||
freeptr_t bf_freeptr;
|
||||
};
|
||||
+#ifdef CONFIG_SECURITY
|
||||
+ void *security;
|
||||
+#endif
|
||||
};
|
||||
|
||||
#define backing_file(f) container_of(f, struct backing_file, file)
|
||||
@@ -67,8 +70,21 @@ void backing_file_set_user_path(struct file *f, const struct path *path)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(backing_file_set_user_path);
|
||||
|
||||
+#ifdef CONFIG_SECURITY
|
||||
+void *backing_file_security(const struct file *f)
|
||||
+{
|
||||
+ return backing_file(f)->security;
|
||||
+}
|
||||
+
|
||||
+void backing_file_set_security(struct file *f, void *security)
|
||||
+{
|
||||
+ backing_file(f)->security = security;
|
||||
+}
|
||||
+#endif /* CONFIG_SECURITY */
|
||||
+
|
||||
static inline void backing_file_free(struct backing_file *ff)
|
||||
{
|
||||
+ security_backing_file_free(&ff->file);
|
||||
path_put(&ff->user_path);
|
||||
kmem_cache_free(bfilp_cachep, ff);
|
||||
}
|
||||
@@ -283,10 +299,12 @@ struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred)
|
||||
return f;
|
||||
}
|
||||
|
||||
-static int init_backing_file(struct backing_file *ff)
|
||||
+static int init_backing_file(struct backing_file *ff,
|
||||
+ const struct file *user_file)
|
||||
{
|
||||
memset(&ff->user_path, 0, sizeof(ff->user_path));
|
||||
- return 0;
|
||||
+ backing_file_set_security(&ff->file, NULL);
|
||||
+ return security_backing_file_alloc(&ff->file, user_file);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -296,7 +314,8 @@ static int init_backing_file(struct backing_file *ff)
|
||||
* This is only for kernel internal use, and the allocate file must not be
|
||||
* installed into file tables or such.
|
||||
*/
|
||||
-struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
|
||||
+struct file *alloc_empty_backing_file(int flags, const struct cred *cred,
|
||||
+ const struct file *user_file)
|
||||
{
|
||||
struct backing_file *ff;
|
||||
int error;
|
||||
@@ -313,7 +332,7 @@ struct file *alloc_empty_backing_file(int flags, const struct cred *cred)
|
||||
|
||||
/* The f_mode flags must be set before fput(). */
|
||||
ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT;
|
||||
- error = init_backing_file(ff);
|
||||
+ error = init_backing_file(ff, user_file);
|
||||
if (unlikely(error)) {
|
||||
fput(&ff->file);
|
||||
return ERR_PTR(error);
|
||||
diff --git a/fs/fuse/passthrough.c b/fs/fuse/passthrough.c
|
||||
index bbac547dfcb3..91a43c4939ec 100644
|
||||
--- a/fs/fuse/passthrough.c
|
||||
+++ b/fs/fuse/passthrough.c
|
||||
@@ -321,7 +321,7 @@ struct fuse_backing *fuse_passthrough_open(struct file *file,
|
||||
goto out;
|
||||
|
||||
/* Allocate backing file per fuse file to store fuse path */
|
||||
- backing_file = backing_file_open(&file->f_path, file->f_flags,
|
||||
+ backing_file = backing_file_open(file, file->f_flags,
|
||||
&fb->file->f_path, fb->cred);
|
||||
err = PTR_ERR(backing_file);
|
||||
if (IS_ERR(backing_file)) {
|
||||
diff --git a/fs/internal.h b/fs/internal.h
|
||||
index 67e2e164c647..049c800a3b16 100644
|
||||
--- a/fs/internal.h
|
||||
+++ b/fs/internal.h
|
||||
@@ -99,7 +99,8 @@ extern void chroot_fs_refs(const struct path *, const struct path *);
|
||||
*/
|
||||
struct file *alloc_empty_file(int flags, const struct cred *cred);
|
||||
struct file *alloc_empty_file_noaccount(int flags, const struct cred *cred);
|
||||
-struct file *alloc_empty_backing_file(int flags, const struct cred *cred);
|
||||
+struct file *alloc_empty_backing_file(int flags, const struct cred *cred,
|
||||
+ const struct file *user_file);
|
||||
void backing_file_set_user_path(struct file *f, const struct path *path);
|
||||
|
||||
static inline void file_put_write_access(struct file *file)
|
||||
diff --git a/fs/overlayfs/dir.c b/fs/overlayfs/dir.c
|
||||
index ab65e98a1def..1c8009bf194b 100644
|
||||
--- a/fs/overlayfs/dir.c
|
||||
+++ b/fs/overlayfs/dir.c
|
||||
@@ -1320,7 +1320,7 @@ static int ovl_create_tmpfile(struct file *file, struct dentry *dentry,
|
||||
goto out_revert_creds;
|
||||
|
||||
ovl_path_upper(dentry->d_parent, &realparentpath);
|
||||
- realfile = backing_tmpfile_open(&file->f_path, flags, &realparentpath,
|
||||
+ realfile = backing_tmpfile_open(file, flags, &realparentpath,
|
||||
mode, current_cred());
|
||||
err = PTR_ERR_OR_ZERO(realfile);
|
||||
pr_debug("tmpfile/open(%pd2, 0%o) = %i\n", realparentpath.dentry, mode, err);
|
||||
diff --git a/fs/overlayfs/file.c b/fs/overlayfs/file.c
|
||||
index 4444c78e2e0c..84aad9d19bdd 100644
|
||||
--- a/fs/overlayfs/file.c
|
||||
+++ b/fs/overlayfs/file.c
|
||||
@@ -48,7 +48,7 @@ static struct file *ovl_open_realfile(const struct file *file,
|
||||
if (!inode_owner_or_capable(real_idmap, realinode))
|
||||
flags &= ~O_NOATIME;
|
||||
|
||||
- realfile = backing_file_open(&file->f_path, flags, realpath,
|
||||
+ realfile = backing_file_open(file, flags, realpath,
|
||||
current_cred());
|
||||
}
|
||||
revert_creds(old_cred);
|
||||
diff --git a/include/linux/backing-file.h b/include/linux/backing-file.h
|
||||
index 2eed0ffb5e8f..cd18acd7ac5b 100644
|
||||
--- a/include/linux/backing-file.h
|
||||
+++ b/include/linux/backing-file.h
|
||||
@@ -19,10 +19,10 @@ struct backing_file_ctx {
|
||||
void (*end_write)(struct file *, loff_t, ssize_t);
|
||||
};
|
||||
|
||||
-struct file *backing_file_open(const struct path *user_path, int flags,
|
||||
+struct file *backing_file_open(const struct file *user_file, int flags,
|
||||
const struct path *real_path,
|
||||
const struct cred *cred);
|
||||
-struct file *backing_tmpfile_open(const struct path *user_path, int flags,
|
||||
+struct file *backing_tmpfile_open(const struct file *user_file, int flags,
|
||||
const struct path *real_parentpath,
|
||||
umode_t mode, const struct cred *cred);
|
||||
ssize_t backing_file_read_iter(struct file *file, struct iov_iter *iter,
|
||||
diff --git a/include/linux/fs.h b/include/linux/fs.h
|
||||
index 04309befc557..975afa36e9aa 100644
|
||||
--- a/include/linux/fs.h
|
||||
+++ b/include/linux/fs.h
|
||||
@@ -2795,6 +2795,19 @@ struct file *dentry_create(const struct path *path, int flags, umode_t mode,
|
||||
const struct cred *cred);
|
||||
struct path *backing_file_user_path(const struct file *f);
|
||||
|
||||
+#ifdef CONFIG_SECURITY
|
||||
+void *backing_file_security(const struct file *f);
|
||||
+void backing_file_set_security(struct file *f, void *security);
|
||||
+#else
|
||||
+static inline void *backing_file_security(const struct file *f)
|
||||
+{
|
||||
+ return NULL;
|
||||
+}
|
||||
+static inline void backing_file_set_security(struct file *f, void *security)
|
||||
+{
|
||||
+}
|
||||
+#endif /* CONFIG_SECURITY */
|
||||
+
|
||||
/*
|
||||
* When mmapping a file on a stackable filesystem (e.g., overlayfs), the file
|
||||
* stored in ->vm_file is a backing file whose f_inode is on the underlying
|
||||
diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h
|
||||
index 97a8b21eb033..c0a2839253fa 100644
|
||||
--- a/include/linux/lsm_audit.h
|
||||
+++ b/include/linux/lsm_audit.h
|
||||
@@ -93,7 +93,7 @@ struct common_audit_data {
|
||||
#endif
|
||||
char *kmod_name;
|
||||
struct lsm_ioctlop_audit *op;
|
||||
- struct file *file;
|
||||
+ const struct file *file;
|
||||
struct lsm_ibpkey_audit *ibpkey;
|
||||
struct lsm_ibendport_audit *ibendport;
|
||||
int reason;
|
||||
diff --git a/include/linux/lsm_hook_defs.h b/include/linux/lsm_hook_defs.h
|
||||
index 27d599bde74a..e06665ae5102 100644
|
||||
--- a/include/linux/lsm_hook_defs.h
|
||||
+++ b/include/linux/lsm_hook_defs.h
|
||||
@@ -189,6 +189,9 @@ LSM_HOOK(int, 0, file_permission, struct file *file, int mask)
|
||||
LSM_HOOK(int, 0, file_alloc_security, struct file *file)
|
||||
LSM_HOOK(void, LSM_RET_VOID, file_release, struct file *file)
|
||||
LSM_HOOK(void, LSM_RET_VOID, file_free_security, struct file *file)
|
||||
+LSM_HOOK(int, 0, backing_file_alloc, struct file *backing_file,
|
||||
+ const struct file *user_file)
|
||||
+LSM_HOOK(void, LSM_RET_VOID, backing_file_free, struct file *backing_file)
|
||||
LSM_HOOK(int, 0, file_ioctl, struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd,
|
||||
@@ -196,6 +199,8 @@ LSM_HOOK(int, 0, file_ioctl_compat, struct file *file, unsigned int cmd,
|
||||
LSM_HOOK(int, 0, mmap_addr, unsigned long addr)
|
||||
LSM_HOOK(int, 0, mmap_file, struct file *file, unsigned long reqprot,
|
||||
unsigned long prot, unsigned long flags)
|
||||
+LSM_HOOK(int, 0, mmap_backing_file, struct vm_area_struct *vma,
|
||||
+ struct file *backing_file, struct file *user_file)
|
||||
LSM_HOOK(int, 0, file_mprotect, struct vm_area_struct *vma,
|
||||
unsigned long reqprot, unsigned long prot)
|
||||
LSM_HOOK(int, 0, file_lock, struct file *file, unsigned int cmd)
|
||||
diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h
|
||||
index a7ecb0791a0f..f1c6db9c0cff 100644
|
||||
--- a/include/linux/lsm_hooks.h
|
||||
+++ b/include/linux/lsm_hooks.h
|
||||
@@ -104,6 +104,7 @@ struct security_hook_list {
|
||||
struct lsm_blob_sizes {
|
||||
unsigned int lbs_cred;
|
||||
unsigned int lbs_file;
|
||||
+ unsigned int lbs_backing_file;
|
||||
unsigned int lbs_ib;
|
||||
unsigned int lbs_inode;
|
||||
unsigned int lbs_sock;
|
||||
diff --git a/include/linux/security.h b/include/linux/security.h
|
||||
index 2db88ddbe9a9..0a2ef373267b 100644
|
||||
--- a/include/linux/security.h
|
||||
+++ b/include/linux/security.h
|
||||
@@ -487,11 +487,17 @@ int security_file_permission(struct file *file, int mask);
|
||||
int security_file_alloc(struct file *file);
|
||||
void security_file_release(struct file *file);
|
||||
void security_file_free(struct file *file);
|
||||
+int security_backing_file_alloc(struct file *backing_file,
|
||||
+ const struct file *user_file);
|
||||
+void security_backing_file_free(struct file *backing_file);
|
||||
int security_file_ioctl(struct file *file, unsigned int cmd, unsigned long arg);
|
||||
int security_file_ioctl_compat(struct file *file, unsigned int cmd,
|
||||
unsigned long arg);
|
||||
int security_mmap_file(struct file *file, unsigned long prot,
|
||||
unsigned long flags);
|
||||
+int security_mmap_backing_file(struct vm_area_struct *vma,
|
||||
+ struct file *backing_file,
|
||||
+ struct file *user_file);
|
||||
int security_mmap_addr(unsigned long addr);
|
||||
int security_file_mprotect(struct vm_area_struct *vma, unsigned long reqprot,
|
||||
unsigned long prot);
|
||||
@@ -1147,6 +1153,15 @@ static inline void security_file_release(struct file *file)
|
||||
static inline void security_file_free(struct file *file)
|
||||
{ }
|
||||
|
||||
+static inline int security_backing_file_alloc(struct file *backing_file,
|
||||
+ const struct file *user_file)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline void security_backing_file_free(struct file *backing_file)
|
||||
+{ }
|
||||
+
|
||||
static inline int security_file_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
@@ -1166,6 +1181,13 @@ static inline int security_mmap_file(struct file *file, unsigned long prot,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static inline int security_mmap_backing_file(struct vm_area_struct *vma,
|
||||
+ struct file *backing_file,
|
||||
+ struct file *user_file)
|
||||
+{
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static inline int security_mmap_addr(unsigned long addr)
|
||||
{
|
||||
return cap_mmap_addr(addr);
|
||||
diff --git a/security/lsm.h b/security/lsm.h
|
||||
index 8dc267977ae0..c3a1a9cd121e 100644
|
||||
--- a/security/lsm.h
|
||||
+++ b/security/lsm.h
|
||||
@@ -29,6 +29,7 @@ extern struct lsm_blob_sizes blob_sizes;
|
||||
|
||||
/* LSM blob caches */
|
||||
extern struct kmem_cache *lsm_file_cache;
|
||||
+extern struct kmem_cache *lsm_backing_file_cache;
|
||||
extern struct kmem_cache *lsm_inode_cache;
|
||||
|
||||
/* LSM blob allocators */
|
||||
diff --git a/security/lsm_init.c b/security/lsm_init.c
|
||||
index bef21da72c16..31bc9e2d0f5d 100644
|
||||
--- a/security/lsm_init.c
|
||||
+++ b/security/lsm_init.c
|
||||
@@ -202,6 +202,8 @@ static void __init lsm_prepare(struct lsm_info *lsm)
|
||||
blobs = lsm->blobs;
|
||||
lsm_blob_size_update(&blobs->lbs_cred, &blob_sizes.lbs_cred);
|
||||
lsm_blob_size_update(&blobs->lbs_file, &blob_sizes.lbs_file);
|
||||
+ lsm_blob_size_update(&blobs->lbs_backing_file,
|
||||
+ &blob_sizes.lbs_backing_file);
|
||||
lsm_blob_size_update(&blobs->lbs_ib, &blob_sizes.lbs_ib);
|
||||
/* inode blob gets an rcu_head in addition to LSM blobs. */
|
||||
if (blobs->lbs_inode && blob_sizes.lbs_inode == 0)
|
||||
@@ -405,6 +407,8 @@ int __init security_init(void)
|
||||
if (lsm_debug) {
|
||||
lsm_pr("blob(cred) size %d\n", blob_sizes.lbs_cred);
|
||||
lsm_pr("blob(file) size %d\n", blob_sizes.lbs_file);
|
||||
+ lsm_pr("blob(backing_file) size %d\n",
|
||||
+ blob_sizes.lbs_backing_file);
|
||||
lsm_pr("blob(ib) size %d\n", blob_sizes.lbs_ib);
|
||||
lsm_pr("blob(inode) size %d\n", blob_sizes.lbs_inode);
|
||||
lsm_pr("blob(ipc) size %d\n", blob_sizes.lbs_ipc);
|
||||
@@ -423,6 +427,11 @@ int __init security_init(void)
|
||||
lsm_file_cache = kmem_cache_create("lsm_file_cache",
|
||||
blob_sizes.lbs_file, 0,
|
||||
SLAB_PANIC, NULL);
|
||||
+ if (blob_sizes.lbs_backing_file)
|
||||
+ lsm_backing_file_cache = kmem_cache_create(
|
||||
+ "lsm_backing_file_cache",
|
||||
+ blob_sizes.lbs_backing_file,
|
||||
+ 0, SLAB_PANIC, NULL);
|
||||
if (blob_sizes.lbs_inode)
|
||||
lsm_inode_cache = kmem_cache_create("lsm_inode_cache",
|
||||
blob_sizes.lbs_inode, 0,
|
||||
diff --git a/security/security.c b/security/security.c
|
||||
index 56c48725e334..d9a645d0038e 100644
|
||||
--- a/security/security.c
|
||||
+++ b/security/security.c
|
||||
@@ -82,6 +82,7 @@ const struct lsm_id *lsm_idlist[MAX_LSM_COUNT];
|
||||
struct lsm_blob_sizes blob_sizes;
|
||||
|
||||
struct kmem_cache *lsm_file_cache;
|
||||
+struct kmem_cache *lsm_backing_file_cache;
|
||||
struct kmem_cache *lsm_inode_cache;
|
||||
|
||||
#define SECURITY_HOOK_ACTIVE_KEY(HOOK, IDX) security_hook_active_##HOOK##_##IDX
|
||||
@@ -173,6 +174,30 @@ static int lsm_file_alloc(struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * lsm_backing_file_alloc - allocate a composite backing file blob
|
||||
+ * @backing_file: the backing file
|
||||
+ *
|
||||
+ * Allocate the backing file blob for all the modules.
|
||||
+ *
|
||||
+ * Returns 0, or -ENOMEM if memory can't be allocated.
|
||||
+ */
|
||||
+static int lsm_backing_file_alloc(struct file *backing_file)
|
||||
+{
|
||||
+ void *blob;
|
||||
+
|
||||
+ if (!lsm_backing_file_cache) {
|
||||
+ backing_file_set_security(backing_file, NULL);
|
||||
+ return 0;
|
||||
+ }
|
||||
+
|
||||
+ blob = kmem_cache_zalloc(lsm_backing_file_cache, GFP_KERNEL);
|
||||
+ backing_file_set_security(backing_file, blob);
|
||||
+ if (!blob)
|
||||
+ return -ENOMEM;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* lsm_blob_alloc - allocate a composite blob
|
||||
* @dest: the destination for the blob
|
||||
@@ -2350,6 +2375,57 @@ void security_file_free(struct file *file)
|
||||
}
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * security_backing_file_alloc() - Allocate and setup a backing file blob
|
||||
+ * @backing_file: the backing file
|
||||
+ * @user_file: the associated user visible file
|
||||
+ *
|
||||
+ * Allocate a backing file LSM blob and perform any necessary initialization of
|
||||
+ * the LSM blob. There will be some operations where the LSM will not have
|
||||
+ * access to @user_file after this point, so any important state associated
|
||||
+ * with @user_file that is important to the LSM should be captured in the
|
||||
+ * backing file's LSM blob.
|
||||
+ *
|
||||
+ * LSM's should avoid taking a reference to @user_file in this hook as it will
|
||||
+ * result in problems later when the system attempts to drop/put the file
|
||||
+ * references due to a circular dependency.
|
||||
+ *
|
||||
+ * Return: Return 0 if the hook is successful, negative values otherwise.
|
||||
+ */
|
||||
+int security_backing_file_alloc(struct file *backing_file,
|
||||
+ const struct file *user_file)
|
||||
+{
|
||||
+ int rc;
|
||||
+
|
||||
+ rc = lsm_backing_file_alloc(backing_file);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ rc = call_int_hook(backing_file_alloc, backing_file, user_file);
|
||||
+ if (unlikely(rc))
|
||||
+ security_backing_file_free(backing_file);
|
||||
+
|
||||
+ return rc;
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * security_backing_file_free() - Free a backing file blob
|
||||
+ * @backing_file: the backing file
|
||||
+ *
|
||||
+ * Free any LSM state associate with a backing file's LSM blob, including the
|
||||
+ * blob itself.
|
||||
+ */
|
||||
+void security_backing_file_free(struct file *backing_file)
|
||||
+{
|
||||
+ void *blob = backing_file_security(backing_file);
|
||||
+
|
||||
+ call_void_hook(backing_file_free, backing_file);
|
||||
+
|
||||
+ if (blob) {
|
||||
+ backing_file_set_security(backing_file, NULL);
|
||||
+ kmem_cache_free(lsm_backing_file_cache, blob);
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
/**
|
||||
* security_file_ioctl() - Check if an ioctl is allowed
|
||||
* @file: associated file
|
||||
@@ -2438,6 +2514,32 @@ int security_mmap_file(struct file *file, unsigned long prot,
|
||||
flags);
|
||||
}
|
||||
|
||||
+/**
|
||||
+ * security_mmap_backing_file - Check if mmap'ing a backing file is allowed
|
||||
+ * @vma: the vm_area_struct for the mmap'd region
|
||||
+ * @backing_file: the backing file being mmap'd
|
||||
+ * @user_file: the user file being mmap'd
|
||||
+ *
|
||||
+ * Check permissions for a mmap operation on a stacked filesystem. This hook
|
||||
+ * is called after the security_mmap_file() and is responsible for authorizing
|
||||
+ * the mmap on @backing_file. It is important to note that the mmap operation
|
||||
+ * on @user_file has already been authorized and the @vma->vm_file has been
|
||||
+ * set to @backing_file.
|
||||
+ *
|
||||
+ * Return: Returns 0 if permission is granted.
|
||||
+ */
|
||||
+int security_mmap_backing_file(struct vm_area_struct *vma,
|
||||
+ struct file *backing_file,
|
||||
+ struct file *user_file)
|
||||
+{
|
||||
+ /* recommended by the stackable filesystem devs */
|
||||
+ if (WARN_ON_ONCE(!(backing_file->f_mode & FMODE_BACKING)))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ return call_int_hook(mmap_backing_file, vma, backing_file, user_file);
|
||||
+}
|
||||
+EXPORT_SYMBOL_GPL(security_mmap_backing_file);
|
||||
+
|
||||
/**
|
||||
* security_mmap_addr() - Check if mmap'ing an address is allowed
|
||||
* @addr: address
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
429
1323-selinux-fix-overlayfs-mmap-and-mprotect-access-checks.patch
Normal file
429
1323-selinux-fix-overlayfs-mmap-and-mprotect-access-checks.patch
Normal file
@ -0,0 +1,429 @@
|
||||
From d3989d6fe668083ccd03e1cc73a46b9ed88edd54 Mon Sep 17 00:00:00 2001
|
||||
From: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 10:26:36 +0200
|
||||
Subject: [PATCH] selinux: fix overlayfs mmap() and mprotect() access checks
|
||||
|
||||
JIRA: https://issues.redhat.com/browse/RHEL-179440
|
||||
CVE: CVE-2026-46054
|
||||
Conflicts:
|
||||
- security/selinux/hooks.c: trivial context fuzz
|
||||
|
||||
commit 82544d36b1729153c8aeb179e84750f0c085d3b1
|
||||
Author: Paul Moore <paul@paul-moore.com>
|
||||
Date: Thu Jan 1 17:19:18 2026 -0500
|
||||
|
||||
selinux: fix overlayfs mmap() and mprotect() access checks
|
||||
|
||||
The existing SELinux security model for overlayfs is to allow access if
|
||||
the current task is able to access the top level file (the "user" file)
|
||||
and the mounter's credentials are sufficient to access the lower
|
||||
level file (the "backing" file). Unfortunately, the current code does
|
||||
not properly enforce these access controls for both mmap() and mprotect()
|
||||
operations on overlayfs filesystems.
|
||||
|
||||
This patch makes use of the newly created security_mmap_backing_file()
|
||||
LSM hook to provide the missing backing file enforcement for mmap()
|
||||
operations, and leverages the backing file API and new LSM blob to
|
||||
provide the necessary information to properly enforce the mprotect()
|
||||
access controls.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Acked-by: Amir Goldstein <amir73il@gmail.com>
|
||||
Signed-off-by: Paul Moore <paul@paul-moore.com>
|
||||
|
||||
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
|
||||
|
||||
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
|
||||
index a2323c6daafe..853cf9cee2ec 100644
|
||||
--- a/security/selinux/hooks.c
|
||||
+++ b/security/selinux/hooks.c
|
||||
@@ -1724,49 +1724,72 @@ static inline int file_path_has_perm(const struct cred *cred,
|
||||
static int bpf_fd_pass(const struct file *file, u32 sid);
|
||||
#endif
|
||||
|
||||
-/* Check whether a task can use an open file descriptor to
|
||||
- access an inode in a given way. Check access to the
|
||||
- descriptor itself, and then use dentry_has_perm to
|
||||
- check a particular permission to the file.
|
||||
- Access to the descriptor is implicitly granted if it
|
||||
- has the same SID as the process. If av is zero, then
|
||||
- access to the file is not checked, e.g. for cases
|
||||
- where only the descriptor is affected like seek. */
|
||||
-static int file_has_perm(const struct cred *cred,
|
||||
- struct file *file,
|
||||
- u32 av)
|
||||
+static int __file_has_perm(const struct cred *cred, const struct file *file,
|
||||
+ u32 av, bool bf_user_file)
|
||||
+
|
||||
{
|
||||
- struct file_security_struct *fsec = selinux_file(file);
|
||||
- struct inode *inode = file_inode(file);
|
||||
struct common_audit_data ad;
|
||||
- u32 sid = cred_sid(cred);
|
||||
+ struct inode *inode;
|
||||
+ u32 ssid = cred_sid(cred);
|
||||
+ u32 tsid_fd;
|
||||
int rc;
|
||||
|
||||
- ad.type = LSM_AUDIT_DATA_FILE;
|
||||
- ad.u.file = file;
|
||||
+ if (bf_user_file) {
|
||||
+ struct backing_file_security_struct *bfsec;
|
||||
+ const struct path *path;
|
||||
|
||||
- if (sid != fsec->sid) {
|
||||
- rc = avc_has_perm(sid, fsec->sid,
|
||||
- SECCLASS_FD,
|
||||
- FD__USE,
|
||||
- &ad);
|
||||
+ if (WARN_ON(!(file->f_mode & FMODE_BACKING)))
|
||||
+ return -EIO;
|
||||
+
|
||||
+ bfsec = selinux_backing_file(file);
|
||||
+ path = backing_file_user_path(file);
|
||||
+ tsid_fd = bfsec->uf_sid;
|
||||
+ inode = d_inode(path->dentry);
|
||||
+
|
||||
+ ad.type = LSM_AUDIT_DATA_PATH;
|
||||
+ ad.u.path = *path;
|
||||
+ } else {
|
||||
+ struct file_security_struct *fsec = selinux_file(file);
|
||||
+
|
||||
+ tsid_fd = fsec->sid;
|
||||
+ inode = file_inode(file);
|
||||
+
|
||||
+ ad.type = LSM_AUDIT_DATA_FILE;
|
||||
+ ad.u.file = file;
|
||||
+ }
|
||||
+
|
||||
+ if (ssid != tsid_fd) {
|
||||
+ rc = avc_has_perm(ssid, tsid_fd, SECCLASS_FD, FD__USE, &ad);
|
||||
if (rc)
|
||||
- goto out;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BPF_SYSCALL
|
||||
- rc = bpf_fd_pass(file, cred_sid(cred));
|
||||
+ /* regardless of backing vs user file, use the underlying file here */
|
||||
+ rc = bpf_fd_pass(file, ssid);
|
||||
if (rc)
|
||||
return rc;
|
||||
#endif
|
||||
|
||||
/* av is zero if only checking access to the descriptor. */
|
||||
- rc = 0;
|
||||
if (av)
|
||||
- rc = inode_has_perm(cred, inode, av, &ad);
|
||||
+ return inode_has_perm(cred, inode, av, &ad);
|
||||
|
||||
-out:
|
||||
- return rc;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Check whether a task can use an open file descriptor to
|
||||
+ access an inode in a given way. Check access to the
|
||||
+ descriptor itself, and then use dentry_has_perm to
|
||||
+ check a particular permission to the file.
|
||||
+ Access to the descriptor is implicitly granted if it
|
||||
+ has the same SID as the process. If av is zero, then
|
||||
+ access to the file is not checked, e.g. for cases
|
||||
+ where only the descriptor is affected like seek. */
|
||||
+static inline int file_has_perm(const struct cred *cred,
|
||||
+ const struct file *file, u32 av)
|
||||
+{
|
||||
+ return __file_has_perm(cred, file, av, false);
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -3656,6 +3679,17 @@ static int selinux_file_alloc_security(struct file *file)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int selinux_backing_file_alloc(struct file *backing_file,
|
||||
+ const struct file *user_file)
|
||||
+{
|
||||
+ struct backing_file_security_struct *bfsec;
|
||||
+
|
||||
+ bfsec = selinux_backing_file(backing_file);
|
||||
+ bfsec->uf_sid = selinux_file(user_file)->sid;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Check whether a task has the ioctl permission and cmd
|
||||
* operation to an inode.
|
||||
@@ -3773,42 +3807,55 @@ static int selinux_file_ioctl_compat(struct file *file, unsigned int cmd,
|
||||
|
||||
static int default_noexec __ro_after_init;
|
||||
|
||||
-static int file_map_prot_check(struct file *file, unsigned long prot, int shared)
|
||||
+static int __file_map_prot_check(const struct cred *cred,
|
||||
+ const struct file *file, unsigned long prot,
|
||||
+ bool shared, bool bf_user_file)
|
||||
{
|
||||
- const struct cred *cred = current_cred();
|
||||
- u32 sid = cred_sid(cred);
|
||||
- int rc = 0;
|
||||
+ struct inode *inode = NULL;
|
||||
+ bool prot_exec = prot & PROT_EXEC;
|
||||
+ bool prot_write = prot & PROT_WRITE;
|
||||
+
|
||||
+ if (file) {
|
||||
+ if (bf_user_file)
|
||||
+ inode = d_inode(backing_file_user_path(file)->dentry);
|
||||
+ else
|
||||
+ inode = file_inode(file);
|
||||
+ }
|
||||
+
|
||||
+ if (default_noexec && prot_exec &&
|
||||
+ (!file || IS_PRIVATE(inode) || (!shared && prot_write))) {
|
||||
+ int rc;
|
||||
+ u32 sid = cred_sid(cred);
|
||||
|
||||
- if (default_noexec &&
|
||||
- (prot & PROT_EXEC) && (!file || IS_PRIVATE(file_inode(file)) ||
|
||||
- (!shared && (prot & PROT_WRITE)))) {
|
||||
/*
|
||||
- * We are making executable an anonymous mapping or a
|
||||
- * private file mapping that will also be writable.
|
||||
- * This has an additional check.
|
||||
+ * We are making executable an anonymous mapping or a private
|
||||
+ * file mapping that will also be writable.
|
||||
*/
|
||||
- rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
|
||||
- PROCESS__EXECMEM, NULL);
|
||||
+ rc = avc_has_perm(sid, sid, SECCLASS_PROCESS, PROCESS__EXECMEM,
|
||||
+ NULL);
|
||||
if (rc)
|
||||
- goto error;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
if (file) {
|
||||
- /* read access is always possible with a mapping */
|
||||
+ /* "read" always possible, "write" only if shared */
|
||||
u32 av = FILE__READ;
|
||||
-
|
||||
- /* write access only matters if the mapping is shared */
|
||||
- if (shared && (prot & PROT_WRITE))
|
||||
+ if (shared && prot_write)
|
||||
av |= FILE__WRITE;
|
||||
-
|
||||
- if (prot & PROT_EXEC)
|
||||
+ if (prot_exec)
|
||||
av |= FILE__EXECUTE;
|
||||
|
||||
- return file_has_perm(cred, file, av);
|
||||
+ return __file_has_perm(cred, file, av, bf_user_file);
|
||||
}
|
||||
|
||||
-error:
|
||||
- return rc;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+static inline int file_map_prot_check(const struct cred *cred,
|
||||
+ const struct file *file,
|
||||
+ unsigned long prot, bool shared)
|
||||
+{
|
||||
+ return __file_map_prot_check(cred, file, prot, shared, false);
|
||||
}
|
||||
|
||||
static int selinux_mmap_addr(unsigned long addr)
|
||||
@@ -3824,36 +3871,80 @@ static int selinux_mmap_addr(unsigned long addr)
|
||||
return rc;
|
||||
}
|
||||
|
||||
-static int selinux_mmap_file(struct file *file,
|
||||
- unsigned long reqprot __always_unused,
|
||||
- unsigned long prot, unsigned long flags)
|
||||
+static int selinux_mmap_file_common(const struct cred *cred, struct file *file,
|
||||
+ unsigned long prot, bool shared)
|
||||
{
|
||||
- struct common_audit_data ad;
|
||||
- int rc;
|
||||
-
|
||||
if (file) {
|
||||
+ int rc;
|
||||
+ struct common_audit_data ad;
|
||||
+
|
||||
ad.type = LSM_AUDIT_DATA_FILE;
|
||||
ad.u.file = file;
|
||||
- rc = inode_has_perm(current_cred(), file_inode(file),
|
||||
- FILE__MAP, &ad);
|
||||
+ rc = inode_has_perm(cred, file_inode(file), FILE__MAP, &ad);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
- return file_map_prot_check(file, prot,
|
||||
- (flags & MAP_TYPE) == MAP_SHARED);
|
||||
+ return file_map_prot_check(cred, file, prot, shared);
|
||||
+}
|
||||
+
|
||||
+static int selinux_mmap_file(struct file *file,
|
||||
+ unsigned long reqprot __always_unused,
|
||||
+ unsigned long prot, unsigned long flags)
|
||||
+{
|
||||
+ return selinux_mmap_file_common(current_cred(), file, prot,
|
||||
+ (flags & MAP_TYPE) == MAP_SHARED);
|
||||
+}
|
||||
+
|
||||
+/**
|
||||
+ * selinux_mmap_backing_file - Check mmap permissions on a backing file
|
||||
+ * @vma: memory region
|
||||
+ * @backing_file: stacked filesystem backing file
|
||||
+ * @user_file: user visible file
|
||||
+ *
|
||||
+ * This is called after selinux_mmap_file() on stacked filesystems, and it
|
||||
+ * is this function's responsibility to verify access to @backing_file and
|
||||
+ * setup the SELinux state for possible later use in the mprotect() code path.
|
||||
+ *
|
||||
+ * By the time this function is called, mmap() access to @user_file has already
|
||||
+ * been authorized and @vma->vm_file has been set to point to @backing_file.
|
||||
+ *
|
||||
+ * Return zero on success, negative values otherwise.
|
||||
+ */
|
||||
+static int selinux_mmap_backing_file(struct vm_area_struct *vma,
|
||||
+ struct file *backing_file,
|
||||
+ struct file *user_file __always_unused)
|
||||
+{
|
||||
+ unsigned long prot = 0;
|
||||
+
|
||||
+ /* translate vma->vm_flags perms into PROT perms */
|
||||
+ if (vma->vm_flags & VM_READ)
|
||||
+ prot |= PROT_READ;
|
||||
+ if (vma->vm_flags & VM_WRITE)
|
||||
+ prot |= PROT_WRITE;
|
||||
+ if (vma->vm_flags & VM_EXEC)
|
||||
+ prot |= PROT_EXEC;
|
||||
+
|
||||
+ return selinux_mmap_file_common(backing_file->f_cred, backing_file,
|
||||
+ prot, vma->vm_flags & VM_SHARED);
|
||||
}
|
||||
|
||||
static int selinux_file_mprotect(struct vm_area_struct *vma,
|
||||
unsigned long reqprot __always_unused,
|
||||
unsigned long prot)
|
||||
{
|
||||
+ int rc;
|
||||
const struct cred *cred = current_cred();
|
||||
u32 sid = cred_sid(cred);
|
||||
+ const struct file *file = vma->vm_file;
|
||||
+ bool backing_file;
|
||||
+ bool shared = vma->vm_flags & VM_SHARED;
|
||||
+
|
||||
+ /* check if we need to trigger the "backing files are awful" mode */
|
||||
+ backing_file = file && (file->f_mode & FMODE_BACKING);
|
||||
|
||||
if (default_noexec &&
|
||||
(prot & PROT_EXEC) && !(vma->vm_flags & VM_EXEC)) {
|
||||
- int rc = 0;
|
||||
/*
|
||||
* We don't use the vma_is_initial_heap() helper as it has
|
||||
* a history of problems and is currently broken on systems
|
||||
@@ -3867,11 +3958,15 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
|
||||
vma->vm_end <= vma->vm_mm->brk) {
|
||||
rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
|
||||
PROCESS__EXECHEAP, NULL);
|
||||
- } else if (!vma->vm_file && (vma_is_initial_stack(vma) ||
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ } else if (!file && (vma_is_initial_stack(vma) ||
|
||||
vma_is_stack_for_current(vma))) {
|
||||
rc = avc_has_perm(sid, sid, SECCLASS_PROCESS,
|
||||
PROCESS__EXECSTACK, NULL);
|
||||
- } else if (vma->vm_file && vma->anon_vma) {
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ } else if (file && vma->anon_vma) {
|
||||
/*
|
||||
* We are making executable a file mapping that has
|
||||
* had some COW done. Since pages might have been
|
||||
@@ -3879,13 +3974,29 @@ static int selinux_file_mprotect(struct vm_area_struct *vma,
|
||||
* modified content. This typically should only
|
||||
* occur for text relocations.
|
||||
*/
|
||||
- rc = file_has_perm(cred, vma->vm_file, FILE__EXECMOD);
|
||||
+ rc = __file_has_perm(cred, file, FILE__EXECMOD,
|
||||
+ backing_file);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ if (backing_file) {
|
||||
+ rc = file_has_perm(file->f_cred, file,
|
||||
+ FILE__EXECMOD);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ }
|
||||
}
|
||||
+ }
|
||||
+
|
||||
+ rc = __file_map_prot_check(cred, file, prot, shared, backing_file);
|
||||
+ if (rc)
|
||||
+ return rc;
|
||||
+ if (backing_file) {
|
||||
+ rc = file_map_prot_check(file->f_cred, file, prot, shared);
|
||||
if (rc)
|
||||
return rc;
|
||||
}
|
||||
|
||||
- return file_map_prot_check(vma->vm_file, prot, vma->vm_flags&VM_SHARED);
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int selinux_file_lock(struct file *file, unsigned int cmd)
|
||||
@@ -6996,6 +7107,7 @@ static void selinux_bpf_token_free(struct bpf_token *token)
|
||||
struct lsm_blob_sizes selinux_blob_sizes __ro_after_init = {
|
||||
.lbs_cred = sizeof(struct task_security_struct),
|
||||
.lbs_file = sizeof(struct file_security_struct),
|
||||
+ .lbs_backing_file = sizeof(struct backing_file_security_struct),
|
||||
.lbs_inode = sizeof(struct inode_security_struct),
|
||||
.lbs_ipc = sizeof(struct ipc_security_struct),
|
||||
.lbs_key = sizeof(struct key_security_struct),
|
||||
@@ -7201,9 +7313,11 @@ static struct security_hook_list selinux_hooks[] __ro_after_init = {
|
||||
|
||||
LSM_HOOK_INIT(file_permission, selinux_file_permission),
|
||||
LSM_HOOK_INIT(file_alloc_security, selinux_file_alloc_security),
|
||||
+ LSM_HOOK_INIT(backing_file_alloc, selinux_backing_file_alloc),
|
||||
LSM_HOOK_INIT(file_ioctl, selinux_file_ioctl),
|
||||
LSM_HOOK_INIT(file_ioctl_compat, selinux_file_ioctl_compat),
|
||||
LSM_HOOK_INIT(mmap_file, selinux_mmap_file),
|
||||
+ LSM_HOOK_INIT(mmap_backing_file, selinux_mmap_backing_file),
|
||||
LSM_HOOK_INIT(mmap_addr, selinux_mmap_addr),
|
||||
LSM_HOOK_INIT(file_mprotect, selinux_file_mprotect),
|
||||
LSM_HOOK_INIT(file_lock, selinux_file_lock),
|
||||
diff --git a/security/selinux/include/objsec.h b/security/selinux/include/objsec.h
|
||||
index c88cae81ee4c..dc42282a2c05 100644
|
||||
--- a/security/selinux/include/objsec.h
|
||||
+++ b/security/selinux/include/objsec.h
|
||||
@@ -61,6 +61,10 @@ struct file_security_struct {
|
||||
u32 pseqno; /* Policy seqno at the time of file open */
|
||||
};
|
||||
|
||||
+struct backing_file_security_struct {
|
||||
+ u32 uf_sid; /* associated user file fsec->sid */
|
||||
+};
|
||||
+
|
||||
struct superblock_security_struct {
|
||||
u32 sid; /* SID of file system superblock */
|
||||
u32 def_sid; /* default SID for labeling */
|
||||
@@ -159,6 +163,13 @@ static inline struct file_security_struct *selinux_file(const struct file *file)
|
||||
return file->f_security + selinux_blob_sizes.lbs_file;
|
||||
}
|
||||
|
||||
+static inline struct backing_file_security_struct *
|
||||
+selinux_backing_file(const struct file *backing_file)
|
||||
+{
|
||||
+ void *blob = backing_file_security(backing_file);
|
||||
+ return blob + selinux_blob_sizes.lbs_backing_file;
|
||||
+}
|
||||
+
|
||||
static inline struct inode_security_struct *
|
||||
selinux_inode(const struct inode *inode)
|
||||
{
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,70 @@
|
||||
From 7a4465d25de718e57ced42030bc7194017ee4f64 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:33:16 +0200
|
||||
Subject: [PATCH] scripts/sorttable: fix orc_sort_cmp() to maintain symmetry
|
||||
and transitivity
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 0210d251162f4033350a94a43f95b1c39ec84a90
|
||||
Author: Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
Date: Thu Dec 26 22:03:32 2024 +0800
|
||||
|
||||
scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity
|
||||
|
||||
The orc_sort_cmp() function, used with qsort(), previously violated the
|
||||
symmetry and transitivity rules required by the C standard. Specifically,
|
||||
when both entries are ORC_TYPE_UNDEFINED, it could result in both a < b
|
||||
and b < a, which breaks the required symmetry and transitivity. This can
|
||||
lead to undefined behavior and incorrect sorting results, potentially
|
||||
causing memory corruption in glibc implementations [1].
|
||||
|
||||
Symmetry: If x < y, then y > x.
|
||||
Transitivity: If x < y and y < z, then x < z.
|
||||
|
||||
Fix the comparison logic to return 0 when both entries are
|
||||
ORC_TYPE_UNDEFINED, ensuring compliance with qsort() requirements.
|
||||
|
||||
Link: https://www.qualys.com/2024/01/30/qsort.txt [1]
|
||||
Link: https://lkml.kernel.org/r/20241226140332.2670689-1-visitorckw@gmail.com
|
||||
Fixes: 57fa18994285 ("scripts/sorttable: Implement build-time ORC unwind table sorting")
|
||||
Fixes: fb799447ae29 ("x86,objtool: Split UNWIND_HINT_EMPTY in two")
|
||||
Signed-off-by: Kuan-Wei Chiu <visitorckw@gmail.com>
|
||||
Cc: Ching-Chun (Jim) Huang <jserv@ccns.ncku.edu.tw>
|
||||
Cc: <chuang@cs.nycu.edu.tw>
|
||||
Cc: Ingo Molnar <mingo@kernel.org>
|
||||
Cc: Josh Poimboeuf <jpoimboe@kernel.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Shile Zhang <shile.zhang@linux.alibaba.com>
|
||||
Cc: Steven Rostedt <rostedt@goodmis.org>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 7bd0184380d3..a7c5445baf00 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -110,7 +110,7 @@ static inline unsigned long orc_ip(const int *ip)
|
||||
|
||||
static int orc_sort_cmp(const void *_a, const void *_b)
|
||||
{
|
||||
- struct orc_entry *orc_a;
|
||||
+ struct orc_entry *orc_a, *orc_b;
|
||||
const int *a = g_orc_ip_table + *(int *)_a;
|
||||
const int *b = g_orc_ip_table + *(int *)_b;
|
||||
unsigned long a_val = orc_ip(a);
|
||||
@@ -128,6 +128,9 @@ static int orc_sort_cmp(const void *_a, const void *_b)
|
||||
* whitelisted .o files which didn't get objtool generation.
|
||||
*/
|
||||
orc_a = g_orc_table + (a - g_orc_ip_table);
|
||||
+ orc_b = g_orc_table + (b - g_orc_ip_table);
|
||||
+ if (orc_a->type == ORC_TYPE_UNDEFINED && orc_b->type == ORC_TYPE_UNDEFINED)
|
||||
+ return 0;
|
||||
return orc_a->type == ORC_TYPE_UNDEFINED ? -1 : 1;
|
||||
}
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
104
1325-scripts-sorttable-remove-unused-macro-defines.patch
Normal file
104
1325-scripts-sorttable-remove-unused-macro-defines.patch
Normal file
@ -0,0 +1,104 @@
|
||||
From 90e4b4c6300522c4494664bc95285cb94e137b17 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:21:58 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Remove unused macro defines
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 28b24394c6e9a3166fcb4480cba054562526657c
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:12 2025 -0500
|
||||
|
||||
scripts/sorttable: Remove unused macro defines
|
||||
|
||||
The code of sorttable.h was copied from the recordmcount.h which defined
|
||||
a bunch of Elf MACROs so that they could be used between 32bit and 64bit
|
||||
functions. But there's several MACROs that sorttable.h does not use but
|
||||
was copied over. Remove them to clean up the code.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162344.128870118@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index a7c5445baf00..14d0c4d843e8 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -27,19 +27,10 @@
|
||||
#undef Elf_Ehdr
|
||||
#undef Elf_Shdr
|
||||
#undef Elf_Rel
|
||||
-#undef Elf_Rela
|
||||
#undef Elf_Sym
|
||||
-#undef ELF_R_SYM
|
||||
-#undef Elf_r_sym
|
||||
-#undef ELF_R_INFO
|
||||
-#undef Elf_r_info
|
||||
-#undef ELF_ST_BIND
|
||||
#undef ELF_ST_TYPE
|
||||
-#undef fn_ELF_R_SYM
|
||||
-#undef fn_ELF_R_INFO
|
||||
#undef uint_t
|
||||
#undef _r
|
||||
-#undef _w
|
||||
|
||||
#ifdef SORTTABLE_64
|
||||
# define extable_ent_size 16
|
||||
@@ -52,19 +43,10 @@
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
# define Elf_Rel Elf64_Rel
|
||||
-# define Elf_Rela Elf64_Rela
|
||||
# define Elf_Sym Elf64_Sym
|
||||
-# define ELF_R_SYM ELF64_R_SYM
|
||||
-# define Elf_r_sym Elf64_r_sym
|
||||
-# define ELF_R_INFO ELF64_R_INFO
|
||||
-# define Elf_r_info Elf64_r_info
|
||||
-# define ELF_ST_BIND ELF64_ST_BIND
|
||||
# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
-# define fn_ELF_R_SYM fn_ELF64_R_SYM
|
||||
-# define fn_ELF_R_INFO fn_ELF64_R_INFO
|
||||
# define uint_t uint64_t
|
||||
# define _r r8
|
||||
-# define _w w8
|
||||
#else
|
||||
# define extable_ent_size 8
|
||||
# define compare_extable compare_extable_32
|
||||
@@ -76,19 +58,10 @@
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
# define Elf_Rel Elf32_Rel
|
||||
-# define Elf_Rela Elf32_Rela
|
||||
# define Elf_Sym Elf32_Sym
|
||||
-# define ELF_R_SYM ELF32_R_SYM
|
||||
-# define Elf_r_sym Elf32_r_sym
|
||||
-# define ELF_R_INFO ELF32_R_INFO
|
||||
-# define Elf_r_info Elf32_r_info
|
||||
-# define ELF_ST_BIND ELF32_ST_BIND
|
||||
# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
-# define fn_ELF_R_SYM fn_ELF32_R_SYM
|
||||
-# define fn_ELF_R_INFO fn_ELF32_R_INFO
|
||||
# define uint_t uint32_t
|
||||
# define _r r
|
||||
-# define _w w
|
||||
#endif
|
||||
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
102
1326-scripts-sorttable-remove-unused-write-functions.patch
Normal file
102
1326-scripts-sorttable-remove-unused-write-functions.patch
Normal file
@ -0,0 +1,102 @@
|
||||
From 3e1ec2703946dbf8d8f658865fc5c601e3a2cdea Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:02 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Remove unused write functions
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 4f48a28b37d594dab38092514a42ae9f4b781553
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:13 2025 -0500
|
||||
|
||||
scripts/sorttable: Remove unused write functions
|
||||
|
||||
The code of sorttable.h was copied from the recordmcount.h which defined
|
||||
various write functions for different sizes (2, 4, 8 byte lengths). But
|
||||
sorttable only uses the 4 byte writes. Remove the extra versions as they
|
||||
are not used.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162344.314385504@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 83cdb843d92f..4dcdbf7a5e26 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -68,8 +68,6 @@ static uint32_t (*r)(const uint32_t *);
|
||||
static uint16_t (*r2)(const uint16_t *);
|
||||
static uint64_t (*r8)(const uint64_t *);
|
||||
static void (*w)(uint32_t, uint32_t *);
|
||||
-static void (*w2)(uint16_t, uint16_t *);
|
||||
-static void (*w8)(uint64_t, uint64_t *);
|
||||
typedef void (*table_sort_t)(char *, int);
|
||||
|
||||
/*
|
||||
@@ -146,31 +144,11 @@ static void wbe(uint32_t val, uint32_t *x)
|
||||
put_unaligned_be32(val, x);
|
||||
}
|
||||
|
||||
-static void w2be(uint16_t val, uint16_t *x)
|
||||
-{
|
||||
- put_unaligned_be16(val, x);
|
||||
-}
|
||||
-
|
||||
-static void w8be(uint64_t val, uint64_t *x)
|
||||
-{
|
||||
- put_unaligned_be64(val, x);
|
||||
-}
|
||||
-
|
||||
static void wle(uint32_t val, uint32_t *x)
|
||||
{
|
||||
put_unaligned_le32(val, x);
|
||||
}
|
||||
|
||||
-static void w2le(uint16_t val, uint16_t *x)
|
||||
-{
|
||||
- put_unaligned_le16(val, x);
|
||||
-}
|
||||
-
|
||||
-static void w8le(uint64_t val, uint64_t *x)
|
||||
-{
|
||||
- put_unaligned_le64(val, x);
|
||||
-}
|
||||
-
|
||||
/*
|
||||
* Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
|
||||
* the way to -256..-1, to avoid conflicting with real section
|
||||
@@ -277,16 +255,12 @@ static int do_file(char const *const fname, void *addr)
|
||||
r2 = r2le;
|
||||
r8 = r8le;
|
||||
w = wle;
|
||||
- w2 = w2le;
|
||||
- w8 = w8le;
|
||||
break;
|
||||
case ELFDATA2MSB:
|
||||
r = rbe;
|
||||
r2 = r2be;
|
||||
r8 = r8be;
|
||||
w = wbe;
|
||||
- w2 = w2be;
|
||||
- w8 = w8be;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
118
1327-scripts-sorttable-remove-unneeded-elf-rel.patch
Normal file
118
1327-scripts-sorttable-remove-unneeded-elf-rel.patch
Normal file
@ -0,0 +1,118 @@
|
||||
From b0006591a4fb4d08bab55e02d904a225bb97f803 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:06 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Remove unneeded Elf_Rel
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 6f2c2f93a190467cebd6ebd03feb49514fead5ca
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:14 2025 -0500
|
||||
|
||||
scripts/sorttable: Remove unneeded Elf_Rel
|
||||
|
||||
The code had references to initialize the Elf_Rel relocation tables, but
|
||||
it was never used. Remove it.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162344.515342233@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 14d0c4d843e8..18d07fdb2716 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -26,7 +26,6 @@
|
||||
#undef Elf_Addr
|
||||
#undef Elf_Ehdr
|
||||
#undef Elf_Shdr
|
||||
-#undef Elf_Rel
|
||||
#undef Elf_Sym
|
||||
#undef ELF_ST_TYPE
|
||||
#undef uint_t
|
||||
@@ -42,7 +41,6 @@
|
||||
# define Elf_Addr Elf64_Addr
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
-# define Elf_Rel Elf64_Rel
|
||||
# define Elf_Sym Elf64_Sym
|
||||
# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
# define uint_t uint64_t
|
||||
@@ -57,7 +55,6 @@
|
||||
# define Elf_Addr Elf32_Addr
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
-# define Elf_Rel Elf32_Rel
|
||||
# define Elf_Sym Elf32_Sym
|
||||
# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
# define uint_t uint32_t
|
||||
@@ -248,14 +245,10 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
Elf32_Word *symtab_shndx = NULL;
|
||||
Elf_Sym *sort_needed_sym = NULL;
|
||||
Elf_Shdr *sort_needed_sec;
|
||||
- Elf_Rel *relocs = NULL;
|
||||
- int relocs_size = 0;
|
||||
uint32_t *sort_needed_loc;
|
||||
const char *secstrings;
|
||||
const char *strtab;
|
||||
char *extab_image;
|
||||
- int extab_index = 0;
|
||||
- int i;
|
||||
int idx;
|
||||
unsigned int shnum;
|
||||
unsigned int shstrndx;
|
||||
@@ -279,23 +272,15 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
if (shnum == SHN_UNDEF)
|
||||
shnum = _r(&shdr[0].sh_size);
|
||||
|
||||
- for (i = 0, s = shdr; s < shdr + shnum; i++, s++) {
|
||||
+ for (s = shdr; s < shdr + shnum; s++) {
|
||||
idx = r(&s->sh_name);
|
||||
- if (!strcmp(secstrings + idx, "__ex_table")) {
|
||||
+ if (!strcmp(secstrings + idx, "__ex_table"))
|
||||
extab_sec = s;
|
||||
- extab_index = i;
|
||||
- }
|
||||
if (!strcmp(secstrings + idx, ".symtab"))
|
||||
symtab_sec = s;
|
||||
if (!strcmp(secstrings + idx, ".strtab"))
|
||||
strtab_sec = s;
|
||||
|
||||
- if ((r(&s->sh_type) == SHT_REL ||
|
||||
- r(&s->sh_type) == SHT_RELA) &&
|
||||
- r(&s->sh_info) == extab_index) {
|
||||
- relocs = (void *)ehdr + _r(&s->sh_offset);
|
||||
- relocs_size = _r(&s->sh_size);
|
||||
- }
|
||||
if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
|
||||
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
|
||||
_r(&s->sh_offset));
|
||||
@@ -397,10 +382,6 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
extable_ent_size, compare_extable);
|
||||
}
|
||||
|
||||
- /* If there were relocations, we no longer need them. */
|
||||
- if (relocs)
|
||||
- memset(relocs, 0, relocs_size);
|
||||
-
|
||||
/* find the flag main_extable_sort_needed */
|
||||
for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
|
||||
sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
From 8b98d95b2f3df8cdec1154dcce05f292bdde59d0 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:10 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Have the ORC code use the _r() functions
|
||||
to read
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 66990c003306c240d570b3ba274ec4f68cf18c91
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:15 2025 -0500
|
||||
|
||||
scripts/sorttable: Have the ORC code use the _r() functions to read
|
||||
|
||||
The ORC code reads the section information directly from the file. This
|
||||
currently works because the default read function is for 64bit little
|
||||
endian machines. But if for some reason that ever changes, this will
|
||||
break. Instead of having a surprise breakage, use the _r() functions that
|
||||
will read the values from the file properly.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162344.721480386@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 18d07fdb2716..58f7ab5f5644 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -299,14 +299,14 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
/* locate the ORC unwind tables */
|
||||
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
|
||||
- orc_ip_size = s->sh_size;
|
||||
+ orc_ip_size = _r(&s->sh_size);
|
||||
g_orc_ip_table = (int *)((void *)ehdr +
|
||||
- s->sh_offset);
|
||||
+ _r(&s->sh_offset));
|
||||
}
|
||||
if (!strcmp(secstrings + idx, ".orc_unwind")) {
|
||||
- orc_size = s->sh_size;
|
||||
+ orc_size = _r(&s->sh_size);
|
||||
g_orc_table = (struct orc_entry *)((void *)ehdr +
|
||||
- s->sh_offset);
|
||||
+ _r(&s->sh_offset));
|
||||
}
|
||||
#endif
|
||||
} /* for loop */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,132 @@
|
||||
From 3f3c4e53bd362a76e3a097c1dac3c8975cb99926 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:13 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Make compare_extable() into two functions
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 7ffc0d0819f438779ed592e2e2e3576f43ce14f0
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:16 2025 -0500
|
||||
|
||||
scripts/sorttable: Make compare_extable() into two functions
|
||||
|
||||
Instead of having the compare_extable() part of the sorttable.h header
|
||||
where it get's defined twice, since it is a very simple function, just
|
||||
define it twice in sorttable.c, and then it can use the proper read
|
||||
functions for the word size and endianess and the Elf_Addr macro can be
|
||||
removed from sorttable.h.
|
||||
|
||||
Also add a micro optimization. Instead of:
|
||||
|
||||
if (a < b)
|
||||
return -1;
|
||||
if (a > b)
|
||||
return 1;
|
||||
return 0;
|
||||
|
||||
That can be shorten to:
|
||||
|
||||
if (a < b)
|
||||
return -1;
|
||||
return a > b;
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162344.945299671@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 4dcdbf7a5e26..3e2c17e91485 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -173,6 +173,26 @@ static inline unsigned int get_secindex(unsigned int shndx,
|
||||
return r(&symtab_shndx_start[sym_offs]);
|
||||
}
|
||||
|
||||
+static int compare_extable_32(const void *a, const void *b)
|
||||
+{
|
||||
+ Elf32_Addr av = r(a);
|
||||
+ Elf32_Addr bv = r(b);
|
||||
+
|
||||
+ if (av < bv)
|
||||
+ return -1;
|
||||
+ return av > bv;
|
||||
+}
|
||||
+
|
||||
+static int compare_extable_64(const void *a, const void *b)
|
||||
+{
|
||||
+ Elf64_Addr av = r8(a);
|
||||
+ Elf64_Addr bv = r8(b);
|
||||
+
|
||||
+ if (av < bv)
|
||||
+ return -1;
|
||||
+ return av > bv;
|
||||
+}
|
||||
+
|
||||
/* 32 bit and 64 bit are very similar */
|
||||
#include "sorttable.h"
|
||||
#define SORTTABLE_64
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 58f7ab5f5644..36655ff16b39 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -23,7 +23,6 @@
|
||||
#undef sort_mcount_loc
|
||||
#undef elf_mcount_loc
|
||||
#undef do_sort
|
||||
-#undef Elf_Addr
|
||||
#undef Elf_Ehdr
|
||||
#undef Elf_Shdr
|
||||
#undef Elf_Sym
|
||||
@@ -38,7 +37,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_64
|
||||
# define elf_mcount_loc elf_mcount_loc_64
|
||||
# define do_sort do_sort_64
|
||||
-# define Elf_Addr Elf64_Addr
|
||||
# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
# define Elf_Sym Elf64_Sym
|
||||
@@ -52,7 +50,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_32
|
||||
# define elf_mcount_loc elf_mcount_loc_32
|
||||
# define do_sort do_sort_32
|
||||
-# define Elf_Addr Elf32_Addr
|
||||
# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
# define Elf_Sym Elf32_Sym
|
||||
@@ -160,17 +157,6 @@ static void *sort_orctable(void *arg)
|
||||
}
|
||||
#endif
|
||||
|
||||
-static int compare_extable(const void *a, const void *b)
|
||||
-{
|
||||
- Elf_Addr av = _r(a);
|
||||
- Elf_Addr bv = _r(b);
|
||||
-
|
||||
- if (av < bv)
|
||||
- return -1;
|
||||
- if (av > bv)
|
||||
- return 1;
|
||||
- return 0;
|
||||
-}
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
pthread_t mcount_sort_thread;
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
212
1330-scripts-sorttable-convert-elf-ehdr-to-union.patch
Normal file
212
1330-scripts-sorttable-convert-elf-ehdr-to-union.patch
Normal file
@ -0,0 +1,212 @@
|
||||
From a9cb56b10f496e1e39543627f47eecda2d65213f Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:16 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Convert Elf_Ehdr to union
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 157fb5b3cfd2cb5950314f926a76e567fc1921c5
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:17 2025 -0500
|
||||
|
||||
scripts/sorttable: Convert Elf_Ehdr to union
|
||||
|
||||
In order to remove the double #include of sorttable.h for 64 and 32 bit
|
||||
to create duplicate functions for both, replace the Elf_Ehdr macro with a
|
||||
union that defines both Elf64_Ehdr and Elf32_Ehdr, with field e64 for the
|
||||
64bit version, and e32 for the 32bit version.
|
||||
|
||||
Then a macro etype can be used instead to get to the proper value.
|
||||
|
||||
This will eventually be replaced with just single functions that can
|
||||
handle both 32bit and 64bit ELF parsing.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162345.148224465@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 3e2c17e91485..67cbbfc8214d 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -64,6 +64,11 @@
|
||||
#define EM_LOONGARCH 258
|
||||
#endif
|
||||
|
||||
+typedef union {
|
||||
+ Elf32_Ehdr e32;
|
||||
+ Elf64_Ehdr e64;
|
||||
+} Elf_Ehdr;
|
||||
+
|
||||
static uint32_t (*r)(const uint32_t *);
|
||||
static uint16_t (*r2)(const uint16_t *);
|
||||
static uint64_t (*r8)(const uint64_t *);
|
||||
@@ -266,10 +271,10 @@ static void sort_relative_table_with_data(char *extab_image, int image_size)
|
||||
static int do_file(char const *const fname, void *addr)
|
||||
{
|
||||
int rc = -1;
|
||||
- Elf32_Ehdr *ehdr = addr;
|
||||
+ Elf_Ehdr *ehdr = addr;
|
||||
table_sort_t custom_sort = NULL;
|
||||
|
||||
- switch (ehdr->e_ident[EI_DATA]) {
|
||||
+ switch (ehdr->e32.e_ident[EI_DATA]) {
|
||||
case ELFDATA2LSB:
|
||||
r = rle;
|
||||
r2 = r2le;
|
||||
@@ -284,18 +289,18 @@ static int do_file(char const *const fname, void *addr)
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
|
||||
- ehdr->e_ident[EI_DATA], fname);
|
||||
+ ehdr->e32.e_ident[EI_DATA], fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 ||
|
||||
- (r2(&ehdr->e_type) != ET_EXEC && r2(&ehdr->e_type) != ET_DYN) ||
|
||||
- ehdr->e_ident[EI_VERSION] != EV_CURRENT) {
|
||||
+ if (memcmp(ELFMAG, ehdr->e32.e_ident, SELFMAG) != 0 ||
|
||||
+ (r2(&ehdr->e32.e_type) != ET_EXEC && r2(&ehdr->e32.e_type) != ET_DYN) ||
|
||||
+ ehdr->e32.e_ident[EI_VERSION] != EV_CURRENT) {
|
||||
fprintf(stderr, "unrecognized ET_EXEC/ET_DYN file %s\n", fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- switch (r2(&ehdr->e_machine)) {
|
||||
+ switch (r2(&ehdr->e32.e_machine)) {
|
||||
case EM_386:
|
||||
case EM_AARCH64:
|
||||
case EM_LOONGARCH:
|
||||
@@ -318,14 +323,14 @@ static int do_file(char const *const fname, void *addr)
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized e_machine %d %s\n",
|
||||
- r2(&ehdr->e_machine), fname);
|
||||
+ r2(&ehdr->e32.e_machine), fname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
- switch (ehdr->e_ident[EI_CLASS]) {
|
||||
+ switch (ehdr->e32.e_ident[EI_CLASS]) {
|
||||
case ELFCLASS32:
|
||||
- if (r2(&ehdr->e_ehsize) != sizeof(Elf32_Ehdr) ||
|
||||
- r2(&ehdr->e_shentsize) != sizeof(Elf32_Shdr)) {
|
||||
+ if (r2(&ehdr->e32.e_ehsize) != sizeof(Elf32_Ehdr) ||
|
||||
+ r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
|
||||
fprintf(stderr,
|
||||
"unrecognized ET_EXEC/ET_DYN file: %s\n", fname);
|
||||
break;
|
||||
@@ -334,20 +339,19 @@ static int do_file(char const *const fname, void *addr)
|
||||
break;
|
||||
case ELFCLASS64:
|
||||
{
|
||||
- Elf64_Ehdr *const ghdr = (Elf64_Ehdr *)ehdr;
|
||||
- if (r2(&ghdr->e_ehsize) != sizeof(Elf64_Ehdr) ||
|
||||
- r2(&ghdr->e_shentsize) != sizeof(Elf64_Shdr)) {
|
||||
+ if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
|
||||
+ r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
|
||||
fprintf(stderr,
|
||||
"unrecognized ET_EXEC/ET_DYN file: %s\n",
|
||||
fname);
|
||||
break;
|
||||
}
|
||||
- rc = do_sort_64(ghdr, fname, custom_sort);
|
||||
+ rc = do_sort_64(ehdr, fname, custom_sort);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF class %d %s\n",
|
||||
- ehdr->e_ident[EI_CLASS], fname);
|
||||
+ ehdr->e32.e_ident[EI_CLASS], fname);
|
||||
break;
|
||||
}
|
||||
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 36655ff16b39..be8b529498fb 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -23,12 +23,12 @@
|
||||
#undef sort_mcount_loc
|
||||
#undef elf_mcount_loc
|
||||
#undef do_sort
|
||||
-#undef Elf_Ehdr
|
||||
#undef Elf_Shdr
|
||||
#undef Elf_Sym
|
||||
#undef ELF_ST_TYPE
|
||||
#undef uint_t
|
||||
#undef _r
|
||||
+#undef etype
|
||||
|
||||
#ifdef SORTTABLE_64
|
||||
# define extable_ent_size 16
|
||||
@@ -37,12 +37,12 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_64
|
||||
# define elf_mcount_loc elf_mcount_loc_64
|
||||
# define do_sort do_sort_64
|
||||
-# define Elf_Ehdr Elf64_Ehdr
|
||||
# define Elf_Shdr Elf64_Shdr
|
||||
# define Elf_Sym Elf64_Sym
|
||||
# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
# define uint_t uint64_t
|
||||
# define _r r8
|
||||
+# define etype e64
|
||||
#else
|
||||
# define extable_ent_size 8
|
||||
# define compare_extable compare_extable_32
|
||||
@@ -50,12 +50,12 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_32
|
||||
# define elf_mcount_loc elf_mcount_loc_32
|
||||
# define do_sort do_sort_32
|
||||
-# define Elf_Ehdr Elf32_Ehdr
|
||||
# define Elf_Shdr Elf32_Shdr
|
||||
# define Elf_Sym Elf32_Sym
|
||||
# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
# define uint_t uint32_t
|
||||
# define _r r
|
||||
+# define etype e32
|
||||
#endif
|
||||
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
@@ -222,7 +222,7 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
table_sort_t custom_sort)
|
||||
{
|
||||
int rc = -1;
|
||||
- Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->e_shoff));
|
||||
+ Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
|
||||
Elf_Shdr *strtab_sec = NULL;
|
||||
Elf_Shdr *symtab_sec = NULL;
|
||||
Elf_Shdr *extab_sec = NULL;
|
||||
@@ -249,12 +249,12 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
unsigned int orc_num_entries = 0;
|
||||
#endif
|
||||
|
||||
- shstrndx = r2(&ehdr->e_shstrndx);
|
||||
+ shstrndx = r2(&ehdr->etype.e_shstrndx);
|
||||
if (shstrndx == SHN_XINDEX)
|
||||
shstrndx = r(&shdr[0].sh_link);
|
||||
secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
|
||||
|
||||
- shnum = r2(&ehdr->e_shnum);
|
||||
+ shnum = r2(&ehdr->etype.e_shnum);
|
||||
if (shnum == SHN_UNDEF)
|
||||
shnum = _r(&shdr[0].sh_size);
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
257
1331-scripts-sorttable-replace-elf-shdr-macro-with-a-union.patch
Normal file
257
1331-scripts-sorttable-replace-elf-shdr-macro-with-a-union.patch
Normal file
@ -0,0 +1,257 @@
|
||||
From e5bf3a68ca49663c4c12c03dbbb236a86ae7ef45 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:20 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Replace Elf_Shdr Macro with a union
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 545f6cf8f4c9a268e0bab2637f1d279679befdbf
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:18 2025 -0500
|
||||
|
||||
scripts/sorttable: Replace Elf_Shdr Macro with a union
|
||||
|
||||
In order to remove the double #include of sorttable.h for 64 and 32 bit
|
||||
to create duplicate functions for both, replace the Elf_Shdr macro with a
|
||||
union that defines both Elf64_Shdr and Elf32_Shdr, with field e64 for the
|
||||
64bit version, and e32 for the 32bit version.
|
||||
|
||||
It can then use the macro etype to get the proper value.
|
||||
|
||||
This will eventually be replaced with just single functions that can
|
||||
handle both 32bit and 64bit ELF parsing.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162345.339462681@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 67cbbfc8214d..94497b8ab04c 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -69,6 +69,11 @@ typedef union {
|
||||
Elf64_Ehdr e64;
|
||||
} Elf_Ehdr;
|
||||
|
||||
+typedef union {
|
||||
+ Elf32_Shdr e32;
|
||||
+ Elf64_Shdr e64;
|
||||
+} Elf_Shdr;
|
||||
+
|
||||
static uint32_t (*r)(const uint32_t *);
|
||||
static uint16_t (*r2)(const uint16_t *);
|
||||
static uint64_t (*r8)(const uint64_t *);
|
||||
@@ -198,6 +203,11 @@ static int compare_extable_64(const void *a, const void *b)
|
||||
return av > bv;
|
||||
}
|
||||
|
||||
+static inline void *get_index(void *start, int entsize, int index)
|
||||
+{
|
||||
+ return start + (entsize * index);
|
||||
+}
|
||||
+
|
||||
/* 32 bit and 64 bit are very similar */
|
||||
#include "sorttable.h"
|
||||
#define SORTTABLE_64
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index be8b529498fb..3daf37bb6b9a 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -23,7 +23,6 @@
|
||||
#undef sort_mcount_loc
|
||||
#undef elf_mcount_loc
|
||||
#undef do_sort
|
||||
-#undef Elf_Shdr
|
||||
#undef Elf_Sym
|
||||
#undef ELF_ST_TYPE
|
||||
#undef uint_t
|
||||
@@ -37,7 +36,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_64
|
||||
# define elf_mcount_loc elf_mcount_loc_64
|
||||
# define do_sort do_sort_64
|
||||
-# define Elf_Shdr Elf64_Shdr
|
||||
# define Elf_Sym Elf64_Sym
|
||||
# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
# define uint_t uint64_t
|
||||
@@ -50,7 +48,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_32
|
||||
# define elf_mcount_loc elf_mcount_loc_32
|
||||
# define do_sort do_sort_32
|
||||
-# define Elf_Shdr Elf32_Shdr
|
||||
# define Elf_Sym Elf32_Sym
|
||||
# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
# define uint_t uint32_t
|
||||
@@ -171,8 +168,8 @@ struct elf_mcount_loc {
|
||||
static void *sort_mcount_loc(void *arg)
|
||||
{
|
||||
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
|
||||
- uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->sh_addr)
|
||||
- + _r(&(emloc->init_data_sec)->sh_offset);
|
||||
+ uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
|
||||
+ + _r(&(emloc->init_data_sec)->etype.sh_offset);
|
||||
uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
unsigned char *start_loc = (void *)emloc->ehdr + offset;
|
||||
|
||||
@@ -222,10 +219,11 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
table_sort_t custom_sort)
|
||||
{
|
||||
int rc = -1;
|
||||
- Elf_Shdr *s, *shdr = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
|
||||
+ Elf_Shdr *shdr_start;
|
||||
Elf_Shdr *strtab_sec = NULL;
|
||||
Elf_Shdr *symtab_sec = NULL;
|
||||
Elf_Shdr *extab_sec = NULL;
|
||||
+ Elf_Shdr *string_sec;
|
||||
Elf_Sym *sym;
|
||||
const Elf_Sym *symtab;
|
||||
Elf32_Word *symtab_shndx = NULL;
|
||||
@@ -235,7 +233,10 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
const char *secstrings;
|
||||
const char *strtab;
|
||||
char *extab_image;
|
||||
+ int sort_need_index;
|
||||
+ int shentsize;
|
||||
int idx;
|
||||
+ int i;
|
||||
unsigned int shnum;
|
||||
unsigned int shstrndx;
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
@@ -249,34 +250,40 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
unsigned int orc_num_entries = 0;
|
||||
#endif
|
||||
|
||||
+ shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
|
||||
+ shentsize = r2(&ehdr->etype.e_shentsize);
|
||||
+
|
||||
shstrndx = r2(&ehdr->etype.e_shstrndx);
|
||||
if (shstrndx == SHN_XINDEX)
|
||||
- shstrndx = r(&shdr[0].sh_link);
|
||||
- secstrings = (const char *)ehdr + _r(&shdr[shstrndx].sh_offset);
|
||||
+ shstrndx = r(&shdr_start->etype.sh_link);
|
||||
+ string_sec = get_index(shdr_start, shentsize, shstrndx);
|
||||
+ secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
|
||||
|
||||
shnum = r2(&ehdr->etype.e_shnum);
|
||||
if (shnum == SHN_UNDEF)
|
||||
- shnum = _r(&shdr[0].sh_size);
|
||||
+ shnum = _r(&shdr_start->etype.sh_size);
|
||||
+
|
||||
+ for (i = 0; i < shnum; i++) {
|
||||
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
|
||||
|
||||
- for (s = shdr; s < shdr + shnum; s++) {
|
||||
- idx = r(&s->sh_name);
|
||||
+ idx = r(&shdr->etype.sh_name);
|
||||
if (!strcmp(secstrings + idx, "__ex_table"))
|
||||
- extab_sec = s;
|
||||
+ extab_sec = shdr;
|
||||
if (!strcmp(secstrings + idx, ".symtab"))
|
||||
- symtab_sec = s;
|
||||
+ symtab_sec = shdr;
|
||||
if (!strcmp(secstrings + idx, ".strtab"))
|
||||
- strtab_sec = s;
|
||||
+ strtab_sec = shdr;
|
||||
|
||||
- if (r(&s->sh_type) == SHT_SYMTAB_SHNDX)
|
||||
+ if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
|
||||
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
|
||||
- _r(&s->sh_offset));
|
||||
+ _r(&shdr->etype.sh_offset));
|
||||
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
/* locate the .init.data section in vmlinux */
|
||||
if (!strcmp(secstrings + idx, ".init.data")) {
|
||||
get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
|
||||
mstruct.ehdr = ehdr;
|
||||
- mstruct.init_data_sec = s;
|
||||
+ mstruct.init_data_sec = shdr;
|
||||
mstruct.start_mcount_loc = _start_mcount_loc;
|
||||
mstruct.stop_mcount_loc = _stop_mcount_loc;
|
||||
}
|
||||
@@ -285,14 +292,14 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
/* locate the ORC unwind tables */
|
||||
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
|
||||
- orc_ip_size = _r(&s->sh_size);
|
||||
+ orc_ip_size = _r(&shdr->etype.sh_size);
|
||||
g_orc_ip_table = (int *)((void *)ehdr +
|
||||
- _r(&s->sh_offset));
|
||||
+ _r(&shdr->etype.sh_offset));
|
||||
}
|
||||
if (!strcmp(secstrings + idx, ".orc_unwind")) {
|
||||
- orc_size = _r(&s->sh_size);
|
||||
+ orc_size = _r(&shdr->etype.sh_size);
|
||||
g_orc_table = (struct orc_entry *)((void *)ehdr +
|
||||
- _r(&s->sh_offset));
|
||||
+ _r(&shdr->etype.sh_offset));
|
||||
}
|
||||
#endif
|
||||
} /* for loop */
|
||||
@@ -355,22 +362,22 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- extab_image = (void *)ehdr + _r(&extab_sec->sh_offset);
|
||||
- strtab = (const char *)ehdr + _r(&strtab_sec->sh_offset);
|
||||
+ extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
|
||||
+ strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
|
||||
symtab = (const Elf_Sym *)((const char *)ehdr +
|
||||
- _r(&symtab_sec->sh_offset));
|
||||
+ _r(&symtab_sec->etype.sh_offset));
|
||||
|
||||
if (custom_sort) {
|
||||
- custom_sort(extab_image, _r(&extab_sec->sh_size));
|
||||
+ custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
|
||||
} else {
|
||||
- int num_entries = _r(&extab_sec->sh_size) / extable_ent_size;
|
||||
+ int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
|
||||
qsort(extab_image, num_entries,
|
||||
extable_ent_size, compare_extable);
|
||||
}
|
||||
|
||||
/* find the flag main_extable_sort_needed */
|
||||
- for (sym = (void *)ehdr + _r(&symtab_sec->sh_offset);
|
||||
- sym < sym + _r(&symtab_sec->sh_size) / sizeof(Elf_Sym);
|
||||
+ for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
|
||||
+ sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
|
||||
sym++) {
|
||||
if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
|
||||
continue;
|
||||
@@ -388,13 +395,14 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- sort_needed_sec = &shdr[get_secindex(r2(&sym->st_shndx),
|
||||
- sort_needed_sym - symtab,
|
||||
- symtab_shndx)];
|
||||
+ sort_need_index = get_secindex(r2(&sym->st_shndx),
|
||||
+ sort_needed_sym - symtab,
|
||||
+ symtab_shndx);
|
||||
+ sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
|
||||
sort_needed_loc = (void *)ehdr +
|
||||
- _r(&sort_needed_sec->sh_offset) +
|
||||
+ _r(&sort_needed_sec->etype.sh_offset) +
|
||||
_r(&sort_needed_sym->st_value) -
|
||||
- _r(&sort_needed_sec->sh_addr);
|
||||
+ _r(&sort_needed_sec->etype.sh_addr);
|
||||
|
||||
/* extable has been sorted, clear the flag */
|
||||
w(0, sort_needed_loc);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,141 @@
|
||||
From d95dcd72b2a2511fa93a2b185611cba7f4624f7c Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:23 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Convert Elf_Sym MACRO over to a union
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 200d015e73b4da69bcd8212a7c58695452b12bad
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:19 2025 -0500
|
||||
|
||||
scripts/sorttable: Convert Elf_Sym MACRO over to a union
|
||||
|
||||
In order to remove the double #include of sorttable.h for 64 and 32 bit
|
||||
to create duplicate functions for both, replace the Elf_Sym macro with a
|
||||
union that defines both Elf64_Sym and Elf32_Sym, with field e64 for the
|
||||
64bit version, and e32 for the 32bit version.
|
||||
|
||||
It can then use the macro etype to get the proper value.
|
||||
|
||||
This will eventually be replaced with just single functions that can
|
||||
handle both 32bit and 64bit ELF parsing.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162345.528626969@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 94497b8ab04c..57792cf2aa89 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -74,6 +74,11 @@ typedef union {
|
||||
Elf64_Shdr e64;
|
||||
} Elf_Shdr;
|
||||
|
||||
+typedef union {
|
||||
+ Elf32_Sym e32;
|
||||
+ Elf64_Sym e64;
|
||||
+} Elf_Sym;
|
||||
+
|
||||
static uint32_t (*r)(const uint32_t *);
|
||||
static uint16_t (*r2)(const uint16_t *);
|
||||
static uint64_t (*r8)(const uint64_t *);
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 3daf37bb6b9a..cd4429c8a9f4 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -23,7 +23,6 @@
|
||||
#undef sort_mcount_loc
|
||||
#undef elf_mcount_loc
|
||||
#undef do_sort
|
||||
-#undef Elf_Sym
|
||||
#undef ELF_ST_TYPE
|
||||
#undef uint_t
|
||||
#undef _r
|
||||
@@ -36,7 +35,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_64
|
||||
# define elf_mcount_loc elf_mcount_loc_64
|
||||
# define do_sort do_sort_64
|
||||
-# define Elf_Sym Elf64_Sym
|
||||
# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
# define uint_t uint64_t
|
||||
# define _r r8
|
||||
@@ -48,7 +46,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_32
|
||||
# define elf_mcount_loc elf_mcount_loc_32
|
||||
# define do_sort do_sort_32
|
||||
-# define Elf_Sym Elf32_Sym
|
||||
# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
# define uint_t uint32_t
|
||||
# define _r r
|
||||
@@ -230,10 +227,13 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
Elf_Sym *sort_needed_sym = NULL;
|
||||
Elf_Shdr *sort_needed_sec;
|
||||
uint32_t *sort_needed_loc;
|
||||
+ void *sym_start;
|
||||
+ void *sym_end;
|
||||
const char *secstrings;
|
||||
const char *strtab;
|
||||
char *extab_image;
|
||||
int sort_need_index;
|
||||
+ int symentsize;
|
||||
int shentsize;
|
||||
int idx;
|
||||
int i;
|
||||
@@ -376,12 +376,15 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
}
|
||||
|
||||
/* find the flag main_extable_sort_needed */
|
||||
- for (sym = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
|
||||
- sym < sym + _r(&symtab_sec->etype.sh_size) / sizeof(Elf_Sym);
|
||||
- sym++) {
|
||||
- if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT)
|
||||
+ sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
|
||||
+ sym_end = sym_start + _r(&symtab_sec->etype.sh_size);
|
||||
+ symentsize = _r(&symtab_sec->etype.sh_entsize);
|
||||
+
|
||||
+ for (sym = sym_start; (void *)sym + symentsize < sym_end;
|
||||
+ sym = (void *)sym + symentsize) {
|
||||
+ if (ELF_ST_TYPE(sym->etype.st_info) != STT_OBJECT)
|
||||
continue;
|
||||
- if (!strcmp(strtab + r(&sym->st_name),
|
||||
+ if (!strcmp(strtab + r(&sym->etype.st_name),
|
||||
"main_extable_sort_needed")) {
|
||||
sort_needed_sym = sym;
|
||||
break;
|
||||
@@ -395,13 +398,13 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- sort_need_index = get_secindex(r2(&sym->st_shndx),
|
||||
- sort_needed_sym - symtab,
|
||||
+ sort_need_index = get_secindex(r2(&sym->etype.st_shndx),
|
||||
+ ((void *)sort_needed_sym - (void *)symtab) / symentsize,
|
||||
symtab_shndx);
|
||||
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
|
||||
sort_needed_loc = (void *)ehdr +
|
||||
_r(&sort_needed_sec->etype.sh_offset) +
|
||||
- _r(&sort_needed_sym->st_value) -
|
||||
+ _r(&sort_needed_sym->etype.st_value) -
|
||||
_r(&sort_needed_sec->etype.sh_addr);
|
||||
|
||||
/* extable has been sorted, clear the flag */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
139
1333-scripts-sorttable-add-helper-functions-for-elf-ehdr.patch
Normal file
139
1333-scripts-sorttable-add-helper-functions-for-elf-ehdr.patch
Normal file
@ -0,0 +1,139 @@
|
||||
From 1278ee787a87aaaa378d44f173cdae2fb07501ae Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:33 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Add helper functions for Elf_Ehdr
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 1dfb59a228dde59ad7d99b2fa2104e90004995c7
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:20 2025 -0500
|
||||
|
||||
scripts/sorttable: Add helper functions for Elf_Ehdr
|
||||
|
||||
In order to remove the double #include of sorttable.h for 64 and 32 bit
|
||||
to create duplicate functions, add helper functions for Elf_Ehdr. This
|
||||
will create a function pointer for each helper that will get assigned to
|
||||
the appropriate function to handle either the 64bit or 32bit version.
|
||||
|
||||
This also moves the _r()/r() wrappers for the Elf_Ehdr references that
|
||||
handle endian and size differences between the different architectures,
|
||||
into the helper function and out of the open code which is more error
|
||||
prone.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162345.736369526@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 57792cf2aa89..5dfa734eff09 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -85,6 +85,31 @@ static uint64_t (*r8)(const uint64_t *);
|
||||
static void (*w)(uint32_t, uint32_t *);
|
||||
typedef void (*table_sort_t)(char *, int);
|
||||
|
||||
+static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
|
||||
+{
|
||||
+ return r8(&ehdr->e64.e_shoff);
|
||||
+}
|
||||
+
|
||||
+static uint64_t ehdr32_shoff(Elf_Ehdr *ehdr)
|
||||
+{
|
||||
+ return r(&ehdr->e32.e_shoff);
|
||||
+}
|
||||
+
|
||||
+#define EHDR_HALF(fn_name) \
|
||||
+static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
|
||||
+{ \
|
||||
+ return r2(&ehdr->e64.e_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
|
||||
+{ \
|
||||
+ return r2(&ehdr->e32.e_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+EHDR_HALF(shentsize)
|
||||
+EHDR_HALF(shstrndx)
|
||||
+EHDR_HALF(shnum)
|
||||
+
|
||||
/*
|
||||
* Get the whole file as a programming convenience in order to avoid
|
||||
* malloc+lseek+read+free of many pieces. If successful, then mmap
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index cd4429c8a9f4..97278c973bc9 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -27,6 +27,10 @@
|
||||
#undef uint_t
|
||||
#undef _r
|
||||
#undef etype
|
||||
+#undef ehdr_shoff
|
||||
+#undef ehdr_shentsize
|
||||
+#undef ehdr_shstrndx
|
||||
+#undef ehdr_shnum
|
||||
|
||||
#ifdef SORTTABLE_64
|
||||
# define extable_ent_size 16
|
||||
@@ -39,6 +43,10 @@
|
||||
# define uint_t uint64_t
|
||||
# define _r r8
|
||||
# define etype e64
|
||||
+# define ehdr_shoff ehdr64_shoff
|
||||
+# define ehdr_shentsize ehdr64_shentsize
|
||||
+# define ehdr_shstrndx ehdr64_shstrndx
|
||||
+# define ehdr_shnum ehdr64_shnum
|
||||
#else
|
||||
# define extable_ent_size 8
|
||||
# define compare_extable compare_extable_32
|
||||
@@ -50,6 +58,10 @@
|
||||
# define uint_t uint32_t
|
||||
# define _r r
|
||||
# define etype e32
|
||||
+# define ehdr_shoff ehdr32_shoff
|
||||
+# define ehdr_shentsize ehdr32_shentsize
|
||||
+# define ehdr_shstrndx ehdr32_shstrndx
|
||||
+# define ehdr_shnum ehdr32_shnum
|
||||
#endif
|
||||
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
@@ -250,16 +262,16 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
unsigned int orc_num_entries = 0;
|
||||
#endif
|
||||
|
||||
- shdr_start = (Elf_Shdr *)((char *)ehdr + _r(&ehdr->etype.e_shoff));
|
||||
- shentsize = r2(&ehdr->etype.e_shentsize);
|
||||
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
|
||||
+ shentsize = ehdr_shentsize(ehdr);
|
||||
|
||||
- shstrndx = r2(&ehdr->etype.e_shstrndx);
|
||||
+ shstrndx = ehdr_shstrndx(ehdr);
|
||||
if (shstrndx == SHN_XINDEX)
|
||||
shstrndx = r(&shdr_start->etype.sh_link);
|
||||
string_sec = get_index(shdr_start, shentsize, shstrndx);
|
||||
secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
|
||||
|
||||
- shnum = r2(&ehdr->etype.e_shnum);
|
||||
+ shnum = ehdr_shnum(ehdr);
|
||||
if (shnum == SHN_UNDEF)
|
||||
shnum = _r(&shdr_start->etype.sh_size);
|
||||
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
253
1334-scripts-sorttable-add-helper-functions-for-elf-shdr.patch
Normal file
253
1334-scripts-sorttable-add-helper-functions-for-elf-shdr.patch
Normal file
@ -0,0 +1,253 @@
|
||||
From a5efd249d8b52767833dcd9ca0b7f8f5470cf289 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:40 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Add helper functions for Elf_Shdr
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 67afb7f504400e5b4e5ff895459fbb3eb63d4450
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:21 2025 -0500
|
||||
|
||||
scripts/sorttable: Add helper functions for Elf_Shdr
|
||||
|
||||
In order to remove the double #include of sorttable.h for 64 and 32 bit
|
||||
to create duplicate functions, add helper functions for Elf_Shdr. This
|
||||
will create a function pointer for each helper that will get assigned to
|
||||
the appropriate function to handle either the 64bit or 32bit version.
|
||||
|
||||
This also moves the _r()/r() wrappers for the Elf_Shdr references that
|
||||
handle endian and size differences between the different architectures,
|
||||
into the helper function and out of the open code which is more error
|
||||
prone.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162345.940924221@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 5dfa734eff09..b2b96ff261d6 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -110,6 +110,48 @@ EHDR_HALF(shentsize)
|
||||
EHDR_HALF(shstrndx)
|
||||
EHDR_HALF(shnum)
|
||||
|
||||
+#define SHDR_WORD(fn_name) \
|
||||
+static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return r(&shdr->e64.sh_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return r(&shdr->e32.sh_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+#define SHDR_ADDR(fn_name) \
|
||||
+static uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return r8(&shdr->e64.sh_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return r(&shdr->e32.sh_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+#define SHDR_WORD(fn_name) \
|
||||
+static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return r(&shdr->e64.sh_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return r(&shdr->e32.sh_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+SHDR_ADDR(addr)
|
||||
+SHDR_ADDR(offset)
|
||||
+SHDR_ADDR(size)
|
||||
+SHDR_ADDR(entsize)
|
||||
+
|
||||
+SHDR_WORD(link)
|
||||
+SHDR_WORD(name)
|
||||
+SHDR_WORD(type)
|
||||
+
|
||||
/*
|
||||
* Get the whole file as a programming convenience in order to avoid
|
||||
* malloc+lseek+read+free of many pieces. If successful, then mmap
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index 97278c973bc9..af3a5f0209a3 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -31,6 +31,13 @@
|
||||
#undef ehdr_shentsize
|
||||
#undef ehdr_shstrndx
|
||||
#undef ehdr_shnum
|
||||
+#undef shdr_addr
|
||||
+#undef shdr_offset
|
||||
+#undef shdr_link
|
||||
+#undef shdr_size
|
||||
+#undef shdr_name
|
||||
+#undef shdr_type
|
||||
+#undef shdr_entsize
|
||||
|
||||
#ifdef SORTTABLE_64
|
||||
# define extable_ent_size 16
|
||||
@@ -47,6 +54,13 @@
|
||||
# define ehdr_shentsize ehdr64_shentsize
|
||||
# define ehdr_shstrndx ehdr64_shstrndx
|
||||
# define ehdr_shnum ehdr64_shnum
|
||||
+# define shdr_addr shdr64_addr
|
||||
+# define shdr_offset shdr64_offset
|
||||
+# define shdr_link shdr64_link
|
||||
+# define shdr_size shdr64_size
|
||||
+# define shdr_name shdr64_name
|
||||
+# define shdr_type shdr64_type
|
||||
+# define shdr_entsize shdr64_entsize
|
||||
#else
|
||||
# define extable_ent_size 8
|
||||
# define compare_extable compare_extable_32
|
||||
@@ -62,6 +76,13 @@
|
||||
# define ehdr_shentsize ehdr32_shentsize
|
||||
# define ehdr_shstrndx ehdr32_shstrndx
|
||||
# define ehdr_shnum ehdr32_shnum
|
||||
+# define shdr_addr shdr32_addr
|
||||
+# define shdr_offset shdr32_offset
|
||||
+# define shdr_link shdr32_link
|
||||
+# define shdr_size shdr32_size
|
||||
+# define shdr_name shdr32_name
|
||||
+# define shdr_type shdr32_type
|
||||
+# define shdr_entsize shdr32_entsize
|
||||
#endif
|
||||
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
@@ -177,8 +198,8 @@ struct elf_mcount_loc {
|
||||
static void *sort_mcount_loc(void *arg)
|
||||
{
|
||||
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
|
||||
- uint_t offset = emloc->start_mcount_loc - _r(&(emloc->init_data_sec)->etype.sh_addr)
|
||||
- + _r(&(emloc->init_data_sec)->etype.sh_offset);
|
||||
+ uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
|
||||
+ + shdr_offset(emloc->init_data_sec);
|
||||
uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
unsigned char *start_loc = (void *)emloc->ehdr + offset;
|
||||
|
||||
@@ -267,18 +288,18 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
|
||||
shstrndx = ehdr_shstrndx(ehdr);
|
||||
if (shstrndx == SHN_XINDEX)
|
||||
- shstrndx = r(&shdr_start->etype.sh_link);
|
||||
+ shstrndx = shdr_link(shdr_start);
|
||||
string_sec = get_index(shdr_start, shentsize, shstrndx);
|
||||
- secstrings = (const char *)ehdr + _r(&string_sec->etype.sh_offset);
|
||||
+ secstrings = (const char *)ehdr + shdr_offset(string_sec);
|
||||
|
||||
shnum = ehdr_shnum(ehdr);
|
||||
if (shnum == SHN_UNDEF)
|
||||
- shnum = _r(&shdr_start->etype.sh_size);
|
||||
+ shnum = shdr_size(shdr_start);
|
||||
|
||||
for (i = 0; i < shnum; i++) {
|
||||
Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
|
||||
|
||||
- idx = r(&shdr->etype.sh_name);
|
||||
+ idx = shdr_name(shdr);
|
||||
if (!strcmp(secstrings + idx, "__ex_table"))
|
||||
extab_sec = shdr;
|
||||
if (!strcmp(secstrings + idx, ".symtab"))
|
||||
@@ -286,9 +307,9 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
if (!strcmp(secstrings + idx, ".strtab"))
|
||||
strtab_sec = shdr;
|
||||
|
||||
- if (r(&shdr->etype.sh_type) == SHT_SYMTAB_SHNDX)
|
||||
+ if (shdr_type(shdr) == SHT_SYMTAB_SHNDX)
|
||||
symtab_shndx = (Elf32_Word *)((const char *)ehdr +
|
||||
- _r(&shdr->etype.sh_offset));
|
||||
+ shdr_offset(shdr));
|
||||
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
/* locate the .init.data section in vmlinux */
|
||||
@@ -304,14 +325,14 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
/* locate the ORC unwind tables */
|
||||
if (!strcmp(secstrings + idx, ".orc_unwind_ip")) {
|
||||
- orc_ip_size = _r(&shdr->etype.sh_size);
|
||||
+ orc_ip_size = shdr_size(shdr);
|
||||
g_orc_ip_table = (int *)((void *)ehdr +
|
||||
- _r(&shdr->etype.sh_offset));
|
||||
+ shdr_offset(shdr));
|
||||
}
|
||||
if (!strcmp(secstrings + idx, ".orc_unwind")) {
|
||||
- orc_size = _r(&shdr->etype.sh_size);
|
||||
+ orc_size = shdr_size(shdr);
|
||||
g_orc_table = (struct orc_entry *)((void *)ehdr +
|
||||
- _r(&shdr->etype.sh_offset));
|
||||
+ shdr_offset(shdr));
|
||||
}
|
||||
#endif
|
||||
} /* for loop */
|
||||
@@ -374,23 +395,22 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- extab_image = (void *)ehdr + _r(&extab_sec->etype.sh_offset);
|
||||
- strtab = (const char *)ehdr + _r(&strtab_sec->etype.sh_offset);
|
||||
- symtab = (const Elf_Sym *)((const char *)ehdr +
|
||||
- _r(&symtab_sec->etype.sh_offset));
|
||||
+ extab_image = (void *)ehdr + shdr_offset(extab_sec);
|
||||
+ strtab = (const char *)ehdr + shdr_offset(strtab_sec);
|
||||
+ symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
|
||||
|
||||
if (custom_sort) {
|
||||
- custom_sort(extab_image, _r(&extab_sec->etype.sh_size));
|
||||
+ custom_sort(extab_image, shdr_size(extab_sec));
|
||||
} else {
|
||||
- int num_entries = _r(&extab_sec->etype.sh_size) / extable_ent_size;
|
||||
+ int num_entries = shdr_size(extab_sec) / extable_ent_size;
|
||||
qsort(extab_image, num_entries,
|
||||
extable_ent_size, compare_extable);
|
||||
}
|
||||
|
||||
/* find the flag main_extable_sort_needed */
|
||||
- sym_start = (void *)ehdr + _r(&symtab_sec->etype.sh_offset);
|
||||
- sym_end = sym_start + _r(&symtab_sec->etype.sh_size);
|
||||
- symentsize = _r(&symtab_sec->etype.sh_entsize);
|
||||
+ sym_start = (void *)ehdr + shdr_offset(symtab_sec);
|
||||
+ sym_end = sym_start + shdr_size(symtab_sec);
|
||||
+ symentsize = shdr_entsize(symtab_sec);
|
||||
|
||||
for (sym = sym_start; (void *)sym + symentsize < sym_end;
|
||||
sym = (void *)sym + symentsize) {
|
||||
@@ -415,9 +435,9 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
symtab_shndx);
|
||||
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
|
||||
sort_needed_loc = (void *)ehdr +
|
||||
- _r(&sort_needed_sec->etype.sh_offset) +
|
||||
+ shdr_offset(sort_needed_sec) +
|
||||
_r(&sort_needed_sym->etype.st_value) -
|
||||
- _r(&sort_needed_sec->etype.sh_addr);
|
||||
+ shdr_addr(sort_needed_sec);
|
||||
|
||||
/* extable has been sorted, clear the flag */
|
||||
w(0, sort_needed_loc);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
203
1335-scripts-sorttable-add-helper-functions-for-elf-sym.patch
Normal file
203
1335-scripts-sorttable-add-helper-functions-for-elf-sym.patch
Normal file
@ -0,0 +1,203 @@
|
||||
From 133d6f7d2c3e689e3191bf973e07819dda085f60 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:43 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Add helper functions for Elf_Sym
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 17bed33ac12f011f4695059960e1b1d6457229a7
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:22 2025 -0500
|
||||
|
||||
scripts/sorttable: Add helper functions for Elf_Sym
|
||||
|
||||
In order to remove the double #include of sorttable.h for 64 and 32 bit
|
||||
to create duplicate functions, add helper functions for Elf_Sym. This
|
||||
will create a function pointer for each helper that will get assigned to
|
||||
the appropriate function to handle either the 64bit or 32bit version.
|
||||
|
||||
This also removes the last references of etype and _r() macros from the
|
||||
sorttable.h file as their references are now just defined in the
|
||||
appropriate architecture version of the helper functions. All read
|
||||
functions now exist in the helper functions which makes it easier to
|
||||
maintain, as the helper functions define the necessary architecture sizes.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162346.185740651@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index b2b96ff261d6..20615de18276 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -152,6 +152,53 @@ SHDR_WORD(link)
|
||||
SHDR_WORD(name)
|
||||
SHDR_WORD(type)
|
||||
|
||||
+#define SYM_ADDR(fn_name) \
|
||||
+static uint64_t sym64_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return r8(&sym->e64.st_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint64_t sym32_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return r(&sym->e32.st_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+#define SYM_WORD(fn_name) \
|
||||
+static uint32_t sym64_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return r(&sym->e64.st_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint32_t sym32_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return r(&sym->e32.st_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+#define SYM_HALF(fn_name) \
|
||||
+static uint16_t sym64_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return r2(&sym->e64.st_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint16_t sym32_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return r2(&sym->e32.st_##fn_name); \
|
||||
+}
|
||||
+
|
||||
+static uint8_t sym64_type(Elf_Sym *sym)
|
||||
+{
|
||||
+ return ELF64_ST_TYPE(sym->e64.st_info);
|
||||
+}
|
||||
+
|
||||
+static uint8_t sym32_type(Elf_Sym *sym)
|
||||
+{
|
||||
+ return ELF32_ST_TYPE(sym->e32.st_info);
|
||||
+}
|
||||
+
|
||||
+SYM_ADDR(value)
|
||||
+SYM_WORD(name)
|
||||
+SYM_HALF(shndx)
|
||||
+
|
||||
/*
|
||||
* Get the whole file as a programming convenience in order to avoid
|
||||
* malloc+lseek+read+free of many pieces. If successful, then mmap
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index af3a5f0209a3..ef7e5161db31 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -23,10 +23,7 @@
|
||||
#undef sort_mcount_loc
|
||||
#undef elf_mcount_loc
|
||||
#undef do_sort
|
||||
-#undef ELF_ST_TYPE
|
||||
#undef uint_t
|
||||
-#undef _r
|
||||
-#undef etype
|
||||
#undef ehdr_shoff
|
||||
#undef ehdr_shentsize
|
||||
#undef ehdr_shstrndx
|
||||
@@ -38,6 +35,10 @@
|
||||
#undef shdr_name
|
||||
#undef shdr_type
|
||||
#undef shdr_entsize
|
||||
+#undef sym_type
|
||||
+#undef sym_name
|
||||
+#undef sym_value
|
||||
+#undef sym_shndx
|
||||
|
||||
#ifdef SORTTABLE_64
|
||||
# define extable_ent_size 16
|
||||
@@ -46,10 +47,7 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_64
|
||||
# define elf_mcount_loc elf_mcount_loc_64
|
||||
# define do_sort do_sort_64
|
||||
-# define ELF_ST_TYPE ELF64_ST_TYPE
|
||||
# define uint_t uint64_t
|
||||
-# define _r r8
|
||||
-# define etype e64
|
||||
# define ehdr_shoff ehdr64_shoff
|
||||
# define ehdr_shentsize ehdr64_shentsize
|
||||
# define ehdr_shstrndx ehdr64_shstrndx
|
||||
@@ -61,6 +59,10 @@
|
||||
# define shdr_name shdr64_name
|
||||
# define shdr_type shdr64_type
|
||||
# define shdr_entsize shdr64_entsize
|
||||
+# define sym_type sym64_type
|
||||
+# define sym_name sym64_name
|
||||
+# define sym_value sym64_value
|
||||
+# define sym_shndx sym64_shndx
|
||||
#else
|
||||
# define extable_ent_size 8
|
||||
# define compare_extable compare_extable_32
|
||||
@@ -68,10 +70,7 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_32
|
||||
# define elf_mcount_loc elf_mcount_loc_32
|
||||
# define do_sort do_sort_32
|
||||
-# define ELF_ST_TYPE ELF32_ST_TYPE
|
||||
# define uint_t uint32_t
|
||||
-# define _r r
|
||||
-# define etype e32
|
||||
# define ehdr_shoff ehdr32_shoff
|
||||
# define ehdr_shentsize ehdr32_shentsize
|
||||
# define ehdr_shstrndx ehdr32_shstrndx
|
||||
@@ -83,6 +82,10 @@
|
||||
# define shdr_name shdr32_name
|
||||
# define shdr_type shdr32_type
|
||||
# define shdr_entsize shdr32_entsize
|
||||
+# define sym_type sym32_type
|
||||
+# define sym_name sym32_name
|
||||
+# define sym_value sym32_value
|
||||
+# define sym_shndx sym32_shndx
|
||||
#endif
|
||||
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
@@ -414,9 +417,9 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
|
||||
for (sym = sym_start; (void *)sym + symentsize < sym_end;
|
||||
sym = (void *)sym + symentsize) {
|
||||
- if (ELF_ST_TYPE(sym->etype.st_info) != STT_OBJECT)
|
||||
+ if (sym_type(sym) != STT_OBJECT)
|
||||
continue;
|
||||
- if (!strcmp(strtab + r(&sym->etype.st_name),
|
||||
+ if (!strcmp(strtab + sym_name(sym),
|
||||
"main_extable_sort_needed")) {
|
||||
sort_needed_sym = sym;
|
||||
break;
|
||||
@@ -430,14 +433,13 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
- sort_need_index = get_secindex(r2(&sym->etype.st_shndx),
|
||||
+ sort_need_index = get_secindex(sym_shndx(sym),
|
||||
((void *)sort_needed_sym - (void *)symtab) / symentsize,
|
||||
symtab_shndx);
|
||||
sort_needed_sec = get_index(shdr_start, shentsize, sort_need_index);
|
||||
sort_needed_loc = (void *)ehdr +
|
||||
shdr_offset(sort_needed_sec) +
|
||||
- _r(&sort_needed_sym->etype.st_value) -
|
||||
- shdr_addr(sort_needed_sec);
|
||||
+ sym_value(sort_needed_sym) - shdr_addr(sort_needed_sec);
|
||||
|
||||
/* extable has been sorted, clear the flag */
|
||||
w(0, sort_needed_loc);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
140
1336-scripts-sorttable-use-uint64-t-for-mcount-sorting.patch
Normal file
140
1336-scripts-sorttable-use-uint64-t-for-mcount-sorting.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From daa2ce334210ed3ebb054d2f8097312ac7a60ae4 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:22:46 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Use uint64_t for mcount sorting
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 1b649e6ab8dc9188d82c64069493afe66ca0edad
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:23 2025 -0500
|
||||
|
||||
scripts/sorttable: Use uint64_t for mcount sorting
|
||||
|
||||
The mcount sorting defines uint_t to uint64_t on 64bit architectures and
|
||||
uint32_t on 32bit architectures. It can work with just using uint64_t as
|
||||
that will hold the values of both, and they are not used to point into the
|
||||
ELF file.
|
||||
|
||||
sizeof(uint_t) is used for defining the size of the mcount_loc section.
|
||||
Instead of using a type, define long_size and use that instead. This will
|
||||
allow the header code to be moved into the C file as generic functions and
|
||||
not need to include sorttable.h twice, once for 64bit and once for 32bit.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162346.373528925@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.h b/scripts/sorttable.h
|
||||
index ef7e5161db31..17a8541a10d6 100644
|
||||
--- a/scripts/sorttable.h
|
||||
+++ b/scripts/sorttable.h
|
||||
@@ -23,7 +23,6 @@
|
||||
#undef sort_mcount_loc
|
||||
#undef elf_mcount_loc
|
||||
#undef do_sort
|
||||
-#undef uint_t
|
||||
#undef ehdr_shoff
|
||||
#undef ehdr_shentsize
|
||||
#undef ehdr_shstrndx
|
||||
@@ -39,6 +38,7 @@
|
||||
#undef sym_name
|
||||
#undef sym_value
|
||||
#undef sym_shndx
|
||||
+#undef long_size
|
||||
|
||||
#ifdef SORTTABLE_64
|
||||
# define extable_ent_size 16
|
||||
@@ -47,7 +47,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_64
|
||||
# define elf_mcount_loc elf_mcount_loc_64
|
||||
# define do_sort do_sort_64
|
||||
-# define uint_t uint64_t
|
||||
# define ehdr_shoff ehdr64_shoff
|
||||
# define ehdr_shentsize ehdr64_shentsize
|
||||
# define ehdr_shstrndx ehdr64_shstrndx
|
||||
@@ -63,6 +62,7 @@
|
||||
# define sym_name sym64_name
|
||||
# define sym_value sym64_value
|
||||
# define sym_shndx sym64_shndx
|
||||
+# define long_size 8
|
||||
#else
|
||||
# define extable_ent_size 8
|
||||
# define compare_extable compare_extable_32
|
||||
@@ -70,7 +70,6 @@
|
||||
# define sort_mcount_loc sort_mcount_loc_32
|
||||
# define elf_mcount_loc elf_mcount_loc_32
|
||||
# define do_sort do_sort_32
|
||||
-# define uint_t uint32_t
|
||||
# define ehdr_shoff ehdr32_shoff
|
||||
# define ehdr_shentsize ehdr32_shentsize
|
||||
# define ehdr_shstrndx ehdr32_shstrndx
|
||||
@@ -86,6 +85,7 @@
|
||||
# define sym_name sym32_name
|
||||
# define sym_value sym32_value
|
||||
# define sym_shndx sym32_shndx
|
||||
+# define long_size 4
|
||||
#endif
|
||||
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
@@ -193,25 +193,25 @@ pthread_t mcount_sort_thread;
|
||||
struct elf_mcount_loc {
|
||||
Elf_Ehdr *ehdr;
|
||||
Elf_Shdr *init_data_sec;
|
||||
- uint_t start_mcount_loc;
|
||||
- uint_t stop_mcount_loc;
|
||||
+ uint64_t start_mcount_loc;
|
||||
+ uint64_t stop_mcount_loc;
|
||||
};
|
||||
|
||||
/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
|
||||
static void *sort_mcount_loc(void *arg)
|
||||
{
|
||||
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
|
||||
- uint_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
|
||||
+ uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
|
||||
+ shdr_offset(emloc->init_data_sec);
|
||||
- uint_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
+ uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
unsigned char *start_loc = (void *)emloc->ehdr + offset;
|
||||
|
||||
- qsort(start_loc, count/sizeof(uint_t), sizeof(uint_t), compare_extable);
|
||||
+ qsort(start_loc, count/long_size, long_size, compare_extable);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
|
||||
-static void get_mcount_loc(uint_t *_start, uint_t *_stop)
|
||||
+static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
|
||||
{
|
||||
FILE *file_start, *file_stop;
|
||||
char start_buff[20];
|
||||
@@ -277,8 +277,8 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
unsigned int shstrndx;
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
struct elf_mcount_loc mstruct = {0};
|
||||
- uint_t _start_mcount_loc = 0;
|
||||
- uint_t _stop_mcount_loc = 0;
|
||||
+ uint64_t _start_mcount_loc = 0;
|
||||
+ uint64_t _stop_mcount_loc = 0;
|
||||
#endif
|
||||
#if defined(SORTTABLE_64) && defined(UNWINDER_ORC_ENABLED)
|
||||
unsigned int orc_ip_size = 0;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,196 @@
|
||||
From 0e6fd4e629cfcaf1a4f04e2c9e39e8b5776890a2 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:36:32 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Get start/stop_mcount_loc from ELF file
|
||||
directly
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 4acda8edefa1ce66d3de845f1c12745721cd14c3
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Sun Jan 5 11:22:25 2025 -0500
|
||||
|
||||
scripts/sorttable: Get start/stop_mcount_loc from ELF file directly
|
||||
|
||||
The get_mcount_loc() does a cheesy trick to find the start_mcount_loc and
|
||||
stop_mcount_loc values. That trick is:
|
||||
|
||||
file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
|
||||
|
||||
and
|
||||
|
||||
file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
|
||||
|
||||
Those values are stored in the Elf symbol table. Use that to capture those
|
||||
values. Using the symbol table is more efficient and more robust. The
|
||||
above could fail if another variable had "start_mcount" or "stop_mcount"
|
||||
as part of its name.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Link: https://lore.kernel.org/20250105162346.817157047@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index ff9b60fc0dd8..656c1e9b5ad9 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -472,42 +472,41 @@ static void *sort_mcount_loc(void *arg)
|
||||
}
|
||||
|
||||
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
|
||||
-static void get_mcount_loc(uint64_t *_start, uint64_t *_stop)
|
||||
+static void get_mcount_loc(struct elf_mcount_loc *emloc, Elf_Shdr *symtab_sec,
|
||||
+ const char *strtab)
|
||||
{
|
||||
- FILE *file_start, *file_stop;
|
||||
- char start_buff[20];
|
||||
- char stop_buff[20];
|
||||
- int len = 0;
|
||||
+ Elf_Sym *sym, *end_sym;
|
||||
+ int symentsize = shdr_entsize(symtab_sec);
|
||||
+ int found = 0;
|
||||
+
|
||||
+ sym = (void *)emloc->ehdr + shdr_offset(symtab_sec);
|
||||
+ end_sym = (void *)sym + shdr_size(symtab_sec);
|
||||
+
|
||||
+ while (sym < end_sym) {
|
||||
+ if (!strcmp(strtab + sym_name(sym), "__start_mcount_loc")) {
|
||||
+ emloc->start_mcount_loc = sym_value(sym);
|
||||
+ if (++found == 2)
|
||||
+ break;
|
||||
+ } else if (!strcmp(strtab + sym_name(sym), "__stop_mcount_loc")) {
|
||||
+ emloc->stop_mcount_loc = sym_value(sym);
|
||||
+ if (++found == 2)
|
||||
+ break;
|
||||
+ }
|
||||
+ sym = (void *)sym + symentsize;
|
||||
+ }
|
||||
|
||||
- file_start = popen(" grep start_mcount System.map | awk '{print $1}' ", "r");
|
||||
- if (!file_start) {
|
||||
+ if (!emloc->start_mcount_loc) {
|
||||
fprintf(stderr, "get start_mcount_loc error!");
|
||||
return;
|
||||
}
|
||||
|
||||
- file_stop = popen(" grep stop_mcount System.map | awk '{print $1}' ", "r");
|
||||
- if (!file_stop) {
|
||||
+ if (!emloc->stop_mcount_loc) {
|
||||
fprintf(stderr, "get stop_mcount_loc error!");
|
||||
- pclose(file_start);
|
||||
return;
|
||||
}
|
||||
-
|
||||
- while (fgets(start_buff, sizeof(start_buff), file_start) != NULL) {
|
||||
- len = strlen(start_buff);
|
||||
- start_buff[len - 1] = '\0';
|
||||
- }
|
||||
- *_start = strtoul(start_buff, NULL, 16);
|
||||
-
|
||||
- while (fgets(stop_buff, sizeof(stop_buff), file_stop) != NULL) {
|
||||
- len = strlen(stop_buff);
|
||||
- stop_buff[len - 1] = '\0';
|
||||
- }
|
||||
- *_stop = strtoul(stop_buff, NULL, 16);
|
||||
-
|
||||
- pclose(file_start);
|
||||
- pclose(file_stop);
|
||||
}
|
||||
#endif
|
||||
+
|
||||
static int do_sort(Elf_Ehdr *ehdr,
|
||||
char const *const fname,
|
||||
table_sort_t custom_sort)
|
||||
@@ -538,8 +537,6 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
unsigned int shstrndx;
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
struct elf_mcount_loc mstruct = {0};
|
||||
- uint64_t _start_mcount_loc = 0;
|
||||
- uint64_t _stop_mcount_loc = 0;
|
||||
#endif
|
||||
#ifdef UNWINDER_ORC_ENABLED
|
||||
unsigned int orc_ip_size = 0;
|
||||
@@ -577,13 +574,8 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
/* locate the .init.data section in vmlinux */
|
||||
- if (!strcmp(secstrings + idx, ".init.data")) {
|
||||
- get_mcount_loc(&_start_mcount_loc, &_stop_mcount_loc);
|
||||
- mstruct.ehdr = ehdr;
|
||||
+ if (!strcmp(secstrings + idx, ".init.data"))
|
||||
mstruct.init_data_sec = shdr;
|
||||
- mstruct.start_mcount_loc = _start_mcount_loc;
|
||||
- mstruct.stop_mcount_loc = _stop_mcount_loc;
|
||||
- }
|
||||
#endif
|
||||
|
||||
#ifdef UNWINDER_ORC_ENABLED
|
||||
@@ -627,23 +619,6 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
goto out;
|
||||
}
|
||||
#endif
|
||||
-
|
||||
-#ifdef MCOUNT_SORT_ENABLED
|
||||
- if (!mstruct.init_data_sec || !_start_mcount_loc || !_stop_mcount_loc) {
|
||||
- fprintf(stderr,
|
||||
- "incomplete mcount's sort in file: %s\n",
|
||||
- fname);
|
||||
- goto out;
|
||||
- }
|
||||
-
|
||||
- /* create thread to sort mcount_loc concurrently */
|
||||
- if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
|
||||
- fprintf(stderr,
|
||||
- "pthread_create mcount_sort_thread failed '%s': %s\n",
|
||||
- strerror(errno), fname);
|
||||
- goto out;
|
||||
- }
|
||||
-#endif
|
||||
if (!extab_sec) {
|
||||
fprintf(stderr, "no __ex_table in file: %s\n", fname);
|
||||
goto out;
|
||||
@@ -663,6 +638,26 @@ static int do_sort(Elf_Ehdr *ehdr,
|
||||
strtab = (const char *)ehdr + shdr_offset(strtab_sec);
|
||||
symtab = (const Elf_Sym *)((const char *)ehdr + shdr_offset(symtab_sec));
|
||||
|
||||
+#ifdef MCOUNT_SORT_ENABLED
|
||||
+ mstruct.ehdr = ehdr;
|
||||
+ get_mcount_loc(&mstruct, symtab_sec, strtab);
|
||||
+
|
||||
+ if (!mstruct.init_data_sec || !mstruct.start_mcount_loc || !mstruct.stop_mcount_loc) {
|
||||
+ fprintf(stderr,
|
||||
+ "incomplete mcount's sort in file: %s\n",
|
||||
+ fname);
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ /* create thread to sort mcount_loc concurrently */
|
||||
+ if (pthread_create(&mcount_sort_thread, NULL, &sort_mcount_loc, &mstruct)) {
|
||||
+ fprintf(stderr,
|
||||
+ "pthread_create mcount_sort_thread failed '%s': %s\n",
|
||||
+ strerror(errno), fname);
|
||||
+ goto out;
|
||||
+ }
|
||||
+#endif
|
||||
+
|
||||
if (custom_sort) {
|
||||
custom_sort(extab_image, shdr_size(extab_sec));
|
||||
} else {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,327 @@
|
||||
From 1ca873e533dd7f3f3abd7518a7c356fa7bb6ef91 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:52:42 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Use a structure of function pointers for
|
||||
elf helpers
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 1e5f6771c247b28135307058d2cfe3b0153733dc
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Fri Jan 10 07:54:59 2025 -0500
|
||||
|
||||
scripts/sorttable: Use a structure of function pointers for elf helpers
|
||||
|
||||
Instead of having a series of function pointers that gets assigned to the
|
||||
Elf64 or Elf32 versions, put them all into a single structure and use
|
||||
that. Add the helper function that chooses the structure into the macros
|
||||
that build the different versions of the elf functions.
|
||||
|
||||
Link: https://lore.kernel.org/all/CAHk-=wiafEyX7UgOeZgvd6fvuByE5WXUPh9599kwOc_d-pdeug@mail.gmail.com/
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Stephen Rothwell <sfr@canb.auug.org.au>
|
||||
Link: https://lore.kernel.org/20250110075459.13d4b94c@gandalf.local.home
|
||||
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 656c1e9b5ad9..9f41575afd7a 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -85,6 +85,25 @@ static uint64_t (*r8)(const uint64_t *);
|
||||
static void (*w)(uint32_t, uint32_t *);
|
||||
typedef void (*table_sort_t)(char *, int);
|
||||
|
||||
+static struct elf_funcs {
|
||||
+ int (*compare_extable)(const void *a, const void *b);
|
||||
+ uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
|
||||
+ uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
|
||||
+ uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
|
||||
+ uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
|
||||
+ uint64_t (*shdr_addr)(Elf_Shdr *shdr);
|
||||
+ uint64_t (*shdr_offset)(Elf_Shdr *shdr);
|
||||
+ uint64_t (*shdr_size)(Elf_Shdr *shdr);
|
||||
+ uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
|
||||
+ uint32_t (*shdr_link)(Elf_Shdr *shdr);
|
||||
+ uint32_t (*shdr_name)(Elf_Shdr *shdr);
|
||||
+ uint32_t (*shdr_type)(Elf_Shdr *shdr);
|
||||
+ uint8_t (*sym_type)(Elf_Sym *sym);
|
||||
+ uint32_t (*sym_name)(Elf_Sym *sym);
|
||||
+ uint64_t (*sym_value)(Elf_Sym *sym);
|
||||
+ uint16_t (*sym_shndx)(Elf_Sym *sym);
|
||||
+} e;
|
||||
+
|
||||
static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
|
||||
{
|
||||
return r8(&ehdr->e64.e_shoff);
|
||||
@@ -95,6 +114,11 @@ static uint64_t ehdr32_shoff(Elf_Ehdr *ehdr)
|
||||
return r(&ehdr->e32.e_shoff);
|
||||
}
|
||||
|
||||
+static uint64_t ehdr_shoff(Elf_Ehdr *ehdr)
|
||||
+{
|
||||
+ return e.ehdr_shoff(ehdr);
|
||||
+}
|
||||
+
|
||||
#define EHDR_HALF(fn_name) \
|
||||
static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
|
||||
{ \
|
||||
@@ -104,6 +128,11 @@ static uint16_t ehdr64_##fn_name(Elf_Ehdr *ehdr) \
|
||||
static uint16_t ehdr32_##fn_name(Elf_Ehdr *ehdr) \
|
||||
{ \
|
||||
return r2(&ehdr->e32.e_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint16_t ehdr_##fn_name(Elf_Ehdr *ehdr) \
|
||||
+{ \
|
||||
+ return e.ehdr_##fn_name(ehdr); \
|
||||
}
|
||||
|
||||
EHDR_HALF(shentsize)
|
||||
@@ -119,6 +148,11 @@ static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
|
||||
static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
|
||||
{ \
|
||||
return r(&shdr->e32.sh_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return e.shdr_##fn_name(shdr); \
|
||||
}
|
||||
|
||||
#define SHDR_ADDR(fn_name) \
|
||||
@@ -130,6 +164,11 @@ static uint64_t shdr64_##fn_name(Elf_Shdr *shdr) \
|
||||
static uint64_t shdr32_##fn_name(Elf_Shdr *shdr) \
|
||||
{ \
|
||||
return r(&shdr->e32.sh_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint64_t shdr_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return e.shdr_##fn_name(shdr); \
|
||||
}
|
||||
|
||||
#define SHDR_WORD(fn_name) \
|
||||
@@ -141,6 +180,10 @@ static uint32_t shdr64_##fn_name(Elf_Shdr *shdr) \
|
||||
static uint32_t shdr32_##fn_name(Elf_Shdr *shdr) \
|
||||
{ \
|
||||
return r(&shdr->e32.sh_##fn_name); \
|
||||
+} \
|
||||
+static uint32_t shdr_##fn_name(Elf_Shdr *shdr) \
|
||||
+{ \
|
||||
+ return e.shdr_##fn_name(shdr); \
|
||||
}
|
||||
|
||||
SHDR_ADDR(addr)
|
||||
@@ -161,6 +204,11 @@ static uint64_t sym64_##fn_name(Elf_Sym *sym) \
|
||||
static uint64_t sym32_##fn_name(Elf_Sym *sym) \
|
||||
{ \
|
||||
return r(&sym->e32.st_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint64_t sym_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return e.sym_##fn_name(sym); \
|
||||
}
|
||||
|
||||
#define SYM_WORD(fn_name) \
|
||||
@@ -172,6 +220,11 @@ static uint32_t sym64_##fn_name(Elf_Sym *sym) \
|
||||
static uint32_t sym32_##fn_name(Elf_Sym *sym) \
|
||||
{ \
|
||||
return r(&sym->e32.st_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint32_t sym_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return e.sym_##fn_name(sym); \
|
||||
}
|
||||
|
||||
#define SYM_HALF(fn_name) \
|
||||
@@ -183,6 +236,11 @@ static uint16_t sym64_##fn_name(Elf_Sym *sym) \
|
||||
static uint16_t sym32_##fn_name(Elf_Sym *sym) \
|
||||
{ \
|
||||
return r2(&sym->e32.st_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint16_t sym_##fn_name(Elf_Sym *sym) \
|
||||
+{ \
|
||||
+ return e.sym_##fn_name(sym); \
|
||||
}
|
||||
|
||||
static uint8_t sym64_type(Elf_Sym *sym)
|
||||
@@ -195,6 +253,11 @@ static uint8_t sym32_type(Elf_Sym *sym)
|
||||
return ELF32_ST_TYPE(sym->e32.st_info);
|
||||
}
|
||||
|
||||
+static uint8_t sym_type(Elf_Sym *sym)
|
||||
+{
|
||||
+ return e.sym_type(sym);
|
||||
+}
|
||||
+
|
||||
SYM_ADDR(value)
|
||||
SYM_WORD(name)
|
||||
SYM_HALF(shndx)
|
||||
@@ -322,29 +385,16 @@ static int compare_extable_64(const void *a, const void *b)
|
||||
return av > bv;
|
||||
}
|
||||
|
||||
+static int compare_extable(const void *a, const void *b)
|
||||
+{
|
||||
+ return e.compare_extable(a, b);
|
||||
+}
|
||||
+
|
||||
static inline void *get_index(void *start, int entsize, int index)
|
||||
{
|
||||
return start + (entsize * index);
|
||||
}
|
||||
|
||||
-
|
||||
-static int (*compare_extable)(const void *a, const void *b);
|
||||
-static uint64_t (*ehdr_shoff)(Elf_Ehdr *ehdr);
|
||||
-static uint16_t (*ehdr_shstrndx)(Elf_Ehdr *ehdr);
|
||||
-static uint16_t (*ehdr_shentsize)(Elf_Ehdr *ehdr);
|
||||
-static uint16_t (*ehdr_shnum)(Elf_Ehdr *ehdr);
|
||||
-static uint64_t (*shdr_addr)(Elf_Shdr *shdr);
|
||||
-static uint64_t (*shdr_offset)(Elf_Shdr *shdr);
|
||||
-static uint64_t (*shdr_size)(Elf_Shdr *shdr);
|
||||
-static uint64_t (*shdr_entsize)(Elf_Shdr *shdr);
|
||||
-static uint32_t (*shdr_link)(Elf_Shdr *shdr);
|
||||
-static uint32_t (*shdr_name)(Elf_Shdr *shdr);
|
||||
-static uint32_t (*shdr_type)(Elf_Shdr *shdr);
|
||||
-static uint8_t (*sym_type)(Elf_Sym *sym);
|
||||
-static uint32_t (*sym_name)(Elf_Sym *sym);
|
||||
-static uint64_t (*sym_value)(Elf_Sym *sym);
|
||||
-static uint16_t (*sym_shndx)(Elf_Sym *sym);
|
||||
-
|
||||
static int extable_ent_size;
|
||||
static int long_size;
|
||||
|
||||
@@ -864,7 +914,30 @@ static int do_file(char const *const fname, void *addr)
|
||||
}
|
||||
|
||||
switch (ehdr->e32.e_ident[EI_CLASS]) {
|
||||
- case ELFCLASS32:
|
||||
+ case ELFCLASS32: {
|
||||
+ struct elf_funcs efuncs = {
|
||||
+ .compare_extable = compare_extable_32,
|
||||
+ .ehdr_shoff = ehdr32_shoff,
|
||||
+ .ehdr_shentsize = ehdr32_shentsize,
|
||||
+ .ehdr_shstrndx = ehdr32_shstrndx,
|
||||
+ .ehdr_shnum = ehdr32_shnum,
|
||||
+ .shdr_addr = shdr32_addr,
|
||||
+ .shdr_offset = shdr32_offset,
|
||||
+ .shdr_link = shdr32_link,
|
||||
+ .shdr_size = shdr32_size,
|
||||
+ .shdr_name = shdr32_name,
|
||||
+ .shdr_type = shdr32_type,
|
||||
+ .shdr_entsize = shdr32_entsize,
|
||||
+ .sym_type = sym32_type,
|
||||
+ .sym_name = sym32_name,
|
||||
+ .sym_value = sym32_value,
|
||||
+ .sym_shndx = sym32_shndx,
|
||||
+ };
|
||||
+
|
||||
+ e = efuncs;
|
||||
+ long_size = 4;
|
||||
+ extable_ent_size = 8;
|
||||
+
|
||||
if (r2(&ehdr->e32.e_ehsize) != sizeof(Elf32_Ehdr) ||
|
||||
r2(&ehdr->e32.e_shentsize) != sizeof(Elf32_Shdr)) {
|
||||
fprintf(stderr,
|
||||
@@ -872,26 +945,32 @@ static int do_file(char const *const fname, void *addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- compare_extable = compare_extable_32;
|
||||
- ehdr_shoff = ehdr32_shoff;
|
||||
- ehdr_shentsize = ehdr32_shentsize;
|
||||
- ehdr_shstrndx = ehdr32_shstrndx;
|
||||
- ehdr_shnum = ehdr32_shnum;
|
||||
- shdr_addr = shdr32_addr;
|
||||
- shdr_offset = shdr32_offset;
|
||||
- shdr_link = shdr32_link;
|
||||
- shdr_size = shdr32_size;
|
||||
- shdr_name = shdr32_name;
|
||||
- shdr_type = shdr32_type;
|
||||
- shdr_entsize = shdr32_entsize;
|
||||
- sym_type = sym32_type;
|
||||
- sym_name = sym32_name;
|
||||
- sym_value = sym32_value;
|
||||
- sym_shndx = sym32_shndx;
|
||||
- long_size = 4;
|
||||
- extable_ent_size = 8;
|
||||
+ }
|
||||
break;
|
||||
- case ELFCLASS64:
|
||||
+ case ELFCLASS64: {
|
||||
+ struct elf_funcs efuncs = {
|
||||
+ .compare_extable = compare_extable_64,
|
||||
+ .ehdr_shoff = ehdr64_shoff,
|
||||
+ .ehdr_shentsize = ehdr64_shentsize,
|
||||
+ .ehdr_shstrndx = ehdr64_shstrndx,
|
||||
+ .ehdr_shnum = ehdr64_shnum,
|
||||
+ .shdr_addr = shdr64_addr,
|
||||
+ .shdr_offset = shdr64_offset,
|
||||
+ .shdr_link = shdr64_link,
|
||||
+ .shdr_size = shdr64_size,
|
||||
+ .shdr_name = shdr64_name,
|
||||
+ .shdr_type = shdr64_type,
|
||||
+ .shdr_entsize = shdr64_entsize,
|
||||
+ .sym_type = sym64_type,
|
||||
+ .sym_name = sym64_name,
|
||||
+ .sym_value = sym64_value,
|
||||
+ .sym_shndx = sym64_shndx,
|
||||
+ };
|
||||
+
|
||||
+ e = efuncs;
|
||||
+ long_size = 8;
|
||||
+ extable_ent_size = 16;
|
||||
+
|
||||
if (r2(&ehdr->e64.e_ehsize) != sizeof(Elf64_Ehdr) ||
|
||||
r2(&ehdr->e64.e_shentsize) != sizeof(Elf64_Shdr)) {
|
||||
fprintf(stderr,
|
||||
@@ -900,25 +979,7 @@ static int do_file(char const *const fname, void *addr)
|
||||
return -1;
|
||||
}
|
||||
|
||||
- compare_extable = compare_extable_64;
|
||||
- ehdr_shoff = ehdr64_shoff;
|
||||
- ehdr_shentsize = ehdr64_shentsize;
|
||||
- ehdr_shstrndx = ehdr64_shstrndx;
|
||||
- ehdr_shnum = ehdr64_shnum;
|
||||
- shdr_addr = shdr64_addr;
|
||||
- shdr_offset = shdr64_offset;
|
||||
- shdr_link = shdr64_link;
|
||||
- shdr_size = shdr64_size;
|
||||
- shdr_name = shdr64_name;
|
||||
- shdr_type = shdr64_type;
|
||||
- shdr_entsize = shdr64_entsize;
|
||||
- sym_type = sym64_type;
|
||||
- sym_name = sym64_name;
|
||||
- sym_value = sym64_value;
|
||||
- sym_shndx = sym64_shndx;
|
||||
- long_size = 8;
|
||||
- extable_ent_size = 16;
|
||||
-
|
||||
+ }
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF class %d %s\n",
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,373 @@
|
||||
From 4b605df96d9249250134a81573caa2ab136e0ce8 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:55:45 +0200
|
||||
Subject: [PATCH] arm64: scripts/sorttable: Implement sorting mcount_loc at
|
||||
boot for arm64
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
Conflicts: Context change from missing commit a762e9267dca ("ftrace:
|
||||
Add CONFIG_HAVE_FTRACE_GRAPH_FUNC")
|
||||
|
||||
commit b3d09d06e052e1d754645acea4e4d1e96f81c934
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 18 14:59:19 2025 -0500
|
||||
|
||||
arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64
|
||||
|
||||
The mcount_loc section holds the addresses of the functions that get
|
||||
patched by ftrace when enabling function callbacks. It can contain tens of
|
||||
thousands of entries. These addresses must be sorted. If they are not
|
||||
sorted at compile time, they are sorted at boot. Sorting at boot does take
|
||||
some time and does have a small impact on boot performance.
|
||||
|
||||
x86 and arm32 have the addresses in the mcount_loc section of the ELF
|
||||
file. But for arm64, the section just contains zeros. The .rela.dyn
|
||||
Elf_Rela section holds the addresses and they get patched at boot during
|
||||
the relocation phase.
|
||||
|
||||
In order to sort these addresses, the Elf_Rela needs to be updated instead
|
||||
of the location in the binary that holds the mcount_loc section. Have the
|
||||
sorttable code, allocate an array to hold the functions, load the
|
||||
addresses from the Elf_Rela entries, sort them, then put them back in
|
||||
order into the Elf_rela entries so that they will be sorted at boot up
|
||||
without having to sort them during boot up.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/20250218200022.373319428@goodmis.org
|
||||
Acked-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
(cherry picked from commit b3d09d06e052e1d754645acea4e4d1e96f81c934)
|
||||
Assisted-by: Patchpal
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
|
||||
index 534daec407ef..add6005c5e8b 100644
|
||||
--- a/arch/arm64/Kconfig
|
||||
+++ b/arch/arm64/Kconfig
|
||||
@@ -219,6 +219,7 @@ config ARM64
|
||||
if DYNAMIC_FTRACE_WITH_ARGS
|
||||
select HAVE_SAMPLE_FTRACE_DIRECT
|
||||
select HAVE_SAMPLE_FTRACE_DIRECT_MULTI
|
||||
+ select HAVE_BUILDTIME_MCOUNT_SORT
|
||||
select HAVE_EFFICIENT_UNALIGNED_ACCESS
|
||||
select HAVE_GUP_FAST
|
||||
select HAVE_FTRACE_MCOUNT_RECORD
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 9f41575afd7a..4a34c275123e 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
+#include <stdbool.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
@@ -79,10 +80,16 @@ typedef union {
|
||||
Elf64_Sym e64;
|
||||
} Elf_Sym;
|
||||
|
||||
+typedef union {
|
||||
+ Elf32_Rela e32;
|
||||
+ Elf64_Rela e64;
|
||||
+} Elf_Rela;
|
||||
+
|
||||
static uint32_t (*r)(const uint32_t *);
|
||||
static uint16_t (*r2)(const uint16_t *);
|
||||
static uint64_t (*r8)(const uint64_t *);
|
||||
static void (*w)(uint32_t, uint32_t *);
|
||||
+static void (*w8)(uint64_t, uint64_t *);
|
||||
typedef void (*table_sort_t)(char *, int);
|
||||
|
||||
static struct elf_funcs {
|
||||
@@ -102,6 +109,10 @@ static struct elf_funcs {
|
||||
uint32_t (*sym_name)(Elf_Sym *sym);
|
||||
uint64_t (*sym_value)(Elf_Sym *sym);
|
||||
uint16_t (*sym_shndx)(Elf_Sym *sym);
|
||||
+ uint64_t (*rela_offset)(Elf_Rela *rela);
|
||||
+ uint64_t (*rela_info)(Elf_Rela *rela);
|
||||
+ uint64_t (*rela_addend)(Elf_Rela *rela);
|
||||
+ void (*rela_write_addend)(Elf_Rela *rela, uint64_t val);
|
||||
} e;
|
||||
|
||||
static uint64_t ehdr64_shoff(Elf_Ehdr *ehdr)
|
||||
@@ -262,6 +273,38 @@ SYM_ADDR(value)
|
||||
SYM_WORD(name)
|
||||
SYM_HALF(shndx)
|
||||
|
||||
+#define __maybe_unused __attribute__((__unused__))
|
||||
+
|
||||
+#define RELA_ADDR(fn_name) \
|
||||
+static uint64_t rela64_##fn_name(Elf_Rela *rela) \
|
||||
+{ \
|
||||
+ return r8((uint64_t *)&rela->e64.r_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint64_t rela32_##fn_name(Elf_Rela *rela) \
|
||||
+{ \
|
||||
+ return r((uint32_t *)&rela->e32.r_##fn_name); \
|
||||
+} \
|
||||
+ \
|
||||
+static uint64_t __maybe_unused rela_##fn_name(Elf_Rela *rela) \
|
||||
+{ \
|
||||
+ return e.rela_##fn_name(rela); \
|
||||
+}
|
||||
+
|
||||
+RELA_ADDR(offset)
|
||||
+RELA_ADDR(info)
|
||||
+RELA_ADDR(addend)
|
||||
+
|
||||
+static void rela64_write_addend(Elf_Rela *rela, uint64_t val)
|
||||
+{
|
||||
+ w8(val, (uint64_t *)&rela->e64.r_addend);
|
||||
+}
|
||||
+
|
||||
+static void rela32_write_addend(Elf_Rela *rela, uint64_t val)
|
||||
+{
|
||||
+ w(val, (uint32_t *)&rela->e32.r_addend);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Get the whole file as a programming convenience in order to avoid
|
||||
* malloc+lseek+read+free of many pieces. If successful, then mmap
|
||||
@@ -341,6 +384,16 @@ static void wle(uint32_t val, uint32_t *x)
|
||||
put_unaligned_le32(val, x);
|
||||
}
|
||||
|
||||
+static void w8be(uint64_t val, uint64_t *x)
|
||||
+{
|
||||
+ put_unaligned_be64(val, x);
|
||||
+}
|
||||
+
|
||||
+static void w8le(uint64_t val, uint64_t *x)
|
||||
+{
|
||||
+ put_unaligned_le64(val, x);
|
||||
+}
|
||||
+
|
||||
/*
|
||||
* Move reserved section indices SHN_LORESERVE..SHN_HIRESERVE out of
|
||||
* the way to -256..-1, to avoid conflicting with real section
|
||||
@@ -398,13 +451,12 @@ static inline void *get_index(void *start, int entsize, int index)
|
||||
static int extable_ent_size;
|
||||
static int long_size;
|
||||
|
||||
+#define ERRSTR_MAXSZ 256
|
||||
|
||||
#ifdef UNWINDER_ORC_ENABLED
|
||||
/* ORC unwinder only support X86_64 */
|
||||
#include <asm/orc_types.h>
|
||||
|
||||
-#define ERRSTR_MAXSZ 256
|
||||
-
|
||||
static char g_err[ERRSTR_MAXSZ];
|
||||
static int *g_orc_ip_table;
|
||||
static struct orc_entry *g_orc_table;
|
||||
@@ -499,7 +551,19 @@ static void *sort_orctable(void *arg)
|
||||
#endif
|
||||
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
+
|
||||
+/* Only used for sorting mcount table */
|
||||
+static void rela_write_addend(Elf_Rela *rela, uint64_t val)
|
||||
+{
|
||||
+ e.rela_write_addend(rela, val);
|
||||
+}
|
||||
+
|
||||
static pthread_t mcount_sort_thread;
|
||||
+static bool sort_reloc;
|
||||
+
|
||||
+static long rela_type;
|
||||
+
|
||||
+static char m_err[ERRSTR_MAXSZ];
|
||||
|
||||
struct elf_mcount_loc {
|
||||
Elf_Ehdr *ehdr;
|
||||
@@ -508,6 +572,103 @@ struct elf_mcount_loc {
|
||||
uint64_t stop_mcount_loc;
|
||||
};
|
||||
|
||||
+/* Sort the relocations not the address itself */
|
||||
+static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
+{
|
||||
+ Elf_Shdr *shdr_start;
|
||||
+ Elf_Rela *rel;
|
||||
+ unsigned int shnum;
|
||||
+ unsigned int count;
|
||||
+ int shentsize;
|
||||
+ void *vals;
|
||||
+ void *ptr;
|
||||
+
|
||||
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
|
||||
+ shentsize = ehdr_shentsize(ehdr);
|
||||
+
|
||||
+ vals = malloc(long_size * size);
|
||||
+ if (!vals) {
|
||||
+ snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
|
||||
+ pthread_exit(m_err);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ ptr = vals;
|
||||
+
|
||||
+ shnum = ehdr_shnum(ehdr);
|
||||
+ if (shnum == SHN_UNDEF)
|
||||
+ shnum = shdr_size(shdr_start);
|
||||
+
|
||||
+ for (int i = 0; i < shnum; i++) {
|
||||
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
|
||||
+ void *end;
|
||||
+
|
||||
+ if (shdr_type(shdr) != SHT_RELA)
|
||||
+ continue;
|
||||
+
|
||||
+ rel = (void *)ehdr + shdr_offset(shdr);
|
||||
+ end = (void *)rel + shdr_size(shdr);
|
||||
+
|
||||
+ for (; (void *)rel < end; rel = (void *)rel + shdr_entsize(shdr)) {
|
||||
+ uint64_t offset = rela_offset(rel);
|
||||
+
|
||||
+ if (offset >= start_loc && offset < start_loc + size) {
|
||||
+ if (ptr + long_size > vals + size) {
|
||||
+ free(vals);
|
||||
+ snprintf(m_err, ERRSTR_MAXSZ,
|
||||
+ "Too many relocations");
|
||||
+ pthread_exit(m_err);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ /* Make sure this has the correct type */
|
||||
+ if (rela_info(rel) != rela_type) {
|
||||
+ free(vals);
|
||||
+ snprintf(m_err, ERRSTR_MAXSZ,
|
||||
+ "rela has type %lx but expected %lx\n",
|
||||
+ (long)rela_info(rel), rela_type);
|
||||
+ pthread_exit(m_err);
|
||||
+ return NULL;
|
||||
+ }
|
||||
+
|
||||
+ if (long_size == 4)
|
||||
+ *(uint32_t *)ptr = rela_addend(rel);
|
||||
+ else
|
||||
+ *(uint64_t *)ptr = rela_addend(rel);
|
||||
+ ptr += long_size;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ count = ptr - vals;
|
||||
+ qsort(vals, count / long_size, long_size, compare_extable);
|
||||
+
|
||||
+ ptr = vals;
|
||||
+ for (int i = 0; i < shnum; i++) {
|
||||
+ Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
|
||||
+ void *end;
|
||||
+
|
||||
+ if (shdr_type(shdr) != SHT_RELA)
|
||||
+ continue;
|
||||
+
|
||||
+ rel = (void *)ehdr + shdr_offset(shdr);
|
||||
+ end = (void *)rel + shdr_size(shdr);
|
||||
+
|
||||
+ for (; (void *)rel < end; rel = (void *)rel + shdr_entsize(shdr)) {
|
||||
+ uint64_t offset = rela_offset(rel);
|
||||
+
|
||||
+ if (offset >= start_loc && offset < start_loc + size) {
|
||||
+ if (long_size == 4)
|
||||
+ rela_write_addend(rel, *(uint32_t *)ptr);
|
||||
+ else
|
||||
+ rela_write_addend(rel, *(uint64_t *)ptr);
|
||||
+ ptr += long_size;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ free(vals);
|
||||
+ return NULL;
|
||||
+}
|
||||
+
|
||||
/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
|
||||
static void *sort_mcount_loc(void *arg)
|
||||
{
|
||||
@@ -517,6 +678,9 @@ static void *sort_mcount_loc(void *arg)
|
||||
uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
unsigned char *start_loc = (void *)emloc->ehdr + offset;
|
||||
|
||||
+ if (sort_reloc)
|
||||
+ return sort_relocs(emloc->ehdr, emloc->start_mcount_loc, count);
|
||||
+
|
||||
qsort(start_loc, count/long_size, long_size, compare_extable);
|
||||
return NULL;
|
||||
}
|
||||
@@ -866,12 +1030,14 @@ static int do_file(char const *const fname, void *addr)
|
||||
r2 = r2le;
|
||||
r8 = r8le;
|
||||
w = wle;
|
||||
+ w8 = w8le;
|
||||
break;
|
||||
case ELFDATA2MSB:
|
||||
r = rbe;
|
||||
r2 = r2be;
|
||||
r8 = r8be;
|
||||
w = wbe;
|
||||
+ w8 = w8be;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "unrecognized ELF data encoding %d: %s\n",
|
||||
@@ -887,8 +1053,13 @@ static int do_file(char const *const fname, void *addr)
|
||||
}
|
||||
|
||||
switch (r2(&ehdr->e32.e_machine)) {
|
||||
- case EM_386:
|
||||
case EM_AARCH64:
|
||||
+#ifdef MCOUNT_SORT_ENABLED
|
||||
+ sort_reloc = true;
|
||||
+ rela_type = 0x403;
|
||||
+#endif
|
||||
+ /* fallthrough */
|
||||
+ case EM_386:
|
||||
case EM_LOONGARCH:
|
||||
case EM_RISCV:
|
||||
case EM_S390:
|
||||
@@ -932,6 +1103,10 @@ static int do_file(char const *const fname, void *addr)
|
||||
.sym_name = sym32_name,
|
||||
.sym_value = sym32_value,
|
||||
.sym_shndx = sym32_shndx,
|
||||
+ .rela_offset = rela32_offset,
|
||||
+ .rela_info = rela32_info,
|
||||
+ .rela_addend = rela32_addend,
|
||||
+ .rela_write_addend = rela32_write_addend,
|
||||
};
|
||||
|
||||
e = efuncs;
|
||||
@@ -965,6 +1140,10 @@ static int do_file(char const *const fname, void *addr)
|
||||
.sym_name = sym64_name,
|
||||
.sym_value = sym64_value,
|
||||
.sym_shndx = sym64_shndx,
|
||||
+ .rela_offset = rela64_offset,
|
||||
+ .rela_info = rela64_info,
|
||||
+ .rela_addend = rela64_addend,
|
||||
+ .rela_write_addend = rela64_write_addend,
|
||||
};
|
||||
|
||||
e = efuncs;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,103 @@
|
||||
From 93c8c28c2ce439d598d5fd49d10a4bd5cb0401ea Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:57:27 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Have mcount rela sort use direct values
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit a0265659322540d656727b9e132edfb6f06b6c1a
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 18 14:59:20 2025 -0500
|
||||
|
||||
scripts/sorttable: Have mcount rela sort use direct values
|
||||
|
||||
The mcount_loc sorting for when the values are stored in the Elf_Rela
|
||||
entries uses the compare_extable() function to do the compares in the
|
||||
qsort(). That function does handle byte swapping if the machine being
|
||||
compiled for is a different endian than the host machine. But the
|
||||
sort_relocs() function sorts an array that pulled in the values from the
|
||||
Elf_Rela section and has already done the swapping.
|
||||
|
||||
Create two new compare functions that will sort the direct values. One
|
||||
will sort 32 bit values and the other will sort the 64 bit value. One of
|
||||
these will be assigned to a compare_values function pointer and that will
|
||||
be used for sorting the Elf_Rela mcount values.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/20250218200022.538888594@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 4a34c275123e..f62a91d8af0a 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -552,6 +552,28 @@ static void *sort_orctable(void *arg)
|
||||
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
|
||||
+static int compare_values_64(const void *a, const void *b)
|
||||
+{
|
||||
+ uint64_t av = *(uint64_t *)a;
|
||||
+ uint64_t bv = *(uint64_t *)b;
|
||||
+
|
||||
+ if (av < bv)
|
||||
+ return -1;
|
||||
+ return av > bv;
|
||||
+}
|
||||
+
|
||||
+static int compare_values_32(const void *a, const void *b)
|
||||
+{
|
||||
+ uint32_t av = *(uint32_t *)a;
|
||||
+ uint32_t bv = *(uint32_t *)b;
|
||||
+
|
||||
+ if (av < bv)
|
||||
+ return -1;
|
||||
+ return av > bv;
|
||||
+}
|
||||
+
|
||||
+static int (*compare_values)(const void *a, const void *b);
|
||||
+
|
||||
/* Only used for sorting mcount table */
|
||||
static void rela_write_addend(Elf_Rela *rela, uint64_t val)
|
||||
{
|
||||
@@ -583,6 +605,8 @@ static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
void *vals;
|
||||
void *ptr;
|
||||
|
||||
+ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
|
||||
+
|
||||
shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
|
||||
shentsize = ehdr_shentsize(ehdr);
|
||||
|
||||
@@ -640,7 +664,7 @@ static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
}
|
||||
}
|
||||
count = ptr - vals;
|
||||
- qsort(vals, count / long_size, long_size, compare_extable);
|
||||
+ qsort(vals, count / long_size, long_size, compare_values);
|
||||
|
||||
ptr = vals;
|
||||
for (int i = 0; i < shnum; i++) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,239 @@
|
||||
From d39567e1f737a3f1959b0597eeeba7bdf25d0249 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:57:34 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Always use an array for the mcount_loc
|
||||
sorting
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 5fb964f5ba53afda0e2b6dbc00b8205461ffe04a
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 18 14:59:21 2025 -0500
|
||||
|
||||
scripts/sorttable: Always use an array for the mcount_loc sorting
|
||||
|
||||
The sorting of the mcount_loc section is done directly to the section for
|
||||
x86 and arm32 but it uses a separate array for arm64 as arm64 has the
|
||||
values for the mcount_loc stored in the rela sections of the vmlinux ELF
|
||||
file.
|
||||
|
||||
In order to use the same code to remove weak functions, always use a
|
||||
separate array to do the sorting. This requires splitting up the filling
|
||||
of the array into one function and the placing the contents of the array
|
||||
back into the rela sections or into the mcount_loc section into a separate
|
||||
file.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/20250218200022.710676551@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index f62a91d8af0a..ec02a2852efb 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -594,31 +594,19 @@ struct elf_mcount_loc {
|
||||
uint64_t stop_mcount_loc;
|
||||
};
|
||||
|
||||
-/* Sort the relocations not the address itself */
|
||||
-static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
+/* Fill the array with the content of the relocs */
|
||||
+static int fill_relocs(void *ptr, uint64_t size, Elf_Ehdr *ehdr, uint64_t start_loc)
|
||||
{
|
||||
Elf_Shdr *shdr_start;
|
||||
Elf_Rela *rel;
|
||||
unsigned int shnum;
|
||||
- unsigned int count;
|
||||
+ unsigned int count = 0;
|
||||
int shentsize;
|
||||
- void *vals;
|
||||
- void *ptr;
|
||||
-
|
||||
- compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
|
||||
+ void *array_end = ptr + size;
|
||||
|
||||
shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
|
||||
shentsize = ehdr_shentsize(ehdr);
|
||||
|
||||
- vals = malloc(long_size * size);
|
||||
- if (!vals) {
|
||||
- snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
|
||||
- pthread_exit(m_err);
|
||||
- return NULL;
|
||||
- }
|
||||
-
|
||||
- ptr = vals;
|
||||
-
|
||||
shnum = ehdr_shnum(ehdr);
|
||||
if (shnum == SHN_UNDEF)
|
||||
shnum = shdr_size(shdr_start);
|
||||
@@ -637,22 +625,18 @@ static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
uint64_t offset = rela_offset(rel);
|
||||
|
||||
if (offset >= start_loc && offset < start_loc + size) {
|
||||
- if (ptr + long_size > vals + size) {
|
||||
- free(vals);
|
||||
+ if (ptr + long_size > array_end) {
|
||||
snprintf(m_err, ERRSTR_MAXSZ,
|
||||
"Too many relocations");
|
||||
- pthread_exit(m_err);
|
||||
- return NULL;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
/* Make sure this has the correct type */
|
||||
if (rela_info(rel) != rela_type) {
|
||||
- free(vals);
|
||||
snprintf(m_err, ERRSTR_MAXSZ,
|
||||
"rela has type %lx but expected %lx\n",
|
||||
(long)rela_info(rel), rela_type);
|
||||
- pthread_exit(m_err);
|
||||
- return NULL;
|
||||
+ return -1;
|
||||
}
|
||||
|
||||
if (long_size == 4)
|
||||
@@ -660,13 +644,28 @@ static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
else
|
||||
*(uint64_t *)ptr = rela_addend(rel);
|
||||
ptr += long_size;
|
||||
+ count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
- count = ptr - vals;
|
||||
- qsort(vals, count / long_size, long_size, compare_values);
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+/* Put the sorted vals back into the relocation elements */
|
||||
+static void replace_relocs(void *ptr, uint64_t size, Elf_Ehdr *ehdr, uint64_t start_loc)
|
||||
+{
|
||||
+ Elf_Shdr *shdr_start;
|
||||
+ Elf_Rela *rel;
|
||||
+ unsigned int shnum;
|
||||
+ int shentsize;
|
||||
+
|
||||
+ shdr_start = (Elf_Shdr *)((char *)ehdr + ehdr_shoff(ehdr));
|
||||
+ shentsize = ehdr_shentsize(ehdr);
|
||||
+
|
||||
+ shnum = ehdr_shnum(ehdr);
|
||||
+ if (shnum == SHN_UNDEF)
|
||||
+ shnum = shdr_size(shdr_start);
|
||||
|
||||
- ptr = vals;
|
||||
for (int i = 0; i < shnum; i++) {
|
||||
Elf_Shdr *shdr = get_index(shdr_start, shentsize, i);
|
||||
void *end;
|
||||
@@ -689,8 +688,32 @@ static void *sort_relocs(Elf_Ehdr *ehdr, uint64_t start_loc, uint64_t size)
|
||||
}
|
||||
}
|
||||
}
|
||||
- free(vals);
|
||||
- return NULL;
|
||||
+}
|
||||
+
|
||||
+static int fill_addrs(void *ptr, uint64_t size, void *addrs)
|
||||
+{
|
||||
+ void *end = ptr + size;
|
||||
+ int count = 0;
|
||||
+
|
||||
+ for (; ptr < end; ptr += long_size, addrs += long_size, count++) {
|
||||
+ if (long_size == 4)
|
||||
+ *(uint32_t *)ptr = r(addrs);
|
||||
+ else
|
||||
+ *(uint64_t *)ptr = r8(addrs);
|
||||
+ }
|
||||
+ return count;
|
||||
+}
|
||||
+
|
||||
+static void replace_addrs(void *ptr, uint64_t size, void *addrs)
|
||||
+{
|
||||
+ void *end = ptr + size;
|
||||
+
|
||||
+ for (; ptr < end; ptr += long_size, addrs += long_size) {
|
||||
+ if (long_size == 4)
|
||||
+ w(*(uint32_t *)ptr, addrs);
|
||||
+ else
|
||||
+ w8(*(uint64_t *)ptr, addrs);
|
||||
+ }
|
||||
}
|
||||
|
||||
/* Sort the addresses stored between __start_mcount_loc to __stop_mcount_loc in vmlinux */
|
||||
@@ -699,14 +722,49 @@ static void *sort_mcount_loc(void *arg)
|
||||
struct elf_mcount_loc *emloc = (struct elf_mcount_loc *)arg;
|
||||
uint64_t offset = emloc->start_mcount_loc - shdr_addr(emloc->init_data_sec)
|
||||
+ shdr_offset(emloc->init_data_sec);
|
||||
- uint64_t count = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
+ uint64_t size = emloc->stop_mcount_loc - emloc->start_mcount_loc;
|
||||
unsigned char *start_loc = (void *)emloc->ehdr + offset;
|
||||
+ Elf_Ehdr *ehdr = emloc->ehdr;
|
||||
+ void *e_msg = NULL;
|
||||
+ void *vals;
|
||||
+ int count;
|
||||
+
|
||||
+ vals = malloc(long_size * size);
|
||||
+ if (!vals) {
|
||||
+ snprintf(m_err, ERRSTR_MAXSZ, "Failed to allocate sort array");
|
||||
+ pthread_exit(m_err);
|
||||
+ }
|
||||
|
||||
if (sort_reloc)
|
||||
- return sort_relocs(emloc->ehdr, emloc->start_mcount_loc, count);
|
||||
+ count = fill_relocs(vals, size, ehdr, emloc->start_mcount_loc);
|
||||
+ else
|
||||
+ count = fill_addrs(vals, size, start_loc);
|
||||
+
|
||||
+ if (count < 0) {
|
||||
+ e_msg = m_err;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ if (count != size / long_size) {
|
||||
+ snprintf(m_err, ERRSTR_MAXSZ, "Expected %u mcount elements but found %u\n",
|
||||
+ (int)(size / long_size), count);
|
||||
+ e_msg = m_err;
|
||||
+ goto out;
|
||||
+ }
|
||||
+
|
||||
+ compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
|
||||
+
|
||||
+ qsort(vals, count, long_size, compare_values);
|
||||
+
|
||||
+ if (sort_reloc)
|
||||
+ replace_relocs(vals, size, ehdr, emloc->start_mcount_loc);
|
||||
+ else
|
||||
+ replace_addrs(vals, size, start_loc);
|
||||
+
|
||||
+out:
|
||||
+ free(vals);
|
||||
|
||||
- qsort(start_loc, count/long_size, long_size, compare_extable);
|
||||
- return NULL;
|
||||
+ pthread_exit(e_msg);
|
||||
}
|
||||
|
||||
/* Get the address of __start_mcount_loc and __stop_mcount_loc in System.map */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,316 @@
|
||||
From 8cde64d5091653560e13e7cd34a385258372db58 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Mon, 1 Jun 2026 15:57:38 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Zero out weak functions in mcount_loc
|
||||
table
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit ef378c3b8233855497a414b9d67bf22592c928a4
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 18 14:59:22 2025 -0500
|
||||
|
||||
scripts/sorttable: Zero out weak functions in mcount_loc table
|
||||
|
||||
When a function is annotated as "weak" and is overridden, the code is not
|
||||
removed. If it is traced, the fentry/mcount location in the weak function
|
||||
will be referenced by the "__mcount_loc" section. This will then be added
|
||||
to the available_filter_functions list. Since only the address of the
|
||||
functions are listed, to find the name to show, a search of kallsyms is
|
||||
used.
|
||||
|
||||
Since kallsyms will return the function by simply finding the function
|
||||
that the address is after but before the next function, an address of a
|
||||
weak function will show up as the function before it. This is because
|
||||
kallsyms does not save names of weak functions. This has caused issues in
|
||||
the past, as now the traced weak function will be listed in
|
||||
available_filter_functions with the name of the function before it.
|
||||
|
||||
At best, this will cause the previous function's name to be listed twice.
|
||||
At worse, if the previous function was marked notrace, it will now show up
|
||||
as a function that can be traced. Note that it only shows up that it can
|
||||
be traced but will not be if enabled, which causes confusion.
|
||||
|
||||
https://lore.kernel.org/all/20220412094923.0abe90955e5db486b7bca279@kernel.org/
|
||||
|
||||
The commit b39181f7c6907 ("ftrace: Add FTRACE_MCOUNT_MAX_OFFSET to avoid
|
||||
adding weak function") was a workaround to this by checking the function
|
||||
address before printing its name. If the address was too far from the
|
||||
function given by the name then instead of printing the name it would
|
||||
print: __ftrace_invalid_address___<invalid-offset>
|
||||
|
||||
The real issue is that these invalid addresses are listed in the ftrace
|
||||
table look up which available_filter_functions is derived from. A place
|
||||
holder must be listed in that file because set_ftrace_filter may take a
|
||||
series of indexes into that file instead of names to be able to do O(1)
|
||||
lookups to enable filtering (many tools use this method).
|
||||
|
||||
Even if kallsyms saved the size of the function, it does not remove the
|
||||
need of having these place holders. The real solution is to not add a weak
|
||||
function into the ftrace table in the first place.
|
||||
|
||||
To solve this, the sorttable.c code that sorts the mcount regions during
|
||||
the build is modified to take a "nm -S vmlinux" input, sort it, and any
|
||||
function listed in the mcount_loc section that is not within a boundary of
|
||||
the function list given by nm is considered a weak function and is zeroed
|
||||
out.
|
||||
|
||||
Note, this does not mean they will remain zero when booting as KASLR
|
||||
will still shift those addresses. To handle this, the entries in the
|
||||
mcount_loc section will be ignored if they are zero or match the
|
||||
kaslr_offset() value.
|
||||
|
||||
Before:
|
||||
|
||||
~# grep __ftrace_invalid_address___ /sys/kernel/tracing/available_filter_functions | wc -l
|
||||
551
|
||||
|
||||
After:
|
||||
|
||||
~# grep __ftrace_invalid_address___ /sys/kernel/tracing/available_filter_functions | wc -l
|
||||
0
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/20250218200022.883095980@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
||||
index 57b8fad660cf..792c57d1f0b9 100644
|
||||
--- a/kernel/trace/ftrace.c
|
||||
+++ b/kernel/trace/ftrace.c
|
||||
@@ -7052,6 +7052,7 @@ static int ftrace_process_locs(struct module *mod,
|
||||
unsigned long count;
|
||||
unsigned long *p;
|
||||
unsigned long addr;
|
||||
+ unsigned long kaslr;
|
||||
unsigned long flags = 0; /* Shut up gcc */
|
||||
int ret = -ENOMEM;
|
||||
|
||||
@@ -7100,6 +7101,9 @@ static int ftrace_process_locs(struct module *mod,
|
||||
ftrace_pages->next = start_pg;
|
||||
}
|
||||
|
||||
+ /* For zeroed locations that were shifted for core kernel */
|
||||
+ kaslr = !mod ? kaslr_offset() : 0;
|
||||
+
|
||||
p = start;
|
||||
pg = start_pg;
|
||||
while (p < end) {
|
||||
@@ -7111,7 +7115,7 @@ static int ftrace_process_locs(struct module *mod,
|
||||
* object files to satisfy alignments.
|
||||
* Skip any NULL pointers.
|
||||
*/
|
||||
- if (!addr) {
|
||||
+ if (!addr || addr == kaslr) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
diff --git a/scripts/link-vmlinux.sh b/scripts/link-vmlinux.sh
|
||||
index cdf16029fc58..8619ae612997 100755
|
||||
--- a/scripts/link-vmlinux.sh
|
||||
+++ b/scripts/link-vmlinux.sh
|
||||
@@ -174,12 +174,14 @@ mksysmap()
|
||||
|
||||
sorttable()
|
||||
{
|
||||
- ${objtree}/scripts/sorttable ${1}
|
||||
+ ${NM} -S ${1} > .tmp_vmlinux.nm-sort
|
||||
+ ${objtree}/scripts/sorttable -s .tmp_vmlinux.nm-sort ${1}
|
||||
}
|
||||
|
||||
cleanup()
|
||||
{
|
||||
rm -f .btf.*
|
||||
+ rm -f .tmp_vmlinux.nm-sort
|
||||
rm -f System.map
|
||||
rm -f vmlinux
|
||||
rm -f vmlinux.map
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index ec02a2852efb..23c7e0e6c024 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -580,6 +580,98 @@ static void rela_write_addend(Elf_Rela *rela, uint64_t val)
|
||||
e.rela_write_addend(rela, val);
|
||||
}
|
||||
|
||||
+struct func_info {
|
||||
+ uint64_t addr;
|
||||
+ uint64_t size;
|
||||
+};
|
||||
+
|
||||
+/* List of functions created by: nm -S vmlinux */
|
||||
+static struct func_info *function_list;
|
||||
+static int function_list_size;
|
||||
+
|
||||
+/* Allocate functions in 1k blocks */
|
||||
+#define FUNC_BLK_SIZE 1024
|
||||
+#define FUNC_BLK_MASK (FUNC_BLK_SIZE - 1)
|
||||
+
|
||||
+static int add_field(uint64_t addr, uint64_t size)
|
||||
+{
|
||||
+ struct func_info *fi;
|
||||
+ int fsize = function_list_size;
|
||||
+
|
||||
+ if (!(fsize & FUNC_BLK_MASK)) {
|
||||
+ fsize += FUNC_BLK_SIZE;
|
||||
+ fi = realloc(function_list, fsize * sizeof(struct func_info));
|
||||
+ if (!fi)
|
||||
+ return -1;
|
||||
+ function_list = fi;
|
||||
+ }
|
||||
+ fi = &function_list[function_list_size++];
|
||||
+ fi->addr = addr;
|
||||
+ fi->size = size;
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+/* Only return match if the address lies inside the function size */
|
||||
+static int cmp_func_addr(const void *K, const void *A)
|
||||
+{
|
||||
+ uint64_t key = *(const uint64_t *)K;
|
||||
+ const struct func_info *a = A;
|
||||
+
|
||||
+ if (key < a->addr)
|
||||
+ return -1;
|
||||
+ return key >= a->addr + a->size;
|
||||
+}
|
||||
+
|
||||
+/* Find the function in function list that is bounded by the function size */
|
||||
+static int find_func(uint64_t key)
|
||||
+{
|
||||
+ return bsearch(&key, function_list, function_list_size,
|
||||
+ sizeof(struct func_info), cmp_func_addr) != NULL;
|
||||
+}
|
||||
+
|
||||
+static int cmp_funcs(const void *A, const void *B)
|
||||
+{
|
||||
+ const struct func_info *a = A;
|
||||
+ const struct func_info *b = B;
|
||||
+
|
||||
+ if (a->addr < b->addr)
|
||||
+ return -1;
|
||||
+ return a->addr > b->addr;
|
||||
+}
|
||||
+
|
||||
+static int parse_symbols(const char *fname)
|
||||
+{
|
||||
+ FILE *fp;
|
||||
+ char addr_str[20]; /* Only need 17, but round up to next int size */
|
||||
+ char size_str[20];
|
||||
+ char type;
|
||||
+
|
||||
+ fp = fopen(fname, "r");
|
||||
+ if (!fp) {
|
||||
+ perror(fname);
|
||||
+ return -1;
|
||||
+ }
|
||||
+
|
||||
+ while (fscanf(fp, "%16s %16s %c %*s\n", addr_str, size_str, &type) == 3) {
|
||||
+ uint64_t addr;
|
||||
+ uint64_t size;
|
||||
+
|
||||
+ /* Only care about functions */
|
||||
+ if (type != 't' && type != 'T' && type != 'W')
|
||||
+ continue;
|
||||
+
|
||||
+ addr = strtoull(addr_str, NULL, 16);
|
||||
+ size = strtoull(size_str, NULL, 16);
|
||||
+ if (add_field(addr, size) < 0)
|
||||
+ return -1;
|
||||
+ }
|
||||
+ fclose(fp);
|
||||
+
|
||||
+ qsort(function_list, function_list_size, sizeof(struct func_info), cmp_funcs);
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static pthread_t mcount_sort_thread;
|
||||
static bool sort_reloc;
|
||||
|
||||
@@ -752,6 +844,21 @@ static void *sort_mcount_loc(void *arg)
|
||||
goto out;
|
||||
}
|
||||
|
||||
+ /* zero out any locations not found by function list */
|
||||
+ if (function_list_size) {
|
||||
+ for (void *ptr = vals; ptr < vals + size; ptr += long_size) {
|
||||
+ uint64_t key;
|
||||
+
|
||||
+ key = long_size == 4 ? r((uint32_t *)ptr) : r8((uint64_t *)ptr);
|
||||
+ if (!find_func(key)) {
|
||||
+ if (long_size == 4)
|
||||
+ *(uint32_t *)ptr = 0;
|
||||
+ else
|
||||
+ *(uint64_t *)ptr = 0;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+
|
||||
compare_values = long_size == 4 ? compare_values_32 : compare_values_64;
|
||||
|
||||
qsort(vals, count, long_size, compare_values);
|
||||
@@ -801,6 +908,8 @@ static void get_mcount_loc(struct elf_mcount_loc *emloc, Elf_Shdr *symtab_sec,
|
||||
return;
|
||||
}
|
||||
}
|
||||
+#else /* MCOUNT_SORT_ENABLED */
|
||||
+static inline int parse_symbols(const char *fname) { return 0; }
|
||||
#endif
|
||||
|
||||
static int do_sort(Elf_Ehdr *ehdr,
|
||||
@@ -1256,14 +1365,29 @@ int main(int argc, char *argv[])
|
||||
int i, n_error = 0; /* gcc-4.3.0 false positive complaint */
|
||||
size_t size = 0;
|
||||
void *addr = NULL;
|
||||
+ int c;
|
||||
+
|
||||
+ while ((c = getopt(argc, argv, "s:")) >= 0) {
|
||||
+ switch (c) {
|
||||
+ case 's':
|
||||
+ if (parse_symbols(optarg) < 0) {
|
||||
+ fprintf(stderr, "Could not parse %s\n", optarg);
|
||||
+ return -1;
|
||||
+ }
|
||||
+ break;
|
||||
+ default:
|
||||
+ fprintf(stderr, "usage: sorttable [-s nm-file] vmlinux...\n");
|
||||
+ return 0;
|
||||
+ }
|
||||
+ }
|
||||
|
||||
- if (argc < 2) {
|
||||
+ if ((argc - optind) < 1) {
|
||||
fprintf(stderr, "usage: sorttable vmlinux...\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Process each file in turn, allowing deep failure. */
|
||||
- for (i = 1; i < argc; i++) {
|
||||
+ for (i = optind; i < argc; i++) {
|
||||
addr = mmap_file(argv[i], &size);
|
||||
if (!addr) {
|
||||
++n_error;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,78 @@
|
||||
From fb85259106c9afdbf7808aecc128d41aacab22ea Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:40:50 +0200
|
||||
Subject: [PATCH] ftrace: Update the mcount_loc check of skipped entries
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 4a3efc6baff931da9a85c6d2e42c87bd9a827399
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 18 14:59:23 2025 -0500
|
||||
|
||||
ftrace: Update the mcount_loc check of skipped entries
|
||||
|
||||
Now that weak functions turn into skipped entries, update the check to
|
||||
make sure the amount that was allocated would fit both the entries that
|
||||
were allocated as well as those that were skipped.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/20250218200023.055162048@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
||||
index 792c57d1f0b9..4956ad9f9a20 100644
|
||||
--- a/kernel/trace/ftrace.c
|
||||
+++ b/kernel/trace/ftrace.c
|
||||
@@ -7159,7 +7159,28 @@ static int ftrace_process_locs(struct module *mod,
|
||||
|
||||
/* We should have used all pages unless we skipped some */
|
||||
if (pg_unuse) {
|
||||
- WARN_ON(!skipped);
|
||||
+ unsigned long pg_remaining, remaining = 0;
|
||||
+ unsigned long skip;
|
||||
+
|
||||
+ /* Count the number of entries unused and compare it to skipped. */
|
||||
+ pg_remaining = (ENTRIES_PER_PAGE << pg->order) - pg->index;
|
||||
+
|
||||
+ if (!WARN(skipped < pg_remaining, "Extra allocated pages for ftrace")) {
|
||||
+
|
||||
+ skip = skipped - pg_remaining;
|
||||
+
|
||||
+ for (pg = pg_unuse; pg; pg = pg->next)
|
||||
+ remaining += 1 << pg->order;
|
||||
+
|
||||
+ skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
|
||||
+
|
||||
+ /*
|
||||
+ * Check to see if the number of pages remaining would
|
||||
+ * just fit the number of entries skipped.
|
||||
+ */
|
||||
+ WARN(skip != remaining, "Extra allocated pages for ftrace: %lu with %lu skipped",
|
||||
+ remaining, skipped);
|
||||
+ }
|
||||
/* Need to synchronize with ftrace_location_range() */
|
||||
synchronize_rcu();
|
||||
ftrace_free_pages(pg_unuse);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
115
1345-ftrace-have-ftrace-pages-output-reflect-freed-pages.patch
Normal file
115
1345-ftrace-have-ftrace-pages-output-reflect-freed-pages.patch
Normal file
@ -0,0 +1,115 @@
|
||||
From d705caa45a6f9061420687f3d7d86f28e35881e2 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:40:54 +0200
|
||||
Subject: [PATCH] ftrace: Have ftrace pages output reflect freed pages
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 264143c4e54412095f4b615e65bf736fc3c60af0
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 18 14:59:24 2025 -0500
|
||||
|
||||
ftrace: Have ftrace pages output reflect freed pages
|
||||
|
||||
The amount of memory that ftrace uses to save the descriptors to manage
|
||||
the functions it can trace is shown at output. But if there are a lot of
|
||||
functions that are skipped because they were weak or the architecture
|
||||
added holes into the tables, then the extra pages that were allocated are
|
||||
freed. But these freed pages are not reflected in the numbers shown, and
|
||||
they can even be inconsistent with what is reported:
|
||||
|
||||
ftrace: allocating 57482 entries in 225 pages
|
||||
ftrace: allocated 224 pages with 3 groups
|
||||
|
||||
The above shows the number of original entries that are in the mcount_loc
|
||||
section and the pages needed to save them (225), but the second output
|
||||
reflects the number of pages that were actually used. The two should be
|
||||
consistent as:
|
||||
|
||||
ftrace: allocating 56739 entries in 224 pages
|
||||
ftrace: allocated 224 pages with 3 groups
|
||||
|
||||
The above also shows the accurate number of entires that were actually
|
||||
stored and does not include the entries that were removed.
|
||||
|
||||
Cc: bpf <bpf@vger.kernel.org>
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Nicolas Schier <nicolas@fjasle.eu>
|
||||
Cc: Zheng Yejian <zhengyejian1@huawei.com>
|
||||
Cc: Martin Kelly <martin.kelly@crowdstrike.com>
|
||||
Cc: Christophe Leroy <christophe.leroy@csgroup.eu>
|
||||
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/20250218200023.221100846@goodmis.org
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
||||
index 4956ad9f9a20..5e131970a70e 100644
|
||||
--- a/kernel/trace/ftrace.c
|
||||
+++ b/kernel/trace/ftrace.c
|
||||
@@ -7054,6 +7054,7 @@ static int ftrace_process_locs(struct module *mod,
|
||||
unsigned long addr;
|
||||
unsigned long kaslr;
|
||||
unsigned long flags = 0; /* Shut up gcc */
|
||||
+ unsigned long pages;
|
||||
int ret = -ENOMEM;
|
||||
|
||||
count = end - start;
|
||||
@@ -7061,6 +7062,8 @@ static int ftrace_process_locs(struct module *mod,
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
+ pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
|
||||
+
|
||||
/*
|
||||
* Sorting mcount in vmlinux at build time depend on
|
||||
* CONFIG_BUILDTIME_MCOUNT_SORT, while mcount loc in
|
||||
@@ -7172,6 +7175,8 @@ static int ftrace_process_locs(struct module *mod,
|
||||
for (pg = pg_unuse; pg; pg = pg->next)
|
||||
remaining += 1 << pg->order;
|
||||
|
||||
+ pages -= remaining;
|
||||
+
|
||||
skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
|
||||
|
||||
/*
|
||||
@@ -7185,6 +7190,13 @@ static int ftrace_process_locs(struct module *mod,
|
||||
synchronize_rcu();
|
||||
ftrace_free_pages(pg_unuse);
|
||||
}
|
||||
+
|
||||
+ if (!mod) {
|
||||
+ count -= skipped;
|
||||
+ pr_info("ftrace: allocating %ld entries in %ld pages\n",
|
||||
+ count, pages);
|
||||
+ }
|
||||
+
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -7836,9 +7848,6 @@ void __init ftrace_init(void)
|
||||
goto failed;
|
||||
}
|
||||
|
||||
- pr_info("ftrace: allocating %ld entries in %ld pages\n",
|
||||
- count, DIV_ROUND_UP(count, ENTRIES_PER_PAGE));
|
||||
-
|
||||
ret = ftrace_process_locs(NULL,
|
||||
__start_mcount_loc,
|
||||
__stop_mcount_loc);
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
166
1346-ftrace-do-not-over-allocate-ftrace-memory.patch
Normal file
166
1346-ftrace-do-not-over-allocate-ftrace-memory.patch
Normal file
@ -0,0 +1,166 @@
|
||||
From 7a2ec4e50744d195d6a66868ef6f3fb39f15b8b7 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:56:18 +0200
|
||||
Subject: [PATCH] ftrace: Do not over-allocate ftrace memory
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit be55257fab181b93af38f8c4b1b3cb453a78d742
|
||||
Author: Guenter Roeck <linux@roeck-us.net>
|
||||
Date: Tue Jan 13 07:22:42 2026 -0800
|
||||
|
||||
ftrace: Do not over-allocate ftrace memory
|
||||
|
||||
The pg_remaining calculation in ftrace_process_locs() assumes that
|
||||
ENTRIES_PER_PAGE multiplied by 2^order equals the actual capacity of the
|
||||
allocated page group. However, ENTRIES_PER_PAGE is PAGE_SIZE / ENTRY_SIZE
|
||||
(integer division). When PAGE_SIZE is not a multiple of ENTRY_SIZE (e.g.
|
||||
4096 / 24 = 170 with remainder 16), high-order allocations (like 256 pages)
|
||||
have significantly more capacity than 256 * 170. This leads to pg_remaining
|
||||
being underestimated, which in turn makes skip (derived from skipped -
|
||||
pg_remaining) larger than expected, causing the WARN(skip != remaining)
|
||||
to trigger.
|
||||
|
||||
Extra allocated pages for ftrace: 2 with 654 skipped
|
||||
WARNING: CPU: 0 PID: 0 at kernel/trace/ftrace.c:7295 ftrace_process_locs+0x5bf/0x5e0
|
||||
|
||||
A similar problem in ftrace_allocate_records() can result in allocating
|
||||
too many pages. This can trigger the second warning in
|
||||
ftrace_process_locs().
|
||||
|
||||
Extra allocated pages for ftrace
|
||||
WARNING: CPU: 0 PID: 0 at kernel/trace/ftrace.c:7276 ftrace_process_locs+0x548/0x580
|
||||
|
||||
Use the actual capacity of a page group to determine the number of pages
|
||||
to allocate. Have ftrace_allocate_pages() return the number of allocated
|
||||
pages to avoid having to calculate it. Use the actual page group capacity
|
||||
when validating the number of unused pages due to skipped entries.
|
||||
Drop the definition of ENTRIES_PER_PAGE since it is no longer used.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 4a3efc6baff93 ("ftrace: Update the mcount_loc check of skipped entries")
|
||||
Link: https://patch.msgid.link/20260113152243.3557219-1-linux@roeck-us.net
|
||||
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
||||
index 5e131970a70e..877f943832c9 100644
|
||||
--- a/kernel/trace/ftrace.c
|
||||
+++ b/kernel/trace/ftrace.c
|
||||
@@ -1122,7 +1122,6 @@ struct ftrace_page {
|
||||
};
|
||||
|
||||
#define ENTRY_SIZE sizeof(struct dyn_ftrace)
|
||||
-#define ENTRIES_PER_PAGE (PAGE_SIZE / ENTRY_SIZE)
|
||||
|
||||
static struct ftrace_page *ftrace_pages_start;
|
||||
static struct ftrace_page *ftrace_pages;
|
||||
@@ -3754,7 +3753,8 @@ static int ftrace_update_code(struct module *mod, struct ftrace_page *new_pgs)
|
||||
return 0;
|
||||
}
|
||||
|
||||
-static int ftrace_allocate_records(struct ftrace_page *pg, int count)
|
||||
+static int ftrace_allocate_records(struct ftrace_page *pg, int count,
|
||||
+ unsigned long *num_pages)
|
||||
{
|
||||
int order;
|
||||
int pages;
|
||||
@@ -3764,7 +3764,7 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
|
||||
return -EINVAL;
|
||||
|
||||
/* We want to fill as much as possible, with no empty pages */
|
||||
- pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
|
||||
+ pages = DIV_ROUND_UP(count * ENTRY_SIZE, PAGE_SIZE);
|
||||
order = fls(pages) - 1;
|
||||
|
||||
again:
|
||||
@@ -3779,6 +3779,7 @@ static int ftrace_allocate_records(struct ftrace_page *pg, int count)
|
||||
}
|
||||
|
||||
ftrace_number_of_pages += 1 << order;
|
||||
+ *num_pages += 1 << order;
|
||||
ftrace_number_of_groups++;
|
||||
|
||||
cnt = (PAGE_SIZE << order) / ENTRY_SIZE;
|
||||
@@ -3807,12 +3808,14 @@ static void ftrace_free_pages(struct ftrace_page *pages)
|
||||
}
|
||||
|
||||
static struct ftrace_page *
|
||||
-ftrace_allocate_pages(unsigned long num_to_init)
|
||||
+ftrace_allocate_pages(unsigned long num_to_init, unsigned long *num_pages)
|
||||
{
|
||||
struct ftrace_page *start_pg;
|
||||
struct ftrace_page *pg;
|
||||
int cnt;
|
||||
|
||||
+ *num_pages = 0;
|
||||
+
|
||||
if (!num_to_init)
|
||||
return NULL;
|
||||
|
||||
@@ -3826,7 +3829,7 @@ ftrace_allocate_pages(unsigned long num_to_init)
|
||||
* waste as little space as possible.
|
||||
*/
|
||||
for (;;) {
|
||||
- cnt = ftrace_allocate_records(pg, num_to_init);
|
||||
+ cnt = ftrace_allocate_records(pg, num_to_init, num_pages);
|
||||
if (cnt < 0)
|
||||
goto free_pages;
|
||||
|
||||
@@ -7062,8 +7065,6 @@ static int ftrace_process_locs(struct module *mod,
|
||||
if (!count)
|
||||
return 0;
|
||||
|
||||
- pages = DIV_ROUND_UP(count, ENTRIES_PER_PAGE);
|
||||
-
|
||||
/*
|
||||
* Sorting mcount in vmlinux at build time depend on
|
||||
* CONFIG_BUILDTIME_MCOUNT_SORT, while mcount loc in
|
||||
@@ -7076,7 +7077,7 @@ static int ftrace_process_locs(struct module *mod,
|
||||
test_is_sorted(start, count);
|
||||
}
|
||||
|
||||
- start_pg = ftrace_allocate_pages(count);
|
||||
+ start_pg = ftrace_allocate_pages(count, &pages);
|
||||
if (!start_pg)
|
||||
return -ENOMEM;
|
||||
|
||||
@@ -7163,27 +7164,27 @@ static int ftrace_process_locs(struct module *mod,
|
||||
/* We should have used all pages unless we skipped some */
|
||||
if (pg_unuse) {
|
||||
unsigned long pg_remaining, remaining = 0;
|
||||
- unsigned long skip;
|
||||
+ long skip;
|
||||
|
||||
/* Count the number of entries unused and compare it to skipped. */
|
||||
- pg_remaining = (ENTRIES_PER_PAGE << pg->order) - pg->index;
|
||||
+ pg_remaining = (PAGE_SIZE << pg->order) / ENTRY_SIZE - pg->index;
|
||||
|
||||
if (!WARN(skipped < pg_remaining, "Extra allocated pages for ftrace")) {
|
||||
|
||||
skip = skipped - pg_remaining;
|
||||
|
||||
- for (pg = pg_unuse; pg; pg = pg->next)
|
||||
+ for (pg = pg_unuse; pg && skip > 0; pg = pg->next) {
|
||||
remaining += 1 << pg->order;
|
||||
+ skip -= (PAGE_SIZE << pg->order) / ENTRY_SIZE;
|
||||
+ }
|
||||
|
||||
pages -= remaining;
|
||||
|
||||
- skip = DIV_ROUND_UP(skip, ENTRIES_PER_PAGE);
|
||||
-
|
||||
/*
|
||||
* Check to see if the number of pages remaining would
|
||||
* just fit the number of entries skipped.
|
||||
*/
|
||||
- WARN(skip != remaining, "Extra allocated pages for ftrace: %lu with %lu skipped",
|
||||
+ WARN(pg || skip > 0, "Extra allocated pages for ftrace: %lu with %lu skipped",
|
||||
remaining, skipped);
|
||||
}
|
||||
/* Need to synchronize with ftrace_location_range() */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,66 @@
|
||||
From 611153910e7701fddefdbc91f75953b89e698331 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:56:21 +0200
|
||||
Subject: [PATCH] ftrace: Test mcount_loc addr before calling
|
||||
ftrace_call_addr()
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 6eeca746fa5f1dd03c6ee05cb03f5eb1ddda1c81
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 25 13:20:05 2025 -0500
|
||||
|
||||
ftrace: Test mcount_loc addr before calling ftrace_call_addr()
|
||||
|
||||
The addresses in the mcount_loc can be zeroed and then moved by KASLR
|
||||
making them invalid addresses. ftrace_call_addr() for ARM 64 expects a
|
||||
valid address to kernel text. If the addr read from the mcount_loc section
|
||||
is invalid, it must not call ftrace_call_addr(). Move the addr check
|
||||
before calling ftrace_call_addr() in ftrace_process_locs().
|
||||
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Mark Brown <broonie@kernel.org>
|
||||
Link: https://lore.kernel.org/20250225182054.290128736@goodmis.org
|
||||
Fixes: ef378c3b8233 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
|
||||
Reported-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Reported-by: "Arnd Bergmann" <arnd@arndb.de>
|
||||
Tested-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Closes: https://lore.kernel.org/all/20250225025631.GA271248@ax162/
|
||||
Closes: https://lore.kernel.org/all/91523154-072b-437b-bbdc-0b70e9783fd0@app.fastmail.com/
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
||||
index 877f943832c9..59069b58fcd4 100644
|
||||
--- a/kernel/trace/ftrace.c
|
||||
+++ b/kernel/trace/ftrace.c
|
||||
@@ -7112,7 +7112,9 @@ static int ftrace_process_locs(struct module *mod,
|
||||
pg = start_pg;
|
||||
while (p < end) {
|
||||
unsigned long end_offset;
|
||||
- addr = ftrace_call_adjust(*p++);
|
||||
+
|
||||
+ addr = *p++;
|
||||
+
|
||||
/*
|
||||
* Some architecture linkers will pad between
|
||||
* the different mcount_loc sections of different
|
||||
@@ -7124,6 +7126,8 @@ static int ftrace_process_locs(struct module *mod,
|
||||
continue;
|
||||
}
|
||||
|
||||
+ addr = ftrace_call_adjust(addr);
|
||||
+
|
||||
end_offset = (pg->index+1) * sizeof(pg->records[0]);
|
||||
if (end_offset > PAGE_SIZE << pg->order) {
|
||||
/* We should have allocated enough */
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,85 @@
|
||||
From 4460650d8c24b8689e42d47abeff7fe520f911a3 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:56:25 +0200
|
||||
Subject: [PATCH] ftrace: Check against is_kernel_text() instead of
|
||||
kaslr_offset()
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit da0f622b344be769ed61e7c1caf95cd0cdb47964
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 25 13:20:06 2025 -0500
|
||||
|
||||
ftrace: Check against is_kernel_text() instead of kaslr_offset()
|
||||
|
||||
As kaslr_offset() is architecture dependent and also may not be defined by
|
||||
all architectures, when zeroing out unused weak functions, do not check
|
||||
against kaslr_offset(), but instead check if the address is within the
|
||||
kernel text sections. If KASLR added a shift to the zeroed out function,
|
||||
it would still not be located in the kernel text. This is a more robust
|
||||
way to test if the text is valid or not.
|
||||
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: "Arnd Bergmann" <arnd@arndb.de>
|
||||
Link: https://lore.kernel.org/20250225182054.471759017@goodmis.org
|
||||
Fixes: ef378c3b8233 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
|
||||
Reported-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Reported-by: Mark Brown <broonie@kernel.org>
|
||||
Tested-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Closes: https://lore.kernel.org/all/20250224180805.GA1536711@ax162/
|
||||
Closes: https://lore.kernel.org/all/5225b07b-a9b2-4558-9d5f-aa60b19f6317@sirena.org.uk/
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
|
||||
index 59069b58fcd4..63ed9688f491 100644
|
||||
--- a/kernel/trace/ftrace.c
|
||||
+++ b/kernel/trace/ftrace.c
|
||||
@@ -7055,7 +7055,6 @@ static int ftrace_process_locs(struct module *mod,
|
||||
unsigned long count;
|
||||
unsigned long *p;
|
||||
unsigned long addr;
|
||||
- unsigned long kaslr;
|
||||
unsigned long flags = 0; /* Shut up gcc */
|
||||
unsigned long pages;
|
||||
int ret = -ENOMEM;
|
||||
@@ -7105,9 +7104,6 @@ static int ftrace_process_locs(struct module *mod,
|
||||
ftrace_pages->next = start_pg;
|
||||
}
|
||||
|
||||
- /* For zeroed locations that were shifted for core kernel */
|
||||
- kaslr = !mod ? kaslr_offset() : 0;
|
||||
-
|
||||
p = start;
|
||||
pg = start_pg;
|
||||
while (p < end) {
|
||||
@@ -7121,7 +7117,18 @@ static int ftrace_process_locs(struct module *mod,
|
||||
* object files to satisfy alignments.
|
||||
* Skip any NULL pointers.
|
||||
*/
|
||||
- if (!addr || addr == kaslr) {
|
||||
+ if (!addr) {
|
||||
+ skipped++;
|
||||
+ continue;
|
||||
+ }
|
||||
+
|
||||
+ /*
|
||||
+ * If this is core kernel, make sure the address is in core
|
||||
+ * or inittext, as weak functions get zeroed and KASLR can
|
||||
+ * move them to something other than zero. It just will not
|
||||
+ * move it to an area where kernel text is.
|
||||
+ */
|
||||
+ if (!mod && !(is_kernel_text(addr) || is_kernel_inittext(addr))) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,67 @@
|
||||
From 5c8bd640b0ee1f1e0d7137f122996180f9bd5590 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:56:27 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Use normal sort if theres no relocs in the
|
||||
mcount section
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 46514b3c2c17c67cefe84b0c1a59e0aaf6093131
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 25 13:20:07 2025 -0500
|
||||
|
||||
scripts/sorttable: Use normal sort if theres no relocs in the mcount section
|
||||
|
||||
When ARM 64 is compiled with gcc, the mcount_loc section will be filled
|
||||
with zeros and the addresses will be located in the Elf_Rela sections. To
|
||||
sort the mcount_loc section, the addresses from the Elf_Rela need to be
|
||||
placed into an array and that is sorted.
|
||||
|
||||
But when ARM 64 is compiled with clang, it does it the same way as other
|
||||
architectures and leaves the addresses as is in the mcount_loc section.
|
||||
|
||||
To handle both cases, ARM 64 will first try to sort the Elf_Rela section,
|
||||
and if it doesn't find any functions, it will then fall back to the
|
||||
sorting of the addresses in the mcount_loc section itself.
|
||||
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: Mark Brown <broonie@kernel.org>
|
||||
Link: https://lore.kernel.org/20250225182054.648398403@goodmis.org
|
||||
Fixes: b3d09d06e052 ("arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64")
|
||||
Reported-by: "Arnd Bergmann" <arnd@arndb.de>
|
||||
Tested-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Closes: https://lore.kernel.org/all/893cd8f1-8585-4d25-bf0f-4197bf872465@app.fastmail.com/
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 23c7e0e6c024..07ad8116bc8d 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -827,9 +827,14 @@ static void *sort_mcount_loc(void *arg)
|
||||
pthread_exit(m_err);
|
||||
}
|
||||
|
||||
- if (sort_reloc)
|
||||
+ if (sort_reloc) {
|
||||
count = fill_relocs(vals, size, ehdr, emloc->start_mcount_loc);
|
||||
- else
|
||||
+ /* gcc may use relocs to save the addresses, but clang does not. */
|
||||
+ if (!count) {
|
||||
+ count = fill_addrs(vals, size, start_loc);
|
||||
+ sort_reloc = 0;
|
||||
+ }
|
||||
+ } else
|
||||
count = fill_addrs(vals, size, start_loc);
|
||||
|
||||
if (count < 0) {
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,73 @@
|
||||
From 7d08b5aa28b2bdd1d1bedbd6e8722bf3799dce71 Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:56:31 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Allow matches to functions before function
|
||||
entry
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit dc208c69c033d3caba0509da1ae065d2b5ff165f
|
||||
Author: Steven Rostedt <rostedt@goodmis.org>
|
||||
Date: Tue Feb 25 13:20:08 2025 -0500
|
||||
|
||||
scripts/sorttable: Allow matches to functions before function entry
|
||||
|
||||
ARM 64 uses -fpatchable-function-entry=4,2 which adds padding before the
|
||||
function and the addresses in the mcount_loc point there instead of the
|
||||
function entry that is returned by nm. In order to find a function from nm
|
||||
to make sure it's not an unused weak function, the entries in the
|
||||
mcount_loc section needs to match the entries from nm. Since it can be an
|
||||
instruction before the entry, add a before_func variable that ARM 64 can
|
||||
set to 8, and if the mcount_loc entry is within 8 bytes of the nm function
|
||||
entry, then it will be considered a match.
|
||||
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Mark Rutland <mark.rutland@arm.com>
|
||||
Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com>
|
||||
Cc: Andrew Morton <akpm@linux-foundation.org>
|
||||
Cc: Masahiro Yamada <masahiroy@kernel.org>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Will Deacon <will@kernel.org>
|
||||
Cc: "Arnd Bergmann" <arnd@arndb.de>
|
||||
Cc: Mark Brown <broonie@kernel.org>
|
||||
Link: https://lore.kernel.org/20250225182054.815536219@goodmis.org
|
||||
Fixes: ef378c3b82338 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
|
||||
Tested-by: Nathan Chancellor <nathan@kernel.org>
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 07ad8116bc8d..7b4b3714b1af 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -611,13 +611,16 @@ static int add_field(uint64_t addr, uint64_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
+/* Used for when mcount/fentry is before the function entry */
|
||||
+static int before_func;
|
||||
+
|
||||
/* Only return match if the address lies inside the function size */
|
||||
static int cmp_func_addr(const void *K, const void *A)
|
||||
{
|
||||
uint64_t key = *(const uint64_t *)K;
|
||||
const struct func_info *a = A;
|
||||
|
||||
- if (key < a->addr)
|
||||
+ if (key + before_func < a->addr)
|
||||
return -1;
|
||||
return key >= a->addr + a->size;
|
||||
}
|
||||
@@ -1253,6 +1256,8 @@ static int do_file(char const *const fname, void *addr)
|
||||
#ifdef MCOUNT_SORT_ENABLED
|
||||
sort_reloc = true;
|
||||
rela_type = 0x403;
|
||||
+ /* arm64 uses patchable function entry placing before function */
|
||||
+ before_func = 8;
|
||||
#endif
|
||||
/* fallthrough */
|
||||
case EM_386:
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
@ -0,0 +1,55 @@
|
||||
From 3436470d40a0906b91d65287931fc22524334dba Mon Sep 17 00:00:00 2001
|
||||
From: Jerome Marchand <jmarchan@redhat.com>
|
||||
Date: Tue, 2 Jun 2026 15:56:34 +0200
|
||||
Subject: [PATCH] scripts/sorttable: Fix endianness handling in build-time
|
||||
mcount sort
|
||||
|
||||
JIRA: https://redhat.atlassian.net/browse/RHEL-180193
|
||||
|
||||
commit 023f124a64174c47e18340ded7e2a39b96eb9523
|
||||
Author: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Date: Wed Apr 2 03:15:35 2025 +0200
|
||||
|
||||
scripts/sorttable: Fix endianness handling in build-time mcount sort
|
||||
|
||||
Kernel cross-compilation with BUILDTIME_MCOUNT_SORT produces zeroed
|
||||
mcount values if the build-host endianness does not match the ELF
|
||||
file endianness.
|
||||
|
||||
The mcount values array is converted from ELF file
|
||||
endianness to build-host endianness during initialization in
|
||||
fill_relocs()/fill_addrs(). Avoid extra conversion of these values during
|
||||
weak-function zeroing; otherwise, they do not match nm-parsed addresses
|
||||
and all mcount values are zeroed out.
|
||||
|
||||
Cc: Masami Hiramatsu <mhiramat@kernel.org>
|
||||
Cc: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Cc: Nathan Chancellor <nathan@kernel.org>
|
||||
Cc: Heiko Carstens <hca@linux.ibm.com>
|
||||
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
|
||||
Link: https://lore.kernel.org/patch.git-dca31444b0f1.your-ad-here.call-01743554658-ext-8692@work.hours
|
||||
Fixes: ef378c3b8233 ("scripts/sorttable: Zero out weak functions in mcount_loc table")
|
||||
Reported-by: Ilya Leoshkevich <iii@linux.ibm.com>
|
||||
Reported-by: Ihor Solodrai <ihor.solodrai@linux.dev>
|
||||
Closes: https://lore.kernel.org/all/your-ad-here.call-01743522822-ext-4975@work.hours/
|
||||
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
|
||||
Signed-off-by: Steven Rostedt (Google) <rostedt@goodmis.org>
|
||||
|
||||
Signed-off-by: Jerome Marchand <jmarchan@redhat.com>
|
||||
|
||||
diff --git a/scripts/sorttable.c b/scripts/sorttable.c
|
||||
index 7b4b3714b1af..deed676bfe38 100644
|
||||
--- a/scripts/sorttable.c
|
||||
+++ b/scripts/sorttable.c
|
||||
@@ -857,7 +857,7 @@ static void *sort_mcount_loc(void *arg)
|
||||
for (void *ptr = vals; ptr < vals + size; ptr += long_size) {
|
||||
uint64_t key;
|
||||
|
||||
- key = long_size == 4 ? r((uint32_t *)ptr) : r8((uint64_t *)ptr);
|
||||
+ key = long_size == 4 ? *(uint32_t *)ptr : *(uint64_t *)ptr;
|
||||
if (!find_func(key)) {
|
||||
if (long_size == 4)
|
||||
*(uint32_t *)ptr = 0;
|
||||
--
|
||||
2.50.1 (Apple Git-155)
|
||||
|
||||
204
kernel.spec
204
kernel.spec
@ -176,13 +176,13 @@ Summary: The Linux kernel
|
||||
%define specrpmversion 6.12.0
|
||||
%define specversion 6.12.0
|
||||
%define patchversion 6.12
|
||||
%define pkgrelease 211.7.1
|
||||
%define pkgrelease 211.22.1
|
||||
%define kversion 6
|
||||
%define tarfile_release 6.12.0-211.7.1.el10_2
|
||||
# This is needed to do merge window version magic
|
||||
%define patchlevel 12
|
||||
# This allows pkg_release to have configurable %%{?dist} tag
|
||||
%define specrelease 211.20.1%{?buildid}%{?dist}
|
||||
%define specrelease 211.22.1%{?buildid}%{?dist}
|
||||
# This defines the kabi tarball version
|
||||
%define kabiversion 6.12.0-211.7.1.el10_2
|
||||
|
||||
@ -1322,6 +1322,70 @@ Patch1284: 1284-smb-client-fix-oob-reads-parsing-symlink-error-response.patch
|
||||
Patch1285: 1285-sched-deadline-fix-dl-server-time-accounting.patch
|
||||
Patch1286: 1286-redhat-configs-automotive-disable-config-io-uring.patch
|
||||
Patch1287: 1287-rhel-kabi-dpll-adaptation.patch
|
||||
Patch1288: 1288-net-bonding-fix-use-after-free-in-bond-xmit-broadcast.patch
|
||||
Patch1289: 1289-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch
|
||||
Patch1290: 1290-ice-fix-stats-array-overflow-when-vf-requests-more-queues.patch
|
||||
Patch1291: 1291-s390-dasd-fix-gendisk-parent-after-copy-pair-swap.patch
|
||||
Patch1292: 1292-s390-dasd-move-quiesce-state-with-pprc-swap.patch
|
||||
Patch1293: 1293-s390-dasd-copy-detected-format-information-to-secondary-devi.patch
|
||||
Patch1294: 1294-nouveau-gsp-drop-warn-on-in-acpi-probes.patch
|
||||
Patch1295: 1295-can-raw-fix-ro-uniq-use-after-free-in-raw-rcv.patch
|
||||
Patch1296: 1296-erofs-add-gfp-noio-in-the-bio-completion-if-needed.patch
|
||||
Patch1297: 1297-alsa-6fire-fix-use-after-free-on-disconnect.patch
|
||||
Patch1298: 1298-ip6-tunnel-clear-skb2-cb-in-ip4ip6-err.patch
|
||||
Patch1299: 1299-ipv6-rpl-reserve-mac-len-headroom-when-recompressed-srh-grow.patch
|
||||
Patch1300: 1300-fs-constify-file-ptr-in-backing-file-accessor-helpers.patch
|
||||
Patch1301: 1301-lsm-split-the-notifier-code-out-into-lsm-notifier-c.patch
|
||||
Patch1302: 1302-lsm-split-the-init-code-out-into-lsm-init-c.patch
|
||||
Patch1303: 1303-lsm-consolidate-lsm-allowed-and-prepare-lsm-into-lsm-prepare.patch
|
||||
Patch1304: 1304-lsm-introduce-looping-macros-for-the-initialization-code.patch
|
||||
Patch1305: 1305-lsm-integrate-report-lsm-order-code-into-caller.patch
|
||||
Patch1306: 1306-lsm-integrate-lsm-early-cred-and-lsm-early-task-into-caller.patch
|
||||
Patch1307: 1307-lsm-rename-ordered-lsm-init-to-lsm-init-ordered.patch
|
||||
Patch1308: 1308-lsm-replace-the-name-field-with-a-pointer-to-the-lsm-id-stru.patch
|
||||
Patch1309: 1309-lsm-rename-the-lsm-order-variables-for-consistency.patch
|
||||
Patch1310: 1310-lsm-rework-lsm-active-cnt-and-lsm-idlist.patch
|
||||
Patch1311: 1311-lsm-get-rid-of-the-lsm-names-list-and-do-some-cleanup.patch
|
||||
Patch1312: 1312-lsm-rework-the-lsm-enable-disable-setter-getter-functions.patch
|
||||
Patch1313: 1313-lsm-rename-exists-ordered-lsm-to-lsm-order-exists.patch
|
||||
Patch1314: 1314-lsm-rename-rework-append-ordered-lsm-into-lsm-order-append.patch
|
||||
Patch1315: 1315-lsm-rename-rework-ordered-lsm-parse-to-lsm-order-parse.patch
|
||||
Patch1316: 1316-lsm-cleanup-the-lsm-blob-size-code.patch
|
||||
Patch1317: 1317-lsm-cleanup-initialize-lsm-and-rename-to-lsm-init-single.patch
|
||||
Patch1318: 1318-lsm-fold-lsm-init-ordered-into-security-init.patch
|
||||
Patch1319: 1319-lsm-add-tweak-function-header-comment-blocks-in-lsm-init-c.patch
|
||||
Patch1320: 1320-lsm-cleanup-the-debug-and-console-output-in-lsm-init-c.patch
|
||||
Patch1321: 1321-fs-prepare-for-adding-lsm-blob-to-backing-file.patch
|
||||
Patch1322: 1322-lsm-add-backing-file-lsm-hooks.patch
|
||||
Patch1323: 1323-selinux-fix-overlayfs-mmap-and-mprotect-access-checks.patch
|
||||
Patch1324: 1324-scripts-sorttable-fix-orc-sort-cmp-to-maintain-symmetry-and-.patch
|
||||
Patch1325: 1325-scripts-sorttable-remove-unused-macro-defines.patch
|
||||
Patch1326: 1326-scripts-sorttable-remove-unused-write-functions.patch
|
||||
Patch1327: 1327-scripts-sorttable-remove-unneeded-elf-rel.patch
|
||||
Patch1328: 1328-scripts-sorttable-have-the-orc-code-use-the-r-functions-to-r.patch
|
||||
Patch1329: 1329-scripts-sorttable-make-compare-extable-into-two-functions.patch
|
||||
Patch1330: 1330-scripts-sorttable-convert-elf-ehdr-to-union.patch
|
||||
Patch1331: 1331-scripts-sorttable-replace-elf-shdr-macro-with-a-union.patch
|
||||
Patch1332: 1332-scripts-sorttable-convert-elf-sym-macro-over-to-a-union.patch
|
||||
Patch1333: 1333-scripts-sorttable-add-helper-functions-for-elf-ehdr.patch
|
||||
Patch1334: 1334-scripts-sorttable-add-helper-functions-for-elf-shdr.patch
|
||||
Patch1335: 1335-scripts-sorttable-add-helper-functions-for-elf-sym.patch
|
||||
Patch1336: 1336-scripts-sorttable-use-uint64-t-for-mcount-sorting.patch
|
||||
Patch1337: 1337-scripts-sorttable-move-code-from-sorttable-h-into-sorttable-.patch
|
||||
Patch1338: 1338-scripts-sorttable-get-start-stop-mcount-loc-from-elf-file-di.patch
|
||||
Patch1339: 1339-scripts-sorttable-use-a-structure-of-function-pointers-for-e.patch
|
||||
Patch1340: 1340-arm64-scripts-sorttable-implement-sorting-mcount-loc-at-boot.patch
|
||||
Patch1341: 1341-scripts-sorttable-have-mcount-rela-sort-use-direct-values.patch
|
||||
Patch1342: 1342-scripts-sorttable-always-use-an-array-for-the-mcount-loc-sor.patch
|
||||
Patch1343: 1343-scripts-sorttable-zero-out-weak-functions-in-mcount-loc-tabl.patch
|
||||
Patch1344: 1344-ftrace-update-the-mcount-loc-check-of-skipped-entries.patch
|
||||
Patch1345: 1345-ftrace-have-ftrace-pages-output-reflect-freed-pages.patch
|
||||
Patch1346: 1346-ftrace-do-not-over-allocate-ftrace-memory.patch
|
||||
Patch1347: 1347-ftrace-test-mcount-loc-addr-before-calling-ftrace-call-addr.patch
|
||||
Patch1348: 1348-ftrace-check-against-is-kernel-text-instead-of-kaslr-offset.patch
|
||||
Patch1349: 1349-scripts-sorttable-use-normal-sort-if-theres-no-relocs-in-the.patch
|
||||
Patch1350: 1350-scripts-sorttable-allow-matches-to-functions-before-function.patch
|
||||
Patch1351: 1351-scripts-sorttable-fix-endianness-handling-in-build-time-mcou.patch
|
||||
# END OF PATCH DEFINITIONS
|
||||
|
||||
%description
|
||||
@ -2366,6 +2430,70 @@ ApplyPatch 1284-smb-client-fix-oob-reads-parsing-symlink-error-response.patch
|
||||
ApplyPatch 1285-sched-deadline-fix-dl-server-time-accounting.patch
|
||||
ApplyPatch 1286-redhat-configs-automotive-disable-config-io-uring.patch
|
||||
ApplyPatch 1287-rhel-kabi-dpll-adaptation.patch
|
||||
ApplyPatch 1288-net-bonding-fix-use-after-free-in-bond-xmit-broadcast.patch
|
||||
ApplyPatch 1289-s390-pci-avoid-deadlock-between-pci-error-recovery-and-mlx5-.patch
|
||||
ApplyPatch 1290-ice-fix-stats-array-overflow-when-vf-requests-more-queues.patch
|
||||
ApplyPatch 1291-s390-dasd-fix-gendisk-parent-after-copy-pair-swap.patch
|
||||
ApplyPatch 1292-s390-dasd-move-quiesce-state-with-pprc-swap.patch
|
||||
ApplyPatch 1293-s390-dasd-copy-detected-format-information-to-secondary-devi.patch
|
||||
ApplyPatch 1294-nouveau-gsp-drop-warn-on-in-acpi-probes.patch
|
||||
ApplyPatch 1295-can-raw-fix-ro-uniq-use-after-free-in-raw-rcv.patch
|
||||
ApplyPatch 1296-erofs-add-gfp-noio-in-the-bio-completion-if-needed.patch
|
||||
ApplyPatch 1297-alsa-6fire-fix-use-after-free-on-disconnect.patch
|
||||
ApplyPatch 1298-ip6-tunnel-clear-skb2-cb-in-ip4ip6-err.patch
|
||||
ApplyPatch 1299-ipv6-rpl-reserve-mac-len-headroom-when-recompressed-srh-grow.patch
|
||||
ApplyPatch 1300-fs-constify-file-ptr-in-backing-file-accessor-helpers.patch
|
||||
ApplyPatch 1301-lsm-split-the-notifier-code-out-into-lsm-notifier-c.patch
|
||||
ApplyPatch 1302-lsm-split-the-init-code-out-into-lsm-init-c.patch
|
||||
ApplyPatch 1303-lsm-consolidate-lsm-allowed-and-prepare-lsm-into-lsm-prepare.patch
|
||||
ApplyPatch 1304-lsm-introduce-looping-macros-for-the-initialization-code.patch
|
||||
ApplyPatch 1305-lsm-integrate-report-lsm-order-code-into-caller.patch
|
||||
ApplyPatch 1306-lsm-integrate-lsm-early-cred-and-lsm-early-task-into-caller.patch
|
||||
ApplyPatch 1307-lsm-rename-ordered-lsm-init-to-lsm-init-ordered.patch
|
||||
ApplyPatch 1308-lsm-replace-the-name-field-with-a-pointer-to-the-lsm-id-stru.patch
|
||||
ApplyPatch 1309-lsm-rename-the-lsm-order-variables-for-consistency.patch
|
||||
ApplyPatch 1310-lsm-rework-lsm-active-cnt-and-lsm-idlist.patch
|
||||
ApplyPatch 1311-lsm-get-rid-of-the-lsm-names-list-and-do-some-cleanup.patch
|
||||
ApplyPatch 1312-lsm-rework-the-lsm-enable-disable-setter-getter-functions.patch
|
||||
ApplyPatch 1313-lsm-rename-exists-ordered-lsm-to-lsm-order-exists.patch
|
||||
ApplyPatch 1314-lsm-rename-rework-append-ordered-lsm-into-lsm-order-append.patch
|
||||
ApplyPatch 1315-lsm-rename-rework-ordered-lsm-parse-to-lsm-order-parse.patch
|
||||
ApplyPatch 1316-lsm-cleanup-the-lsm-blob-size-code.patch
|
||||
ApplyPatch 1317-lsm-cleanup-initialize-lsm-and-rename-to-lsm-init-single.patch
|
||||
ApplyPatch 1318-lsm-fold-lsm-init-ordered-into-security-init.patch
|
||||
ApplyPatch 1319-lsm-add-tweak-function-header-comment-blocks-in-lsm-init-c.patch
|
||||
ApplyPatch 1320-lsm-cleanup-the-debug-and-console-output-in-lsm-init-c.patch
|
||||
ApplyPatch 1321-fs-prepare-for-adding-lsm-blob-to-backing-file.patch
|
||||
ApplyPatch 1322-lsm-add-backing-file-lsm-hooks.patch
|
||||
ApplyPatch 1323-selinux-fix-overlayfs-mmap-and-mprotect-access-checks.patch
|
||||
ApplyPatch 1324-scripts-sorttable-fix-orc-sort-cmp-to-maintain-symmetry-and-.patch
|
||||
ApplyPatch 1325-scripts-sorttable-remove-unused-macro-defines.patch
|
||||
ApplyPatch 1326-scripts-sorttable-remove-unused-write-functions.patch
|
||||
ApplyPatch 1327-scripts-sorttable-remove-unneeded-elf-rel.patch
|
||||
ApplyPatch 1328-scripts-sorttable-have-the-orc-code-use-the-r-functions-to-r.patch
|
||||
ApplyPatch 1329-scripts-sorttable-make-compare-extable-into-two-functions.patch
|
||||
ApplyPatch 1330-scripts-sorttable-convert-elf-ehdr-to-union.patch
|
||||
ApplyPatch 1331-scripts-sorttable-replace-elf-shdr-macro-with-a-union.patch
|
||||
ApplyPatch 1332-scripts-sorttable-convert-elf-sym-macro-over-to-a-union.patch
|
||||
ApplyPatch 1333-scripts-sorttable-add-helper-functions-for-elf-ehdr.patch
|
||||
ApplyPatch 1334-scripts-sorttable-add-helper-functions-for-elf-shdr.patch
|
||||
ApplyPatch 1335-scripts-sorttable-add-helper-functions-for-elf-sym.patch
|
||||
ApplyPatch 1336-scripts-sorttable-use-uint64-t-for-mcount-sorting.patch
|
||||
ApplyPatch 1337-scripts-sorttable-move-code-from-sorttable-h-into-sorttable-.patch
|
||||
ApplyPatch 1338-scripts-sorttable-get-start-stop-mcount-loc-from-elf-file-di.patch
|
||||
ApplyPatch 1339-scripts-sorttable-use-a-structure-of-function-pointers-for-e.patch
|
||||
ApplyPatch 1340-arm64-scripts-sorttable-implement-sorting-mcount-loc-at-boot.patch
|
||||
ApplyPatch 1341-scripts-sorttable-have-mcount-rela-sort-use-direct-values.patch
|
||||
ApplyPatch 1342-scripts-sorttable-always-use-an-array-for-the-mcount-loc-sor.patch
|
||||
ApplyPatch 1343-scripts-sorttable-zero-out-weak-functions-in-mcount-loc-tabl.patch
|
||||
ApplyPatch 1344-ftrace-update-the-mcount-loc-check-of-skipped-entries.patch
|
||||
ApplyPatch 1345-ftrace-have-ftrace-pages-output-reflect-freed-pages.patch
|
||||
ApplyPatch 1346-ftrace-do-not-over-allocate-ftrace-memory.patch
|
||||
ApplyPatch 1347-ftrace-test-mcount-loc-addr-before-calling-ftrace-call-addr.patch
|
||||
ApplyPatch 1348-ftrace-check-against-is-kernel-text-instead-of-kaslr-offset.patch
|
||||
ApplyPatch 1349-scripts-sorttable-use-normal-sort-if-theres-no-relocs-in-the.patch
|
||||
ApplyPatch 1350-scripts-sorttable-allow-matches-to-functions-before-function.patch
|
||||
ApplyPatch 1351-scripts-sorttable-fix-endianness-handling-in-build-time-mcou.patch
|
||||
# END OF PATCH APPLICATIONS
|
||||
|
||||
# Any further pre-build tree manipulations happen here.
|
||||
@ -4870,6 +4998,78 @@ fi\
|
||||
#
|
||||
#
|
||||
%changelog
|
||||
* Wed Jun 11 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 6.12.0-211.22.1
|
||||
- Recreate RHEL 6.12.0-211.22.1 from CentOS Stream 10 and upstream stable backports (1288-1352)
|
||||
- RHEL changelog for 211.21.1..211.22.1 follows:
|
||||
|
||||
* Wed Jun 10 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.22.1.el10_2]
|
||||
- scripts/sorttable: Fix endianness handling in build-time mcount sort (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Allow matches to functions before function entry (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Use normal sort if theres no relocs in the mcount section (Jerome Marchand) [RHEL-180932]
|
||||
- ftrace: Check against is_kernel_text() instead of kaslr_offset() (Jerome Marchand) [RHEL-180932]
|
||||
- ftrace: Test mcount_loc addr before calling ftrace_call_addr() (Jerome Marchand) [RHEL-180932]
|
||||
- ftrace: Do not over-allocate ftrace memory (Jerome Marchand) [RHEL-180932]
|
||||
- ftrace: Have ftrace pages output reflect freed pages (Jerome Marchand) [RHEL-180932]
|
||||
- ftrace: Update the mcount_loc check of skipped entries (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Zero out weak functions in mcount_loc table (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Always use an array for the mcount_loc sorting (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Have mcount rela sort use direct values (Jerome Marchand) [RHEL-180932]
|
||||
- arm64: scripts/sorttable: Implement sorting mcount_loc at boot for arm64 (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Use a structure of function pointers for elf helpers (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Get start/stop_mcount_loc from ELF file directly (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Move code from sorttable.h into sorttable.c (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Use uint64_t for mcount sorting (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Add helper functions for Elf_Sym (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Add helper functions for Elf_Shdr (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Add helper functions for Elf_Ehdr (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Convert Elf_Sym MACRO over to a union (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Replace Elf_Shdr Macro with a union (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Convert Elf_Ehdr to union (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Make compare_extable() into two functions (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Have the ORC code use the _r() functions to read (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Remove unneeded Elf_Rel (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Remove unused write functions (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: Remove unused macro defines (Jerome Marchand) [RHEL-180932]
|
||||
- scripts/sorttable: fix orc_sort_cmp() to maintain symmetry and transitivity (Jerome Marchand) [RHEL-180932]
|
||||
- selinux: fix overlayfs mmap() and mprotect() access checks (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: add backing_file LSM hooks (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- fs: prepare for adding LSM blob to backing_file (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: cleanup the debug and console output in lsm_init.c (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: add/tweak function header comment blocks in lsm_init.c (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: fold lsm_init_ordered() into security_init() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: cleanup initialize_lsm() and rename to lsm_init_single() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: cleanup the LSM blob size code (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rename/rework ordered_lsm_parse() to lsm_order_parse() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rename/rework append_ordered_lsm() into lsm_order_append() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rename exists_ordered_lsm() to lsm_order_exists() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rework the LSM enable/disable setter/getter functions (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: get rid of the lsm_names list and do some cleanup (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rework lsm_active_cnt and lsm_idlist[] (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rename the lsm order variables for consistency (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: replace the name field with a pointer to the lsm_id struct (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: rename ordered_lsm_init() to lsm_init_ordered() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: integrate lsm_early_cred() and lsm_early_task() into caller (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: integrate report_lsm_order() code into caller (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: introduce looping macros for the initialization code (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: consolidate lsm_allowed() and prepare_lsm() into lsm_prepare() (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: split the init code out into lsm_init.c (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- lsm: split the notifier code out into lsm_notifier.c (Ondrej Mosnacek) [RHEL-179437] {CVE-2026-46054}
|
||||
- fs: constify file ptr in backing_file accessor helpers (Ondrej Mosnacek) [RHEL-179437]
|
||||
- ipv6: rpl: reserve mac_len headroom when recompressed SRH grows (Antoine Tenart) [RHEL-178413] {CVE-2026-43501}
|
||||
- ip6_tunnel: clear skb2->cb[] in ip4ip6_err() (Guillaume Nault) [RHEL-172651] {CVE-2026-43037}
|
||||
- ALSA: 6fire: fix use-after-free on disconnect (CKI Backport Bot) [RHEL-172973] {CVE-2026-31581}
|
||||
- erofs: add GFP_NOIO in the bio completion if needed (CKI Backport Bot) [RHEL-171686] {CVE-2026-31467}
|
||||
- can: raw: fix ro->uniq use-after-free in raw_rcv() (CKI Backport Bot) [RHEL-170764] {CVE-2026-31532}
|
||||
- nouveau/gsp: drop WARN_ON in ACPI probes (Gary Guo) [RHEL-167788]
|
||||
|
||||
* Thu Jun 04 2026 CKI KWF Bot <cki-ci-bot+kwf-gitlab-com@redhat.com> [6.12.0-211.21.1.el10_2]
|
||||
- s390/dasd: Copy detected format information to secondary device (Ramesh Chhetri) [RHEL-176473]
|
||||
- s390/dasd: Move quiesce state with pprc swap (Ramesh Chhetri) [RHEL-176473]
|
||||
- s390/dasd: Fix gendisk parent after copy pair swap (Ramesh Chhetri) [RHEL-176473]
|
||||
- ice: fix stats array overflow when VF requests more queues (Michal Schmidt) [RHEL-177518]
|
||||
- s390/pci: Avoid deadlock between PCI error recovery and mlx5 crdump (Mircea Dragan) [RHEL-166855]
|
||||
- net: bonding: fix use-after-free in bond_xmit_broadcast() (CKI Backport Bot) [RHEL-168073] {CVE-2026-31419}
|
||||
|
||||
* Sun Jun 07 2026 Andrew Lukoshko <alukoshko@almalinux.org> - 6.12.0-211.20.1
|
||||
- Recreate RHEL 6.12.0-211.20.1 from CentOS Stream 10 and upstream stable backports (1245-1287)
|
||||
- smb cifs.spnego now shipped by RHEL too; existing ahead-fix 1105 is identical (RHEL's redundant copy omitted)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user