Дескриптор (программирование)

Дескриптор или хэндл (англ. handle — 'рукоять') — это абстрактная ссылка на ресурс, которая используется, когда программа обращается к блокам памяти или объектам, которыми управляет другая система, например, база данных или операционная система.

Дескриптор ресурса может быть непрозрачным идентификатором, часто представляющим собой целое число (часто индекс в массиве или «таблице», используемой для управления данным типом ресурсов), или это может быть указатель, который позволяет получить дальнейшую информацию. К распространённым дескрипторам ресурсов[1] относятся файловые дескрипторы[2][3], сетевые сокеты, соединением с базой данных, идентификаторы процессов (PIDs) и ID заданий. Идентификаторы процессов и заданий являются явно видимыми целыми числами. Файловые дескрипторы и сокеты (часто реализуемые как разновидность файловых дескрипторов) также представлены числами, но обычно считаются непрозрачными. В традиционных реализациях файловые дескрипторы служат индексами в таблице файловых дескрипторов(для каждого процесса), которая, в свою очередь, ссылается на системную таблицу файлов.

Дескрипторы и указатели

В то время как указатель содержит адрес объекта, на который он ссылается, дескриптор является абстракцией ссылки, управляемой извне. Его непрозрачность позволяет системе перемещать объект, на который он ссылается, в памяти, не делая сам дескриптор недействительным, что похоже на виртуальную память для указателей, но ещё более абстрактно. Аналогично, дополнительный уровень косвенности увеличивает контроль управляющей системы над операциями, выполняемыми над объектом. Обычно дескриптор представляет собой индекс или указатель в глобальный массив «надгробий»[4].

Утечка дескрипторов — это тип программной ошибки, возникающий, когда компьютерная программа не освобождает ранее выделенный ею дескриптор[5][6]. Это форма утечки ресурсов, аналогичная утечке ранее выделенной памяти.

Безопасность

В терминах компьютерной безопасности, поскольку доступ к ресурсу через дескриптор осуществляется другим системным компонентом, дескриптор функционирует как полномочия — он не только идентифицирует объект, но и определяет права доступа к нему. Например, если имя файла может быть подделано (это просто угадываемый идентификатор), то дескриптор выдаётся пользователю внешней системой и, следовательно, представляет собой не только идентификацию, но и предоставленный доступ.

Например, если программа хочет прочитать системный файл паролей (/etc/passwd) в режиме чтения/записи (O_RDWR), она может попытаться открыть файл с помощью следующего вызова:

int fd = open("/etc/passwd", O_RDWR);

Этот вызов просит операционную систему открыть указанный файл с заданными правами доступа. Если ОС разрешает это, она открывает файл (создаёт запись в таблице файловых дескрипторов процесса) и возвращает пользователю дескриптор (дескриптор файла, индекс в таблице). Фактический доступ контролируется операционной системой, а дескриптор является маркером доступа (токеном) к файлу. В противном случае ОС может отказать в доступе, не открывая файл и не возвращая дескриптор[7].

В системе, основанной на полномочиях, дескрипторы могут передаваться между процессами вместе с соответствующими правами доступа. В таких случаях дескриптор должен быть чем-то иным, чем общесистемно уникальное малое целое число, иначе его можно подделать. Тем не менее, такое целое число может использоваться для идентификации возможности внутри процесса; например, файловый дескриптор в Linux не подделывается, потому что его числовое значение само по себе бессмысленно, и только в контексте процесса оно может ссылаться на что-либо. Передача такого дескриптора требует особой осторожности, поскольку его значение часто должно отличаться в отправляющем и принимающем процессах.

В системах, не основанных на полномочиях, напротив, каждый процесс должен получить собственный отдельный дескриптор, указав идентификатор ресурса и желаемые права доступа (например, каждый процесс должен сам открыть файл, указав его имя и режим доступа). Такое использование встречается чаще даже в современных системах, поддерживающих передачу дескрипторов, но оно подвержено уязвимостям, таким как проблема обманутого посредника[8][9].

Примеры

Дескрипторы были популярным решением для управления памятью в операционных системах 1990-х годов, таких как Mac OS[10] и Windows. В стандартной библиотеке ввода-вывода языка Си файл определяется файловым дескриптором, абстрагирующим от нижележащего представления файла[11]. Как и другие среды рабочего стола, Windows API активно использует дескрипторы для представления объектов в системе и обеспечения пути связи между операционной системой и пользовательским пространством. Например, окно на рабочем столе представлено дескриптором типа HWND (дескриптор окна)[12].

Двойные косвенные дескрипторы (где дескриптор не обязательно является указателем, а может быть, например, целым числом) в последнее время вышли из употребления, поскольку увеличение доступной памяти и улучшенные алгоритмы виртуальной памяти сделали использование более простого указателя более привлекательным. Однако многие операционные системы по-прежнему применяют этот термин к указателям на непрозрачные, «приватные» структуры данных — непрозрачные указатели — или к индексам во внутренних массивах, передаваемых от процесса его клиенту.

См. также

Примечания

  1. Обзор дескрипторов. Microsoft Ignite (13 июня 2023). Дата обращения: 10 ноября 2025.
  2. Белякова, Валерия. Файловый дескриптор: что это простыми словами. Хекслет (27 февраля 2025). Дата обращения: 10 ноября 2025.
  3. Работа с дескрипторами файлов. IBM AIX (3 марта 2021). Дата обращения: 10 ноября 2025.
  4. Tombstone — это маркер, указывающий, что запись удалена логически, но физически все еще находится в базе данных. Такой подход позволяет системе лучше справляться с репликацией и конфликтами данных, а также обеспечивает корректное выполнение запросов к данным, которые могли быть удалены.
    См. Статью
    Стручков, Марк. Tombstone. Struchkov’s Garden (12 апреля 2025). Дата обращения: 10 ноября 2025.
  5. Отслеживание утечек дескрипторов в фоновых процессах: практические советы и инструменты (22 декабря 2024). Дата обращения: 10 ноября 2025.
  6. ITBro, Алексей. Выявление утечек ресурсов (файловых дескрипторов, соединений) (7 октября 2025). Дата обращения: 10 ноября 2025.
  7. Г.М. ЧЕРНОКНИЖНЫЙ, И.Н. ВАСИЛЬЕВА. БЕЗОПАСНОСТЬ ОПЕРАЦИОННЫХ СИСТЕМ. — СПбГЭУ, 2019. — С. 57—58. — ISBN 978-5-7310-4781-4.
  8. Turner-Trauring, Itamar. Never use the word “User” in your code (21 сентября 2018). Дата обращения: 10 ноября 2025.
  9. What is cross-site request forgery? CLOUDFLARE. Дата обращения: 10 ноября 2025.
  10. Hertzfeld, Andy. The Original Macintosh: Hungarian (январь 1982). Дата обращения: 10 мая 2010.
  11. Ivanov, Nikolay N. Глава 5. НИЗКОУРОВНЕВЫЙ ВВОД-ВЫВОД. OpenNET. Дата обращения: 10 мая 2010. См. 5.2 Файловые дескрипторы
  12. Структура оконного приложения. Дата обращения: 10 мая 2010.

Ссылки