추가질문. User와 Kernel 중간 영역에 코드 삽입

조성현 2008.06.18 19:23 조회 수 : 6938 추천:28

우려하던대로, 답글이 없네요. ㅜ.ㅜ;;
먼저, 제가 전에 문의드린 내용에 부족한 점이 많은 것 같아 죄송하다는 말씀을 드리고 싶네요.

방향을 조금 바꿔보았습니다. 바로 Callgate가 아닌 IDT를 이용하는 것으로요.

새로운 세그먼트는 arch/x86/kernel/cpu/common.c 라는 파일에 [GDT_ENTRY_SECURE_CS] = {....DPL:1, read+execute, 나머지는 커널과 거의 같음....}와 [GDT_ENTRY_SECURE_DS] = {....DPL:1, read+write+confirm, 나머지는 커널과 거의 같음....}로 정의하였습니다. 물론, include/asm-x86/segment_32.h 파일에 unused라고 되어 있는 28~29번을 사용하였습니다.

-------------segment_32.h에 정의한 내용 ---------------------
#define GDT_ENTRY_SECURE_BASE   28
#define GDT_ENTRY_SECURE_CS             (GDT_ENTRY_SECURE_BASE + 0)
#define __SECURE_CS (GDT_ENTRY_SECURE_CS * 8 + 1)
#define GDT_ENTRY_SECURE_DS             (GDT_ENTRY_SECURE_BASE + 1)
#define __SECURE_DS (GDT_ENTRY_SECURE_DS * 8 + 1)
---------------------------------------------------------------------

위와 같이 세그먼트 셀렉터는 __SECURE_CS와 __SECURE_DS가 되는데, 각각 0xE1과 0xE9가 되죠.

하지만, 아직까지 User(CPL:3) 입장에서 lcall 0xE1:0x0000으로 접근이 불가능한 상황입니다. 그래서 Callgate를 새로 선언해서 사용해보려고 했지만, TSS 레지스터를 사용해야된다는 의견이 있어서 그만 두고, 바로 IDT를 이용해보았습니다.

-------------------arch/x86/kernel/entry_32.S---------------------
/* Add my code (wbhacker) */
ENTRY(secure_test)
    RING0_INT_FRAME
    SAVE_ALL
    pushl $context_msg
    call printk
    addl $4, %esp
    RESTORE_REGS
    INTERRUPT_RETURN
    CFI_ENDPROC
context_msg:
    .ascii  
            "EBX : 0x%08xnECX : 0x%08xnEDX : 0x%08xnESI : 0x%08xn"
            "EDI : 0x%08xnEBP : 0x%08xnEAX : 0x%08xn"
            "DS : 0x%08xnES : 0x%08xnFS : 0x%08xnx0"
ENDPROC(secure_test)
---------------------------------------------------------------------------

위와 같이 엔트리에 어셈블리어로 추가하고,

-------------------arch/x86/kernel/traps_32.c----------------------
/* add my code */
    set_system_gate(0xef, &secure_test);
----------------------------------------------------------------------------

위와 같이 trap에 새로 정의하여 사용자가 int 0xef를 통해 연결되도록 하였습니다.
소스가 잘 적용되어 수행이 되었습니다. printk 함수를 잘 수행되었습니다.

-----------------------------------------------------------------------------
// traps_32.c에 정의되어 있는 set_system_gate 함수 내용
static void __init set_system_gate(unsigned int n, void *addr)
{
        _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __KERNEL_CS);
}
// 제가 새로 정의한 함수로, __SECURE_CS로 IDT의 DPL이 1임을 알 수 있죠.
static void __init set_system_gate_secure(unsigned int n, void *addr)
{
        _set_gate(n, DESCTYPE_TRAP | DESCTYPE_DPL3, addr, __SECURE_CS);
}
-----------------------------------------------------------------------------

하지만, 위와 같이 __SECURE_CS로 접근하려고 하면, 접근은 불가능하게 되었습니다.

__KERNEL_CS로 하면 접근이 잘되고 코드 수행도 잘 되었죠. 그런데, 제가 하고자 하는 DPL:1 권한으로는 안되는 겁니다.

----------------int 0xef일 때 나오는 메시지(KERNEL_CS일 때)-------
EBX : 0x40149ff0
[  566.213324] ECX : 0x00000000
[  566.213328] EDX : 0x08049440
[  566.213331] ESI : 0x4014c41c
[  566.213333] EDI : 0x00000000
[  566.213335] EBP : 0xbfe4f018
[  566.213337] EAX : 0x00000010
[  566.213339] DS : 0x0000007b
[  566.213340] ES : 0x0000007b
[  566.213342] FS : 0xffff0000
----------------int 0xef일 때 나오는 메시지(SECURE_CS일 때)-------
trap[3052]: segfault at c010413c eip c010413c esp bf9fc3c4 error 5
-----------------------------------------------------------------------------

저와 같이 진행중인 후배가 생각하기엔 메모리 접근쪽 문제일 가능성이 큰데요.
책을 살펴보니, 리눅스에서의 메모리 접근 권한 체크는 0xC0000000 영역부터 커널이라고 하는데, 그 영역의 접근 권한으로 Page의 User/Supervisor로 한다고 합니다.

즉 0x00000000~0xBFFFFFFF는 Page가 User권한이며, 0xC0000000~0xFFFFFFFF는 Page가 Supervisor권한이라는 겁니다. 세그먼트 정책으로는 KERNEL_CS와 USER_CS가 모두 BaseAddress는 0x0이고, Limit는 4G이기 때문에, 접근 제한 체크가 없을 것 같고요.

제가 원하는 것은 User 영역을 0x00000000~0xAFFFFFFF 정도로 하고, Secure 영역으로 0xB0000000~0xBFFFFFFF를 잡고 싶은 겁니다. -_-; 제가 접근해야 될 것이 어떤 방법이 있을까요?

모든 프로세스가 생성될 때마다 수행이 되는 쪽으로 해야할 것 같아 do_fork나 do_execv를 분석해야 된다는 생각은 있고, 조금 분석해보긴 했는데, 너무 어렵더군요. 이렇게 접근하면 되는지요? 관련 서적도 알려주시면 감사하겠습니다. 현재는 "리눅스 커널의 이해 - 한빛미디어", "리눅스 커널 프로그래밍 - 교학사", "박장수의 리눅스 커널 분석 2.4 - 가메출판사", "만들면서 배우는 OS 커널의 구조와 원리 - 한빛미디어", "IA-32 Intel(R) Architecture Software Developer's Manual(3)"을 보고 있습니다.

뭐라도 좋으니, 조언 해주시면 감사하겠습니다. -- 2008-06-18 19:23 wbhacker
번호 제목 글쓴이 날짜 조회 수
공지 [공지] 프로그래밍 관련 Q&A 게시판 입니다. woos 2016.04.09 22253
38 sleep과 재진입가능 함수. [1] 김기욱 2008.11.15 9159
37 ramdisk 는 물리적으로 연속적인 메모리인가요?? [10] 신철수 2008.11.06 6330
36 [질문] printf 소스는 어디에 있나요? [1] 손성원 2008.09.23 10914
35 hypervisor 위에서 돌아가는 guest에서 vt-x 를 사용할 수 없나요? [1] 남현우 2008.09.11 6896
34 [질문] 리눅스 서버 구축 [3] 맥주 2008.08.08 5869
33 커널 hang 걸렸을 때 관련정보 볼 수 잇는 방법이 있을까요?? [2] 신철수 2008.08.06 7879
32 리눅스 커널 디버깅 (kdb) 질문 있습니다!!!!! [2] 조성훈 2008.07.09 8836
31 new call-gate, cs, ds 추가관련 질문입니다. [2] 조성현 2008.05.31 5998
» 추가질문. User와 Kernel 중간 영역에 코드 삽입 [1] 조성현 2008.06.18 6938
29 XEN 스케쥴링 관련하여 질문 좀 부탁드리겠습니다... 장형근 2008.04.30 6942
28 [re] XEN 스케쥴링 관련하여 질문 좀 부탁드리겠습니다... 박세율 2008.07.05 7752
27 ^^ 안녕하세요. pmd_large() 함수 질문입니다. [3] 박종섭 2008.04.10 7440
26 [질문] 세미나관련..공유라이브러리 [3] 박은병 2008.04.08 6840
25 Kernel 분석 5기 멤버 모집은 언제쯤 하시는 지요 ?? [2] 석헌영 2008.04.06 5784
24 백창우님, 질문 있습니다~ [2] 김기태 2008.04.06 6818
23 [질문] 스터티 참가 문의 [1] 김연찬 2008.04.03 5835
22 [질문] 쓰 레 드 ...... [4] 박은병 2008.03.28 6749
21 USB host 관련 porting 이나 non bus type 으로 작업 해보신 분 계신가요? [3] 신철수 2008.02.27 7301
20 이 문서 가지고 계시는 분 리형중 2008.02.25 6099
19 혼자서 커널공부하는데 조언을 부탁드립니다. [2] 김현중 2008.02.09 7800
XE Login