DuplicateHandle
Mar 8, 2007 · CommentsПрограммированиеWindows
Функция DuplicateHandle обладает одной особенностью. Она позволяет указывать набор прав доступа (параметр dwDesiredAccess), которыми должна обладать создаваемая копия описателя. Причем, что интересно, в некоторых случаях новый описатель может получить больше прав доступа, чем оригинал. Об этом вскользь упоминается в MSDN, однако никаких дополнительных разъяснений не даётся:
In some cases, the new handle can have more access rights than the original handle. However, in other cases, DuplicateHandle cannot create a handle with more access rights than the original. For example, a file handle created with the GENERIC_READ access right cannot be duplicated so that it has both the GENERIC_READ and GENERIC_WRITE access right.
Каким образом это работает? Для каждого описателя ядро поддерживает эффективную маску доступа - комбинацию флагов, описывающую права доступа выданные данному описателю. В процессе копирования описателя функция NtDuplicateObject, вызываемая из DuplicateHandle, сверяет запрошенную маску доступа с эффективной маской доступа исходного описателя. Если запрошенная маска не содержит новых битов, копия создаётся безо всяких дальнейших проверок, так как исходный описатель уже обладает всеми нужными правами. В противном случае, выполняется полная проверка прав, точно такая же, как и при открытии существующего объекта.
Фактически это означает, что максимальный уровень доступа к объекту, который можно получить с помощью DuplicateHandle, не определяется уровнем доступа исходного описателя, а определяется ACL этого объекта. В этом плане DuplicateHandle ничем не отличается от OpenXxx функций. Теоретически, это может привести к тому, что неуполномоченный код получит больше прав, чем было задумано, но в реальности это вряд ли возможно.
Не обошлось и без исключений. Это т механизм не работает для файлов (как сказано в цитате из MSDN), ключей реестра, устройств (Device), драйверов (Driver) и объектов типа WmiGuid. Причина этого в том, что перечисленные типы объектов используют нестандартную Security Procedure – функцию, которая используется при операциях с ACL объекта. В таком случае NtDuplicateObject предполагает, что данный объект использует нестандартную модель безопасности, и поэтому она не вправе давать новому описателю больше прав, чем имеет исходный.