コード日進月歩

しんくうの技術的な小話、メモ、つれづれ、など

TOCTOU(Time Of Check to Time Of Use)とは何なのかざっくりまとめる

略語として馴染みがなかったのでざっくりまとめる

TOCTOUとは

データのチェック時(Time of check,TOC)と利用時(Time of use,TOU)に差異がある場合に引き起こされる問題があるときに使われるフレーズ。

具体例

例えば以下のような仕様があるとする。

物が詰まった箱がある。
この箱の重量が25kg以内の場合だけ、荷運び用の台車に乗せることができる。

このような仕様において「25kg以内であることをチェック(TOC)して、即座に台座に乗せる(TOU)」ということであれば問題ないが「25kg以内であることをチェックしたあとに、誰でも箱にものが入れられる状態にして翌日題材乗せる」とした場合、TOCとTOUの差があるのでチェック時と差異がある状態が発生してしまう

TOCTOU競合とは

TOCTOU競合とは競合しないようにチェックしなければいけない事象が意図通りではない挙動がTOCTOUの性質で競合してしまう状態のこと。

具体例

APIとしてファイル保存のAPIを提供する。
そのAPIはリクエストを受け付けたら `/tmp/file/` ディレクトリに保存するが
もし同じファイル名があった場合は、ファイル名の末尾にハイフンとUNIX時間の数値をつける。
たとえば 2023-04-01 15:20:20 に hoge.png というファイルがすでにある状態で
hoge.pngを受け付けたらそのファイルはhoge-1680330020.pngとする

このような仕様においては実装を以下のようにしたとする

  1. 「受け付けたファイル名がディレクトリにあるか?」をチェックする
  2. 1がNOであればそのままファイルをディレクトリに保存する
  3. 2がYESであればファイル名の末尾に現在時点のUNIX時間を付け足して保存する

この際に1秒間に hoge.png というリクエストが2つ来るとすると、チェック処理と実行が離れていることにより1つ目のリクエストの中身は2つ目のリクエストに上書きされてしまう。

回避策

このような処理の場合は、チェックと処理が別れていることが問題なので、以下のような考え方で回避できる

  • チェックと更新を同時に行うようにする(アトミックな制御)
  • 排他制御をする

具体例に関しては参考サイト参照のこと

参考リンク