SHOEISHA iD

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

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

Javaセキュアコーディング入門

整数オーバーフロー検出の3つのアプローチ
――mezzofantiのバグ修正

Javaセキュアコーディング入門(3)

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

 Java/Androidの世界では、バッファオーバーフローが問題になることはありませんが、整数オーバーフローには注意する必要があります。今回は整数オーバーフローとその対策について、Androidアプリケーションの実例を交えながら紹介します。

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

はじめに

 C/C++の世界では、バッファオーバーフロー(CWE-120)は攻撃者による任意のコード実行を可能にする脅威の高い脆弱性として知られています。バッファオーバーフローに至る例の多くでは、整数の不適切な取り扱いによる整数オーバーフロー(CWE-190)が原因になっています。最初に次のコードを見てみましょう。

public static void main(String[] args) {
    long OVERFLOW = 24 * 60 * 60 * 1000 * 1000;
    System.out.println("One day is :" + OVERFLOW + " microseconds.");
  }
}

 これは、1日をマイクロ秒(マイクロ秒は100万分の1秒)に換算する計算を行うコードです。実行すると以下が出力されます。

One day is 500654080 microseconds.

 1日24時間は、24×60×60=86,400秒。1秒は1,000,000マイクロ秒なので、86,400×1,000,000=86,400,000,000が出力されるはずでした。なぜこのような結果が出力されてしまったのでしょう。

Javaと整数型

 今回問題となるのはJavaにおける整数の取り扱いです。Javaのデータ型をまとめると以下の図のようになります。

図1. Javaのデータ型
図1. Javaのデータ型

 Javaの整数型(Integral Type)には、符号付き整数型であるbyte、short、int、longと、符号なし整数型であるcharの4つの型が存在します。前述のコード

long OVERFLOW = 24 * 60 * 60 * 1000 * 1000;

では、整数リテラル同士のかけ算の結果がlong型変数に代入されています。問題はこのかけ算です。Java言語仕様§3.10.1「整数リテラル」には次のように書かれています。

整数リテラルは、ASCII文字Lまたはl(小文字のエル)が末尾にある場合、long型となり、それ以外の場合は、int型となる。

 つまり、右辺の24、60、1000といった整数はint型として解釈され、かけ算はint型の幅で演算されるということです。Javaのint型は、2の補数で表現される32ビット符号付き整数なので、表現できる値の範囲は-2,147,483,648から2,147,483,647です。一方、先ほどのかけ算の結果の値86,400,000,000は、int型の最大値を超えるため、整数オーバーフローが発生します。結果として、ラップアラウンドしたint型の値500,654,080が出力されたというわけです。

 このような単純な整数リテラル同士のかけ算であれば、オペランドの一つに接尾辞Lをつけるか、あるいはかけ算の一つをlongにキャストすることで、かけ算がlong型のビット幅で行われるようになり、オーバーフローを防ぐことができます(これを「アップキャスト」と呼びます)。

long NO_OVERFLOW = 24L * 60 * 60 * 1000 * 1000; //  あるいは (long)24 * 60 * ... 

 様々な整数型変数が混在する複雑な式になると、整数オーバーフローは発見しづらくなります。また、整数値がプログラムの外部から取得される場合、攻撃に悪用される危険もあるでしょう。

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

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

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

メールバックナンバー

次のページ
Javaにおける整数オーバーフロー

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

  • このエントリーをはてなブックマークに追加
Javaセキュアコーディング入門連載記事一覧

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/6309 2011/12/16 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング