2017-03-25 31 views
0

自分のデバイス用のカスタムカーネルlinuxをビルドしています(埋め込みデバイスなど)。 killシステムコールのすべての情報を記録したい。だから私は、システムコールを殺すコードを修正し、殺すためにPIDを取得します。しかし、私はそれのための完全なプロセスのパスを取得することはできません、私はちょうど現在のプロセスのフルパスを取得しています。 これは私のコードは、プロセスパスをPIDから取得することです。カーネルlinuxのpidからフルプロセスパスを取得

long GetProcessPathFromPid(const pid_t p_id, char* pszProcessPath, int iSize) 
{ 
    struct task_struct *task = NULL; 
    struct pid *pid_struct = NULL; 
    struct mm_struct *mm = NULL; 
    //struct file *exe_file = NULL; 
    //char buf[256] = {0}; 
    //char *result = ERR_PTR(-ENOENT); 
    //int iResultLength = 0; 

    pid_struct = find_get_pid(p_id); 
    if (pid_struct == NULL) 
    { 
     printk("Fail to find_get_pid.\n"); 
    } 
    task = pid_task(pid_struct, PIDTYPE_PID);        // Get task_struct 
    if (task == NULL) 
    { 
     printk("Fail to pid_task.\n"); 
    } 
    mm = get_task_mm(task);            // Get mm of task_struct 
    mmput(mm); 

    printk("Finish hook kill process\n."); 
    return 0;            // Get mm of task_struct 
} 

そして、私は、ファームウェアを更新するとき、これは誤りです:

Call Trace: 
[<8042971c>] printk+0x24/0x30 
[<800c37c8>] GetProcessPathFromPid+0x38/0x88 
[<800c3b60>] LogKillProcess+0x64/0xf4 
[<800443d4>] sys_kill+0x30/0x1d8 
[<800354b0>] do_wait+0x11c/0x220 
[<8042e234>] wait_for_completion_killable+0x18/0x30 
[<80043a3c>] set_current_blocked+0x30/0x48 
[<>] repair_env_string+0x0/0x94 
[<8003664c>] sys_wait4+0x80/0xfc 
[<800344d8>] child_wait_callback+0x0/0x8c 
[<>] repair_env_string+0x0/0x94 
[<8001b59c>] stack_done+0x20/0x40 
[<800b07a8>] sys_close+0x0/0x158 
[<>] repair_env_string+0x0/0x94 


Call Trace: 
[<8042fe88>] _raw_spin_lock+0x10/0x3c 
[<8002ef68>] get_task_mm+0x20/0x7c 
[<800c37c8>] GetProcessPathFromPid+0x38/0x88 
[<800c3b60>] LogKillProcess+0x64/0xf4 
[<800443d4>] sys_kill+0x30/0x1d8 
[<8001b59c>] stack_done+0x20/0x40 


Code: 24630001 af830014 3c020001 <c0830000> 00622821 e0850000 10a0fffc 00032c02 3063ffff 
pe=GPON 

---[ end trace aee100dae37dfc66 ]--- 
note: init[1] exited with preempt_count 1 
FinWLmngr Daeish hook kill process 
.mon is running 
!!!! PLL locked !!!!!!  !!!! RX CDR locked !!!!!!  !!!! TX CDR locked !!!!!! GPON BEN Calibration Done 
GPON SerDes Initialization Sequence Done 
Kernel panic - not syncing: Attempted to kill init! exitcode=0x0000000b 

あなたは私を助けることができますか?ありがとう!

+0

エラーメッセージ(失敗した場合)は何ですか? pidは何ですか?カーネルに '/ proc/$ PID/exe'リンクを生成するコードがあります:http://lxr.free-electrons.com/source/fs/proc/base.c?v=4.8#L1556 fs/proc/base.c 'proc_exe_link'は' get_proc_task'/'get_task_exe_file' /' path_get'を使います。 – osgx

+1

これはチェックアウトしません。間違った実行可能パスを取得するか、カーネルパニックを起こしますか? –

+0

フルパスプロセスの検索にその関数を使用することはできませんが、解決方法が見つかりました。ご協力ありがとうございました! – rum

答えて

0

pidからフルパスプロセスを取得する方法が見つかりました。 フルパスプロセスは/ proc // exeのシンボリックリンクですので、シンボリックリンクを見つける必要があります。 ここにコードは

long GetSymLinkOfFile(const char *pzsFilePath, char *pszRealPath, int iSize) 
{ 
    struct path path_struct; 
    char pszBuffer[256]; 
    char *result = ERR_PTR(-ENOENT); 
    int err = 0; 
    int iLengthOfResult = 0; 

    if (pzsFilePath == NULL || pszRealPath == NULL) 
    { 
     printk("Buffer is NULL.\n"); 
     return -EINVAL; 
    } 

    err = kern_path(pzsFilePath, LOOKUP_FOLLOW, &path_struct); 

    if (err < 0) 
    { 
     printk("kern_path error, error code: %d", err); 
     return iLengthOfResult; 
    } 

    result = d_path(&path_struct, pszBuffer, 256); 

    if (IS_ERR(result) == true) 
    { 
     printk("d_path GetSymlink error: %s", result); 
     return iLengthOfResult; 
    } 

    iLengthOfResult = strlen(result); 

    if (iLengthOfResult <= iSize) 
     strcpy(pszRealPath, result); 

    return iLengthOfResult; 
} 
関連する問題