NDKでforkを利用して、ネイティブ上で常駐する子プロセスを作成することはダメなのでしょうか?

591 views
Skip to first unread message

masa

unread,
May 1, 2014, 5:22:40 AM5/1/14
to android-g...@googlegroups.com
NDKでforkを利用して、ネイティブ上で常駐する子プロセスを作成することはダメなのでしょうか?
このようなブログを見つけました。http://d.hatena.ne.jp/embedded/20110605/p1

やりたい事はアプリ(自分)をアンインストールした場合、その情報をサーバ側に通知したいと思っています。
Android SDK上では、自分自身のPACKAGE_REMOVEDのブロードキャストを受信できないために無理と判断しました。

NDK上からforkで子プロセスを作成して、そのプロセスがアプリのファイル(ディレクトリ)削除をinotify_add_watchを利用して
自分自身のディレクトリが削除されたタイミングで、サーバと通信を行うサンプルプログラムを作成しました。
テストでは問題なくアンインストール時にファイルアクセスを検知してサーバと通信を行いまたが、上記の書きこみ気になり質問させていただきました。


Shigeo Mutoh

unread,
May 1, 2014, 11:07:05 AM5/1/14
to android-g...@googlegroups.com
武藤です。

面白いアプローチで興味深いです。

たぶん、ひとつの.apkの中に、本来の仕事をする部分と、uninstallを監視する
部分とで分かれていて、forkした後execしないという方針なのではないかと
思うのですが違います?

だとすると、ロードする自.apkが削除されたり、自group/user idが削除
されたりすれば、もはや死に体です。

しかしそれでも、ほんのしばらくの間生きていることは珍しくないので、
うまく動くようには見えるけれど、そりゃ危険すぎるということでは
ないでしょうか。

では。

Message has been deleted

masa

unread,
May 1, 2014, 10:00:26 PM5/1/14
to android-g...@googlegroups.com
返信ありがとうございます。

> たぶん、ひとつの.apkの中に、本来の仕事をする部分と、uninstallを監視する 
> 部分とで分かれていて、forkした後execしないという方針なのではないかと 
> 思うのですが違います? 

その通りです。apkの本来の機能は社内の資産管理を行うアプリなので、ユーザが自分からアプリをアンインストールした場合に、
その情報をサーバに通知する必要があります。

実装部分のコードは以下になります。(大分省いていますが・・)
起動時に1回呼ばれfork後に作成された子プロセスが常時アンインストールを監視します。


pid_t pid = fork();

if (pid == 0) {

//forkで子プロセスとして実行される

int fd = inotify_init();
if (fd < 0) {
return false;
}

//監視対象のディレクトリ(自分自身)を指定
int wd = inotify_add_watch(fd, "data/data/hogehoge", IN_DELETE);
if (wd < 0) {
return false;
}

void *p_buf = malloc(sizeof(struct inotify_event));
if (p_buf == NULL) {
return false;
}

//アンインストールされるまで待機
size_t readBytes = read(fd, p_buf, sizeof(struct inotify_event));
free(p_buf);

inotify_rm_watch(fd, IN_DELETE);


//ここにアンインストール時に行いたい処理を追加
}


一応手持ちのNexus7では成功したのですが、実運用で全端末でテストした場合にアンインストールの検知ができない、
もしくは、アプリ(親プロセス)が落ちる端末が出ることを懸念しています。

2014年5月2日金曜日 0時07分05秒 UTC+9 TM:

Shigeo Mutoh

unread,
May 1, 2014, 11:13:32 PM5/1/14
to android-g...@googlegroups.com
武藤です。

だいたい思ったとおりの実装ですね。
どのみち危険ではあると思うのですよ。

まず現状のandroid osの実装ではforkを禁止していないけれど、いつ
禁止されるかわからないのがひとつ。

またはuninstall時に、該当プロセスの子プロセスを皆殺しにするように
いつされるかわからないのがひとつ。

あと、どうやって監視プロセスが綺麗に死ねるかという問題。
親プロセスが先に死んでるから子はzonbe化しませんか?
コールスタックは綺麗に巻き戻るわけにいかないので、exitしているのかな?
そうすると何かグローバルなリソースをリークさせたりしませんか?

心配事が尽きません。

では。

(2014/05/02 10:58), masa wrote:
> 返信ありがとうございます。
>
>> たぶん、ひとつの.apkの中に、本来の仕事をする部分と、uninstallを監視する
>> 部分とで分かれていて、forkした後execしないという方針なのではないかと
>> 思うのですが違います?
>
> はい、apkの本来の機能は社内の資産管理を行うアプリなので、ユーザが自分からアプリをアンインストールした場合に、
> その情報をサーバに通知する必要があります。
>
> 実装部分のコードは以下になります。(大分省いていますが・・)
> 起動時に1回呼ばれfork後に作成された子プロセスが常時アンインストールを監視します。
>
>
> pid_t pid = fork();
>
> if (pid == 0) {
>
> //forkで子プロセスとして実行される
>
> int fd = inotify_init();
> if (fd < 0) {
> return false;
> }
>
> //監視対象のディレクトリ(自分自身)を指定
> int wd = inotify_add_watch(fd, "data/data/hogehoge", IN_DELETE);
> if (wd < 0) {
> return false;
> }
>
> void *p_buf = malloc(sizeof(struct inotify_event));
> if (p_buf == NULL) {
> return false;
> }
>
> //アンインストールされるまで待機
> size_t readBytes = read(fd, p_buf, sizeof(struct inotify_event));
> free(p_buf);
>
> inotify_rm_watch(fd, IN_DELETE);
>
>
> //ここにアンインストール時に行いたい処理を追加
> }
>
>
> 一応手持ちのNexus7では成功したのですが、実運用で全端末でテストした場合にアンインストールの検知ができない、
> もしくは、アプリ(親プロセス)が落ちる端末が出ることを懸念しています。
>
>
>
>
> 2014年5月2日金曜日 0時07分05秒 UTC+9 TM:
>>

