疑似端末のマスター部分を開いた後
int fd_pseudo_term_master = open("/dev/ptmx",O_RDWR);
疑似端末のslave
部分を表す、作成されたファイル_/dev/pts/[NUMBER]
_があります。
私のような無知な人は、ptsname(fd_pseudo_term_master,filename_pseudo_term_slave,buflen);
を実行した後、simplydo int fd_pseudo_term_slave = open(filename_pseudo_term_slave,O_RDWR);
に設定して問題を解決する必要があると想像するかもしれません。
ただし、「ロックされた」疑似端末スレーブの非常に重要な使用例が必要です。単純にするために、open
呼び出しを行う前に、 man 3unlockpt)を使用する必要があるためです。 、「ロックを解除」します。
このユースケースが何であるかを知ることができませんでしたか?疑似端末を最初にロックする必要はありますか?コードで達成されること(libcから取得)
_/* Unlock the slave pseudo terminal associated with the master pseudo
terminal specified by FD. */
int
unlockpt (int fd)
{
#ifdef TIOCSPTLCK
int save_errno = errno;
int unlock = 0;
if (ioctl (fd, TIOCSPTLCK, &unlock))
{
if (errno == EINVAL)
{
errno = save_errno;
return 0;
}
else
return -1;
}
#endif
/* If we have no TIOCSPTLCK ioctl, all slave pseudo terminals are
unlocked by default. */
return 0;
}
_
可能であれば、答えはユースケース、履歴、または実際の詳細を示します。
質問のボーナス部分は次のようになります:
現在のLinuxカーネルは、「ロックされた疑似端末スレーブ」のこの機能に引き続き依存していますか?
アイデア:これはレースのコンティションを回避するための非効率的な試みですか?
答えを待っている私は、自分自身に良い答えがないまま、Linuxカーネルソースを詳しく調べました。ただし、疑似端末の最初のロックダウンの場合から「抽出」できる1つの用途は、疑似端末マスタープロセスが_/dev/pts/[NUMBER]
_にあるファイルへのアクセス権を設定するための時間を提供することです。そもそも一部のユーザーがファイルにアクセスできないようにするため。これは答えの一部になることができますか?しかし、ひどく、そのような「初期ロックダウン」状態は、少なくともここでアトミック性が保証されていると私が考える限り、とにかくスレーブファイルの複数のオープンを実際に防ぐことはできないようです。
疑似端末スレーブデバイス用の古いAT&T System 5メカニズムは、それらが/dev
の下の通常の永続的文字デバイスノードであったというものでした。 /dev/ptmx
にマルチプレクサmasterデバイスがありました。疑似端末デバイス用の古い4.3BSDメカニズムには、/dev
の下に通常の永続的マスターデバイスノードとスレーブデバイスノードの並列ペアがありました。
どちらの場合も、これは、スレーブデバイスファイルが最後のファイル記述子のクローズ後も最後の所有権とアクセス許可を保持することを意味しました。したがって、(再利用された)疑似端末が(再)割り当てられた後、スレーブデバイスファイルの所有権とアクセス許可を修正するためのgrantpt()
関数の進化。
これは、プログラムがopen()
とgrantpt()
の間に再利用された疑似端末をセットアップしているときに、事前にスレーブデバイスを所有していた人が侵入して侵入できるウィンドウがあったことを意味します。それも開いて、他の誰かの端末にアクセスできる可能性があります。したがって、疑似端末スレーブ文字デバイスは、unlockpt()
が正常に実行された後、開くことができず、grantpt()
によってロック解除されるロック状態で開始するという考えです。
何年にもわたって、これは不要であることが判明しました。
現在、カーネルは/dev
自体で物事を作成および破棄するため、スレーブデバイスファイルは永続的ではありません。マスターデバイスを開く動作は、スレーブデバイスのアクセス許可と所有権をリセットするか、スレーブデバイスファイルを完全に作成します(後者の場合、開いているすべてのファイル記述子が閉じられるとスレーブデバイスファイルが再び消えます)。同じシステムコール。
/dev/ptm
デバイス上のPTMGET
I/Oコントロールの機能の一部です。 /dev
はまだディスクボリュームであり、カーネルは内部で関連する呼び出しを発行して、そこに新しいデバイスノードを作成し、それらの所有権とアクセス許可をリセットします。posix_openpt()
システムコールによって行われます。 /dev
はディスクボリュームではありません。これはdevfs
ファイルシステムです。 posix_openpt()
は完全なシステムコールであり、開いているファイル記述子でラップされたioctl()
ではないため、「マルチプレクサ」デバイスもマスターデバイスファイルも含まれていません。スレーブデバイスは、pts/
ディレクトリの下のdevfs
ファイルシステムに表示されます。したがって、カーネルは、最初から適切な権限と所有権を持っていることを保証し、古いものを持っている機会の窓はありません。したがって、grantpt()
およびunlockpt()
ライブラリ関数は基本的に操作なしであり、残りの機能は、渡されたファイル記述子をチェックし、疑似端末のマスター側でない場合はEINVAL
を設定することだけです。 、プログラムは、これらの関数に非疑似端末ファイル記述子を渡し、エラーを返すことを期待するなど、巧妙なことをしている可能性があるためです。
Linuxではしばらくの間、疑似端末スレーブデバイスは永続的なデバイスノードでした。 GNU Cライブラリのgrantpt()
はシステムコールではありませんでした。むしろ、pt_chown
という名前のset-UIDヘルパープログラムをフォークして実行しましたが、no set-UID実行可能ファイル群集。(grantpt()
は、特権のないユーザーが特別なデバイスファイルの所有権とアクセス許可を変更できるようにする必要があります。必然的に所有していることを覚えておいてください。)したがって、まだチャンスの窓があり、Linuxはunlockpt()
のロックを維持する必要がありました。
その「新しい」devpts
ファイルシステム(「新しい」はかなり数年前に導入されたことを意味します)ほぼはFreeBSDと同じ方法で物事を行うことができますただし、devfs
を使用します。いくつかの違いがあります。
devpts
システムでは、これは別のptmx
ファイルシステムのdevtmpfs
デバイスであり、devpts
ファイルシステムには自動的に作成/破棄されたスレーブのみが含まれていましたデバイスファイル。従来、セットアップは/dev/ptmx
であり、それに付随するdevpts
は/dev/pts
にマウントされていました。devpts
ファイルシステムの複数の完全に独立したインスタンスを持ちたいと考えていました。正しい)多くのdevtmpfs
およびdevpts
ファイルシステムがあった場合の2つのファイルシステム。したがって、newer "new" devpts
システムでは、マルチプレクサとスレーブのすべてのデバイスが1つのファイルシステムにあります。下位互換性のために、デフォルトでは、新しいptmx
マウントオプションを設定しない限り、新しいptmxmode
ノードにアクセスできませんでした。devpts
では、ptmx
ファイルシステムのdevpts
デバイスファイルがプライマリマルチプレクサになり、ptmx
のdevtmpfs
はいずれかです。シンボリックリンク、バインドマウント、またはpts/ptmx
へのプレーンな古いactualシンボリックリンクを模倣しようとするカーネルによって提供されるshim。grantpt()
のように所有権と権限を常に設定するとは限りません。間違ったマウントオプションを設定すると、gid
GID以外のtty
または0620以外のmode
が、GNU Cライブラリでフォールバック動作をトリガーします。grantpt()
をに減らすために必要に応じてGNU Cライブラリで操作を行わない場合、カーネルはnotオープニングプロセスのグループを割り当てる必要があります(つまり、明示的なgid
設定が必要です)、割り当てられるグループはtty
グループである必要があり、新しく作成されたスレーブデバイスのmode
は正確に0620である必要があります。デフォルトで/dev/pts/ptmx
をオンにせず、GNU Cライブラリがgrantpt()
を完全にノーオペレーションに削減しないのは、カーネルとCライブラリがロックステップで維持されていないためです。 Linuxはまだ古い/dev/ptmx
を提供する必要がありました。GNU Cライブラリは、正しいdevpts
ファイルシステムがない場合でもpt_chown
の実行にフォールバックする必要があります。オプションを所定の位置にマウントします。
したがって、devpts
マウントオプションが間違っていて、GNU Cライブラリが実際に何かを実行するようにフォールバックする必要がある場合、Linuxでunlockpt()
が防御する機会はまだ存在しますgrantpt()
で。
Documentation/filesystems/devpts.txt
。 Linuxカーネル。/dev/pts
は、コンテナのセキュリティ問題を回避するために、「newinstance」マウントフラグを使用する必要があります。 RedHatバグ#501718。open-controlling-tty
。 noshガイド。ソフトウェア。vc-get-tty
。 noshガイド。ソフトウェア。pty-get-tty
。 noshガイド。ソフトウェア。