]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: check for stale pid in get_lease_type()
authorRalph Boehme <slow@samba.org>
Thu, 2 Jul 2020 12:47:12 +0000 (14:47 +0200)
committerKarolin Seeger <kseeger@samba.org>
Thu, 6 Aug 2020 12:18:21 +0000 (12:18 +0000)
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 <slow@samba.org>
Autobuild-User(master): Stefan Metzmacher <metze@samba.org>
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

index 83539693b9c7ecd010ffdb7a2039a174cbff5ab2..bafd6c74c383006151123669415b5194f032eeab 100644 (file)
@@ -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");
 }
 
 /****************************************************************************