masa

unread,
May 2, 2014, 1:23:30 AM5/2/14
to android-g...@googlegroups.com
ご指摘ありがとうございます。

確かに、子プロセスの終了するタイミングが分からないのは怖いですね。偶然手持ちの端末がうまく動いているだけの可能性もありますし。
また、他のバグでアプリ本体が落ちたときにシステム自体が30秒ほどフリーズする現象が発生しました・・・

Google側もこの機能の需要を見越して、アンインストール実行前にブロードキャストされるイベントを作成して欲しいですね(希望)
ただ、現実的に悪意のあるソフトウェアなどがアンインストールの妨害など、セキュリティ上の問題になりそうなのも確かだと思います。


2014年5月2日金曜日 12時13分32秒 UTC+9 TM:

Makoto Yamazaki

unread,
May 2, 2014, 2:32:02 AM5/2/14
to android-g...@googlegroups.com
zakI です。

社内の資産管理のアプリなのであれば、 Android の DeviceAdministration の機能を使って
実装するのが正攻法に思います。DeviceAdministration 対応のアプリでは、設定画面で一度
DeviceAdmin としてアプリを登録すると設定画面から登録解除するまでアンインストール
できなくなります。また、DeviceAdmin として登録されているアプリは設定画面から
登録解除された際に通知を受け取ることが出来るので、アプリのアンインストール時ではなく、
DeviceAdmin の登録解除されたときにサーバへ通信することができます。





2014-05-02 10:58 GMT+09:00 masa <minadu...@gmail.com>:
返信ありがとうございます。

> たぶん、ひとつの.apkの中に、本来の仕事をする部分と、uninstallを監視する 
> 部分とで分かれていて、forkした後execしないという方針なのではないかと 
> 思うのですが違います? 





2014年5月2日金曜日 0時07分05秒 UTC+9 TM:
武藤です。

--
このメールは Google グループのグループ「日本Androidの会」に登録しているユーザーに送られています。

このグループから退会し、グループからのメールの配信を停止するには android-group-j...@googlegroups.com にメールを送信してください。
このグループに投稿するには android-g...@googlegroups.com にメールを送信してください。
http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。



--
YAMAZAKI Makoto

Shigeo Mutoh

unread,
May 2, 2014, 5:49:59 AM5/2/14
to android-g...@googlegroups.com
武藤です。

私も同感です。
ただ、uninstall時に通信可能である前提が夢物語に思えますから、
確実にuninstallをサーバに伝えることは、100%は不可能だと思います。

なので結局のところ、いわゆる運用でカバー(おまいらuninstallしたら
即クビだ!)するか、pollingベースで稼動していることを一定間隔で
通知し続け、pollingが止んだら障害発生かuninstallの疑いということで
本人呼び出しの上現行犯逮捕するぐらいしか手がないと思います。

では。

masa

unread,
May 7, 2014, 3:06:26 AM5/7/14
to android-g...@googlegroups.com
返信遅れてしまい申し訳ありませんでした。
知らないことまで教えていただきありがとうございます。

>> Zaiさん
DeviceAdministrationに関して少し調べてみました。
今回の開発ではユーザに対してデバイス管理の設定をしていただくなど一手間をかけさせるのが難しいため使えない可能性が高い感じがします。
運用面でのアンインストールしないようにアナウンスする形で落とそうと思っています。
ただ、個人的に興味があるので引き続き調べてみます。

>>TMさん
おっしゃる通り運用面でアンインストールしないようにアナウンスを行い、使用していただく方法で考えたいと思います。




斎藤良太

unread,
May 7, 2014, 3:12:44 AM5/7/14
to android-g...@googlegroups.com
斎藤といいます。

いわゆるMDMサービスなどを利用するのはダメなんでしょうか?

2014年5月7日 16:06 masa <minadu...@gmail.com>:
> --
> このメールは Google グループのグループ「日本Androidの会」に登録しているユーザーに送られています。
> このグループから退会し、グループからのメールの配信を停止するには
> android-group-j...@googlegroups.com にメールを送信してください。
> このグループに投稿するには android-g...@googlegroups.com にメールを送信してください。
> http://groups.google.com/group/android-group-japan からこのグループにアクセスしてください。
> その他のオプションについては https://groups.google.com/d/optout にアクセスしてください。



--
SAITO Ryota 斎藤 良太
Rising System Inc.
@ryotasaito
ry...@risingsystem.co.jp
Reply all
Reply to author
Forward
0 new messages