無料Wikiサービス | デモページ
検索

アクセス数
最近のコメント
kprobe - ななし
ksetの実装 - スーパーコピー
カーネルスレッドとは - ノース
カーネルスレッドとは - nbyst
asmlinkageってなに? - ノース
asmlinkageってなに? - よろしく
はじめ - ノース
はじめ - ノース
はじめ - 楽打連動ユーザー
はじめ - 楽打連動ユーザー
Adsense
広告情報が設定されていません。

スクリプトファイルの起動(補足)


スクリプトファイルの起動で、シェルスクリプトはカーネルが起動する。としていましたが、さらに調べてみると、シェルスクリプトはシェル自身が起動しているようです。fedora16ですが、lsmodすると、それらしいモジュールがinsされていません。search_binary_handlerにて動的にinsしているのかな?
[root@localhost kitamura]# lsmod | grep binfmt
binfmt_misc            17207  1
search_binary_handle()は、formatsをヘッドとするリスト登録されているstruct linux_binfmtをチェックし、なければ、対応するフォーマットのモジュールをinsする事で、再度リストを捜査していました。

CONFIG_MODULESの時(でないとlkmが利用できない。)、動的にモジュールをinsします。1回目の走査の結果が、ENOEXEC(該当するフォーマットが無い)時、request_moduleマクロで動的にモジュールをinsします。

ただし、先頭の4バイトがタブ/改行およびANKでない。事が条件です。従ってスクリプトファイルのようなテキストファイルでは、insされないと言う事です。

なお、insされるモジュール名は、2バイト目からの2バイトの16進数を、binfmt-に追加したものになります。
int search_binary_handler(struct linux_binprm *bprm,struct pt_regs *regs)
{
       unsigned int depth = bprm->recursion_depth;
       int try,retval;
       struct linux_binfmt *fmt;
       pid_t old_pid;

       retval = security_bprm_check(bprm);
       if (retval)
               return retval;

       retval = audit_bprm(bprm);
       if (retval)
               return retval;

       rcu_read_lock();
       old_pid = task_pid_nr_ns(current, task_active_pid_ns(current->parent));
       rcu_read_unlock();

       retval = -ENOENT;
       for (try=0; try<2; try++) {
               read_lock(&binfmt_lock);
               list_for_each_entry(fmt, &formats, lh) {
                       int (*fn)(struct linux_binprm *, struct pt_regs *) = fmt->load_binary;
                       if (!fn)
                               continue;
                       if (!try_module_get(fmt->module))
                               continue;
                       read_unlock(&binfmt_lock);
                       retval = fn(bprm, regs);

                       bprm->recursion_depth = depth;
                       if (retval >= 0) {
                               if (depth == 0) {
                                       UTRACE_HOOK(current, EXEC,
                                               report_exec(fmt, bprm, regs));
                                       ptrace_event(PTRACE_EVENT_EXEC,
                                                       old_pid);
                               }
                               put_binfmt(fmt);
                               allow_write_access(bprm->file);
                               if (bprm->file)
                                       fput(bprm->file);
                               bprm->file = NULL;
                               current->did_exec = 1;
                               proc_exec_connector(current);
                               return retval;
                       }
                       read_lock(&binfmt_lock);
                       put_binfmt(fmt);
                       if (retval != -ENOEXEC || bprm->mm == NULL)
                               break;
                       if (!bprm->file) {
                               read_unlock(&binfmt_lock);
                               return retval;
                       }
               }
               read_unlock(&binfmt_lock);
#ifdef CONFIG_MODULES
               if (retval != -ENOEXEC || bprm->mm == NULL) {
                       break;
               } else {
#define printable(c) (((c)=='\t') || ((c)=='\n') || (0x20<=(c) && (c)<=0x7e))
                       if (printable(bprm->buf[0]) &&
                           printable(bprm->buf[1]) &&
                           printable(bprm->buf[2]) &&
                           printable(bprm->buf[3]))
                               break; /* -ENOEXEC */
                       if (try)
                               break; /* -ENOEXEC */
                       request_module("binfmt-%04x", *(unsigned short *)(&bprm->buf[2]));
               }
#else
               break;
#endif
       }
       return retval;
}

補足

request_moduleマクロは、call_usermodehelper_fns()をコールする事で、ユーザプロセスコマンド/sbin/modprobeをカーネル下で実行しています。

シェルスクリプトは、先頭の#!行を削除しても、動作してくれるようです。カーネルが起動するなら、このような事はできません。


最終更新 2013/01/16 19:09:53 - north
(2013/01/16 19:05:28 作成)