web-dev-qa-db-ja.com

Linuxカーネルデバッグに関するいくつかの質問-メモリ検査

私はこれを読みました LinuxカーネルはカーネルメモリにDEPを使用していますか?

しかし、VMwareスタブを使用してVMware上でLinuxカーネル(x86_64)をデバッグしています。 Linuxカーネルにgdbをアタッチしました。カーネルのバージョンは3.xです

linuxカーネルの実行可能メモリを1か所で変更しました

(gdb) x/i $rip
=> 0xffffffff81190930 <sys_getdents>:   Push   rbp
(gdb) set{long}0xffffffff81190930=0
(gdb) x/x 0xffffffff81190930
0xffffffff81190930 <sys_getdents>:      0x00000000
(gdb) x/i $rip
=> 0xffffffff81190930 <sys_getdents>:   add    BYTE PTR [rax],al

何故ですか?これは私が仮想マシンにいるからですか?

2番目の質問。このコマンドを使用してページを一覧表示できることを知っています

(gdb) info files
Symbols from "/home/a/vmlinux".
Remote serial target in gdb-specific protocol:
Debugging a target over a serial line.
        While running this, GDB does not access memory from...
Local exec file:
        `/home/a/vmlinux', file type elf64-x86-64.
warning: Cannot find section for the entry point of /home/a/vmlinux.
        Entry point: 0x1000000
        0xffffffff81000000 - 0xffffffff815f795f is .text
        0xffffffff815f7960 - 0xffffffff815f7adc is .notes
        0xffffffff815f7ae0 - 0xffffffff815fbb00 is __ex_table
        0xffffffff81600000 - 0xffffffff818427ce is .rodata
        0xffffffff818427d0 - 0xffffffff81849ed4 is __bug_table

しかし、これらのページへの権限をリストする方法-rwx?

4
tigger

私はカーネルをデバッグしたことがないので、私は間違っているかもしれませんが、あなたが見ているものは完全に理にかなっていると思います。それを見てみましょう:

add BYTE PTR [rax],al

何故ですか?これは私が仮想マシンにいるからですか?

それが実際に0x0000に期待することです。これは簡単にテストできます:

[~]$ uname -a
Linux haps 4.7.6-1-Arch #1 SMP PREEMPT Fri Sep 30 19:28:42 CEST 2016 x86_64 GNU/Linux
[~]$ Perl -e 'print "\x00\x00\x00\x00"' > pp
[~]$ ndisasm pp
00000000  0000              add [bx+si],al
00000002  0000              add [bx+si],al

つまり、0x0000はRAXの最初のバイトのaddです(つまり、al)。


しかし、これらのページへの権限をリストする方法-rwx?

それは意味がないと私は主張します。よくある誤解は、カーネルがrootとして実行されているという考えであり、それは完全に真実ではありません。カーネルはkernelmodeで実行され、その他はすべてusermodeで実行されます(syscallの途中でない限り) 。

グローバルページディレクトリでは、カーネルが使用するページのDLP(記述子特権レベル)が0に設定されています。これは、kernelmodeを意味します。ユーザースペースが使用するすべてのページでは、DLPが3に設定されており、usermodeを意味します。 CPUがuserspceプロセスを実行しているとき、それはユーザーモードであるため、DLPが0(または1または2ですが、Linuxでは使用されていません)のあるページにアクセスしようとすると、CPUは例外(割り込み)、カーネルに混乱を取り除くように伝えます。カーネルは、現在アクティブなプロセスのシグナルキューにSEGFAULTをキューイングします。

要約すると、それらのページにアクセスしようとするany userspaceプロセスはsegfaultされます。プロセスがroot特権で実行されているかどうかは問題ではありません。したがって、カーネルが使用するメモリページに一連のアクセス許可を与えることは実際には意味がありません。

追記

あなたは尋ねるかもしれません:しかし、/dev/memはどうですか?これは、ユーザー空間から見ることができるカーネルメモリです。さて、/dev/mem(または/dev/kmem)の読み取りと書き込みは、syscallを引き起こします。そして、copy_to_usercopy_from_userのようなものが呼び出され、DLP 3とDLP 0のページ間でデータを受け渡します。

3
grochmal