...
- commit_creds() 함수는 현재 프로세스에 새 자격 증명 설치, 다음과 같이 동작합니다.
- current가 가지고 있는 현재 프로세스의 정보를 task에 저장합니다.
- task 구조체를 이용하여 현재 프로세스가 사용중인 자격 증명 정보를 old 변수에 저장합니다.
- BUG_ON() 함수를 이용하여 다음과 같은 사항을 확인합니다.
- "task->cred"과 "old"의 자격증명이 다른지 확인합니다.
- "&new→usage"에 저장된 값이 1 보다 작은지 확인합니다.
- "task->cred"과 "old"의 자격증명이 다른지 확인합니다.
- get_cred() 함수를 이용하여 new 변수에 저장된 자격 증명 집합에 대한 참조 가져 오기증명에 참조됨 정보를 가져옵니다.
- uid_eq(), gid_eq() 함수를 이용하여 다음과 같은 구조체 내에 저장된 변수의 값을 확인 합니다.
- euid,egid는 유효 사용자 식별자(effective user ID,
euid
)이라는 의미로 프로세스가 파일에 대해 가지는 권한을 뜻합니다. - fsuid는 리눅스에는 파일 시스템 접근 제어 용도로 사용되는 파일 시스템 사용자 ID(file system user ID, fsuid)를 뜻합니다.
- old->euid, new→euid
- old->egid, new→egid
- old->fsuid, new→fsuid
- old->fsgid, new→fsgid
- old->euid, new→euid
- euid,egid는 유효 사용자 식별자(effective user ID,
- cred_cap_issubset() 함수를 이용하여 두 자격 증명이 동일한 사용자 네임 스페이스에 있는지 확인 합니다.
- 또다시 uid_eq(), gid_eq() 함수를 이용하여 다음과 같은 구조체 내에 저장된 변수의 값을 확인 합니다.
- new→fsuid, old→fsuid
- new→fsgid, old→fsgid
- 값이 다를 경우 key_fsuid_changed(), key_fsgid_changed() 함수를 이용하여 현재 프로세스의 fsuid, fsgid으로 값을 갱신합니다.
- new→fsuid, old→fsuid
Code Block | ||||
---|---|---|---|---|
| ||||
int commit_creds(struct cred *new) { struct task_struct *task = current; const struct cred *old = task->real_cred; kdebug("commit_creds(%p{%d,%d})", new, atomic_read(&new->usage), read_cred_subscribers(new)); BUG_ON(task->cred != old); #ifdef CONFIG_DEBUG_CREDENTIALS BUG_ON(read_cred_subscribers(old) < 2); validate_creds(old); validate_creds(new); #endif BUG_ON(atomic_read(&new->usage) < 1); get_cred(new); /* we will require a ref for the subj creds too */ /* dumpability changes */ if (!uid_eq(old->euid, new->euid) || !gid_eq(old->egid, new->egid) || !uid_eq(old->fsuid, new->fsuid) || !gid_eq(old->fsgid, new->fsgid) || !cred_cap_issubset(old, new)) { if (task->mm) set_dumpable(task->mm, suid_dumpable); task->pdeath_signal = 0; smp_wmb(); } /* alter the thread keyring */ if (!uid_eq(new->fsuid, old->fsuid)) key_fsuid_changed(task); if (!gid_eq(new->fsgid, old->fsgid)) key_fsgid_changed(task); /* do it * RLIMIT_NPROC limits on user->processes have already been checked * in set_user(). */ alter_cred_subscribers(new, 2); if (new->user != old->user) atomic_inc(&new->user->processes); rcu_assign_pointer(task->real_cred, new); rcu_assign_pointer(task->cred, new); if (new->user != old->user) atomic_dec(&old->user->processes); alter_cred_subscribers(old, -2); /* send notifications */ if (!uid_eq(new->uid, old->uid) || !uid_eq(new->euid, old->euid) || !uid_eq(new->suid, old->suid) || !uid_eq(new->fsuid, old->fsuid)) proc_id_connector(task, PROC_EVENT_UID); if (!gid_eq(new->gid, old->gid) || !gid_eq(new->egid, old->egid) || !gid_eq(new->sgid, old->sgid) || !gid_eq(new->fsgid, old->fsgid)) proc_id_connector(task, PROC_EVENT_GID); /* release the old obj and subj refs both */ put_cred(old); put_cred(old); return 0; } EXPORT_SYMBOL(commit_creds); |
...