SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

実例で学ぶ脆弱性対策コーディング

TIFFライブラリに潜む脆弱性をつぶすパッチ(その2)

実例で学ぶ脆弱性対策コーディング 第6回


  • このエントリーをはてなブックマークに追加

 本連載では、脆弱性を含むサンプルコードを題材に、修正方法の例を解説していきます。今回は以前にも取り上げたオープンソースの画像処理ライブラリであるlibtiffに最近見つかった脆弱性を、セキュリティコードレビューを行いながら見てみましょう。

  • このエントリーをはてなブックマークに追加

 今回は、第2回でも取り上げたオープンソースの画像処理ライブラリであるlibtiffに最近見つかった脆弱性を、セキュリティコードレビューを行いながら見てみましょう。

編集部注

 本稿のアップデート版が執筆者のサイトで掲載されています。併せてご参照ください。

サンプルコード

 以下のコードはlibtiff 3.9.2の/libtiff/tif_getimage.cから抜粋したものです。実際のコードでは、マクロを何段にも活用して関数定義を行っています。ここでは、YCbCrtoRGB以外のマクロはすべて展開した形で引用しました。それでは、このコードのどこに問題があるのかを考えてみましょう。

/*
 * YCbCr -> RGB conversion and packing routines.
 */
#define YCbCrtoRGB(dst, Y) { \
  uint32 r, g, b; \
  TIFFYCbCrtoRGB(img->ycbcr, (Y), Cb, Cr, &r, &g, &b); \
  dst = ((uint32)(r)|((uint32)(g)<<8)|((uint32)(b)<<16)|(((uint32)0xffL)<<24)) \
}

/*
 * 8-bit packed YCbCr samples w/ 2,2 subsampling => RGB
 */
static void putcontig8bitYCbCr22tile(
      TIFFRGBAImage* img,
      uint32* cp,
      uint32 x, uint32 y,
      uint32 w, uint32 h,
      int32 fromskew, int32 toskew,
      unsigned char* pp
)
{
  uint32* cp2;
  (void) y;
  fromskew = (fromskew / 2) * 6;
  cp2 = cp+w+toskew;
  while (h>=2) {
    x = w;
    while (x>=2) {
      uint32 Cb = pp[4];
      uint32 Cr = pp[5];
      YCbCrtoRGB(cp[0], pp[0]);
      YCbCrtoRGB(cp[1], pp[1]);
      YCbCrtoRGB(cp2[0], pp[2]);
      YCbCrtoRGB(cp2[1], pp[3]);
      cp += 2;
      cp2 += 2;
      pp += 6;
      x -= 2;
    }
    if (x==1) {
      uint32 Cb = pp[4];
      uint32 Cr = pp[5];
      YCbCrtoRGB(cp[0], pp[0]);
      YCbCrtoRGB(cp2[0], pp[2]);
      cp ++ ;
      cp2 ++ ;
      pp += 6;
    }
    cp += toskew*2+w;
    cp2 += toskew*2+w;
    pp += fromskew;
    h-=2;
  }
  (中略)
}

 putcontig8bitYCbCr22tile()関数は画像データの変換に使われる関数のひとつです。libtiffライブラリ内部では、画像データを1ピクセルRGBA各8ビット合計32ビットで表現しています。入出力においてさまざまな形式の画像データに対応するため、このような変換関数が多数用意されているのです。

 元データは引数に渡されるimgの先にあり、変換したデータを格納するための十分な大きさを持ったバッファはあらかじめ用意され、引数のcpで渡されます。fromskewやtoskewは画像の反転などのような変形操作のパラメータです。whileループのなかでは、各ピクセルデータを指すポインタを動かしながら、各ピクセルの色情報をTIFFYCbCrtoRGB()を使ってYCbCr形式からRGB形式に変換してバッファに書き込んでいくという処理を行っています。

脆弱性の解説:64ビット環境で問題になる整数変換

 このコードで注目すべき箇所は、ポインタを移動させる

cp += toskew*2 + w;

 という演算です。ここで使われている各変数の型を確認してみてください。

ポインタ値 += 2 * int32値 + uint32値

 このコードが64ビット環境でコンパイル・実行されると、int32型の変数値が負の値をとるときに問題が発生します。それでは順を追って見ていきましょう。

 代入式の右辺をみると、(int32型 * 定数) + uint32型となっており、これはint32型 + uint32型の演算式として評価されます。int32型は符号付き整数型、uint32型は符号無し整数型なので、これら2つのオペランドは異なる型を持ちます。このように異なる型が混在する加算演算を行う場合にはどちらか一方の型に合わせるような型変換が行われます。さて、どちらの型に合わせるか分かりますか? Cでは「通常の算術型変換」(usual arithmetic conversion)と呼ばれるルールに従い、型変換が行われます。

会員登録無料すると、続きをお読みいただけます

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

次のページ
「通常の算術型変換」

この記事は参考になりましたか?

  • このエントリーをはてなブックマークに追加
実例で学ぶ脆弱性対策コーディング連載記事一覧

もっと読む

この記事の著者

久保 正樹(JPCERT コーディネーションセンター)(クボ マサキ(JPCERT コーディネーションセンター))

脆弱性アナリストJPCERTコーディネーションセンター慶応義塾大学環境情報学部卒。ソニーでデスクトップPCのソフトウェア開発に携わったのち、米国ダートマス大学にてオーディオ信号処理、電子音響音楽の研究を行い、電子音響音楽修士を取得。2005年4月よりJPCERTコーディネーションセンターにて、脆弱性...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/5348 2013/11/06 13:23

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング