Android 搭載スマートブック IS01 by SHARP (愛称 「メガネケース」) が、 本体価格 0円 + 契約事務手数料 2835円 + 月々 8円 * 2年しばり = 3027円 で入手できるとネット上で話題になっていたので買ってみた。 メジャーアップデート対応なしと公式に宣告されてしまった IS01 ではあるが、 「ワンセグ放送が視聴できて WiFi 通信もできるポメラもどき」 と割りきったとしても激安なので 「ふたつでじゅうぶんですよ」 と言われつつ 3つ入手した。
「グローバル展開もしていないから xda の助けも得られない」 と総統閣下に嘆かれつつも、 RageAgainstTheCage exploit を利用すれば root になることは一応できる (ベースバンドバージョン / ビルド番号 01.00.07 で確認):
senri:/home/sengoku % adb push rageagainstthecage /data/local/tmp/ senri:/home/sengoku % adb shell $ cd /data/local/tmp $ chmod 755 rageagainstthecage $ ./rageagainstthecage [*] CVE-2010-EASY Android local root exploit (C) 2010 by 743C [*] checking NPROC limit ... [+] RLIMIT_NPROC={1856, 1856} [*] Searching for adb ... [+] Found adb as PID 8223 [*] Spawning children. Dont type anything and wait for reset! [*] [*] If you like what we are doing you can send us PayPal money to [*] 7-4-3-C@web.de so we can compensate time, effort and HW costs. [*] If you are a company and feel like you profit from our work, [*] we also accept donations > 1000 USD! [*] [*] adb connection will be reset. restart adb server on desktop and re-login. $ senri:/home/sengoku % adb shell #
ただし rageagainstthecage はタイミングが良くないと失敗するので、 少なくとも数回は繰り返し実行しないと root が取れない (運が悪いと何度実行しても成功しない上に adb で接続できなくなって再起動する羽目に陥ることも)。 IS01 を再起動するたびに rageagainstthecage を実行して root を取り直すのは著しく手間なので、 root が取れたら su コマンドをインストールしておくべき。
インストール先は、 一般ユーザ (shell 権限) でアクセス可能で、 かつ再起動しても消えない (つまり tmpfs とかでない) ボリュームで、 かつ mount 時に nosuid オプションをつけられていないことが必須条件になるが、 幸い IS01 ではフラッシュメモリ /dev/block/mtdblock7 が /sqlite_journals に nosuid 無しで mount されている:
senri:/home/sengoku % adb shell $ grep -v '\(tmpfs\|nosuid\)' /proc/mounts rootfs / rootfs ro 0 0 devpts /dev/pts devpts rw,mode=600 0 0 proc /proc proc rw 0 0 sysfs /sys sysfs rw 0 0 /dev/block/mtdblock7 /sqlite_journals yaffs2 rw 0 0 /dev/block/mtdblock5 /system yaffs2 ro 0 0 $ ls -l /sqlite_journals drwxrwx--x system system 1980-01-06 09:00 com.android.providers.settings drwxrwx--x system system 1980-01-06 09:00 com.android.providers.settingsex drw-rw-rw- root root 2010-11-26 18:51 lost+found
sqlite_journals というディレクトリ名からして SQLite 用のディレクトリと思われるが、 それならなぜ nosuid がつけられていないのだろうか? ガチガチに防御を固めているはずの IS01 にしては珍しい抜け穴の一つ。
ちなみに上記のように /dev/block/mtdblock5 も /system ディレクトリに nosuid オプション無しでマウントされているが、 こちらはカーネルの MTD ドライバで書き込みが禁止されている (SHARP が公開している IS01 のカーネル kernel/drivers/mtd/devices/msm_nand.c 参照) ので、 簡単には変更できそうにない (少なくとも rw で remount するだけでは書込めない)。
というわけで /sqlite_journals に bin ディレクトリを作って ChainsDD の su コマンド (android_system_extras に含まれる) を置いてみる。
# ls -l /sqlite_journals/bin/su -rwsr-sr-x 1 root root 26256 Aug 17 17:27 /sqlite_journals/bin/su
ところが!
senri:/home/sengoku % adb shell $ /sqlite_journals/bin/su su: permission denied
su コマンドにはちゃんと setuid ビットを立てているのに、 なぜ 「permission denied」? と思って Android のエラーログを見てみると、
senri:/home/sengoku % adb logcat ... E/su ( 4804): Getting exe path failed with 13: Permission denied E/su ( 4804): Getting exe path failed with 13: Permission denied W/su ( 4804): request rejected (2000->0 /system/bin/sh)
このエラーを出しているのは、 android_system_extras/su/su.c の 100行目あたり:
/* If this isn't app_process, use the real path instead of argv[0] */ snprintf(path, sizeof(path), "/proc/%u/exe", from->pid); len = readlink(path, exe, sizeof(exe)); if (len < 0) { PLOGE("Getting exe path"); return -1; } exe[len] = '\0'; if (strcmp(exe, "/system/bin/app_process")) { argv0 = exe; }
えっ? 「/proc/*/exe」 のリンクが読めないってこと?
# echo $$ 5374 # ls -l /proc/*/exe ls: /proc/1/exe: cannot read link: Permission denied lrwxrwxrwx 1 root root 0 Nov 27 10:50 /proc/1/exe ... ls: /proc/5374/exe: cannot read link: Permission denied lrwxrwxrwx 1 root root 0 Nov 27 08:37 /proc/5374/exe ... #
うむ〜 root 権限を持っていても root のシンボリックリンクを読めないとわ...
どこまで面倒くさいカーネルなんだ > SHARP
root 権限で /proc/*/exe を読めないのは困ったものだが、 su コマンドが /proc/*/exe を読もうとするのは su コマンドの呼び出し元の cmdline の argv[0] の代りに 「real path」 を調べるためなので、 su コマンドをアプリから呼ぶ限りにおいては、 この処理をスキップしてしまって特に問題はない。
su.c から /proc/*/exe を読もうとする部分 (上で引用した部分) をばっさり削除して su コマンドをビルドし直す:
senri:/usr/local/src/Android/donut % git clone -b donut git://github.com/ChainsDD/android_system_extras.git senri:/usr/local/src/Android/donut % sh $ . build/envsetup.sh including vendor/aosp/vendorsetup.sh $ cd android_system_extras $ mm ============================================ PLATFORM_VERSION_CODENAME=REL PLATFORM_VERSION=1.6 TARGET_PRODUCT=generic TARGET_BUILD_VARIANT=eng TARGET_SIMULATOR= TARGET_BUILD_TYPE=release TARGET_ARCH=arm HOST_ARCH=x86 HOST_OS=linux HOST_BUILD_TYPE=release BUILD_ID=Donut ============================================ make: Entering directory `/usr/local/src/Android/donut' target thumb C: perm_checker <= /usr/local/src/Android/donut/android_system_extras/tests/fstest/perm_checker.c ... Install: out/target/product/generic/system/xbin/su ...
できた out/target/product/generic/system/xbin/su を IS01 の /sqlite_journals/bin/su へコピーし、 chown root:root および chmod 6755 する。 Android マーケットから ChainsDD の Superuser アプリをインストールしておいて、 /sqlite_journals/bin/su を実行すれば、
↑ のような画面が表示がされるので、 「許可」 ボタンを押せばよい。 「記憶する」 にチェックをつけておけば、 su コマンドの呼び出し元 (今回はコマンドラインから呼び出しているので /system/bin/sh) が同一である限り、 ユーザへの問合わせ無しに自動的に許可される。
さて、 これで su コマンドが使えるようになったが、 アプリから su コマンドを呼び出すには PATH が通っているところ、 すなわち /system/bin 以下に su コマンドを置く必要がある。
ところが root 権限があっても /system 以下には書込めないのが IS01 の困ったところ。 仕方ないので私は以下のような shell スクリプトを実行して /system を umount し、 /system ディレクトリを作って /system/bin を /sqlite_journals/bin へのシンボリックリンクにしている。
#!/system/bin/sh export PATH=/sqlite_journals/xbin:/system/bin mount -w -oremount null / mkdir /system.org mkdir /system.new mount -obind /system /system.org cd /system.org for f in [a-o]* pubkey [q-z]*; do ln -s /system.org/$f /system.new/$f done cd / umount -l /system; rmdir /system; mv /system.new /system ln -snf /sqlite_journals/xbin /system/xbin ln -snf /sqlite_journals/bin /system/bin
これで /system/bin が書込み可能になった。 元々 /system/bin 以下にあったコマンドを /sqlite_journals/bin へコピーしておけばよい。
署名募集中 – IS01 に Android2.2 を!
月々実質8円で運用できると話題のキーボー…
Trackback by 侍ズム — 2010年11月28日 @ 12:57
IS01のビルド番号 01.00.09なのですが、
/sqlite_journals/bin に入れたsuコマンドを実行することができないです。
Comment by kako — 2010年11月30日 @ 03:12
「grep /sqlite_journals /proc/mounts」と
「ls -l /sqlite_journals/bin/su」の実行結果はどうなります?
# grep /sqlite_journals /proc/mounts
/dev/block/mtdblock7 /sqlite_journals yaffs2 rw 0 0
# ls -l /sqlite_journals/bin/su
-rwsr-sr-x 1 root root 26228 Nov 27 13:55 /sqlite_journals/bin/su
Comment by hiroaki_sengoku — 2010年11月30日 @ 10:10
IS01を再起動してsuが動作しない状態のまま、termnalで
ls -l /sqlite_journals/bin/su
を実行してみました。
結果は
-rwsr-sr-x shell shell 26228 2010-11-27 18:17 su
となりました。
あと、grepは実行できないので
cat /proc/mountsをみました
/dev/block/mtdplock7 /sqlite_journals yaffs2 rw 0 0
となっていました。
ご参考になりましたら幸いです。
Comment by kako — 2010年11月30日 @ 12:15
ownerの設定していなかったのが問題のようで
rageagainstthecageを動かしたあと、
# cd /sqlite_journals/bin
# chown root su
# chmod 6755 su
として設定して、再起動後にsuコマンドを動作させることができました。
これを試す時に、デバッグモードを有効にするのを忘れていて
rageagainstthecageが動かなくなるという現象で、原因に気が付かず、
結果をここに書くのが遅くなりました。
Comment by kako — 2010年11月30日 @ 15:10
なるほど。chown root に言及するのを忘れていました。
ご指摘に感謝します。
IS01 の /sqlite_journals/bin/su へコピーし、
chmod 6755 する
を
IS01 の /sqlite_journals/bin/su へコピーし、
chown root:root および chmod 6755 する
に修正しました。
Comment by hiroaki_sengoku — 2010年11月30日 @ 15:22
is03はできないですよね
今度試してみます
Comment by fd — 2010年12月3日 @ 23:16
初めましてIS01とwpa2-EAPで検索してここに来ました。
実はIS01を使用していて、wpa2-EAPに繫げられず困っています。
もしできるのならばその方法をお教えて貰えませんか?
自分で試した方法は
mobilehackerzのIS01root.apkをインストール
ChainsDD の Superuser をインストール
Fan ZhangのWifi Helper ver.1.1.1をインストール
wifi helperでNET名,wpq2 enterprise, ID, passを設定して保存
本体の通信設定でNET名から繋ごうとしてまた、ID,passを入力するも
繋がる気配がありません。
(恐らく証明書が必要なのでしょうが、ここから先どうして良いか分かりません)
よろしくお願いします。
Comment by kk — 2010年12月4日 @ 05:11
Android 1.6 で WPA2 EAP は難易度が高いですね。
まずは (1.6以外の) 確実に EAP 接続できるクライアントで
接続できるか確認することから始めてみてはいかがでしょうか?
ちなみに Fan Zhang の Wifi Helper って、
Android Market に登録されている 1.1.1 は、
*This App does not work ANY MORE*
と書いてあるようですが…
Comment by hiroaki_sengoku — 2010年12月7日 @ 09:08
初めまして。IS03で/system以下への書き込みの方法を探してここに辿り着きました。
root化は既に済んでいますが、suにpathを通せなくて困っていました。
最後のshellスクリプトと同じ手がIS03でも使えそうだと思ったのですが、
このスクリプトは端末を再起動させるたびに実行させる必要があるという認識でいいのでしょうか?
言い換えれば、何かあっても電源を入れなおせば元に戻ることが期待できるかということにもなるのですが。
Comment by Isawo-Kikuchi — 2011年5月3日 @ 00:23
ご認識の通りだとは思いますが、あくまで自己責任でお願いします。
つまり何が起きても、ご自身の責任において対処していただきたいと思いますし、私としては一切の責任を負えません。
特に、IS03 など私が持っていない端末に関しては、トラブル復旧のお手伝いがしたくても、原因究明のすべがありませんので (持ってる端末ならお手伝いするかというと、それは時と場合によりけり… ^^;)。
Comment by hiroaki_sengoku — 2011年5月3日 @ 15:57
お返事ありがとうございます。
すでに試させて頂きましたが、IS03は/systemをアンマウントできなくなっているようで。そこはなんとか回避して/systemをいじれるようになったのですが、今度は「不正なアプリケーションが~」と出て再起動を余儀なくされたりと、苦戦中です。ご報告まで。
Comment by Isawo-Kikuchi — 2011年5月3日 @ 16:26