Skip to content

Commit

Permalink
Try NtDuplicateObject instead of DuplicateHandle on Windows 8/8.1 for…
Browse files Browse the repository at this point in the history
… debugging AppContainer related failures.

This patch should be reverted as soon as we get some confirmation that NtDuplicateObject is working better compared to DuplicateHandle.
Theory behind this patch is that it might be possible that on machines which reporting this find of failure have some software like AV which might be intercepting calls to DuplciateHandle and may be failing somewhere in intercepted code path due to AppContainer.
Looking in IDA error code that we are receiving 0xC0000023 (Which translates INSUFFICIENT_BUFFER (0x7a) in win32 language) doesn't seem to be in NtDuplicateObject code path (At least not found easily.).

BUG=468922
R=jschuh@chromium.org,cpu@chromium.org

Review URL: https://codereview.chromium.org/1101913002

Cr-Commit-Position: refs/heads/master@{#326943}
  • Loading branch information
shrikant authored and Commit bot committed Apr 25, 2015
1 parent ab689a4 commit f7d692c
Showing 1 changed file with 44 additions and 5 deletions.
49 changes: 44 additions & 5 deletions base/win/scoped_process_information.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

#include "base/logging.h"
#include "base/win/scoped_handle.h"
#include "base/win/windows_version.h"

namespace base {
namespace win {
Expand All @@ -20,11 +21,49 @@ bool CheckAndDuplicateHandle(HANDLE source, ScopedHandle* target) {
return true;

HANDLE temp = NULL;
if (!::DuplicateHandle(::GetCurrentProcess(), source,
::GetCurrentProcess(), &temp, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
DPLOG(ERROR) << "Failed to duplicate a handle.";
return false;

// TODO(shrikant): Remove following code as soon as we gather some
// information regarding AppContainer related DuplicateHandle failures that
// only seem to happen on certain machine and only random launches (normally
// renderer launches seem to succeed even on those machines.)
if (base::win::GetVersion() == base::win::VERSION_WIN8 ||
base::win::GetVersion() == base::win::VERSION_WIN8_1) {
typedef LONG (WINAPI *NtDuplicateObject)(
IN HANDLE SourceProcess,
IN HANDLE SourceHandle,
IN HANDLE TargetProcess,
OUT PHANDLE TargetHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG Attributes,
IN ULONG Options);

typedef ULONG (WINAPI *RtlNtStatusToDosError)(IN LONG Status);

NtDuplicateObject nt_duplicate_object =
reinterpret_cast<NtDuplicateObject>(::GetProcAddress(
GetModuleHandle(L"ntdll.dll"), "NtDuplicateObject"));
if (nt_duplicate_object != NULL) {
LONG status = nt_duplicate_object(::GetCurrentProcess(), source,
::GetCurrentProcess(), &temp,
0, FALSE, DUPLICATE_SAME_ACCESS);
if (status < 0) {
DPLOG(ERROR) << "Failed to duplicate a handle.";
RtlNtStatusToDosError ntstatus_to_doserror =
reinterpret_cast<RtlNtStatusToDosError>(::GetProcAddress(
GetModuleHandle(L"ntdll.dll"), "RtlNtStatusToDosError"));
if (ntstatus_to_doserror != NULL) {
::SetLastError(ntstatus_to_doserror(status));
}
return false;
}
}
} else {
if (!::DuplicateHandle(::GetCurrentProcess(), source,
::GetCurrentProcess(), &temp, 0, FALSE,
DUPLICATE_SAME_ACCESS)) {
DPLOG(ERROR) << "Failed to duplicate a handle.";
return false;
}
}
target->Set(temp);
return true;
Expand Down

0 comments on commit f7d692c

Please sign in to comment.