プロテクションレベルの歴史とAndroid 6.0での変更点

A+ a-

Android6.0でパミッションモデルの大きな変更が加わりました、その中でINTERNETパミッションのプロテクションレベルがDANGEROUSからNORMALに変更されるなどパミッションのプロテクションレベルの再調整も行われました。

パミッションのプロテクションレベルの変更だけではなく、プロテクションレベルの値の持ち方も変更になりましたので、簡単に解説したいと思います。只開発に役立つか?というと、特殊な領域やっている開発者以外は殆ど役立たない小ネタ知識なので、頭の隅にでもおいておいてもらえたらと思います。

PermissionInfoクラス


PermissionInfoというパミッション情報を纏めるクラスがありますが、Developer Siteを見ると、Android6.0になり記載事項が多くなっておりかなり変更があるように感じられます。実際追加された値も多くなっています。



PermissionInfoクラスの歴史


Android 6.0での変更点を説明する前に、過去にどのような変更があったのかを簡単に説明したいと思います。

パミッションのプロテクションレベルといえば、normal,dangerous,signature,signatureOrSystemの4つを思い浮かべると思います。Android 4.0までは以下のようなシンプルな形となっています。

public static final int PROTECTION_NORMAL = 0;
public static final int PROTECTION_DANGEROUS = 1;
public static final int PROTECTION_SIGNATURE = 2;
public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;
そして、Android 4.1(API Level16)で以下のようなフラグが追加されました。

public static final int PROTECTION_FLAG_SYSTEM = 0x10;
public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;
public static final int PROTECTION_MASK_BASE = 0xf;
public static final int PROTECTION_MASK_FLAGS = 0xf0;

PROTECTION_FLAG_SYSTEMとPROTECTION_FLAG_DEVELOPMENTというフラグが追加され、int protectionLevelの上位ビットにフラグを下位ビットビットに今までのプロテクションレベル(ベースプロテクションレベル)を入れるようになりました。この時代に上位ビット下位ビットだと!!と殺意が沸いたのを思い出します。

さらにFLAG_SYSTEMとSIGNATURE_SYSTEMで「SYSTEM」がダブっているので非常にわかりにくい!案の定以下のような事に…

理論的(使うかどうかは別として)には一つのベースプロテクションレベルに付4つのパターンが発生する事になります。

  1. dangerous
  2. dangerous|system
  3. dangerous|development
  4. dangerous|system|development
dagerousの場合はわかりやすいのですが、signatureOrSystemとなると
  1. signatureOrSystem
  2. signatureOrSystem|system
  3. signatureOrSystem|development
  4. signatureOrSystem|system|development

となり2番目と3番目が、システム、システムって何?と不明瞭ですし、また、
signatureOrSystemとsignature|system
どう違うの??と、ちょっとわけわからなくなります。


その後Android 4.2ではCONSTS_MONEYが追加

public int flags;
public static final int FLAG_COSTS_MONEY = 1<<0;
Android 5.1では例のAPPOPが追加

public static final int PROTECTION_FLAG_APPOP = 0x40;
といった感じで変化してきてました。

Android 6.0 (API Level23)の変更点

そして、今回のAndroid6.0では以下の変更がありました。

1.PTOTECTION_FLAGS_SYSTEMの名称変更

先に述べたAPI Level16で追加された、PROTECTION_FLAG_SYSTEMが非推奨になり、代りにPROTECTION_FLAG_PRIVILEGED が追加されました。
PROTECTION_FLAG_SYSTEM とPROTECTION_FLAG_PRIVILEGED は値が同じなので実質名前変更です。

2.SignatureOrSystemの名称廃止

PROTECTION_SIGNATURE_OR_SYSTEMが非推奨になり、代りにPROTECTION_SIGNATURE|PROTECTION_FLAG_PRIVILEGEDを使うようになりました。実質ベースプロテクションレベル4個が3つになりました。これで、以前のごちゃごちゃがようやくなくなりました。

纏めると以下のようになります。

