ioctl

ウィキペディアから、無料の百科事典
ナビゲーションにジャンプ 検索にジャンプ


コンピューティングでは、 (入出力制御ioctlの略語)は、デバイス固有の入出力操作および通常のシステムコールでは表現できないその他の操作のシステムコールです。リクエストコードを指定するパラメータを取ります。呼び出しの効果は、要求コードに完全に依存します。多くの場合、リクエストコードはデバイス固有です。たとえば、物理デバイスにディスクを取り出すように指示できるCD-ROMデバイスドライバは、そうするための要求コードを提供します。デバイスに依存しないリクエストコードは、コアシステムソフトウェアでのみ使用されている、またはまだ開発中のカーネル機能へのアクセスを ユーザースペースに提供するために使用されることがあります。ioctl

ioctlシステムコールは、Unixのバージョン7でその名前で最初に登場まし利用可能なリクエストコードはシステムごとに異なりますが、LinuxmacOSを含むほとんどのUnixおよびUnixライクなシステムでサポートされています。Microsoft Windowsは、 Win32APIで「 」という名前の同様の関数を提供しますDeviceIoControl

背景

従来のオペレーティングシステムは、ユーザースペースカーネルの2つのレイヤーに分けることができますテキストエディタなどのアプリケーションコードユーザースペースにあり、ネットワークスタックなどのオペレーティングシステムの基盤となる機能はカーネルにあります。カーネルコードは機密性の高いリソースを処理し、アプリケーション間のセキュリティと信頼性の障壁を実装します。このため、ユーザーモードのアプリケーションは、オペレーティングシステムによってカーネルリソースに直接アクセスできなくなります。

ユーザースペースアプリケーションは通常、コードがカーネル層にあるシステムコールを使用してカーネルにリクエストを送信します。システムコールは通常、「システムコールベクトル」の形式を取り、目的のシステムコールがインデックス番号で示されます。たとえば、exit()システムコール番号1とwrite()番号4の場合があります。次に、システムコールベクトルを使用して、要求に必要なカーネル関数を検索します。このように、従来のオペレーティングシステムは通常、ユーザースペースに数百のシステムコールを提供します。

標準のカーネル機能にアクセスするための便利な設計ですが、システムコールは、非標準のハードウェア周辺機器にアクセスするには不適切な場合があります。必然的に、ほとんどのハードウェア周辺機器(別名デバイス)は、カーネル内でのみ直接アドレス指定できます。ただし、ユーザーコードはデバイスと直接通信する必要がある場合があります。たとえば、管理者がイーサネットインターフェイスでメディアタイプを設定する場合があります。最新のオペレーティングシステムはさまざまなデバイスをサポートしており、その多くは多数の機能を備えています。これらの機能の一部は、カーネル設計者が予測できない可能性があり、その結果、カーネルがデバイスを使用するためのシステムコールを提供することは困難です。

この問題を解決するために、カーネルは拡張可能であるように設計されており、カーネル空間で実行され、デバイスを直接アドレス指定できるデバイスドライバーと呼ばれる追加のモジュールを受け入れる場合があります。ioctlインターフェイスは、ユーザースペースがデバイスドライバーと通信するための単一のシステムコールですioctlデバイスドライバーでの要求は、このシステムコールに関して、通常はデバイスへのハンドルと要求番号によってベクトル化されます。したがって、基本カーネルを使用すると、ユーザースペースは、デバイスでサポートされている機能について何も知らなくても、また、管理できないほど大量のシステムコールのコレクションを必要とせずに、デバイスドライバーにアクセスできます。

を使用します

ハードウェアデバイス構成

の一般的な使用法ioctlは、ハードウェアデバイスを制御することです。

たとえば、Win32システムでは、ioctlコールはUSBデバイスと通信したり、接続されたストレージデバイスのドライブジオメトリ情報を検出したりできます。

OpenBSDおよびNetBSDでは、は、疑似デバイスドライバおよびユーティリティによって使用され、に似たベンダーに依存しない統合インターフェイスでRAIDボリューム管理を実装します。[1] [2]ioctlbio(4)bioctlifconfig

NetBSDでは、フレームワークでも使用されます[3]ioctlsysmon

ターミナル

ioctlエンドユーザーアプリケーションに公開されるコード での使用法の1つは、ターミナルI/Oです。

Unixオペレーティングシステムは、従来、コマンドラインインターフェイスを多用してきましたUnixコマンドラインインターフェイスは、VT100などのハードウェアテキスト端末をエミュレートする疑似端末(ptys)上に構築されますptyは、呼び出しを使用して、ハードウェアデバイスであるかのように制御および構成されます。たとえば、ptyのウィンドウサイズは呼び出しを使用して設定されます。TIOCSTI(端末I / O制御、端末入力のシミュレーション)ioctl関数は、文字をデバイスストリームにプッシュできます。[4]ioctlTIOCSWINSZ

カーネル拡張

たとえばネットワーク処理を高速化するためにアプリケーションがカーネルを拡張する必要がある場合、呼び出しはユーザースペースコードをカーネル拡張ioctlにブリッジする便利な方法を提供します。カーネル拡張機能は、名前で開くことができるファイルシステム内の場所を提供できます。これにより、任意の数の呼び出しをディスパッチできるため、オペレーティングシステムにシステム呼び出しを追加せずに拡張機能をプログラムできます。 ioctl

sysctlAlternative

OpenBSDの開発者に よるとioctlカーネルを拡張するためsysctlの2つのシステムコールsysctlであり、おそらく2つのうちのより単純なものです。[5]

NetBSDではハードウェア監視sysmon_envsysのフレームワークは;を使用します。一方、OpenBSDDragonFly BSDは、代わりに対応するフレームワークを使用します。NetBSDの元のリビジョンは、以前に実装されていましたが、フレームワークは実験的なものであり、開発された場合はインターフェイスに置き換える必要があることを示唆するメッセージがありました[6] [7]OpenBSDとその後の2003年の導入。ただし、フレームワークが2007年に再設計されたときioctlproplibsysctlhw.sensorsenvsysioctlproplibsysctl(8)sysctlhw.sensorsenvsysproplib、システムコールはそのままioctlで、メッセージは削除されました。[8]

実装

Unix

ioctlシステムコールは、バージョン7 Unixで、名前が変更されたものとして最初に登場ましstty[9]ioctl呼び出しはパラメーターとして受け取ります

  1. 開いているファイル記述子
  2. リクエストコード番号
  3. 整数値、おそらく符号なし(ドライバーに行く)またはデータへのポインター(ドライバーに行くか、ドライバーから戻るか、またはその両方)。

カーネルは通常、デバイスドライバーに直接呼び出しをディスパッチしますioctlデバイスドライバーは、必要な方法で要求番号とデータを解釈できます。各ドライバードキュメントの作成者は、その特定のドライバーの番号を要求し、ヘッダーファイルで定数として提供します。

Linuxを含む一部のUnixシステムには、デバイスドライバーとの間で転送されるデータのサイズ、データ転送の方向、および要求を実装するドライバーのIDを要求番号内にエンコードする規則があります。ENOTTYこのような規則に従っているかどうかに関係なく、カーネルとドライバーは連携して、認識しないドライバーを要求するアプリケーションに 統一されたエラーコード(記号定数で示される)を配信します。

ニーモニック(従来は「タイプライターではありませんENOTTY」というテキストメッセージに関連付けられていました)は、テレタイプ)デバイスのみがこのエラーを発生させた、呼び出しを組み込んだ最も初期のシステムに由来します。シンボリックニーモニックは互換性要件によって修正されていますが、最近のシステムの中には、「不適切なデバイス制御操作」(またはそのローカリゼーション)などのより一般的なメッセージをより効果的に表示するものがあります。 ioctltty

TCSETSシリアルポートioctlでの呼び出しの例ですシリアルポートでの通常の読み取りおよび書き込み呼び出しは、データバイトを送受信します。このような通常のI/Oとは別の呼び出しは、特殊文字の処理やポートの出力信号(DTR信号など)などのさまざまなドライバーオプションを制御します。 ioctl(fd,TCSETS,data)

Win32

Win32DeviceIoControlはパラメータとして次 のものを取ります。

  1. 開いているオブジェクトハンドル(ファイル記述子に相当するWin32)
  2. リクエストコード番号(「制御コード」)
  3. 入力パラメータ用のバッファ
  4. 入力バッファの長さ
  5. 出力結果用のバッファ
  6. 出力バッファの長さ
  7. オーバーラップI/Oが使用されている場合OVERLAPPED構造。

Win32デバイス制御コードは、実行されている操作のモードを考慮に入れています。

デバイスドライバのセキュリティに影響を与える4つの定義された動作モードがあります-

  1. METHOD_IN_DIRECT:バッファアドレスは、ユーザーモードの呼び出し元が読み取り可能であることが確認されています。
  2. METHOD_OUT_DIRECT:バッファアドレスは、ユーザーモードの呼び出し元によって書き込み可能であることが確認されています。
  3. METHOD_NEITHER:ユーザーモードの仮想アドレスは、マッピングや検証なしでドライバーに渡されます。
  4. METHOD_BUFFERED:IO Managerが制御する共有バッファーは、ユーザーモードとの間でデータを移動するために使用されます。

代替案

その他のベクトル化された呼び出しインターフェース

デバイスとカーネル拡張機能は、追加の新しいシステムコールを使用してユーザースペースにリンクできますがオペレーティングシステムの開発者はシステムコールインターフェイスに焦点を合わせて効率的に維持しようとするため、このアプローチはめったに採用されません。

Unixオペレーティングシステムでは、他の2つのベクトル化されたコールインターフェイスが一般的です。fcntl(「ファイル制御」)システムコールは、開いているファイルを構成し、ノンブロッキングI/Oを有効にするなどの状況で使用されます。setsockopt(「ソケットオプションの設定」)システムコールは、オープンネットワークソケットを構成します。これは、 BSDUnixシステム ipfwでパケットファイアウォールを構成するために使用される機能です。

メモリマッピング

Unix
デバイスインターフェイスと入出力機能は、メモリマップトファイルを使用して提供される場合があります。デバイスと対話するアプリケーションは、呼び出しの場合と同様に、デバイスに対応するファイルシステム上の場所を開きますioctlが、メモリマッピングシステムコールを使用して、アドレス空間の一部をカーネルのアドレス空間に結び付けます。このインターフェイスは、デバイスとユーザースペースアプリケーション間のバルクデータ転送を提供するためのはるかに効率的な方法です。個々のioctlシステムコールまたは読み取り/書き込みシステムコールは、ユーザースペースからカーネルへの遷移が繰り返されるためにオーバーヘッドが発生します。メモリマップされたアドレス範囲へのアクセスでは、そのようなオーバーヘッドは発生しません。
Win32
バッファリングされたIOメソッドまたは名前付きファイルマッピングオブジェクトを使用できます。ただし、単純なデバイスドライバーの場合は、標準のDeviceIoControl METHOD_アクセスで十分です。

ネットリンク

Netlinkは、プロセス間通信(IPC)のソケットのようなメカニズムであり、より柔軟な後継となるように設計されていますioctl

含意

複雑さ

ioctl呼び出しは、カーネルのシステムコールインターフェイスの複雑さを最小限に抑えます。ただし、開発者がカーネルプログラミングインターフェイスの一部を「隠して」おく場所を提供することにより、ioctl呼び出しはユーザーからカーネルへのAPI全体を複雑にします。数百のシステムコールを提供するカーネルは、数千のioctl呼び出しを提供する場合があります。

コールへのインターフェイスioctlは従来のシステムコールとは多少異なるように見えますが、実際には、ioctlコールとシステムコールの間にほとんど違いはありません。コールは、ioctl異なるディスパッチメカニズムを備えた単なるシステムコールです。したがって、カーネルシステムコールインターフェイスの拡張に反対する議論の多くは、インターフェイスに適用できioctlます。

アプリケーション開発者にとって、システムコールはアプリケーションサブルーチンと何ら変わりはありません。それらは、引数を取り、値を返す単なる関数呼び出しです。OSのランタイムライブラリは、システムコールの呼び出しに伴う複雑さを覆い隠します。ioctl残念ながら、ランタイムライブラリは呼び出しを透過的にしません。マシンのIPアドレスを検出するなどの単純な操作では、多くの場合、複雑なioctl呼び出しが必要になり、それぞれにマジックナンバーと引数構造が必要になります。[要出典]

Libpcaplibdnetioctlは、それぞれパケットキャプチャとパケットI / Oのために 、インターフェイスの複雑さを隠すように設計されたサードパーティのラッパーUnixライブラリの2つの例です。

セキュリティ

主流のオペレーティングシステムのユーザーからカーネルへのインターフェイスは、リリース前にコードの欠陥やセキュリティの脆弱性について徹底的に監査されることがよくあります。これらの監査は通常、十分に文書化されたシステムコールインターフェイスに焦点を当てています。たとえば、監査人は、ユーザーIDの変更などの機密性の高いセキュリティ呼び出しを管理ユーザーのみが利用できるようにする場合があります。

ioctlインターフェイスはより複雑で多様であるため、システムコールよりも監査が困難です。さらに、ioctlサードパーティの開発者が通話を提供できるため、多くの場合、コアオペレーティングシステムがリリースされた後、ioctl通話の実装は精査されにくくなり、より多くの脆弱性が潜む可能性があります。最後にioctl、特にサードパーティのデバイスドライバーに対する多くの呼び出しは、文書化されていません。

呼び出しのハンドラーioctlはカーネルモードに直接存在するため、ユーザースペースからの入力は慎重に検証する必要があります。ioctlデバイスドライバーの脆弱性は、無効なバッファーを呼び出し に渡すことにより、ローカルユーザーによって悪用される可能性があります。

