簡體   English   中英

在linux系統調用中查找用戶名

[英]finding the username in a linux system call

我已經向Linux內核添加了一個系統調用,如下所示:

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/list.h>
#include <linux/cred.h>
#include <asm/uaccess.h>

asmlinkage int sys_os_pid_to_uid(int pid, int* puid)
{
    struct task_struct* task;

    rcu_read_lock();

    for_each_process(task)
    {
        if (task->pid == (pid_t) pid)
        {
            copy_to_user(puid, &(task->cred->uid.val), sizeof(task->cred->uid.val));
        }
    }

    rcu_read_unlock();
    return 0;
}

它獲取進程ID( pid )並確定正在執行它的用戶的用戶ID( puid )。

現在,我的問題開始了:我想為這個系統調用添加另一個參數,即char *username ,它將包含ID為puid的用戶的用戶名。 我在cred.h標題中搜索但無法找到與用戶名有關的任何內容。 誰能幫我解決這個問題?

內核不知道用戶名; 它只處理用戶ID。 將用戶名解析為用戶ID(反之亦然getpwent()由libc函數的getpwent()系列( getpwuid()getpwnam()等)完全在用戶空間中處理。

請注意,您的系統調用有點多余; 通過調用/proc/$pid上的stat()或通過讀取/proc/$pid/status來獲取進程的用戶ID已經微不足道了。

您沒有找到它的原因是因為沒有一個: task_struct ,並且內核通常不會保留有關與給定用戶ID相對應的用戶名的內存中信息。 這是完全沒必要的,會增加接口和代碼的混亂,並且會消耗內存而沒有任何額外的好處:關於用戶的所有內容都用數字用戶ID表示和存儲。 比較簡單,節省了內存。

你不應該/不能在系統調用中執行此操作。

我建議你編寫一個包裝器用戶空間函數來調用你的系統調用,然后調用getpwuid(3)getpwuid_r(3)將用戶ID轉換為用戶名。 請注意,這將在用戶空間中完成,而不是在內核空間中完成。

我很確定用戶名空間的唯一概念是基於/ etc / passwd(通常,但可能是其他來源,如NIS或LDAP)。 如果更改/ etc / passwd中現有條目的用戶名,則用戶立即成為該新用戶名,就像更改/ etc / hosts中的主機名條目一樣,從本地計算機的角度更改IP地址的有效主機名。 它只是一個查找/名稱解析。 存儲對象都將包含用戶ID,而不是用戶名。

您可能希望跟蹤命令“getent”和“id”等。 另請參閱lib調用getpwuid()。 通常,如果不是總是,syscalls(內核空間)處理uids。

但這有什么意義呢? 你剛剛玩內核嗎? uid可以在/ proc中找到。 正如其他人所指出的,必須在用戶空間中解析用戶名。

我不禁要問你從哪里接受這個循環,因為它顯然非常低效。 在這里迭代所有進程是有理由的,並且通過讀取也必須找到它的系統調用的源代碼,可以很容易地找到獲取給定pid的task_struct的方法 - 例如kill(2)

最后,我還要注意有問題的代碼是不正確的。 copy_to_user可能導致頁面錯誤,您無法在rcu臨界區中執行此操作。 我很確定內核會告訴你即使沒有發生錯誤,只要你啟用了調試選項。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM