00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include "obp.h"
00022
00023
00024
00025
00026
00027 #define GENERIC_ACCESS (GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE | GENERIC_ALL)
00028
00029
00030
00031
00032
00033
00034 extern KMUTANT ObpInitKillMutant;
00035
00036
00037
00038
00039
00040
NTSTATUS
00041
ObpIncrementHandleDataBase (
00042 IN
POBJECT_HEADER ObjectHeader,
00043 IN
PEPROCESS Process,
00044 OUT PULONG NewProcessHandleCount
00045 );
00046
00047
NTSTATUS
00048
ObpCaptureHandleInformation (
00049 IN OUT PSYSTEM_HANDLE_TABLE_ENTRY_INFO *HandleEntryInfo,
00050 IN HANDLE UniqueProcessId,
00051 IN PVOID HandleTableEntry,
00052 IN HANDLE HandleIndex,
00053 IN ULONG Length,
00054 IN OUT PULONG RequiredLength
00055 );
00056
00057
#ifdef ALLOC_PRAGMA
00058
#pragma alloc_text(PAGE,NtDuplicateObject)
00059
#pragma alloc_text(PAGE,ObGetHandleInformation)
00060
#pragma alloc_text(PAGE,ObpInsertHandleCount)
00061
#pragma alloc_text(PAGE,ObpIncrementHandleCount)
00062
#pragma alloc_text(PAGE,ObpIncrementUnnamedHandleCount)
00063
#pragma alloc_text(PAGE,ObpDecrementHandleCount)
00064
#pragma alloc_text(PAGE,ObpCreateHandle)
00065
#pragma alloc_text(PAGE,ObpCreateUnnamedHandle)
00066
#pragma alloc_text(PAGE,ObpIncrementHandleDataBase)
00067
#endif
00068
00069
00070
00071
00072
00073
00074
00075
00076
#ifdef MPSAFE_HANDLE_COUNT_CHECK
00077
00078
VOID
00079
FASTCALL
00080
ObpIncrPointerCount (
00081 IN
POBJECT_HEADER ObjectHeader
00082 )
00083 {
00084 KIRQL OldIrql;
00085
00086 ExAcquireFastLock( &ObpLock, &OldIrql );
00087 ObjectHeader->PointerCount += 1;
00088 ExReleaseFastLock( &ObpLock, OldIrql );
00089 }
00090
00091
VOID
00092
FASTCALL
00093
ObpDecrPointerCount (
00094 IN
POBJECT_HEADER ObjectHeader
00095 )
00096 {
00097 KIRQL OldIrql;
00098
00099 ExAcquireFastLock( &ObpLock, &OldIrql );
00100 ObjectHeader->PointerCount -= 1;
00101 ExReleaseFastLock( &ObpLock, OldIrql );
00102 }
00103
00104 BOOLEAN
00105
FASTCALL
00106
ObpDecrPointerCountWithResult (
00107 IN
POBJECT_HEADER ObjectHeader
00108 )
00109 {
00110 KIRQL OldIrql;
00111 LONG Result;
00112
00113 ExAcquireFastLock( &ObpLock, &OldIrql );
00114
00115
if (ObjectHeader->PointerCount <= ObjectHeader->HandleCount) {
00116
00117
DbgPrint(
"OB: About to over-dereference object %x (ObjectHeader at %x)\n",
00118 ObjectHeader->Object, ObjectHeader );
00119
00120 DbgBreakPoint();
00121 }
00122
00123 ObjectHeader->PointerCount -= 1;
00124 Result = ObjectHeader->PointerCount;
00125 ExReleaseFastLock( &ObpLock, OldIrql );
00126
return Result == 0;
00127 }
00128
00129
VOID
00130
FASTCALL
00131
ObpIncrHandleCount (
00132 IN
POBJECT_HEADER ObjectHeader
00133 )
00134 {
00135 KIRQL OldIrql;
00136
00137 ExAcquireFastLock( &ObpLock, &OldIrql );
00138 ObjectHeader->HandleCount += 1;
00139 ExReleaseFastLock( &ObpLock, OldIrql );
00140 }
00141
00142 BOOLEAN
00143
FASTCALL
00144
ObpDecrHandleCount (
00145 IN
POBJECT_HEADER ObjectHeader
00146 )
00147 {
00148 KIRQL OldIrql;
00149 LONG Old;
00150
00151 ExAcquireFastLock( &ObpLock, &OldIrql );
00152 Old = ObjectHeader->HandleCount;
00153 ObjectHeader->HandleCount -= 1;
00154 ExReleaseFastLock( &ObpLock, OldIrql );
00155
00156
return Old == 1;
00157 }
00158
00159
#endif // MPSAFE_HANDLE_COUNT_CHECK
00160
00161
00162
NTSTATUS
00163 NtDuplicateObject (
00164 IN HANDLE SourceProcessHandle,
00165 IN HANDLE SourceHandle,
00166 IN HANDLE TargetProcessHandle OPTIONAL,
00167 OUT PHANDLE TargetHandle OPTIONAL,
00168 IN ACCESS_MASK DesiredAccess,
00169 IN ULONG HandleAttributes,
00170 IN ULONG Options
00171 )
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211 {
00212
KPROCESSOR_MODE PreviousMode;
00213
NTSTATUS Status;
00214 PVOID SourceObject;
00215
POBJECT_HEADER ObjectHeader;
00216
POBJECT_TYPE ObjectType;
00217
PEPROCESS SourceProcess;
00218
PEPROCESS TargetProcess;
00219 BOOLEAN Attached;
00220 PVOID ObjectTable;
00221
HANDLE_TABLE_ENTRY ObjectTableEntry;
00222
OBJECT_HANDLE_INFORMATION HandleInformation;
00223 HANDLE NewHandle;
00224
ACCESS_STATE AccessState;
00225
AUX_ACCESS_DATA AuxData;
00226 ACCESS_MASK SourceAccess;
00227 ACCESS_MASK TargetAccess;
00228
PACCESS_STATE PassedAccessState =
NULL;
00229
00230
00231
00232
00233
00234 PreviousMode = KeGetPreviousMode();
00235
00236
if (ARGUMENT_PRESENT( TargetHandle ) && (PreviousMode !=
KernelMode)) {
00237
00238
try {
00239
00240
ProbeForWriteHandle( TargetHandle );
00241
00242 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00243
00244
return( GetExceptionCode() );
00245 }
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
if (!(Options & DUPLICATE_SAME_ACCESS)) {
00255
00256
Status =
ObpValidateDesiredAccess( DesiredAccess );
00257
00258
if (!
NT_SUCCESS(
Status )) {
00259
00260
return(
Status );
00261 }
00262 }
00263
00264
00265
00266
00267
00268
00269
00270 Attached =
FALSE;
00271
00272
00273
00274
00275
00276
00277
Status =
ObReferenceObjectByHandle( SourceProcessHandle,
00278 PROCESS_DUP_HANDLE,
00279
PsProcessType,
00280 PreviousMode,
00281 (PVOID *)&SourceProcess,
00282
NULL );
00283
00284
if (!
NT_SUCCESS(
Status )) {
00285
00286
return Status;
00287 }
00288
00289
00290
00291
00292
00293
KeEnterCriticalRegion();
00294
00295
KeWaitForSingleObject( &
ObpInitKillMutant,
00296
Executive,
00297
KernelMode,
00298
FALSE,
00299
NULL );
00300
00301
00302
00303
00304
00305
if ( SourceProcess->ObjectTable ==
NULL ) {
00306
00307
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00308
00309
KeLeaveCriticalRegion();
00310
00311
ObDereferenceObject( SourceProcess );
00312
00313
return STATUS_PROCESS_IS_TERMINATING;
00314 }
00315
00316
00317
00318
00319
00320
00321
00322
if (
PsGetCurrentProcess() != SourceProcess) {
00323
00324
KeAttachProcess( &SourceProcess->Pcb );
00325
00326 Attached =
TRUE;
00327 }
00328
00329
00330
00331
00332
00333
00334
00335
00336
Status =
ObReferenceObjectByHandle( SourceHandle,
00337 0,
00338 (
POBJECT_TYPE)
NULL,
00339 PreviousMode,
00340 &SourceObject,
00341 &HandleInformation );
00342
00343
if (Attached) {
00344
00345
KeDetachProcess();
00346
00347 Attached =
FALSE;
00348 }
00349
00350
if (!
NT_SUCCESS(
Status )) {
00351
00352
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00353
00354
KeLeaveCriticalRegion();
00355
00356
ObDereferenceObject( SourceProcess );
00357
00358
return(
Status );
00359 }
00360
00361
00362
00363
00364
00365
00366
00367
if (!ARGUMENT_PRESENT( TargetProcessHandle )) {
00368
00369
00370
00371
00372
00373
00374
if (!(Options & DUPLICATE_CLOSE_SOURCE)) {
00375
00376
Status = STATUS_INVALID_PARAMETER;
00377 }
00378
00379
if (Options & DUPLICATE_CLOSE_SOURCE) {
00380
00381
KeAttachProcess( &SourceProcess->Pcb );
00382
00383
NtClose( SourceHandle );
00384
00385
KeDetachProcess();
00386 }
00387
00388
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00389
00390
KeLeaveCriticalRegion();
00391
00392
ObDereferenceObject( SourceObject );
00393
ObDereferenceObject( SourceProcess );
00394
00395
return(
Status );
00396 }
00397
00398 SourceAccess = HandleInformation.
GrantedAccess;
00399
00400
00401
00402
00403
00404
00405
00406
Status =
ObReferenceObjectByHandle( TargetProcessHandle,
00407 PROCESS_DUP_HANDLE,
00408
PsProcessType,
00409 PreviousMode,
00410 (PVOID *)&TargetProcess,
00411
NULL );
00412
00413
00414
00415
00416
00417
00418
if (!
NT_SUCCESS(
Status )) {
00419
00420
if (Options & DUPLICATE_CLOSE_SOURCE) {
00421
00422
KeAttachProcess( &SourceProcess->Pcb );
00423
00424
NtClose( SourceHandle );
00425
00426
KeDetachProcess();
00427 }
00428
00429
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00430
00431
KeLeaveCriticalRegion();
00432
00433
ObDereferenceObject( SourceObject );
00434
ObDereferenceObject( SourceProcess );
00435
00436
return(
Status );
00437 }
00438
00439
00440
00441
00442
00443
if ( TargetProcess->ObjectTable ==
NULL ) {
00444
00445
if (Options & DUPLICATE_CLOSE_SOURCE) {
00446
00447
KeAttachProcess( &SourceProcess->Pcb );
00448
00449
NtClose( SourceHandle );
00450
00451
KeDetachProcess();
00452 }
00453
00454
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00455
00456
KeLeaveCriticalRegion();
00457
00458
ObDereferenceObject( SourceObject );
00459
ObDereferenceObject( SourceProcess );
00460
ObDereferenceObject( TargetProcess );
00461
00462
return STATUS_PROCESS_IS_TERMINATING;
00463 }
00464
00465
00466
00467
00468
00469
00470
if (
PsGetCurrentProcess() != TargetProcess) {
00471
00472
KeAttachProcess( &TargetProcess->Pcb );
00473
00474 Attached =
TRUE;
00475 }
00476
00477
00478
00479
00480
00481
if (Options & DUPLICATE_SAME_ACCESS) {
00482
00483 DesiredAccess = SourceAccess;
00484 }
00485
00486
if (Options & DUPLICATE_SAME_ATTRIBUTES) {
00487
00488 HandleAttributes = HandleInformation.
HandleAttributes;
00489
00490 }
else {
00491
00492
00493
00494
00495
00496 HandleAttributes |= HandleInformation.
HandleAttributes &
OBJ_AUDIT_OBJECT_CLOSE;
00497 }
00498
00499
00500
00501
00502
00503 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( SourceObject );
00504 ObjectType = ObjectHeader->
Type;
00505
00506 ObjectTableEntry.
Object = ObjectHeader;
00507 ObjectTableEntry.
ObAttributes |= (HandleAttributes &
OBJ_HANDLE_ATTRIBUTES);
00508
00509
00510
00511
00512
00513
00514
if ((DesiredAccess &
GENERIC_ACCESS) != 0) {
00515
00516
RtlMapGenericMask( &DesiredAccess,
00517 &ObjectType->
TypeInfo.
GenericMapping );
00518 }
00519
00520
00521
00522
00523
00524
00525 TargetAccess = DesiredAccess &
00526 (ObjectType->
TypeInfo.
ValidAccessMask | ACCESS_SYSTEM_SECURITY);
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
if (TargetAccess & ~SourceAccess) {
00542
00543
if (ObjectType->
TypeInfo.
SecurityProcedure ==
SeDefaultObjectMethod) {
00544
00545
Status =
SeCreateAccessState( &AccessState,
00546 &AuxData,
00547 TargetAccess,
00548 &ObjectType->
TypeInfo.
GenericMapping );
00549
00550 PassedAccessState = &AccessState;
00551
00552 }
else {
00553
00554
Status = STATUS_ACCESS_DENIED;
00555 }
00556
00557 }
else {
00558
00559
00560
00561
00562
00563 PassedAccessState =
NULL;
00564
00565
Status = STATUS_SUCCESS;
00566 }
00567
00568
00569
00570
00571
00572
00573
if (
NT_SUCCESS(
Status )) {
00574
00575
Status =
ObpIncrementHandleCount(
ObDuplicateHandle,
00576
PsGetCurrentProcess(),
00577 SourceObject,
00578 ObjectType,
00579 PassedAccessState,
00580 PreviousMode,
00581 HandleAttributes );
00582
00583 ObjectTable =
ObpGetObjectTable();
00584
00585
ASSERT(ObjectTable);
00586 }
00587
00588
if (Attached) {
00589
00590
KeDetachProcess();
00591
00592 Attached =
FALSE;
00593 }
00594
00595
if (Options & DUPLICATE_CLOSE_SOURCE) {
00596
00597
KeAttachProcess( &SourceProcess->Pcb );
00598
00599
NtClose( SourceHandle );
00600
00601
KeDetachProcess();
00602 }
00603
00604
if (!
NT_SUCCESS(
Status )) {
00605
00606
if (PassedAccessState !=
NULL) {
00607
00608
SeDeleteAccessState( PassedAccessState );
00609 }
00610
00611
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00612
00613
KeLeaveCriticalRegion();
00614
00615
ObDereferenceObject( SourceObject );
00616
ObDereferenceObject( SourceProcess );
00617
ObDereferenceObject( TargetProcess );
00618
00619
return(
Status );
00620 }
00621
00622
if ((PassedAccessState !=
NULL) && (PassedAccessState->
GenerateOnClose ==
TRUE)) {
00623
00624
00625
00626
00627
00628
00629 ObjectTableEntry.
ObAttributes |=
OBJ_AUDIT_OBJECT_CLOSE;
00630 }
00631
00632
#if i386 && !FPO
00633
00634
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
00635
00636 ObjectTableEntry.
GrantedAccessIndex = ObpComputeGrantedAccessIndex( TargetAccess );
00637 ObjectTableEntry.
CreatorBackTraceIndex = RtlLogStackBackTrace();
00638
00639 }
else {
00640
00641 ObjectTableEntry.
GrantedAccess = TargetAccess;
00642 }
00643
00644
#else
00645
00646 ObjectTableEntry.
GrantedAccess = TargetAccess;
00647
00648
#endif // i386 && !FPO
00649
00650
00651
00652
00653
00654
00655 NewHandle =
ExCreateHandle( ObjectTable, &ObjectTableEntry );
00656
00657
if (NewHandle) {
00658
00659
00660
00661
00662
00663
00664
00665
if (PassedAccessState !=
NULL) {
00666
00667
SeAuditHandleCreation( PassedAccessState, NewHandle );
00668 }
00669
00670
if (
SeDetailedAuditing && (ObjectTableEntry.
ObAttributes &
OBJ_AUDIT_OBJECT_CLOSE)) {
00671
00672
SeAuditHandleDuplication( SourceHandle,
00673 NewHandle,
00674 SourceProcess,
00675 TargetProcess );
00676 }
00677
00678
if (ARGUMENT_PRESENT( TargetHandle )) {
00679
00680
try {
00681
00682 *TargetHandle = NewHandle;
00683
00684 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00685
00686
00687
00688
00689 }
00690 }
00691
00692 }
else {
00693
00694
00695
00696
00697
00698
00699
00700
ObpDecrementHandleCount( TargetProcess,
00701 ObjectHeader,
00702 ObjectType,
00703 TargetAccess );
00704
00705
ObDereferenceObject( SourceObject );
00706
00707
if (ARGUMENT_PRESENT( TargetHandle )) {
00708
00709
try {
00710
00711 *TargetHandle = (HANDLE)
NULL;
00712
00713 } except(
EXCEPTION_EXECUTE_HANDLER ) {
00714
00715
00716
00717
00718 }
00719 }
00720
00721
Status = STATUS_INSUFFICIENT_RESOURCES;
00722 }
00723
00724
00725
00726
00727
00728
if (PassedAccessState !=
NULL) {
00729
00730
SeDeleteAccessState( PassedAccessState );
00731 }
00732
00733
KeReleaseMutant( &
ObpInitKillMutant, 0,
FALSE,
FALSE );
00734
00735
KeLeaveCriticalRegion();
00736
00737
ObDereferenceObject( SourceProcess );
00738
ObDereferenceObject( TargetProcess );
00739
00740
return(
Status );
00741 }
00742
00743
00744
NTSTATUS
00745 ObGetHandleInformation (
00746 OUT PSYSTEM_HANDLE_INFORMATION HandleInformation,
00747 IN ULONG Length,
00748 OUT PULONG ReturnLength OPTIONAL
00749 )
00750
00751
00752
00753
00754
00755
00756
00757
00758
00759
00760
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770
00771
00772 {
00773
NTSTATUS Status;
00774 ULONG RequiredLength;
00775
00776
PAGED_CODE();
00777
00778 RequiredLength = FIELD_OFFSET( SYSTEM_HANDLE_INFORMATION, Handles );
00779
00780
if (Length < RequiredLength) {
00781
00782
return( STATUS_INFO_LENGTH_MISMATCH );
00783 }
00784
00785 HandleInformation->NumberOfHandles = 0;
00786
00787
00788
00789
00790
00791
00792
Status =
ExSnapShotHandleTables(
ObpCaptureHandleInformation,
00793 HandleInformation,
00794 Length,
00795 &RequiredLength );
00796
00797
if (ARGUMENT_PRESENT( ReturnLength )) {
00798
00799 *ReturnLength = RequiredLength;
00800 }
00801
00802
return(
Status );
00803 }
00804
00805
00806
NTSTATUS
00807 ObpCaptureHandleInformation (
00808 IN OUT PSYSTEM_HANDLE_TABLE_ENTRY_INFO *HandleEntryInfo,
00809 IN HANDLE UniqueProcessId,
00810 IN
PHANDLE_TABLE_ENTRY ObjectTableEntry,
00811 IN HANDLE HandleIndex,
00812 IN ULONG Length,
00813 IN OUT PULONG RequiredLength
00814 )
00815
00816
00817
00818
00819
00820
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830
00831
00832
00833
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848
00849
00850 {
00851
NTSTATUS Status;
00852
POBJECT_HEADER ObjectHeader;
00853
00854
00855
00856
00857
00858
00859 *RequiredLength +=
sizeof( SYSTEM_HANDLE_TABLE_ENTRY_INFO );
00860
00861
if (Length < *RequiredLength) {
00862
00863
Status = STATUS_INFO_LENGTH_MISMATCH;
00864
00865 }
else {
00866
00867
00868
00869
00870
00871 ObjectHeader = (
POBJECT_HEADER)(((ULONG_PTR)(ObjectTableEntry->Object)) & ~
OBJ_HANDLE_ATTRIBUTES);
00872
00873 (*HandleEntryInfo)->UniqueProcessId = (
USHORT)((ULONG_PTR)UniqueProcessId);
00874 (*HandleEntryInfo)->HandleAttributes = (UCHAR)(ObjectTableEntry->ObAttributes &
OBJ_HANDLE_ATTRIBUTES);
00875 (*HandleEntryInfo)->ObjectTypeIndex = (UCHAR)(ObjectHeader->
Type->
Index);
00876 (*HandleEntryInfo)->HandleValue = (
USHORT)((ULONG_PTR)(HandleIndex));
00877 (*HandleEntryInfo)->Object = &ObjectHeader->
Body;
00878 (*HandleEntryInfo)->CreatorBackTraceIndex = 0;
00879
00880
#if i386 && !FPO
00881
00882
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
00883
00884 (*HandleEntryInfo)->CreatorBackTraceIndex = ObjectTableEntry->CreatorBackTraceIndex;
00885 (*HandleEntryInfo)->GrantedAccess = ObpTranslateGrantedAccessIndex( ObjectTableEntry->GrantedAccessIndex );
00886
00887 }
else {
00888
00889 (*HandleEntryInfo)->GrantedAccess = ObjectTableEntry->GrantedAccess;
00890 }
00891
00892
#else
00893
00894 (*HandleEntryInfo)->GrantedAccess = ObjectTableEntry->GrantedAccess;
00895
00896
#endif // i386 && !FPO
00897
00898 (*HandleEntryInfo)++;
00899
00900
Status = STATUS_SUCCESS;
00901 }
00902
00903
return(
Status );
00904 }
00905
00906
00907
POBJECT_HANDLE_COUNT_ENTRY
00908 ObpInsertHandleCount (
00909
POBJECT_HEADER ObjectHeader
00910 )
00911
00912
00913
00914
00915
00916
00917
00918
00919
00920
00921
00922
00923
00924
00925
00926
00927
00928
00929
00930
00931
00932
00933
00934 {
00935
POBJECT_HEADER_HANDLE_INFO HandleInfo;
00936
POBJECT_HANDLE_COUNT_DATABASE OldHandleCountDataBase;
00937
POBJECT_HANDLE_COUNT_DATABASE NewHandleCountDataBase;
00938
POBJECT_HANDLE_COUNT_ENTRY FreeHandleCountEntry;
00939 ULONG CountEntries;
00940 ULONG OldSize;
00941 ULONG NewSize;
00942
OBJECT_HANDLE_COUNT_DATABASE SingleEntryDataBase;
00943
00944
PAGED_CODE();
00945
00946
00947
00948
00949
00950 HandleInfo =
OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
00951
00952
if (HandleInfo ==
NULL) {
00953
00954
return NULL;
00955 }
00956
00957
00958
00959
00960
00961
00962
00963
00964
if (ObjectHeader->
Flags &
OB_FLAG_SINGLE_HANDLE_ENTRY) {
00965
00966 SingleEntryDataBase.
CountEntries = 1;
00967 SingleEntryDataBase.
HandleCountEntries[0] = HandleInfo->
SingleEntry;
00968
00969 OldHandleCountDataBase = &SingleEntryDataBase;
00970
00971 OldSize =
sizeof( SingleEntryDataBase );
00972
00973 CountEntries = 2;
00974
00975 NewSize =
sizeof(
OBJECT_HANDLE_COUNT_DATABASE) +
00976 ((CountEntries - 1) *
sizeof(
OBJECT_HANDLE_COUNT_ENTRY ));
00977
00978 }
else {
00979
00980
00981
00982
00983
00984
00985 OldHandleCountDataBase = HandleInfo->
HandleCountDataBase;
00986
00987 CountEntries = OldHandleCountDataBase->
CountEntries;
00988
00989 OldSize =
sizeof(
OBJECT_HANDLE_COUNT_DATABASE) +
00990 ((CountEntries - 1) *
sizeof(
OBJECT_HANDLE_COUNT_ENTRY));
00991
00992 CountEntries += 4;
00993
00994 NewSize =
sizeof(
OBJECT_HANDLE_COUNT_DATABASE) +
00995 ((CountEntries - 1) *
sizeof(
OBJECT_HANDLE_COUNT_ENTRY));
00996 }
00997
00998
00999
01000
01001
01002 NewHandleCountDataBase =
ExAllocatePoolWithTag(
PagedPool, NewSize,'dHbO');
01003
01004
if (NewHandleCountDataBase ==
NULL) {
01005
01006
return NULL;
01007 }
01008
01009
01010
01011
01012
01013
01014 RtlMoveMemory(NewHandleCountDataBase, OldHandleCountDataBase, OldSize);
01015
01016
01017
01018
01019
01020
01021
if (ObjectHeader->
Flags &
OB_FLAG_SINGLE_HANDLE_ENTRY) {
01022
01023 ObjectHeader->
Flags &= ~
OB_FLAG_SINGLE_HANDLE_ENTRY;
01024
01025 }
else {
01026
01027
ExFreePool( OldHandleCountDataBase );
01028 }
01029
01030
01031
01032
01033
01034
01035 FreeHandleCountEntry =
01036 (
POBJECT_HANDLE_COUNT_ENTRY)((PCHAR)NewHandleCountDataBase + OldSize);
01037
01038 RtlZeroMemory(FreeHandleCountEntry, NewSize - OldSize);
01039
01040
01041
01042
01043
01044
01045 NewHandleCountDataBase->
CountEntries = CountEntries;
01046
01047 HandleInfo->
HandleCountDataBase = NewHandleCountDataBase;
01048
01049
01050
01051
01052
01053
return FreeHandleCountEntry;
01054 }
01055
01056
01057
NTSTATUS
01058 ObpIncrementHandleDataBase (
01059 IN
POBJECT_HEADER ObjectHeader,
01060 IN
PEPROCESS Process,
01061 OUT PULONG NewProcessHandleCount
01062 )
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087 {
01088
POBJECT_HEADER_HANDLE_INFO HandleInfo;
01089
POBJECT_HANDLE_COUNT_DATABASE HandleCountDataBase;
01090
POBJECT_HANDLE_COUNT_ENTRY HandleCountEntry;
01091
POBJECT_HANDLE_COUNT_ENTRY FreeHandleCountEntry;
01092 ULONG CountEntries;
01093 ULONG ProcessHandleCount;
01094
01095
PAGED_CODE();
01096
01097
01098
01099
01100
01101 HandleInfo =
OBJECT_HEADER_TO_HANDLE_INFO(ObjectHeader);
01102
01103
01104
01105
01106
01107
if (ObjectHeader->Flags &
OB_FLAG_SINGLE_HANDLE_ENTRY) {
01108
01109
01110
01111
01112
01113
01114
if (HandleInfo->
SingleEntry.
HandleCount == 0) {
01115
01116 *NewProcessHandleCount = 1;
01117 HandleInfo->
SingleEntry.
HandleCount = 1;
01118 HandleInfo->
SingleEntry.
Process = Process;
01119
01120
return STATUS_SUCCESS;
01121
01122
01123
01124
01125
01126
01127 }
else if (HandleInfo->
SingleEntry.
Process == Process) {
01128
01129 *NewProcessHandleCount = ++HandleInfo->
SingleEntry.
HandleCount;
01130
01131
return STATUS_SUCCESS;
01132
01133
01134
01135
01136
01137
01138
01139 }
else {
01140
01141 FreeHandleCountEntry =
ObpInsertHandleCount( ObjectHeader );
01142
01143
if (FreeHandleCountEntry ==
NULL) {
01144
01145
return STATUS_INSUFFICIENT_RESOURCES;
01146 }
01147
01148 FreeHandleCountEntry->
Process = Process;
01149 FreeHandleCountEntry->
HandleCount = 1;
01150 *NewProcessHandleCount = 1;
01151
01152
return STATUS_SUCCESS;
01153 }
01154 }
01155
01156
01157
01158
01159
01160
01161
01162
01163
01164
01165 HandleCountDataBase = HandleInfo->
HandleCountDataBase;
01166
01167 FreeHandleCountEntry =
NULL;
01168
01169
01170
01171
01172
01173
if (HandleCountDataBase !=
NULL) {
01174
01175
01176
01177
01178
01179
01180 CountEntries = HandleCountDataBase->
CountEntries;
01181 HandleCountEntry = &HandleCountDataBase->
HandleCountEntries[ 0 ];
01182
01183
01184
01185
01186
01187
01188
01189
01190
while (CountEntries) {
01191
01192
if (HandleCountEntry->
Process == Process) {
01193
01194 *NewProcessHandleCount = ++HandleCountEntry->
HandleCount;
01195
01196
return STATUS_SUCCESS;
01197
01198 }
else if (HandleCountEntry->
HandleCount == 0) {
01199
01200 FreeHandleCountEntry = HandleCountEntry;
01201 }
01202
01203 ++HandleCountEntry;
01204 --CountEntries;
01205 }
01206
01207
01208
01209
01210
01211
01212
if (FreeHandleCountEntry ==
NULL) {
01213
01214 FreeHandleCountEntry =
ObpInsertHandleCount( ObjectHeader );
01215
01216
if (FreeHandleCountEntry ==
NULL) {
01217
01218
return(STATUS_INSUFFICIENT_RESOURCES);
01219 }
01220 }
01221
01222 FreeHandleCountEntry->
Process = Process;
01223 FreeHandleCountEntry->
HandleCount = 1;
01224 *NewProcessHandleCount = 1;
01225 }
01226
01227
return STATUS_SUCCESS;
01228 }
01229
01230
01231
NTSTATUS
01232 ObpIncrementHandleCount (
01233 OB_OPEN_REASON OpenReason,
01234
PEPROCESS Process,
01235 PVOID Object,
01236
POBJECT_TYPE ObjectType,
01237
PACCESS_STATE AccessState OPTIONAL,
01238 KPROCESSOR_MODE AccessMode,
01239 ULONG Attributes
01240 )
01241
01242
01243
01244
01245
01246
01247
01248
01249
01250
01251
01252
01253
01254
01255
01256
01257
01258
01259
01260
01261
01262
01263
01264
01265
01266
01267
01268
01269
01270
01271
01272
01273
01274 {
01275
NTSTATUS Status;
01276 ULONG ProcessHandleCount;
01277 BOOLEAN ExclusiveHandle;
01278
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
01279
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
01280
POBJECT_HEADER ObjectHeader;
01281 BOOLEAN HasPrivilege =
FALSE;
01282 PRIVILEGE_SET Privileges;
01283 BOOLEAN NewObject;
01284 BOOLEAN HoldObjectTypeMutex =
FALSE;
01285
01286
PAGED_CODE();
01287
01288
ObpValidateIrql(
"ObpIncrementHandleCount" );
01289
01290
01291
01292
01293
01294 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01295
01296
01297
01298
01299
01300
Status =
ObpChargeQuotaForObject( ObjectHeader, ObjectType, &NewObject );
01301
01302
if (!
NT_SUCCESS(
Status )) {
01303
01304
return Status;
01305 }
01306
01307
ObpEnterObjectTypeMutex( ObjectType );
01308 HoldObjectTypeMutex =
TRUE;
01309
01310
try {
01311
01312 ExclusiveHandle =
FALSE;
01313
01314
01315
01316
01317
01318
01319
if (Attributes & OBJ_EXCLUSIVE) {
01320
01321
if ((Attributes & OBJ_INHERIT) ||
01322 ((ObjectHeader->
Flags &
OB_FLAG_EXCLUSIVE_OBJECT) == 0)) {
01323
01324
Status = STATUS_INVALID_PARAMETER;
01325 leave;
01326 }
01327
01328
if (((
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) ==
NULL) &&
01329 (ObjectHeader->
HandleCount != 0))
01330
01331 ||
01332
01333 ((
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) !=
NULL) &&
01334 (
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) !=
PsGetCurrentProcess()))) {
01335
01336
Status = STATUS_ACCESS_DENIED;
01337 leave;
01338 }
01339
01340 ExclusiveHandle =
TRUE;
01341
01342
01343
01344
01345
01346
01347 }
else if ((ObjectHeader->
Flags &
OB_FLAG_EXCLUSIVE_OBJECT) &&
01348 (
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) !=
NULL)) {
01349
01350
Status = STATUS_ACCESS_DENIED;
01351 leave;
01352 }
01353
01354
01355
01356
01357
01358
01359
01360
01361
01362
if ((ObjectHeader->
HandleCount == 0) &&
01363 (!NewObject) &&
01364 (ObjectType->
TypeInfo.
MaintainHandleCount) &&
01365 (ObjectType->
TypeInfo.
OpenProcedure ==
NULL) &&
01366 (ObjectType->
TypeInfo.
CloseProcedure !=
NULL)) {
01367
01368
Status = STATUS_UNSUCCESSFUL;
01369 leave;
01370 }
01371
01372
if ((OpenReason ==
ObOpenHandle) ||
01373 ((OpenReason ==
ObDuplicateHandle) && ARGUMENT_PRESENT(AccessState))) {
01374
01375
01376
01377
01378
01379
01380
if (!
ObCheckObjectAccess( Object,
01381 AccessState,
01382
TRUE,
01383 AccessMode,
01384 &
Status )) {
01385
01386 leave;
01387 }
01388
01389 }
else if ((OpenReason ==
ObCreateHandle)) {
01390
01391
01392
01393
01394
01395
01396
01397
01398
01399
01400
01401
01402
01403
01404
01405
01406
01407
01408
01409
01410
if ( AccessState->RemainingDesiredAccess & MAXIMUM_ALLOWED ) {
01411
01412 AccessState->RemainingDesiredAccess &= ~MAXIMUM_ALLOWED;
01413 AccessState->RemainingDesiredAccess |= GENERIC_ALL;
01414 }
01415
01416
if ((
GENERIC_ACCESS & AccessState->RemainingDesiredAccess) != 0) {
01417
01418
RtlMapGenericMask( &AccessState->RemainingDesiredAccess,
01419 &ObjectType->
TypeInfo.
GenericMapping );
01420 }
01421
01422
01423
01424
01425
01426
01427
01428
if ( AccessState->RemainingDesiredAccess & ACCESS_SYSTEM_SECURITY ) {
01429
01430
01431
01432
01433
01434
01435
01436 Privileges.PrivilegeCount = 1;
01437 Privileges.Control = PRIVILEGE_SET_ALL_NECESSARY;
01438 Privileges.Privilege[0].Luid =
SeSecurityPrivilege;
01439 Privileges.Privilege[0].Attributes = 0;
01440
01441 HasPrivilege =
SePrivilegeCheck( &Privileges,
01442 &AccessState->SubjectSecurityContext,
01443 KeGetPreviousMode() );
01444
01445
if (!HasPrivilege) {
01446
01447
SePrivilegedServiceAuditAlarm (
NULL,
01448 &AccessState->SubjectSecurityContext,
01449 &Privileges,
01450
FALSE );
01451
01452
Status = STATUS_PRIVILEGE_NOT_HELD;
01453 leave;
01454 }
01455
01456 AccessState->RemainingDesiredAccess &= ~ACCESS_SYSTEM_SECURITY;
01457 AccessState->PreviouslyGrantedAccess |= ACCESS_SYSTEM_SECURITY;
01458
01459 (
VOID)
SeAppendPrivileges( AccessState,
01460 &Privileges );
01461 }
01462
01463
01464
01465
01466
01467
01468 CreatorInfo =
OBJECT_HEADER_TO_CREATOR_INFO( ObjectHeader );
01469
01470
if (CreatorInfo !=
NULL) {
01471
01472 InsertTailList( &ObjectType->
TypeList, &CreatorInfo->
TypeList );
01473 }
01474 }
01475
01476
if (ExclusiveHandle) {
01477
01478
OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
01479 }
01480
01481
ObpIncrHandleCount( ObjectHeader );
01482 ProcessHandleCount = 0;
01483
01484
01485
01486
01487
01488
01489
if (ObjectType->
TypeInfo.
MaintainHandleCount) {
01490
01491
Status =
ObpIncrementHandleDataBase( ObjectHeader,
01492 Process,
01493 &ProcessHandleCount );
01494
01495
if (!
NT_SUCCESS(
Status)) {
01496
01497
ObpDecrHandleCount( ObjectHeader );
01498
01499 leave;
01500 }
01501 }
01502
01503
01504
01505
01506
01507
01508
Status = STATUS_SUCCESS;
01509
01510
01511
01512
01513
01514
01515
if (ObjectType->
TypeInfo.
OpenProcedure !=
NULL) {
01516
01517 KIRQL SaveIrql;
01518
01519
01520
01521
01522
01523
01524
01525
ObpLeaveObjectTypeMutex( ObjectType );
01526 HoldObjectTypeMutex =
FALSE;
01527
01528
ObpBeginTypeSpecificCallOut( SaveIrql );
01529
01530
try {
01531
01532 (*ObjectType->
TypeInfo.
OpenProcedure)( OpenReason,
01533 Process,
01534 Object,
01535 AccessState ?
01536 AccessState->PreviouslyGrantedAccess :
01537 0,
01538 ProcessHandleCount );
01539
01540 } except(
EXCEPTION_EXECUTE_HANDLER ) {
01541
01542
Status = GetExceptionCode();
01543 }
01544
01545
ObpEndTypeSpecificCallOut( SaveIrql,
"Open", ObjectType, Object );
01546
01547
01548
01549
01550
01551
01552
ObpEnterObjectTypeMutex( ObjectType );
01553 HoldObjectTypeMutex =
TRUE;
01554
01555
if (!
NT_SUCCESS(
Status)) {
01556
01557 (
VOID)
ObpDecrHandleCount( ObjectHeader );
01558 leave;
01559 }
01560 }
01561
01562
01563
01564
01565
01566
01567 ObjectType->
TotalNumberOfHandles += 1;
01568
01569
if (ObjectType->
TotalNumberOfHandles > ObjectType->
HighWaterNumberOfHandles) {
01570
01571 ObjectType->
HighWaterNumberOfHandles = ObjectType->
TotalNumberOfHandles;
01572 }
01573
01574 } finally {
01575
01576
if ( HoldObjectTypeMutex ) {
01577
01578
ObpLeaveObjectTypeMutex( ObjectType );
01579 }
01580 }
01581
01582
return(
Status );
01583 }
01584
01585
01586
NTSTATUS
01587 ObpIncrementUnnamedHandleCount (
01588 PACCESS_MASK DesiredAccess,
01589
PEPROCESS Process,
01590 PVOID Object,
01591
POBJECT_TYPE ObjectType,
01592 KPROCESSOR_MODE AccessMode,
01593 ULONG Attributes
01594 )
01595
01596
01597
01598
01599
01600
01601
01602
01603
01604
01605
01606
01607
01608
01609
01610
01611
01612
01613
01614
01615
01616
01617
01618
01619
01620
01621
01622
01623 {
01624
NTSTATUS Status;
01625 BOOLEAN ExclusiveHandle;
01626
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
01627
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
01628
POBJECT_HEADER ObjectHeader;
01629 BOOLEAN NewObject;
01630 ULONG ProcessHandleCount;
01631 BOOLEAN HoldObjectTypeMutex =
FALSE;
01632
01633
PAGED_CODE();
01634
01635
ObpValidateIrql(
"ObpIncrementUnnamedHandleCount" );
01636
01637
01638
01639
01640
01641 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
01642
01643
01644
01645
01646
01647
Status =
ObpChargeQuotaForObject( ObjectHeader, ObjectType, &NewObject );
01648
01649
if (!
NT_SUCCESS(
Status )) {
01650
01651
return Status;
01652 }
01653
01654
ObpEnterObjectTypeMutex( ObjectType );
01655 HoldObjectTypeMutex =
TRUE;
01656
01657
try {
01658
01659 ExclusiveHandle =
FALSE;
01660
01661
01662
01663
01664
01665
01666
if (Attributes & OBJ_EXCLUSIVE) {
01667
01668
if ((Attributes & OBJ_INHERIT) ||
01669 ((ObjectHeader->
Flags &
OB_FLAG_EXCLUSIVE_OBJECT) == 0)) {
01670
01671
Status = STATUS_INVALID_PARAMETER;
01672 leave;
01673 }
01674
01675
if (((
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) ==
NULL) &&
01676 (ObjectHeader->
HandleCount != 0))
01677
01678 ||
01679
01680 ((
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) !=
NULL) &&
01681 (
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) !=
PsGetCurrentProcess()))) {
01682
01683
Status = STATUS_ACCESS_DENIED;
01684 leave;
01685 }
01686
01687 ExclusiveHandle =
TRUE;
01688
01689
01690
01691
01692
01693
01694 }
else if ((ObjectHeader->
Flags &
OB_FLAG_EXCLUSIVE_OBJECT) &&
01695 (
OBJECT_HEADER_TO_EXCLUSIVE_PROCESS(ObjectHeader) !=
NULL)) {
01696
01697
Status = STATUS_ACCESS_DENIED;
01698 leave;
01699 }
01700
01701
01702
01703
01704
01705
01706
01707
01708
01709
if ((ObjectHeader->
HandleCount == 0) &&
01710 (!NewObject) &&
01711 (ObjectType->
TypeInfo.
MaintainHandleCount) &&
01712 (ObjectType->
TypeInfo.
OpenProcedure ==
NULL) &&
01713 (ObjectType->
TypeInfo.
CloseProcedure !=
NULL)) {
01714
01715
Status = STATUS_UNSUCCESSFUL;
01716
01717 leave;
01718 }
01719
01720
01721
01722
01723
01724
01725
if ( *DesiredAccess & MAXIMUM_ALLOWED ) {
01726
01727 *DesiredAccess &= ~MAXIMUM_ALLOWED;
01728 *DesiredAccess |= GENERIC_ALL;
01729 }
01730
01731
01732
01733
01734
01735
if ((
GENERIC_ACCESS & *DesiredAccess) != 0) {
01736
01737
RtlMapGenericMask( DesiredAccess,
01738 &ObjectType->
TypeInfo.
GenericMapping );
01739 }
01740
01741
01742
01743
01744
01745
01746 CreatorInfo =
OBJECT_HEADER_TO_CREATOR_INFO( ObjectHeader );
01747
01748
if (CreatorInfo !=
NULL) {
01749
01750 InsertTailList( &ObjectType->
TypeList, &CreatorInfo->
TypeList );
01751 }
01752
01753
if (ExclusiveHandle) {
01754
01755
OBJECT_HEADER_TO_QUOTA_INFO(ObjectHeader)->ExclusiveProcess = Process;
01756 }
01757
01758
ObpIncrHandleCount( ObjectHeader );
01759 ProcessHandleCount = 0;
01760
01761
01762
01763
01764
01765
01766
if (ObjectType->
TypeInfo.
MaintainHandleCount) {
01767
01768
Status =
ObpIncrementHandleDataBase( ObjectHeader,
01769 Process,
01770 &ProcessHandleCount );
01771
01772
if (!
NT_SUCCESS(
Status)) {
01773
01774
ObpDecrHandleCount( ObjectHeader );
01775 leave;
01776 }
01777 }
01778
01779
01780
01781
01782
01783
01784
Status = STATUS_SUCCESS;
01785
01786
01787
01788
01789
01790
01791
if (ObjectType->
TypeInfo.
OpenProcedure !=
NULL) {
01792
01793 KIRQL SaveIrql;
01794
01795
01796
01797
01798
01799
01800
01801
ObpLeaveObjectTypeMutex( ObjectType );
01802 HoldObjectTypeMutex =
FALSE;
01803
01804
ObpBeginTypeSpecificCallOut( SaveIrql );
01805
01806
try {
01807
01808 (*ObjectType->
TypeInfo.
OpenProcedure)(
ObCreateHandle,
01809 Process,
01810 Object,
01811 *DesiredAccess,
01812 ProcessHandleCount );
01813
01814 } except(
EXCEPTION_EXECUTE_HANDLER ) {
01815
01816
Status = GetExceptionCode();
01817 }
01818
01819
ObpEndTypeSpecificCallOut( SaveIrql,
"Open", ObjectType, Object );
01820
01821
01822
01823
01824
01825
01826
ObpEnterObjectTypeMutex( ObjectType );
01827 HoldObjectTypeMutex =
TRUE;
01828
01829
if (!
NT_SUCCESS(
Status)) {
01830
01831 (
VOID)
ObpDecrHandleCount( ObjectHeader );
01832 leave;
01833 }
01834 }
01835
01836
01837
01838
01839
01840
01841 ObjectType->
TotalNumberOfHandles += 1;
01842
01843
if (ObjectType->
TotalNumberOfHandles > ObjectType->
HighWaterNumberOfHandles) {
01844
01845 ObjectType->
HighWaterNumberOfHandles = ObjectType->
TotalNumberOfHandles;
01846 }
01847
01848 } finally {
01849
01850
if ( HoldObjectTypeMutex ) {
01851
01852
ObpLeaveObjectTypeMutex( ObjectType );
01853 }
01854 }
01855
01856
return(
Status );
01857 }
01858
01859
01860
NTSTATUS
01861 ObpChargeQuotaForObject (
01862 IN
POBJECT_HEADER ObjectHeader,
01863 IN
POBJECT_TYPE ObjectType,
01864 OUT PBOOLEAN NewObject
01865 )
01866
01867
01868
01869
01870
01871
01872
01873
01874
01875
01876
01877
01878
01879
01880
01881
01882
01883
01884
01885
01886
01887
01888 {
01889
POBJECT_HEADER_QUOTA_INFO QuotaInfo;
01890 ULONG NonPagedPoolCharge;
01891 ULONG PagedPoolCharge;
01892
01893
01894
01895
01896
01897 QuotaInfo =
OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader );
01898
01899 *NewObject =
FALSE;
01900
01901
01902
01903
01904
01905
01906
if (ObjectHeader->Flags &
OB_FLAG_NEW_OBJECT) {
01907
01908
01909
01910
01911
01912 ObjectHeader->Flags &= ~
OB_FLAG_NEW_OBJECT;
01913
01914
01915
01916
01917
01918
01919
01920
if (QuotaInfo !=
NULL) {
01921
01922 PagedPoolCharge = QuotaInfo->
PagedPoolCharge +
01923 QuotaInfo->
SecurityDescriptorCharge;
01924 NonPagedPoolCharge = QuotaInfo->
NonPagedPoolCharge;
01925
01926 }
else {
01927
01928
01929
01930
01931
01932
01933
01934
01935 PagedPoolCharge = ObjectType->TypeInfo.DefaultPagedPoolCharge;
01936
01937
if (ObjectHeader->SecurityDescriptor !=
NULL) {
01938
01939 ObjectHeader->Flags |=
OB_FLAG_DEFAULT_SECURITY_QUOTA;
01940 PagedPoolCharge +=
SE_DEFAULT_SECURITY_QUOTA;
01941 }
01942
01943 NonPagedPoolCharge = ObjectType->TypeInfo.DefaultNonPagedPoolCharge;
01944 }
01945
01946
01947
01948
01949
01950 ObjectHeader->QuotaBlockCharged = (PVOID)
PsChargeSharedPoolQuota(
PsGetCurrentProcess(),
01951 PagedPoolCharge,
01952 NonPagedPoolCharge );
01953
01954
if (ObjectHeader->QuotaBlockCharged ==
NULL) {
01955
01956
return STATUS_QUOTA_EXCEEDED;
01957 }
01958
01959 *NewObject =
TRUE;
01960 }
01961
01962
return STATUS_SUCCESS;
01963 }
01964
01965
01966
VOID
01967 ObpDecrementHandleCount (
01968
PEPROCESS Process,
01969
POBJECT_HEADER ObjectHeader,
01970
POBJECT_TYPE ObjectType,
01971 ACCESS_MASK GrantedAccess
01972 )
01973
01974
01975
01976
01977
01978
01979
01980
01981
01982
01983
01984
01985
01986
01987
01988
01989
01990
01991
01992
01993
01994
01995
01996 {
01997
POBJECT_HEADER_HANDLE_INFO HandleInfo;
01998
POBJECT_HANDLE_COUNT_DATABASE HandleCountDataBase;
01999
POBJECT_HANDLE_COUNT_ENTRY HandleCountEntry;
02000
POBJECT_HEADER_CREATOR_INFO CreatorInfo;
02001 PVOID Object;
02002 ULONG CountEntries;
02003 ULONG ProcessHandleCount;
02004 ULONG SystemHandleCount;
02005 BOOLEAN HandleCountIsZero;
02006
02007
PAGED_CODE();
02008
02009
ObpEnterObjectTypeMutex( ObjectType );
02010
02011 Object = (PVOID)&ObjectHeader->
Body;
02012
02013 SystemHandleCount = ObjectHeader->
HandleCount;
02014 ProcessHandleCount = 0;
02015
02016
02017
02018
02019
02020
02021
02022 HandleCountIsZero =
ObpDecrHandleCount( ObjectHeader );
02023
02024
if ( HandleCountIsZero &&
02025 (ObjectHeader->
Flags &
OB_FLAG_EXCLUSIVE_OBJECT)) {
02026
02027
OBJECT_HEADER_TO_QUOTA_INFO( ObjectHeader )->ExclusiveProcess =
NULL;
02028 }
02029
02030
if ( HandleCountIsZero ) {
02031
02032 CreatorInfo =
OBJECT_HEADER_TO_CREATOR_INFO( ObjectHeader );
02033
02034
02035
02036
02037
02038
02039
if (CreatorInfo !=
NULL && !IsListEmpty( &CreatorInfo->
TypeList )) {
02040
02041 RemoveEntryList( &CreatorInfo->
TypeList );
02042
02043 InitializeListHead( &CreatorInfo->
TypeList );
02044 }
02045 }
02046
02047
02048
02049
02050
02051
02052
02053
if (ObjectType->
TypeInfo.
MaintainHandleCount) {
02054
02055 HandleInfo =
OBJECT_HEADER_TO_HANDLE_INFO( ObjectHeader );
02056
02057
02058
02059
02060
02061
02062
if (ObjectHeader->
Flags &
OB_FLAG_SINGLE_HANDLE_ENTRY) {
02063
02064
ASSERT(HandleInfo->
SingleEntry.
Process == Process);
02065
ASSERT(HandleInfo->
SingleEntry.
HandleCount > 0);
02066
02067 ProcessHandleCount = HandleInfo->
SingleEntry.
HandleCount--;
02068 HandleCountEntry = &HandleInfo->
SingleEntry;
02069
02070 }
else {
02071
02072
02073
02074
02075
02076 HandleCountDataBase = HandleInfo->
HandleCountDataBase;
02077
02078
if (HandleCountDataBase !=
NULL) {
02079
02080 CountEntries = HandleCountDataBase->
CountEntries;
02081 HandleCountEntry = &HandleCountDataBase->
HandleCountEntries[ 0 ];
02082
02083
while (CountEntries) {
02084
02085
if ((HandleCountEntry->
HandleCount != 0) &&
02086 (HandleCountEntry->
Process == Process)) {
02087
02088 ProcessHandleCount = HandleCountEntry->
HandleCount--;
02089
02090
break;
02091 }
02092
02093 HandleCountEntry++;
02094 CountEntries--;
02095 }
02096 }
02097 }
02098
02099
02100
02101
02102
02103
02104
02105
02106
if (ProcessHandleCount == 1) {
02107
02108 HandleCountEntry->
Process =
NULL;
02109 HandleCountEntry->
HandleCount = 0;
02110 }
02111 }
02112
02113
02114
02115
02116
02117
02118
02119
if (ObjectType->
TypeInfo.
CloseProcedure) {
02120
02121 KIRQL SaveIrql;
02122
02123
ObpLeaveObjectTypeMutex( ObjectType );
02124
02125
ObpBeginTypeSpecificCallOut( SaveIrql );
02126
02127 (*ObjectType->
TypeInfo.
CloseProcedure)( Process,
02128 Object,
02129 GrantedAccess,
02130 ProcessHandleCount,
02131 SystemHandleCount );
02132
02133
ObpEndTypeSpecificCallOut( SaveIrql,
"Close", ObjectType, Object );
02134
02135
ObpDeleteNameCheck( Object,
FALSE );
02136
02137 }
else {
02138
02139
02140
02141
02142
02143
02144
02145
02146
ObpDeleteNameCheck( Object,
TRUE );
02147 }
02148
02149
ObpEnterObjectTypeMutex( ObjectType );
02150
02151 ObjectType->
TotalNumberOfHandles -= 1;
02152
02153
ObpLeaveObjectTypeMutex( ObjectType );
02154
02155
return;
02156 }
02157
02158
02159
NTSTATUS
02160 ObpCreateHandle (
02161 IN OB_OPEN_REASON OpenReason,
02162 IN PVOID Object,
02163 IN
POBJECT_TYPE ExpectedObjectType OPTIONAL,
02164 IN
PACCESS_STATE AccessState,
02165 IN ULONG ObjectPointerBias OPTIONAL,
02166 IN ULONG Attributes,
02167 IN BOOLEAN DirectoryLocked,
02168 IN KPROCESSOR_MODE AccessMode,
02169 OUT PVOID *ReferencedNewObject OPTIONAL,
02170 OUT PHANDLE Handle
02171 )
02172
02173
02174
02175
02176
02177
02178
02179
02180
02181
02182
02183
02184
02185
02186
02187
02188
02189
02190
02191
02192
02193
02194
02195
02196
02197
02198
02199
02200
02201
02202
02203
02204
02205
02206
02207
02208
02209
02210
02211 {
02212
NTSTATUS Status;
02213
POBJECT_HEADER ObjectHeader;
02214
POBJECT_TYPE ObjectType;
02215 PVOID ObjectTable;
02216
HANDLE_TABLE_ENTRY ObjectTableEntry;
02217 HANDLE NewHandle;
02218 ACCESS_MASK DesiredAccess;
02219 ACCESS_MASK GrantedAccess;
02220 ULONG BiasCount;
02221 BOOLEAN AttachedToProcess =
FALSE;
02222 BOOLEAN KernelHandle =
FALSE;
02223
KAPC_STATE ApcState;
02224
02225
PAGED_CODE();
02226
02227
ObpValidateIrql(
"ObpCreateHandle" );
02228
02229
02230
02231
02232
02233
02234
02235
02236
02237 DesiredAccess = AccessState->RemainingDesiredAccess |
02238 AccessState->PreviouslyGrantedAccess;
02239
02240
02241
02242
02243
02244 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
02245 ObjectType = ObjectHeader->
Type;
02246
02247
02248
02249
02250
02251
02252
02253
if ((ARGUMENT_PRESENT( ExpectedObjectType )) &&
02254 (ObjectType != ExpectedObjectType )) {
02255
02256
if (DirectoryLocked) {
02257
02258
ObpLeaveRootDirectoryMutex();
02259 }
02260
02261
return( STATUS_OBJECT_TYPE_MISMATCH );
02262 }
02263
02264
02265
02266
02267
02268
02269 ObjectTableEntry.
Object = ObjectHeader;
02270
02271
02272
02273
02274
02275
02276
if ((Attributes & OBJ_KERNEL_HANDLE) && (AccessMode ==
KernelMode)) {
02277
02278 ObjectTable =
ObpKernelHandleTable;
02279 KernelHandle =
TRUE;
02280
02281
02282
02283
02284
02285
if (
PsGetCurrentProcess() !=
PsInitialSystemProcess) {
02286
KeStackAttachProcess (&
PsInitialSystemProcess->
Pcb, &ApcState);
02287 AttachedToProcess =
TRUE;
02288 }
02289
02290
02291 }
else {
02292
02293 ObjectTable =
ObpGetObjectTable();
02294 }
02295
02296
02297
02298
02299
02300
02301
Status =
ObpIncrementHandleCount( OpenReason,
02302
PsGetCurrentProcess(),
02303 Object,
02304 ObjectType,
02305 AccessState,
02306 AccessMode,
02307 Attributes );
02308
02309
if (AccessState->GenerateOnClose) {
02310
02311 Attributes |=
OBJ_AUDIT_OBJECT_CLOSE;
02312 }
02313
02314
02315
02316
02317
02318
02319 ObjectTableEntry.
ObAttributes |= (Attributes &
OBJ_HANDLE_ATTRIBUTES);
02320
02321
02322
02323
02324
02325
02326
02327 DesiredAccess = AccessState->RemainingDesiredAccess |
02328 AccessState->PreviouslyGrantedAccess;
02329
02330 GrantedAccess = DesiredAccess &
02331 (ObjectType->
TypeInfo.
ValidAccessMask | ACCESS_SYSTEM_SECURITY );
02332
02333
02334
02335
02336
02337
02338
if (DirectoryLocked) {
02339
02340
ObpLeaveRootDirectoryMutex();
02341 }
02342
02343
if (!
NT_SUCCESS(
Status )) {
02344
02345
02346
02347
02348
02349
02350
if (AttachedToProcess) {
02351
KeUnstackDetachProcess(&ApcState);
02352 AttachedToProcess =
FALSE;
02353 }
02354
02355
return(
Status );
02356 }
02357
02358
02359
02360
02361
02362
if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)ObjectPointerBias )) {
02363
02364 BiasCount = ObjectPointerBias;
02365
02366
while (BiasCount--) {
02367
02368
ObpIncrPointerCount( ObjectHeader );
02369 }
02370 }
02371
02372
02373
02374
02375
02376
#if i386 && !FPO
02377
02378
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
02379
02380 ObjectTableEntry.
GrantedAccessIndex = ObpComputeGrantedAccessIndex( GrantedAccess );
02381 ObjectTableEntry.
CreatorBackTraceIndex = RtlLogStackBackTrace();
02382
02383 }
else {
02384
02385 ObjectTableEntry.
GrantedAccess = GrantedAccess;
02386 }
02387
02388
#else
02389
02390 ObjectTableEntry.
GrantedAccess = GrantedAccess;
02391
02392
#endif // i386 && !FPO
02393
02394
02395
02396
02397
02398 NewHandle =
ExCreateHandle( ObjectTable, &ObjectTableEntry );
02399
02400
02401
02402
02403
02404
02405
if (NewHandle ==
NULL) {
02406
02407
if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)ObjectPointerBias )) {
02408
02409 BiasCount = ObjectPointerBias;
02410
02411
while (BiasCount--) {
02412
02413
ObpDecrPointerCount( ObjectHeader );
02414 }
02415 }
02416
02417
ObpDecrementHandleCount(
PsGetCurrentProcess(),
02418 ObjectHeader,
02419 ObjectType,
02420 GrantedAccess );
02421
02422
02423
02424
02425
02426
02427
if (AttachedToProcess) {
02428
KeUnstackDetachProcess(&ApcState);
02429 AttachedToProcess =
FALSE;
02430 }
02431
02432
return( STATUS_INSUFFICIENT_RESOURCES );
02433 }
02434
02435
02436
02437
02438
02439
02440
02441
if (KernelHandle) {
02442
02443 NewHandle =
EncodeKernelHandle( NewHandle );
02444 }
02445
02446 *
Handle = NewHandle;
02447
02448
02449
02450
02451
02452
02453
02454
02455
02456
if ( AccessState->GenerateAudit ) {
02457
02458
SeAuditHandleCreation( AccessState,
02459 *
Handle );
02460 }
02461
02462
if (OpenReason ==
ObCreateHandle) {
02463
02464
PAUX_ACCESS_DATA AuxData = AccessState->AuxData;
02465
02466
if ( ( AuxData->
PrivilegesUsed !=
NULL) && (AuxData->
PrivilegesUsed->PrivilegeCount > 0) ) {
02467
02468
SePrivilegeObjectAuditAlarm( *
Handle,
02469 &AccessState->SubjectSecurityContext,
02470 GrantedAccess,
02471 AuxData->
PrivilegesUsed,
02472
TRUE,
02473 KeGetPreviousMode() );
02474 }
02475 }
02476
02477
02478
02479
02480
02481
02482
if ((ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)ObjectPointerBias )) &&
02483 (ARGUMENT_PRESENT( ReferencedNewObject ))) {
02484
02485 *ReferencedNewObject = Object;
02486 }
02487
02488
02489
02490
02491
02492
02493
if (AttachedToProcess) {
02494
KeUnstackDetachProcess(&ApcState);
02495 AttachedToProcess =
FALSE;
02496 }
02497
02498
02499
02500
02501
02502
return( STATUS_SUCCESS );
02503 }
02504
02505
02506
NTSTATUS
02507 ObpCreateUnnamedHandle (
02508 IN PVOID Object,
02509 IN ACCESS_MASK DesiredAccess,
02510 IN ULONG ObjectPointerBias OPTIONAL,
02511 IN ULONG Attributes,
02512 IN KPROCESSOR_MODE AccessMode,
02513 OUT PVOID *ReferencedNewObject OPTIONAL,
02514 OUT PHANDLE Handle
02515 )
02516
02517
02518
02519
02520
02521
02522
02523
02524
02525
02526
02527
02528
02529
02530
02531
02532
02533
02534
02535
02536
02537
02538
02539
02540
02541
02542
02543
02544
02545
02546
02547 {
02548
NTSTATUS Status;
02549
POBJECT_HEADER ObjectHeader;
02550
POBJECT_TYPE ObjectType;
02551 PVOID ObjectTable;
02552
HANDLE_TABLE_ENTRY ObjectTableEntry;
02553 HANDLE NewHandle;
02554 ULONG BiasCount;
02555 ACCESS_MASK GrantedAccess;
02556 BOOLEAN AttachedToProcess =
FALSE;
02557 BOOLEAN KernelHandle =
FALSE;
02558
KAPC_STATE ApcState;
02559
02560
PAGED_CODE();
02561
02562
ObpValidateIrql(
"ObpCreateUnnamedHandle" );
02563
02564
02565
02566
02567
02568 ObjectHeader =
OBJECT_TO_OBJECT_HEADER( Object );
02569 ObjectType = ObjectHeader->
Type;
02570
02571
02572
02573
02574
02575
02576
02577 ObjectTableEntry.
Object = ObjectHeader;
02578
02579 ObjectTableEntry.
ObAttributes |= (Attributes &
OBJ_HANDLE_ATTRIBUTES);
02580
02581
02582
02583
02584
02585
02586
if ((Attributes & OBJ_KERNEL_HANDLE) && (AccessMode ==
KernelMode)) {
02587
02588 ObjectTable =
ObpKernelHandleTable;
02589 KernelHandle =
TRUE;
02590
02591
02592
02593
02594
02595
if (
PsGetCurrentProcess() !=
PsInitialSystemProcess) {
02596
KeStackAttachProcess (&
PsInitialSystemProcess->
Pcb, &ApcState);
02597 AttachedToProcess =
TRUE;
02598 }
02599
02600 }
else {
02601
02602 ObjectTable =
ObpGetObjectTable();
02603 }
02604
02605
02606
02607
02608
02609
02610
Status =
ObpIncrementUnnamedHandleCount( &DesiredAccess,
02611
PsGetCurrentProcess(),
02612 Object,
02613 ObjectType,
02614 AccessMode,
02615 Attributes );
02616
02617
02618 GrantedAccess = DesiredAccess &
02619 (ObjectType->
TypeInfo.
ValidAccessMask | ACCESS_SYSTEM_SECURITY );
02620
02621
if (!
NT_SUCCESS(
Status )) {
02622
02623
02624
02625
02626
02627
02628
if (AttachedToProcess) {
02629
KeUnstackDetachProcess(&ApcState);
02630 AttachedToProcess =
FALSE;
02631 }
02632
02633
return(
Status );
02634 }
02635
02636
02637
02638
02639
02640
if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)ObjectPointerBias )) {
02641
02642 BiasCount = ObjectPointerBias;
02643
02644
while (BiasCount--) {
02645
02646
ObpIncrPointerCount( ObjectHeader );
02647 }
02648 }
02649
02650
02651
02652
02653
02654
#if i386 && !FPO
02655
02656
if (
NtGlobalFlag & FLG_KERNEL_STACK_TRACE_DB) {
02657
02658 ObjectTableEntry.
GrantedAccessIndex = ObpComputeGrantedAccessIndex( GrantedAccess );
02659 ObjectTableEntry.
CreatorBackTraceIndex = RtlLogStackBackTrace();
02660
02661 }
else {
02662
02663 ObjectTableEntry.
GrantedAccess = GrantedAccess;
02664 }
02665
02666
#else
02667
02668 ObjectTableEntry.
GrantedAccess = GrantedAccess;
02669
02670
#endif // i386 && !FPO
02671
02672
02673
02674
02675
02676 NewHandle =
ExCreateHandle( ObjectTable, &ObjectTableEntry );
02677
02678
02679
02680
02681
02682
02683
if (NewHandle ==
NULL) {
02684
02685
if (ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)ObjectPointerBias )) {
02686
02687 BiasCount = ObjectPointerBias;
02688
02689
while (BiasCount--) {
02690
02691
ObpDecrPointerCount( ObjectHeader );
02692 }
02693 }
02694
02695
ObpDecrementHandleCount(
PsGetCurrentProcess(),
02696 ObjectHeader,
02697 ObjectType,
02698 GrantedAccess );
02699
02700
02701
02702
02703
02704
02705
if (AttachedToProcess) {
02706
KeUnstackDetachProcess(&ApcState);
02707 AttachedToProcess =
FALSE;
02708 }
02709
02710
return( STATUS_INSUFFICIENT_RESOURCES );
02711 }
02712
02713
02714
02715
02716
02717
02718
02719
if (KernelHandle) {
02720
02721 NewHandle =
EncodeKernelHandle( NewHandle );
02722 }
02723
02724 *
Handle = NewHandle;
02725
02726
02727
02728
02729
02730
02731
if ((ARGUMENT_PRESENT( (PVOID)(ULONG_PTR)ObjectPointerBias )) &&
02732 (ARGUMENT_PRESENT( ReferencedNewObject ))) {
02733
02734 *ReferencedNewObject = Object;
02735 }
02736
02737
02738
02739
02740
02741
02742
if (AttachedToProcess) {
02743
KeUnstackDetachProcess(&ApcState);
02744 AttachedToProcess =
FALSE;
02745 }
02746
02747
return( STATUS_SUCCESS );
02748 }
02749
02750
02751
NTSTATUS
02752 ObpValidateDesiredAccess (
02753 IN ACCESS_MASK DesiredAccess
02754 )
02755
02756
02757
02758
02759
02760
02761
02762
02763
02764
02765
02766
02767
02768
02769
02770
02771
02772
02773
02774
02775
02776 {
02777
if (DesiredAccess & 0x0CE00000) {
02778
02779
return( STATUS_ACCESS_DENIED );
02780
02781 }
else {
02782
02783
return( STATUS_SUCCESS );
02784 }
02785 }
02786
02787
02788
#if i386 && !FPO
02789
02790
02791
02792
02793
02794
02795 ULONG ObpXXX1;
02796 ULONG ObpXXX2;
02797 ULONG ObpXXX3;
02798
02799
USHORT
02800 ObpComputeGrantedAccessIndex (
02801 ACCESS_MASK GrantedAccess
02802 )
02803
02804
02805
02806
02807
02808
02809
02810
02811
02812
02813
02814
02815
02816
02817
02818
02819
02820
02821 {
02822 KIRQL OldIrql;
02823 ULONG GrantedAccessIndex,
n;
02824 PACCESS_MASK p;
02825
02826 ObpXXX1 += 1;
02827
02828
02829
02830
02831
02832 ExAcquireFastLock( &ObpLock, &OldIrql );
02833
02834
n = ObpCurCachedGrantedAccessIndex;
02835 p = ObpCachedGrantedAccesses;
02836
02837
02838
02839
02840
02841
02842
for (GrantedAccessIndex = 0; GrantedAccessIndex <
n; GrantedAccessIndex++, p++ ) {
02843
02844 ObpXXX2 += 1;
02845
02846
if (*p == GrantedAccess) {
02847
02848 ExReleaseFastLock( &ObpLock, OldIrql );
02849
return (
USHORT)GrantedAccessIndex;
02850 }
02851 }
02852
02853
02854
02855
02856
02857
if (ObpCurCachedGrantedAccessIndex == ObpMaxCachedGrantedAccessIndex) {
02858
02859
DbgPrint(
"OB: GrantedAccess cache limit hit.\n" );
02860 DbgBreakPoint();
02861 }
02862
02863
02864
02865
02866
02867
02868
02869 *p = GrantedAccess;
02870 ObpCurCachedGrantedAccessIndex += 1;
02871
02872 ExReleaseFastLock( &ObpLock, OldIrql );
02873
02874
return (
USHORT)GrantedAccessIndex;
02875 }
02876
02877 ACCESS_MASK
02878 ObpTranslateGrantedAccessIndex (
02879 USHORT GrantedAccessIndex
02880 )
02881
02882
02883
02884
02885
02886
02887
02888
02889
02890
02891
02892
02893
02894
02895
02896
02897
02898
02899 {
02900 KIRQL OldIrql;
02901 ACCESS_MASK GrantedAccess = (ACCESS_MASK)0;
02902
02903 ObpXXX3 += 1;
02904
02905
02906
02907
02908
02909 ExAcquireFastLock( &ObpLock, &OldIrql );
02910
02911
02912
02913
02914
02915
02916
if (GrantedAccessIndex < ObpCurCachedGrantedAccessIndex) {
02917
02918 GrantedAccess = ObpCachedGrantedAccesses[ GrantedAccessIndex ];
02919 }
02920
02921
02922
02923
02924
02925 ExReleaseFastLock( &ObpLock, OldIrql );
02926
02927
return GrantedAccess;
02928 }
02929
02930
#endif // i386 && !FPO
02931