Win32およびUnixオペレーティングシステムは、デバイスに特定のアクセス制御が適用されているアプリケーションによるアクセスからユーザースペースデバイス名を保護できます。デバイスドライバの開発者がユーザースペースでアクセス可能なオブジェクトに適切なアクセス制御を適用しない場合、セキュリティの問題が発生する可能性があります。

最近のオペレーティングシステムの中には、システムコールラッパーを使用して、敵対的なユーザースペースコード(バッファオーバーフローのエクスプロイトに感染したアプリケーションなど)からカーネルを保護するものがありますシステムコールラッパーは、どのシステムコールをどのアプリケーションから呼び出すことができるかを指定することにより、役割ベースのアクセス制御を実装します。たとえば、ラッパーを使用して、メールプログラムが他のプログラムを生成する権利を「取り消す」ことができます。インターフェイスはシステムコールラッパーを複雑にします。これは、それぞれが異なる引数をとる多数のラッパーがあり、その一部は通常のプログラムで必要になる場合があるためです。 ioctl

さらに読む

  • W.リチャードスティーブンスUNIX環境での高度なプログラミング(Addison-Wesley、1992、ISBN  0-201-56317-7)、セクション3.14。
  • GNUCライブラリのオンラインマニュアルの一般的なI/O制御操作
  • ioctl(2) – バージョン7Unixプログラマーマニュアル
  • ioctl(2) –  Linuxプログラマーマニュアル–システムコール
  • ioctl(2) –FreeBSD システムコールマニュアル
  • ioctl(2) –OpenBSD システムコールマニュアル
  • ioctl(2) –Solaris10 システムコールリファレンスマニュアル
  • " MicrosoftDeveloperNetworkDeviceIoControlドキュメント

参照

  1. ^ Niklas Hallqvist(2002); マルコ・ピーレブーム(2006)。「bio(4)—ブロックI /Oioctlトンネル疑似デバイス」BSD相互参照OpenBSD
  2. ^ Marco Peereboom(2005)。「bioctl(8)—RAID管理インターフェース」BSD相互参照OpenBSD
  3. ^ 「sysmon(4)—システム監視および電力管理インターフェース」NetBSD/ dev / sysmonを介して利用可能なioctl(2)インターフェース。
  4. ^ クリスチャンセン、トム; トーキントン、ネイサン(1998)。「12:パッケージ、ライブラリ、およびモジュール」。Perlクックブック:Perlプログラマーのためのソリューションと例(2版)。カリフォルニア州セバストポル:O'Reilly Media、Inc.(2003年発行)。p。482. ISBN  97805965549652016年11月15日取得[...]TIOCSTI[...]は「ターミナルI/O制御、ターミナル入力のシミュレーション」の略です。この関数を実装するシステムでは、1つの文字がデバイスストリームにプッシュされるため、次にプロセスがそのデバイスから読み取るときに、そこに配置された文字が取得されます。
  5. ^ Federico Biancuzzi(2004-10-28)。「OpenBSD3.6Live」ONLampオライリーメディア2004-10-29にオリジナルからアーカイブされました2019-03-20を取得しました。カーネルに機能を追加するために使用できる2つのシステムコールがあります(さらに別のシステムコールを追加することなく):ioctl(2)とsysctl(3)。新機能の実装が非常に簡単だったため、後者が選択されました。
  6. ^ ティムRightnour; ビルスクワイアー(2007-12-19)。「envsys--EnvironmentalSystemsAPI」NetBSD4.0。このAPIは実験的なものであり、いつでも非推奨になる可能性があります...このAPI全体は、開発された場合、sysctl(8)インターフェイスまたはカーネルイベントメカニズムに置き換える必要があります。
  7. ^ コンスタンティンA.ムレニン(2007-04-17)。「3.5.NetBSDのsysmon(4)」。マイクロプロセッサシステムハードウェアモニタとの一般化されたインターフェースネットワーク、センシング、および制御に関する2007 IEEE国際会議の議事録、2007年4月15〜17日。英国ロンドン:IEEEpp。901–906。土井10.1109/ICNSC.2007.372901ISBN 978-1-4244-1076-7IEEE ICNSC 2007、pp。901〜906。
  8. ^ コンスタンティンA.ムレニン(2010-05-21)。「6.1。フレームワークのタイムライン;7.1。NetBSDenvsys/sysmon」。OpenBSDハードウェアセンサー—環境モニタリングとファン制御MMath論文)。ウォータールー大学:UWSpace。hdl10012/5234ドキュメントID:ab71498b6b1a60ff817b29d56997a418。
  9. ^ McIlroy、MD(1987)。Research Unixリーダー:プログラマーマニュアル、1971年から1986年(PDF)(テクニカルレポート)からの注釈付きの抜粋。CSTR。ベル研究所。139。