Android6.0前Android 6.0以降
signaturesignature
signature|systemsignature | privileged
signatureOrSystemsignature | privileged
signatureOrSystem|system使用しない

ただManifestの方への記載は、非推奨にはなっていません。非推奨わすれなのか、影響があるアプリがあるからなのか、ちょっとどちらかかはわかりません。
http://developer.android.com/intl/ja/reference/android/R.attr.html#protectionLevel

3.複数のPROTECTION_FLAGフラグ追加

Int protectionLevelの上位ビット等ではなく、ちゃんとflag変数に保存されます
  • PROTECTION_FLAG_APPOP
  • PROTECTION_FLAG_PRE23
  • PROTECTION_FLAG_INSTALLER
  • PROTECTION_FLAG_VERIFIER
  • PROTECTION_FLAG_PREINSTALLED


各フラグの詳細は、なんとなく名前見ればわかりますが、Nexus 5X既に届いている人もいるのに、全然私の所には届く気配がないので、きちんと調査する気になりません。


付録

以下のToStringメソッドを読むとわかりやすいので貼っておきます

    /** @hide */
190    public static String protectionToString(int level) {
191        String protLevel = "????";
192        switch (level&PROTECTION_MASK_BASE) {
193            case PermissionInfo.PROTECTION_DANGEROUS:
194                protLevel = "dangerous";
195                break;
196            case PermissionInfo.PROTECTION_NORMAL:
197                protLevel = "normal";
198                break;
199            case PermissionInfo.PROTECTION_SIGNATURE:
200                protLevel = "signature";
201                break;
202            case PermissionInfo.PROTECTION_SIGNATURE_OR_SYSTEM:
203                protLevel = "signatureOrSystem";
204                break;
205        }
206        if ((level&PermissionInfo.PROTECTION_FLAG_PRIVILEGED) != 0) {
207            protLevel += "|privileged";
208        }
209        if ((level&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT) != 0) {
210            protLevel += "|development";
211        }
212        if ((level&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
213            protLevel += "|appop";
214        }
215        if ((level&PermissionInfo.PROTECTION_FLAG_PRE23) != 0) {
216            protLevel += "|pre23";
217        }
218        if ((level&PermissionInfo.PROTECTION_FLAG_INSTALLER) != 0) {
219            protLevel += "|installer";
220        }
221        if ((level&PermissionInfo.PROTECTION_FLAG_VERIFIER) != 0) {
222            protLevel += "|verifier";
223        }
224        if ((level&PermissionInfo.PROTECTION_FLAG_PREINSTALLED) != 0) {
225            protLevel += "|preinstalled";
226        }
227        return protLevel;
228    }

最後に

普通アプリ書いてる時に、パミッションのフラグの値が.... なんて事はないと思いますので、興味がある人は少ないんじゃないかと思います。RiskFinder的にはアンドロイドのソースコードを解析プログラムにかけて情報とったりするので、こういう変更は結構いやな物です。結局新、旧両方の仕様に対応しなきゃいけませんし...
といいつつ、このあたりのコードがすっきりしたので、良い変更だなと思いました。

ブログをGoogleのBloggerに変更したのですが、なかなか慣れません。
テーブルとか見にくいし、ソースコード等もいまいち見にくくて申し訳ありません。
すこすずつ改善します。

がく

がく

アンドロイドアプリの脆弱性検査ツールのRiskFinder株式会社 代表取締役 スマフォのセキュリティ色々やってます。

リスクファインダーはAndroidアプリのセキュリティホールを見つけます!

Androidスマートフォンが急速に普及するとともにアプリの脆弱性報告も急増しています。
リスクファインダーは、Androidアプリの脆弱性診断WEBサービスです。
500項目以上のチェックでアプリの脆弱性や問題を検出し、セキュアなアプリ開発をサポートします。

  • ブラウザでファイルをアップロードするだけ
  • アプリの脆弱性を指摘するだけでなく対処方法も提示
  • 頻繁にバージョンアップするAndroidの最新情報に素早く対応

リスクファインダーの詳細はこちら