Patch "fs: dlm: filter user dlm messages for kernel locks" has been added to the 5.10-stable tree

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This is a note to let you know that I've just added the patch titled

    fs: dlm: filter user dlm messages for kernel locks

to the 5.10-stable tree which can be found at:
    http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
     fs-dlm-filter-user-dlm-messages-for-kernel-locks.patch
and it can be found in the queue-5.10 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree,
please let <stable@xxxxxxxxxxxxxxx> know about it.



commit 9f2bf4d49d99a9ff46a7778fe50d9c70202fa2dc
Author: Alexander Aring <aahringo@xxxxxxxxxx>
Date:   Tue Nov 2 15:17:24 2021 -0400

    fs: dlm: filter user dlm messages for kernel locks
    
    [ Upstream commit 6c2e3bf68f3e5e5a647aa52be246d5f552d7496d ]
    
    This patch fixes the following crash by receiving a invalid message:
    
    [  160.672220] ==================================================================
    [  160.676206] BUG: KASAN: user-memory-access in dlm_user_add_ast+0xc3/0x370
    [  160.679659] Read of size 8 at addr 00000000deadbeef by task kworker/u32:13/319
    [  160.681447]
    [  160.681824] CPU: 10 PID: 319 Comm: kworker/u32:13 Not tainted 5.14.0-rc2+ #399
    [  160.683472] Hardware name: Red Hat KVM/RHEL-AV, BIOS 1.14.0-1.module+el8.6.0+12648+6ede71a5 04/01/2014
    [  160.685574] Workqueue: dlm_recv process_recv_sockets
    [  160.686721] Call Trace:
    [  160.687310]  dump_stack_lvl+0x56/0x6f
    [  160.688169]  ? dlm_user_add_ast+0xc3/0x370
    [  160.689116]  kasan_report.cold.14+0x116/0x11b
    [  160.690138]  ? dlm_user_add_ast+0xc3/0x370
    [  160.690832]  dlm_user_add_ast+0xc3/0x370
    [  160.691502]  _receive_unlock_reply+0x103/0x170
    [  160.692241]  _receive_message+0x11df/0x1ec0
    [  160.692926]  ? rcu_read_lock_sched_held+0xa1/0xd0
    [  160.693700]  ? rcu_read_lock_bh_held+0xb0/0xb0
    [  160.694427]  ? lock_acquire+0x175/0x400
    [  160.695058]  ? do_purge.isra.51+0x200/0x200
    [  160.695744]  ? lock_acquired+0x360/0x5d0
    [  160.696400]  ? lock_contended+0x6a0/0x6a0
    [  160.697055]  ? lock_release+0x21d/0x5e0
    [  160.697686]  ? lock_is_held_type+0xe0/0x110
    [  160.698352]  ? lock_is_held_type+0xe0/0x110
    [  160.699026]  ? ___might_sleep+0x1cc/0x1e0
    [  160.699698]  ? dlm_wait_requestqueue+0x94/0x140
    [  160.700451]  ? dlm_process_requestqueue+0x240/0x240
    [  160.701249]  ? down_write_killable+0x2b0/0x2b0
    [  160.701988]  ? do_raw_spin_unlock+0xa2/0x130
    [  160.702690]  dlm_receive_buffer+0x1a5/0x210
    [  160.703385]  dlm_process_incoming_buffer+0x726/0x9f0
    [  160.704210]  receive_from_sock+0x1c0/0x3b0
    [  160.704886]  ? dlm_tcp_shutdown+0x30/0x30
    [  160.705561]  ? lock_acquire+0x175/0x400
    [  160.706197]  ? rcu_read_lock_sched_held+0xa1/0xd0
    [  160.706941]  ? rcu_read_lock_bh_held+0xb0/0xb0
    [  160.707681]  process_recv_sockets+0x32/0x40
    [  160.708366]  process_one_work+0x55e/0xad0
    [  160.709045]  ? pwq_dec_nr_in_flight+0x110/0x110
    [  160.709820]  worker_thread+0x65/0x5e0
    [  160.710423]  ? process_one_work+0xad0/0xad0
    [  160.711087]  kthread+0x1ed/0x220
    [  160.711628]  ? set_kthread_struct+0x80/0x80
    [  160.712314]  ret_from_fork+0x22/0x30
    
    The issue is that we received a DLM message for a user lock but the
    destination lock is a kernel lock. Note that the address which is trying
    to derefence is 00000000deadbeef, which is in a kernel lock
    lkb->lkb_astparam, this field should never be derefenced by the DLM
    kernel stack. In case of a user lock lkb->lkb_astparam is lkb->lkb_ua
    (memory is shared by a union field). The struct lkb_ua will be handled
    by the DLM kernel stack but on a kernel lock it will contain invalid
    data and ends in most likely crashing the kernel.
    
    It can be reproduced with two cluster nodes.
    
    node 2:
    dlm_tool join test
    echo "862 fooobaar 1 2 1" > /sys/kernel/debug/dlm/test_locks
    echo "862 3 1" > /sys/kernel/debug/dlm/test_waiters
    
    node 1:
    dlm_tool join test
    
    python:
    foo = DLM(h_cmd=3, o_nextcmd=1, h_nodeid=1, h_lockspace=0x77222027, \
              m_type=7, m_flags=0x1, m_remid=0x862, m_result=0xFFFEFFFE)
    newFile = open("/sys/kernel/debug/dlm/comms/2/rawmsg", "wb")
    newFile.write(bytes(foo))
    
    Signed-off-by: Alexander Aring <aahringo@xxxxxxxxxx>
    Signed-off-by: David Teigland <teigland@xxxxxxxxxx>
    Signed-off-by: Sasha Levin <sashal@xxxxxxxxxx>

diff --git a/fs/dlm/lock.c b/fs/dlm/lock.c
index 002123efc6b05..1e9d8999b9390 100644
--- a/fs/dlm/lock.c
+++ b/fs/dlm/lock.c
@@ -3975,6 +3975,14 @@ static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
 	int from = ms->m_header.h_nodeid;
 	int error = 0;
 
+	/* currently mixing of user/kernel locks are not supported */
+	if (ms->m_flags & DLM_IFL_USER && ~lkb->lkb_flags & DLM_IFL_USER) {
+		log_error(lkb->lkb_resource->res_ls,
+			  "got user dlm message for a kernel lock");
+		error = -EINVAL;
+		goto out;
+	}
+
 	switch (ms->m_type) {
 	case DLM_MSG_CONVERT:
 	case DLM_MSG_UNLOCK:
@@ -4003,6 +4011,7 @@ static int validate_message(struct dlm_lkb *lkb, struct dlm_message *ms)
 		error = -EINVAL;
 	}
 
+out:
 	if (error)
 		log_error(lkb->lkb_resource->res_ls,
 			  "ignore invalid message %d from %d %x %x %x %d",



[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux