From eb14d8850f8356b0b48d2a8708107599c359121c Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Thu, 2 Jul 2020 14:47:12 +0200 Subject: [PATCH] smbd: check for stale pid in get_lease_type() If leases_db_get() failed the leases_db record might have been cleaned up for stale processes. Check if the share-mode-entry owner is stale in this case and return a 0 lease state. In any other case, log a debug messages and panic. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14428 Signed-off-by: Ralph Boehme Autobuild-User(master): Stefan Metzmacher Autobuild-Date(master): Thu Jul 2 16:45:42 UTC 2020 on sn-devel-184 (backported from commit 05d4466a6d1ad048fa86aea09ec0a56a7b961369) [slow@samba.org: use share_mode_stale_pid() instead of share_entry_stale_pid()] [metze@samba.org: use file_id_string_tos() instead of file_id_str_buf()] --- source3/smbd/oplock.c | 29 +++++++++++++++++++++++++++-- 1 file changed, 27 insertions(+), 2 deletions(-) diff --git a/source3/smbd/oplock.c b/source3/smbd/oplock.c index 83539693b9c..bafd6c74c38 100644 --- a/source3/smbd/oplock.c +++ b/source3/smbd/oplock.c @@ -175,8 +175,10 @@ static void downgrade_file_oplock(files_struct *fsp) uint32_t get_lease_type(struct share_mode_data *d, struct share_mode_entry *e) { + struct GUID_txt_buf guid_strbuf; NTSTATUS status; uint32_t current_state; + int idx; if (e->op_type != LEASE_OPLOCK) { return map_oplock_to_lease_type(e->op_type); @@ -191,8 +193,31 @@ uint32_t get_lease_type(struct share_mode_data *d, NULL, /* breaking_to_required */ NULL, /* lease_version */ NULL); /* epoch */ - SMB_ASSERT(NT_STATUS_IS_OK(status)); - return current_state; + if (NT_STATUS_IS_OK(status)) { + return current_state; + } + + for (idx = 0; idx < d->num_share_modes; idx++) { + struct share_mode_entry *_e = &d->share_modes[idx]; + + if (_e->share_file_id == e->share_file_id) { + break; + } + } + SMB_ASSERT(idx < d->num_share_modes); + + if (share_mode_stale_pid(d, idx)) { + return 0; + } + DBG_ERR("leases_db_get for client_guid [%s] " + "lease_key [%"PRIu64"/%"PRIu64"] " + "file_id [%s] failed: %s\n", + GUID_buf_string(&e->client_guid, &guid_strbuf), + e->lease_key.data[0], + e->lease_key.data[1], + file_id_string_tos(&d->id), + nt_errstr(status)); + smb_panic("leases_db_get() failed"); } /**************************************************************************** -- 2.47.2