Introduction to ioctl interface

A Cloud Chef
2 min readAug 27, 2018

POSIX standard presents to the user space a very clever abstraction of the underlying hardware: everything can be manipulated as a file, using file descriptors and the standard system calls (open, close, read, write, etc.). It allows you to send a job to a printer, read from the console and connect to a remote server (using a socket); all using the same interface.

However, some devices have additional control functions that doesn't translate well to a file-like interface. For example, you have a thumb drive connected to an USB port, how can you access the port itself if all you can do is to read and write to the connected disk?

To help handle this kind of situation, the ioctl system call was created. It handles non-specific interactions with devices without special-purpose system calls. It works sending a special request code to the device driver to set or get specific parameters on the device. The system call accepts the following arguments:

  • the file descriptor of the device
  • the device request code (the complete list of registered request codes can be retrieved calling ioctl_list)
  • an optional pointer to a memory buffer, to receive the requested data or to send data to the device

The code below shows how to open a CD drive tray using ioctl call:

Although very simple to implement and use, it has a number of downsides:

  • Since the interface requires the user program to manipulate device-driver specific internal structures, accomplishing more sophisticate jobs using the interface can become very complex. Moreover, the interface is not necessarily the same between two different device drivers of the same device type (for example, checking the ink level might require a different request for different printer vendors)
  • There is no fixed behavior for the interface, each distinct request code behaves in a different way and produces a different result. This make auditing security vulnerabilities harder than conventional system calls. Besides, it allows the user program to pass arbitrary data to the kernel space, a potential vector for exploiting vulnerabilities in the device driver.

As the name implies, ioctl is specific for I/O devices. There are equivalent system calls for files and sockets: fcntl and getsockopt/setsockopt, respectively.

Nowadays, Linux offers newer alternatives to the venerable ioctl interface, among them:

  • Netlink: uses sockets and a special network protocol (AF_NETLINK) to communicate with kernel. It can be used, for example, to interact with Netfilter, handle iSCSI devices and manipulate network routes from the user space.
  • sysctl: allows the configuration of kernel internal systems. Linux exposes its internal state and configuration using procfs file-system, under /proc/sys directory. A system call interface (sysctl) exists, but it’s considered obsolete and its use is discouraged.
  • sysfs: another interface to kernel connected devices and subsystems. In conjunction with udev and other daemons, enables features like hot plugging.

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet

Write a response