2017-01-27 13 views
0

は私が認証するために、PAMライブラリを使用して、そのアプリケーションがエラーに失敗した:straceのことでなぜ、pam_loginuidモジュールが-EPERMを使って/ proc/self/loginuidへの書き込みに失敗するのですか?

Error writing /proc/self/loginuid: Operation not permitted 

は、私は/ procの/自己/ loginuidファイルへの書き込みに失敗していることがわかりました。

さらなる検査及び(以下のコード)をカーネルにいくつかのデバッグコードを追加:

static ssize_t proc_loginuid_write(struct file * file, const char __user * buf, 
        size_t count, loff_t *ppos) 
{ 
    struct inode * inode = file_inode(file); 
    uid_t loginuid; 
    kuid_t kloginuid; 
    int rv; 

    printk(KERN_DEBUG "proc_loginuid_write\n"); 

    printk(KERN_DEBUG "a+++ %s\n", current->comm); 
    printk(KERN_DEBUG "b+++ %s\n", pid_task(proc_pid(inode), PIDTYPE_PID)->comm); 
    printk(KERN_DEBUG "+++2++ pid = %d\n", current->pid); 
    printk(KERN_DEBUG "+++3++ pid = %d\n", pid_task(proc_pid(inode), PIDTYPE_PID)->pid); 

    rcu_read_lock(); 
    if (current != pid_task(proc_pid(inode), PIDTYPE_PID)) { 
     rcu_read_unlock(); 
     printk(KERN_ERR "proc_loginuid_write failed by permission!\n"); 
     return -EPERM; 
    } 
    rcu_read_unlock(); 


    if (*ppos != 0) { 
     /* No partial writes. */ 
     return -EINVAL; 
    } 

    rv = kstrtou32_from_user(buf, count, 10, &loginuid); 
    if (rv < 0) 
     return rv; 

    /* is userspace tring to explicitly UNSET the loginuid? */ 
    if (loginuid == AUDIT_UID_UNSET) { 
     kloginuid = INVALID_UID; 
    } else { 
     kloginuid = make_kuid(file->f_cred->user_ns, loginuid); 
     if (!uid_valid(kloginuid)) 
      return -EINVAL; 
    } 

    rv = audit_set_loginuid(kloginuid); 
    if (rv < 0) 
     return rv; 
    return count; 
} 

そのdmesgの中に示した:

[ 30.672242] proc_loginuid_write 
[ 30.672249] a+++ testapp 
[ 30.672251] b+++ testapp 
[ 30.672254] +++2++ pid = 2920 
[ 30.672257] +++3++ pid = 2451 
[ 30.672259] proc_loginuid_write failed by permission! 

名testappとは、意図的に名前を変更されます。だから、/ proc/self/loginuidというファイルは、親によって作成されたファイルであり、子スレッドによって読み込まれるようです。

私は同じコードをカーネル3.14と4.9でテストし、3.14カーネルでは動作し、カーネル4.9では動作しません。どうして?

答えて

0

問題の解決方法が見つかりました。

カーネル3.14は設定でオプションCONFIG_AUDITSYSCALLをオフにしています。したがって、/ proc/self/loginuidというファイルはありませんでした.pamモジュールは、そのようなファイルがない場合には気にしません。 4.9オプションが自動的= YCONFIG_AUDITによって選択された新しいカーネルで

。 最も簡単な解決策は、CONFIG_AUDITオプションをオフにすることですが、カーネルの進化のプロセスでなぜCONFIG_AUDITSYSCALLが非制御可能になったのかは、他の質問の問題です。

ありがとうございます!

+0

なぜカーネル進化の過程でCONFIG_AUDITSYSCALLが制御不能なオプションになったのか他の質問のための問題です。 - 通常、新しいカーネル機能は、 "有用性"が欠点よりはるかに大きくてもオプションで、デフォルト。これは、機能の実装が正しくない可能性があるためです。しばらくすると、機能が安定した後、デフォルトが「有効」に変更される可能性があります。 ** AUDITSYSCALL **の設定は、この戦略に正確に従います。 – Tsyvarev

関連する問題