Exemplo n.º 1
0
BOOLEAN
NTAPI
ExCompareExchangeCallBack(IN OUT PEX_CALLBACK CallBack,
                          IN PEX_CALLBACK_ROUTINE_BLOCK NewBlock,
                          IN PEX_CALLBACK_ROUTINE_BLOCK OldBlock)
{
    EX_FAST_REF OldValue;
    PEX_CALLBACK_ROUTINE_BLOCK CallbackBlock;
    ULONG Count;

    /* Check that we have a new block */
    if (NewBlock)
    {
        /* Acquire rundown */
        if (!ExfAcquireRundownProtectionEx(&NewBlock->RundownProtect,
                                           MAX_FAST_REFS + 1))
        {
            /* This should never happen */
            ASSERTMSG("Callback block is already undergoing rundown", FALSE);
            return FALSE;
        }
    }

    /* Do the swap */
    OldValue = ExCompareSwapFastReference(&CallBack->RoutineBlock,
                                          NewBlock,
                                          OldBlock);

    /* Get the routine block */
    CallbackBlock = ExGetObjectFastReference(OldValue);
    Count = ExGetCountFastReference(OldValue);

    /* Make sure the swap worked */
    if (CallbackBlock == OldBlock)
    {
        /* Make sure we replaced a valid pointer */
        if (CallbackBlock)
        {
            /* Acquire the flush lock and immediately release it */
            KeEnterCriticalRegion();
            ExWaitOnPushLock(&ExpCallBackFlush);

            /* Release rundown protection */
            KeLeaveCriticalRegion();
            ExfReleaseRundownProtectionEx(&CallbackBlock->RundownProtect,
                                          Count + 1);
        }

        /* Compare worked */
        return TRUE;
    }
    else
    {
        /* It failed, check if we had a block */
        if (NewBlock)
        {
            /* We did, remove the refernces that we had added */
            ExfReleaseRundownProtectionEx(&NewBlock->RundownProtect,
                                          MAX_FAST_REFS + 1);
        }

        /* Return failure */
        return FALSE;
    }
}
Exemplo n.º 2
0
NTSTATUS
NTAPI
ObSetSecurityDescriptorInfo(IN PVOID Object,
                            IN PSECURITY_INFORMATION SecurityInformation,
                            IN OUT PSECURITY_DESCRIPTOR SecurityDescriptor,
                            IN OUT PSECURITY_DESCRIPTOR *OutputSecurityDescriptor,
                            IN POOL_TYPE PoolType,
                            IN PGENERIC_MAPPING GenericMapping)
{
    NTSTATUS Status;
    POBJECT_HEADER ObjectHeader;
    PSECURITY_DESCRIPTOR OldDescriptor, NewDescriptor, CachedDescriptor;
    PEX_FAST_REF FastRef;
    EX_FAST_REF OldValue;
    ULONG_PTR Count;
    PAGED_CODE();

    /* Get the object header */
    ObjectHeader = OBJECT_TO_OBJECT_HEADER(Object);
    while (TRUE)
    {
        /* Reference the old descriptor */
        OldDescriptor = ObpReferenceSecurityDescriptor(ObjectHeader);
        NewDescriptor = OldDescriptor;

        /* Set the SD information */
        Status = SeSetSecurityDescriptorInfo(Object,
                                             SecurityInformation,
                                             SecurityDescriptor,
                                             &NewDescriptor,
                                             PoolType,
                                             GenericMapping);
        if (NT_SUCCESS(Status))
        {
            /* Now add this to the cache */
            Status = ObLogSecurityDescriptor(NewDescriptor,
                                             &CachedDescriptor,
                                             MAX_FAST_REFS + 1);

            /* Let go of our uncached copy */
            ExFreePool(NewDescriptor);

            /* Check for success */
            if (NT_SUCCESS(Status))
            {
                /* Do the swap */
                FastRef = (PEX_FAST_REF)OutputSecurityDescriptor;
                OldValue = ExCompareSwapFastReference(FastRef,
                                                      CachedDescriptor,
                                                      OldDescriptor);
                
                /* Get the security descriptor */
                SecurityDescriptor = ExGetObjectFastReference(OldValue);
                Count = ExGetCountFastReference(OldValue);
                
                /* Make sure the swap worked */
                if (SecurityDescriptor == OldDescriptor)
                {
                    /* Flush waiters */
                    ObpAcquireObjectLock(ObjectHeader);
                    ObpReleaseObjectLock(ObjectHeader);

                    /* And dereference the old one */
                    ObDereferenceSecurityDescriptor(OldDescriptor, Count + 2);
                    break;
                }
                else
                {
                    /* Someone changed it behind our back -- try again */
                    ObDereferenceSecurityDescriptor(OldDescriptor, 1);
                    ObDereferenceSecurityDescriptor(CachedDescriptor,
                                                    MAX_FAST_REFS + 1);
                }
            }
            else
            {
                /* We failed, dereference the old one */
                ObDereferenceSecurityDescriptor(OldDescriptor, 1);
                break;
            }
        }
        else
        {
            /* We failed, dereference the old one */
            if (OldDescriptor) ObDereferenceSecurityDescriptor(OldDescriptor, 1);
            break;
        }
    }

    /* Return status */
    return Status;
}