【Linux】linux-vdso.so...?

# :(
![スクリーンショット 2022-11-26 18.50.38.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/777324/aa2b3980-3926-ada5-94c4-78e669a72dd0.png)

https://linux-vdso.so/

# linux-vdso.so
linuxの**共有ライブラリ** のこと。

呼び方がアーキテクチャによって異なる。

|ABI  |vDSO |
|---|---|
| arm, aarch64, mips, x86-64 | linux-vdso.so.1 |
| sh, ia64 | linux-gate.so.1 |
| ppc/32 | linux-vdso32.so.1|
| s390x | linux-vdso64.so.1 |

---

## 共有ライブラリ
**動的ライブラリ**ともいう。
自分は **「静的ライブラリ」「動的ライブラリ」** と呼び分けていたが、それぞれ
 **「スタティックライブラリ」「共有ライブラリ」** とも呼ぶのか。

https://tech.pjin.jp/blog/2020/12/01/linux-shared-library-management

---

## vdso
**仮想ELF動的共有オブジェクト**のこと。
`virtual dynamic shared object`

元々システムコール関数（アセンブリで言う`syscall`）はオーバーヘッドが大きかったけど、後に新しくできたプロセッサーは高速に呼び出せる命令が開発された。
その命令は下位互換性がなかったため、いちいちCライブラリが「システムコール関数を起動するための命令」を使えるかどうかを確認する必要があり、それくらいならもうカーネルから渡して使えるようにしたほうが良くねってできたのがvdsoってことかな。

かなり詳しく書いてあるけど、正味あんまりついていけてない。


https://man7.org/linux/man-pages/man7/vdso.7.html



---

### 仮想
実際には実体としてない。
ここでの **「仮想」** とは静的ライブラリのように「stdio.h」のようなファイルとしてストレージに存在するわけではなく、プログラム実行時にメモリへマッピング（使えるようにする）され、ライブラリとして機能する。

つまり、`linux-vdso.so`はカーネルから直接供給されるやつだからファイルへのパスとかそういうのはないっぽい。
> ただ、アドレスとしてメモリにマッピングされるわけだから、スタックトレースとかには出てくる。

 https://unix.stackexchange.com/questions/476971/ldd-shows-no-location-after-arrow-library-does-not-exist-on-system

---

### ELF

https://qiita.com/niwaka_dev/items/eba14873127a6f34c95f

> ELF(Executable and Linkable Format)は、Linuxでデフォルトになっているオブジェクトファイルと実行ファイルのフォーマットです。

BSD派生のOSやLinuxでよく使われる、`a.out`ファイルとかの後継としてよく使われるフォーマットらしい。

https://ja.wikipedia.org/wiki/Executable_and_Linkable_Format

---

### .so
**共有オブジェクト(shared object)** のこと。
`.dylib`とかと一緒の意味ってことでいいのかな？

https://kanonji.hatenadiary.com/entry/20121018/1350538932

# ldd

共有ライブラリを使用している実行ファイルを確認する場合は
`ldd`コマンドを使う。

引数に**絶対パス**でプログラム名を入れるとそこに使われている共有ライブラリを調べることができるらしい。

```bash:Terminal
[syoshika]~$ ldd /bin/ls
	linux-vdso.so.1 =>  (0x00007ffd685b6000)
	libselinux.so.1 => /lib64/libselinux.so.1 (0x00007f0ea493f000)
	libcap.so.2 => /lib64/libcap.so.2 (0x00007f0ea473a000)
	libacl.so.1 => /lib64/libacl.so.1 (0x00007f0ea4531000)
	libc.so.6 => /lib64/libc.so.6 (0x00007f0ea4163000)
	libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f0ea3f01000)
	libdl.so.2 => /lib64/libdl.so.2 (0x00007f0ea3cfd000)
	/lib64/ld-linux-x86-64.so.2 (0x00007f0ea4b66000)
	libattr.so.1 => /lib64/libattr.so.1 (0x00007f0ea3af8000)
	libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f0ea38dc000)
```

## 相対パスの方が使いやすい
関数を組んで使いやすくしてみた

```bash:.bashrc
 function ldd() {
     command ldd `which $1`
 }
```
`which`でパス調べてぶち込む。
`command`は自作関数でループしないように

```bash:Terminal
[syoshika]~$ ldd pwd
	linux-vdso.so.1 =>  (0x00007ffcd4990000)
	libc.so.6 => /lib64/libc.so.6 (0x00007fd010e54000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fd011222000)
[syoshika]~$ ldd cd
	動的実行ファイルではありません
```

`cd`コマンドは共有ライブラリ使ってないんだね。

## おまけ

何度も実行すればわかるけど、共有ライブラリのアドレスが実行の度に異なる。

```bash:Terminal
[syoshika]~$ ldd /bin/ls
	linux-vdso.so.1 =>  (0x00007ffca8de1000)
...
...

[syoshika]~$ ldd /bin/ls
	linux-vdso.so.1 =>  (0x00007ffd6edf9000)
...
...
```

[return-to-libc攻撃](https://www.weblio.jp/content/Return-to-libc%E6%94%BB%E6%92%83)がされないようにランダムでアドレスが変わるらしい。よくできてるなぁ。

https://man7.org/linux/man-pages/man7/vdso.7.html

>   You must not assume the vDSO is mapped at any particular location in the user's memory map.  **The base address will usually be randomized at run time every time a new process image is created (at execve(2) time).** This is done for security reasons, to prevent "return-to-libc" attacks.