Difference between
modified post b1c71ad by Anonymous on Thu 29th Feb 2024 15:59
original post bcf61 by Anonymous on Thu 29th Feb 2024 13:09
Download diff
Show
old version |
new version |
both versions
| 1 | 1 | diff --git a/daemon/daemon_debug.c b/daemon/daemon_debug.c | |
| 2 | 2 | index 9941ce2..f7b521b 100644 | |
| 3 | 3 | --- a/daemon/daemon_debug.c | |
| 4 | 4 | +++ b/daemon/daemon_debug.c | |
| 5 | 5 | @@ -802,3 +802,63 @@ void print_nfs41_file_info( | |
| 6 | 6 | ||
| 7 | 7 | dprintf_out("%s={ %s }\n", label, buf); | |
| 8 | 8 | } | |
| 9 | 9 | + | |
| 10 | 10 | +#define NUM_RECENTLY_DELETED 64 | |
| 11 | 11 | +static struct | |
| 12 | 12 | +{ | |
| 13 | 13 | + SRWLOCK lock; | |
| 14 | 14 | + void *deleted_ptrs[NUM_RECENTLY_DELETED]; | |
| 15 | 15 | + size_t deleted_index; | |
| 16 | 16 | +} ptr_recently_deleted_data = { | |
| 17 | 17 | + .lock = SRWLOCK_INIT, | |
| 18 | 18 | +}; | |
| 19 | 19 | + | |
| 20 | 20 | +bool debug_ptr_was_recently_deleted(void *in_ptr) | |
| 21 | 21 | +{ | |
| 22 | 22 | + size_t i; | |
| 23 | 23 | + bool_t res = false; | |
| 24 | 24 | + | |
| 25 | 25 | + AcquireSRWLockShared(&ptr_recently_deleted_data.lock); | |
| 26 | 26 | + for (i=0 ; i < NUM_RECENTLY_DELETED ; i++) { | |
| 27 | 27 | + if (ptr_recently_deleted_data.deleted_ptrs[i] == in_ptr) { | |
| 28 | 28 | + res = true; | |
| 29 | 29 | + break; | |
| 30 | 30 | + } | |
| 31 | 31 | + } | |
| 32 | 32 | + ReleaseSRWLockShared(&ptr_recently_deleted_data.lock); | |
| 33 | 33 | + return res; | |
| 34 | 34 | +} | |
| 35 | 35 | + | |
| 36 | 36 | +void debug_ptr_add_recently_deleted(void *in_ptr) | |
| 37 | 37 | +{ | |
| 38 | 38 | + size_t i; | |
| 39 | 39 | + | |
| 40 | 40 | + AcquireSRWLockExclusive(&ptr_recently_deleted_data.lock); | |
| 41 | 41 | + i = ptr_recently_deleted_data.deleted_index++ % NUM_RECENTLY_DELETED; | |
| 42 | 42 | + ptr_recently_deleted_data.deleted_ptrs[i] = in_ptr; | |
| 43 | 43 | + ReleaseSRWLockExclusive(&ptr_recently_deleted_data.lock); | |
| 44 | 44 | +} | |
| 45 | 45 | + | |
| 46 | 46 | +#define NUM_DELAY_FREE 2048 | |
| 47 | 47 | +static struct | |
| 48 | 48 | +{ | |
| 49 | 49 | + SRWLOCK lock; | |
| 50 | 50 | + void *free_ptrs[NUM_DELAY_FREE]; | |
| 51 | 51 | + size_t free_ptrs_index; | |
| 52 | 52 | +} debug_delay_free_data = { | |
| 53 | 53 | + .lock = SRWLOCK_INIT, | |
| 54 | 54 | +}; | |
| 55 | 55 | + | |
| 56 | 56 | +void debug_delayed_free(void *in_ptr) | |
| 57 | 57 | +{ | |
| 58 | 58 | + size_t i; | |
| 59 | 59 | + | |
| 60 | 60 | + AcquireSRWLockExclusive(&debug_delay_free_data.lock); | |
| 61 | 61 | + i = debug_delay_free_data.free_ptrs_index++ % NUM_DELAY_FREE; | |
| 62 | 62 | + | |
| 63 | 63 | + if (debug_delay_free_data.free_ptrs[i]) | |
| 64 | 64 | + free(debug_delay_free_data.free_ptrs[i]); | |
| 65 | 65 | + | |
| 66 | 66 | + debug_delay_free_data.free_ptrs[i] = in_ptr; | |
| 67 | 67 | + ReleaseSRWLockExclusive(&debug_delay_free_data.lock); | |
| 68 | 68 | +} | |
| 69 | 69 | diff --git a/daemon/daemon_debug.h b/daemon/daemon_debug.h | |
| 70 | 70 | index 1b693e3..2bb42b6 100644 | |
| 71 | 71 | --- a/daemon/daemon_debug.h | |
| 72 | 72 | +++ b/daemon/daemon_debug.h | |
| 73 | 73 | @@ -31,6 +31,7 @@ | |
| 74 | 74 | #else | |
| 75 | 75 | # include <stdlib.h> | |
| 76 | 76 | #endif | |
| 77 | 77 | +#include <stdbool.h> | |
| 78 | 78 | ||
| 79 | 79 | #define DEFAULT_DEBUG_LEVEL 1 | |
| 80 | 80 | ||
| 81 | 81 | @@ -118,4 +119,9 @@ const char* pnfs_iomode_string(enum pnfs_iomode iomode); | |
| 82 | 82 | void dprint_layout(int level, const struct __pnfs_file_layout *layout); | |
| 83 | 83 | void dprint_device(int level, const struct __pnfs_file_device *device); | |
| 84 | 84 | ||
| 85 | 85 | +bool debug_ptr_was_recently_deleted(void *in_ptr); | |
| 86 | 86 | +void debug_ptr_add_recently_deleted(void *in_ptr); | |
| 87 | 87 | + | |
| 88 | 88 | +void debug_delayed_free(void *in_ptr); | |
| 89 | 89 | + | |
| 90 | 90 | #endif | |
| 91 | 91 | diff --git a/daemon/getattr.c b/daemon/getattr.c | |
| 92 | 92 | index 3c69db3..9d8db95 100644 | |
| 93 | 93 | --- a/daemon/getattr.c | |
| 94 | 94 | +++ b/daemon/getattr.c | |
| 95 | 95 | @@ -68,6 +68,13 @@ static int parse_getattr(unsigned char *buffer, uint32_t length, nfs41_upcall *u | |
| 96 | 96 | goto out; | |
| 97 | 97 | } | |
| 98 | 98 | ||
| 99 | 99 | + if (debug_ptr_was_recently_deleted(upcall->state_ref)) { | |
| 100 | 100 | + eprintf("parse_getattr: upcall->state_ref(=0x%p) was " | |
| 101 | 101 | + "recently deleted\n", upcall->state_ref); | |
| 102 | 102 | + status = ERROR_INVALID_PARAMETER; | |
| 103 | 103 | + goto out; | |
| 104 | 104 | + } | |
| 105 | 105 | + | |
| 106 | 106 | EASSERT_IS_VALID_NON_NULL_PTR(upcall->state_ref); | |
| 107 | 107 | if (!DEBUG_IS_VALID_NON_NULL_PTR(upcall->state_ref)) { | |
| 108 | 108 | status = ERROR_INVALID_PARAMETER; | |
| 109 | 109 | diff --git a/daemon/nfs41.h b/daemon/nfs41.h | |
| 110 | 110 | index c8216dd..698e970 100644 | |
| 111 | 111 | --- a/daemon/nfs41.h | |
| 112 | 112 | +++ b/daemon/nfs41.h | |
| 113 | 113 | @@ -84,7 +84,7 @@ typedef struct __nfs41_server { | |
| 114 | 114 | nfs41_superblock_list superblocks; | |
| 115 | 115 | struct nfs41_name_cache *name_cache; | |
| 116 | 116 | struct list_entry entry; /* position in global server list */ | |
| 117 | 117 | - LONG ref_count; | |
| 118 | 118 | + __declspec(align(8)) volatile LONG ref_count; | |
| 119 | 119 | } nfs41_server; | |
| 120 | 120 | ||
| 121 | 121 | enum delegation_status { | |
| 122 | 122 | @@ -99,7 +99,7 @@ typedef struct __nfs41_delegation_state { | |
| 123 | 123 | nfs41_path_fh parent; | |
| 124 | 124 | nfs41_path_fh file; | |
| 125 | 125 | struct list_entry client_entry; /* entry in nfs41_client.delegations */ | |
| 126 | 126 | - LONG ref_count; | |
| 127 | 127 | + __declspec(align(8)) volatile LONG ref_count; | |
| 128 | 128 | ||
| 129 | 129 | enum delegation_status status; | |
| 130 | 130 | SRWLOCK lock; | |
| 131 | 131 | @@ -138,7 +138,7 @@ typedef struct __nfs41_open_state { | |
| 132 | 132 | struct __pnfs_layout_state *layout; | |
| 133 | 133 | struct list_entry client_entry; /* entry in nfs41_client.opens */ | |
| 134 | 134 | SRWLOCK lock; | |
| 135 | 135 | - LONG ref_count; | |
| 136 | 136 | + __declspec(align(8)) volatile LONG ref_count; | |
| 137 | 137 | uint32_t share_access; | |
| 138 | 138 | uint32_t share_deny; | |
| 139 | 139 | uint64_t pnfs_last_offset; /* for layoutcommit */ | |
| 140 | 140 | @@ -296,7 +296,7 @@ typedef struct __nfs41_root { | |
| 141 | 141 | struct list_entry clients; | |
| 142 | 142 | uint32_t wsize; | |
| 143 | 143 | uint32_t rsize; | |
| 144 | 144 | - LONG ref_count; | |
| 145 | 145 | + __declspec(align(8)) volatile LONG ref_count; | |
| 146 | 146 | uint32_t uid; | |
| 147 | 147 | uint32_t gid; | |
| 148 | 148 | DWORD sec_flavor; | |
| 149 | 149 | diff --git a/daemon/open.c b/daemon/open.c | |
| 150 | - | index 0732aa2..1b9ef26 100644 | |
| 150 | + | index 0732aa2..3f1e516 100644 | |
| 151 | 151 | --- a/daemon/open.c | |
| 152 | 152 | +++ b/daemon/open.c | |
| 153 | 153 | @@ -86,6 +86,10 @@ static void open_state_free( | |
| 154 | 154 | { | |
| 155 | 155 | struct list_entry *entry, *tmp; | |
| 156 | 156 | ||
| 157 | 157 | +#ifdef NFS41_DRIVER_STABILITY_HACKS | |
| 158 | 158 | + debug_ptr_add_recently_deleted(state); | |
| 159 | 159 | +#endif /* NFS41_DRIVER_STABILITY_HACKS */ | |
| 160 | 160 | + | |
| 161 | 161 | EASSERT(waitcriticalsection(&state->ea.lock) == TRUE); | |
| 162 | 162 | EASSERT(waitcriticalsection(&state->locks.lock) == TRUE); | |
| 163 | 163 | ||
| 164 | - | @@ -105,10 +109,13 @@ static void open_state_free( | |
| 164 | + | @@ -105,10 +109,14 @@ static void open_state_free( | |
| 165 | 165 | ||
| 166 | 166 | EASSERT(state->ref_count == 0); | |
| 167 | 167 | ||
| 168 | 168 | +#ifdef NFS41_DRIVER_STABILITY_HACKS | |
| 169 | + | + (void)memset(state, 0, sizeof(nfs41_open_state)); | |
| 169 | 170 | + debug_delayed_free(state); | |
| 170 | 171 | +#else | |
| 171 | 172 | free(state); | |
| 172 | 173 | +#endif /* NFS41_DRIVER_STABILITY_HACKS */ | |
| 173 | 174 | } | |
| 174 | 175 | ||
| 175 | 176 | - | |
| 176 | 177 | /* open state reference counting */ | |
| 177 | 178 | void nfs41_open_state_ref( | |
| 178 | 179 | IN nfs41_open_state *state) | |
| 179 | - | diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c | |
| 180 | + | diff --git a/daemon/upcall.c b/daemon/upcall.c | |
| 180 | - | index 52c633c..99e4187 100644 | |
| 181 | + | index 3a7047b..b35a8f9 100644 | |
| 181 | - | --- a/sys/nfs41_driver.c | |
| 182 | + | --- a/daemon/upcall.c | |
| 182 | - | +++ b/sys/nfs41_driver.c | |
| 183 | + | +++ b/daemon/upcall.c | |
| 183 | - | @@ -1364,7 +1364,56 @@ NTSTATUS handle_upcall( | |
| 184 | + | @@ -115,6 +115,18 @@ int upcall_parse( | |
| 184 | - | ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength; | |
| 185 | + | eprintf("unrecognized upcall opcode %d!\n", upcall->opcode); | |
| 185 | - | unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer; | |
| 186 | + | goto out; | |
| 186 | - | ||
| 187 | + | } | |
| 188 | + | + | |
| 187 | 189 | +#ifdef NFS41_DRIVER_STABILITY_HACKS | |
| 188 | - | + /* | |
| 190 | + | + if (upcall->state_ref != INVALID_HANDLE_VALUE) { | |
| 189 | - | + * Workaround for random crashes like this while compiling | |
| 191 | + | + if (upcall->state_ref->ref_count == 0) { | |
| 190 | - | + * the "gcc" compiler with a highly-parallel build. | |
| 192 | + | + eprintf("upcall->state_ref(=0x%p).ref_count == 0, " | |
| 191 | - | + * Stack trace usually looks like this: | |
| 193 | + | + "opcode %d!\n", upcall->state_ref, upcall->opcode); | |
| 192 | - | + * ---- snip ---- | |
| 194 | + | + status = ERROR_INTERNAL_ERROR; | |
| 193 | - | + * nt!SeTokenCanImpersonate+0x47 | |
| 195 | + | + goto out; | |
| 194 | - | + * nt!PsImpersonateClient+0x126 | |
| 196 | + | + } | |
| 195 | - | + * nt!SeImpersonateClientEx+0x35 | |
| 197 | + | + } | |
| 196 | - | + * nfs41_driver!handle_upcall+0x59 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1367] | |
| 198 | + | +#endif | |
| 197 | - | + * nfs41_driver!nfs41_upcall+0xe7 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1578] | |
| 199 | + | + | |
| 198 | - | + * nfs41_driver!nfs41_DevFcbXXXControlFile+0x128 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 2418] | |
| 200 | + | if (upcall->root_ref != INVALID_HANDLE_VALUE) | |
| 199 | - | + * nfs41_driver!RxXXXControlFileCallthru+0x76 [base\fs\rdr2\rdbss\ntdevfcb.c @ 130] | |
| 201 | + | nfs41_root_ref(upcall->root_ref); | |
| 200 | - | + * nfs41_driver!RxCommonDevFCBIoCtl+0x58 [base\fs\rdr2\rdbss\ntdevfcb.c @ 491] | |
| 202 | + | if (upcall->state_ref != INVALID_HANDLE_VALUE) | |
| 201 | - | + * nfs41_driver!RxFsdCommonDispatch+0x442 [base\fs\rdr2\rdbss\ntfsd.c @ 848] | |
| 203 | + | diff --git a/sys/nfs41_driver.c b/sys/nfs41_driver.c | |
| 202 | - | + * nfs41_driver!RxFsdDispatch+0xfd [base\fs\rdr2\rdbss\ntfsd.c @ 442] | |
| 204 | + | index 52c633c..99e4187 100644 | |
| 203 | - | + * nfs41_driver!nfs41_FsdDispatch+0x67 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 6863] | |
| 205 | + | --- a/sys/nfs41_driver.c | |
| 204 | - | + * nt!IofCallDriver+0x55 | |
| 206 | + | +++ b/sys/nfs41_driver.c | |
| 205 | - | + * mup!MupiCallUncProvider+0xb8 | |
| 207 | + | @@ -1364,7 +1364,56 @@ NTSTATUS handle_upcall( | |
| 206 | - | + * mup!MupStateMachine+0x59 | |
| 208 | + | ULONG cbOut = LowIoContext->ParamsFor.IoCtl.OutputBufferLength; | |
| 207 | - | + * mup!MupFsdIrpPassThrough+0x17e | |
| 209 | + | unsigned char *pbOut = LowIoContext->ParamsFor.IoCtl.pOutputBuffer; | |
| 208 | - | + * nt!IofCallDriver+0x55 | |
| 210 | + | ||
| 209 | - | + * FLTMGR!FltpDispatch+0xd6 | |
| 211 | + | +#ifdef NFS41_DRIVER_STABILITY_HACKS | |
| 210 | - | + * nt!IofCallDriver+0x55 | |
| 212 | + | + /* | |
| 211 | - | + * nt!IopSynchronousServiceTail+0x34c | |
| 213 | + | + * Workaround for random crashes like this while compiling | |
| 212 | - | + * nt!IopXxxControlFile+0xd13 | |
| 214 | + | + * the "gcc" compiler with a highly-parallel build. | |
| 213 | - | + * nt!NtDeviceIoControlFile+0x56 | |
| 215 | + | + * Stack trace usually looks like this: | |
| 223 | 216 | + * ---- snip ---- | |
| 224 | - | + */ | |
| 217 | + | + * nt!SeTokenCanImpersonate+0x47 | |
| 225 | - | + __try { | |
| 218 | + | + * nt!PsImpersonateClient+0x126 | |
| 226 | - | + status = SeImpersonateClientEx(entry->psec_ctx, NULL); | |
| 219 | + | + * nt!SeImpersonateClientEx+0x35 | |
| 227 | - | + } __except(EXCEPTION_EXECUTE_HANDLER) { | |
| 220 | + | + * nfs41_driver!handle_upcall+0x59 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1367] | |
| 228 | - | + NTSTATUS code; | |
| 221 | + | + * nfs41_driver!nfs41_upcall+0xe7 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 1578] | |
| 229 | - | + code = GetExceptionCode(); | |
| 222 | + | + * nfs41_driver!nfs41_DevFcbXXXControlFile+0x128 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 2418] | |
| 230 | - | + print_error("handle_upcall: Call to SeImpersonateClientEx() " | |
| 223 | + | + * nfs41_driver!RxXXXControlFileCallthru+0x76 [base\fs\rdr2\rdbss\ntdevfcb.c @ 130] | |
| 231 | - | + "failed due to exception 0x%0x\n", (int)code); | |
| 224 | + | + * nfs41_driver!RxCommonDevFCBIoCtl+0x58 [base\fs\rdr2\rdbss\ntdevfcb.c @ 491] | |
| 232 | - | + status = STATUS_INTERNAL_ERROR; | |
| 225 | + | + * nfs41_driver!RxFsdCommonDispatch+0x442 [base\fs\rdr2\rdbss\ntfsd.c @ 848] | |
| 233 | - | + } | |
| 226 | + | + * nfs41_driver!RxFsdDispatch+0xfd [base\fs\rdr2\rdbss\ntfsd.c @ 442] | |
| 234 | - | +#else | |
| 227 | + | + * nfs41_driver!nfs41_FsdDispatch+0x67 [C:\cygwin64\home\roland_mainz\work\msnfs41_uidmapping\ms-nfs41-client\sys\nfs41_driver.c @ 6863] | |
| 235 | - | status = SeImpersonateClientEx(entry->psec_ctx, NULL); | |
| 228 | + | + * nt!IofCallDriver+0x55 | |
| 236 | - | +#endif /* NFS41_DRIVER_STABILITY_HACKS */ | |
| 229 | + | + * mup!MupiCallUncProvider+0xb8 | |
| 237 | - | if (status != STATUS_SUCCESS) { | |
| 230 | + | + * mup!MupStateMachine+0x59 | |
| 238 | - | print_error("SeImpersonateClientEx failed %x\n", status); | |
| 231 | + | + * mup!MupFsdIrpPassThrough+0x17e | |
| 239 | - | goto out; | |
| 232 | + | + * nt!IofCallDriver+0x55 | |
| 240 | - | ||
| 233 | + | + * FLTMGR!FltpDispatch+0xd6 | |
| 241 | - | ||
| 234 | + | + * nt!IofCallDriver+0x55 | |
| 242 | - | ||
| 235 | + | + * nt!IopSynchronousServiceTail+0x34c | |
| 243 | - | ||
| 236 | + | + * nt!IopXxxControlFile+0xd13 | |
| 244 | - | ||
| 237 | + | + * nt!NtDeviceIoControlFile+0x56 | |
| 245 | - | ||
| 238 | + | + * nt!KiSystemServiceCopyEnd+0x25 | |
| 246 | - | ||
| 239 | + | + * ntdll!NtDeviceIoControlFile+0x14 | |
| 247 | - | ||
| 240 | + | + * KERNELBASE!DeviceIoControl+0x6b | |
| 248 | - | ||
| 241 | + | + * KERNEL32!DeviceIoControlImplementation+0x81 | |
| 249 | - | ||
| 242 | + | + * nfsd_debug+0xc7b14 | |
| 250 | - | ||
| 243 | + | + * nfsd_debug+0xc79fb | |
| 251 | - | ||
| 244 | + | + * nfsd_debug+0x171e80 | |
| 252 | - | ||
| 245 | + | + * KERNEL32!BaseThreadInitThunk+0x14 | |
| 253 | - | ||
| 246 | + | + * ntdll!RtlUserThreadStart+0x21 | |
| 254 | - | ||
| 247 | + | + * ---- snip ---- | |
| 255 | - | ||
| 248 | + | + */ | |
| 256 | - | ||
| 249 | + | + __try { | |
| 257 | - | ||
| 250 | + | + status = SeImpersonateClientEx(entry->psec_ctx, NULL); | |
| 258 | - | ||
| 251 | + | + } __except(EXCEPTION_EXECUTE_HANDLER) { | |
| 259 | - | ||
| 252 | + | + NTSTATUS code; | |
| 260 | - | ||
| 253 | + | + code = GetExceptionCode(); | |
| 261 | - | ||
| 254 | + | + print_error("handle_upcall: Call to SeImpersonateClientEx() " | |
| 262 | - | ||
| 255 | + | + "failed due to exception 0x%0x\n", (int)code); | |
| 263 | - | ||
| 256 | + | + status = STATUS_INTERNAL_ERROR; | |
| 264 | - | ||
| 257 | + | + } | |
| 265 | - | ||
| 258 | + | +#else | |
| 266 | - | ||
| 259 | + | status = SeImpersonateClientEx(entry->psec_ctx, NULL); | |
| 267 | - | ||
| 260 | + | +#endif /* NFS41_DRIVER_STABILITY_HACKS */ | |
| 268 | - | ||
| 261 | + | if (status != STATUS_SUCCESS) { | |
| 269 | - | ||
| 262 | + | print_error("SeImpersonateClientEx failed %x\n", status); | |
| 270 | - | ||
| 263 | + | goto out; | |
| 271 | 264 |
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.
nrubsig.kpaste.net RSS