読者です 読者をやめる 読者になる 読者になる

宇宙ドーナツ研究会

セキュリティ系お勉強メモ

layers.conf について

$ poky/scripts/yocto-layer create my-recipe

を実行することで、my−recipe というサンプルレイヤを作成できる。

ここで作成されたlayer.confについて、いろいろ考察。

 

===

BBPATH .= ":${LAYERDIR}"

BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend" 

BBFILE_COLLECTIONS += "my-recipes"

BBFILE_PATTERN_my-recipes = "^${LAYERDIR}/"

BBFILE_PRIORITY_my-recipes = "6"

===

 

# LAYERDIR

meta-my-recipes ディレクトリのパス。layer.conf内でのみ有効

 

# BBPATH

bitbakeが.bbclassやらconfigファイルやらを認識するためのもの。

シェルでのPATHと同じ。

 

# BBFILES
レシピファイルのフルリスト。
 

BBFILE_COLLECTIONS += "my-recipes"

このリストを使って、他の BBFILE_* という変数を参照する。

ここでは、本レシピを my−recipes という名前で登録してる。

 

BBFILE_PATTERN_my-recipes = "^${LAYERDIR}/"

BBFILES 変数の中から、本レイヤに関するものを探す際の、検索キーワード設定

 
# BBFILE_PRIORITY_my-recipes = "6"

優先度設定

 

■気づいたこと

# 1

どうやら、${} がつく変数とつかない変数の違いは、環境変数とシェル変数の違いに相当するみたい。

つまり、${} の方は、そのスクリプトや設定ファイル内でのみ有効、

つかない方は、グローバルに共有されるみたい。

 

#2

bitbakeは、最初にbblayers.confに描かれているレイヤのlayer.conf を次々とパーズし、全てのレイヤにおけるレシピファイルのリストを作成するみたい。

その後、レイヤごとの処理に移る。

その際は、BBFILESから、そのレイヤに属すレシピを BBFILE_PATTERN_* 変数を使って検索し、ビルドしていくのかと。

 

#3 

class ファイルを使うことで、設定の継承ができる。

おおもとのclassファイルは、meta/classes/base.bbclass 。

ここには、fetching, unpacking, configuring などのデフォルト処理が記述されており、

全てのレシピは、自動でこれを継承する。

これらの処理は、他のclassファイルにより上書きされていく。

 

 

 

 

gitメモ

rebase

ここ参照。
Git - リベース

# git rebase 統合先
git rebase master

gitリポジトリについて

なんとなく使ってたけど、本質を理解した方がいろいろと使いこなせるので、メモ。
ここがめっちゃ詳しい。
Gitのリポジトリの中身をなるべく正確に理解する | To Be Decided

.git ディレクトリの主な内訳

  • オブジェクト(.git/objects)
  • インデックス(.git/index)
  • 参照(.git/refs)
  • シンボリック参照(.git/symref)
オブジェクト

全てハッシュで表される。
git cat-file -p <HASH> で中身が見れる。

  • ブロブ
    ファイルの中身
  • ツリー
    ディレクトリに相当。ブロブや他ツリーへの参照を持つ。
  • コミットオブジェクト
    コミットに相当。ブロブや他ツリーへの参照を持つ。
  • タグ
    タグ名、コメント、コミットへの参照
インデックス

各ファイルの場所と、それに対応するブロブへのポインタなどの情報が書かれた単一ファイル。
バイナリだけど、git ls-files --stage で内容が見れる。

git add って?

git add した時点で、対象ファイルのスナップショットが、次のコミットのために作成される。
同時に、インデックス内の対象ファイルの項目が、作成されたスナップショットを参照するようになる。

ファイルの変更をaddした後、別ブランチへコミットしようとするとエラーが出るのは、
インデックスにおいて、そのファイルの項目が、参照先を元に戻せなくなってしまうためかと。

git reset って?

要は、元に戻すコマンド。

  • git reset <ファイル名>
    指定ファイルがadd済みの場合、インデックスの参照先をHEADにおけるブロブへ変更する。
    つまり、add と真逆な事をする。

  • git reset <コミット>
    git resetとrevertを図解する | To Be Decided
    HEADを指定コミットに移す。その際、
    –soft:インデックスや作業ディレクトリはそのまま
    –mixed:インデックスを、指定コミットのものへ変更
    – hard:インデックス、作業用ディレクトリともに、指定コミットのものへ変更する

この時、ORIG_HEADが、reset直前のHEADを参照しているコミットを参照するようになる

MACのvirtualbox上でARM用Linuxを動かす話

ここ参照。
KVMを使う(インストール編) « さくらインターネット研究所
QEMU によるシステムのエミュレーション

環境

  • ホストOS
    MAC上で動くVirtual Box 上で動くCentOS 7.3
  • ゲストOS
    – ARM用にビルドしたFedora

FedoraってRHEL系らしい。
FedoraRHELCentOSの関係は、

Fedoraで実験 → 上手くいったらRHELに適用 → CentOSがそれをパクる

という感じらしい。

手順

Linux仮想マシンを扱うには、KVMQEMUが必要。 KVMのページ に書いてるように、 カーネル2.6.23 以降では、kvmはすでに組み込まれてるらしい。 なので、QEMU側のみインストールしてやる。

必要なパッケージをインストールしておく

yum -y install gcc kernel-devel zlib-devel pciutils-devel pciutils-libs gtk2-devel flex bison gettext]

qemuをインストールする。

yumだと色々不自由するらしいので、ソースからビルドする。
QEMUのページ から落としたソースをmakeする。

$ tar -Jxfv 
$ ./configure --target-list=arm-softmmu,x86_64-softmmu
$ make
$ make install

configureでは、arm用とx86_64用のビルドに必要な分だけmakeする設定にしている。 configure –help で、アーキテクチャごとのオプションがわかる。

試しにx86用のOSを動かしてみる

x86_64(amd64)用のFreeBSD https://download.freebsd.org/ftp/snapshots/amd64/amd64/ISO-IMAGES/11.0/

仮想ハードディスクの作成

$ qemu-img create -f qcow2 qemutest.img 10G

仮想ハードディスク生成に使うのは、 qemu-img コマンド。 ここでは、qcow2フォーマットで初期化し10GBの仮想ディスクqemutest.imgを生成。

qcow2 はCopy On Wright が機能するせいか、消費容量は少ないものの、パフォーマンスがかなり落ちる。 10G程度であれば問題無いらしい。

仮想ディスクにOSインストール

bsd-start.sh とかの名前で、OS起動スクリプト作る

#!/bin/sh
qemu-system-x86_64 -hda 仮想ディスク名 -m 1024 -monitor telnet::4444,server,nowait -vnc :0 -daemonize -cdrom イメージ名 -boot d

これで、ゲストOSを操作するための qemuプロンプトが立ち上がるので、インストールを終わらせる。

qemuから仮想マシンをOFF

今の状態だと、cdromからブートする設定になってるので、ディスクブートするように直す。

$ telnet localhost 4444
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
QEMU 0.12.2 monitor - type 'help' for more infomation
(qemu) q                        ←コマンド入力
Connection closed by foreign host.
  • bsd-start.sh をディスクブート用に書き直して(cdromブートの部分を消した)
#!/bin/sh
qemu-system-x86_64 -hda 仮想ディスク名 -m 1024 -monitor telnet::4444,server,nowait -vnc :0 -daemonize
. ./bsd-start.sh

yum -y install qemu-kvm yum -y install libvirt

  • qemu-kvm centos6以前では、qemuというパッケージ名だったが、CentOS7以降は名前が変わったらしい。 よくわからないけど。

  • libvirt kvmが使うライブラリ群。 大事そうなのでインストール。 よくわからないけど。

ちなみに、qemukvmlibvirtの関係についてはこちら。 【仮想化】KVMとqemuとlibvirtの違い・関係 – ZacoDesign

ubuntu 16.04.2 について

ubuntu16.04.2 は、デスクトップ用であれば、デフォでHWEカーネルが入るらしい。 kernel4.8 を使っており、以前のLTS(多分、ubuntu16.04)以降に出たハードウェアをサポートしてるとのこと。 今後も6ヶ月ごとに、ハードウェアのサポートを更新していくとのこと。 Ubuntu 16.04.2 LTS Released, Available to Download Now - OMG! Ubuntu!

The biggest selling point of point release is an updated hardware stack. Ubuntu 16.04.2 LTS is no different. It brings the Linux 4.8 kernel, plus an updated version of the X server that has been back-ported from Ubuntu 16.10.  These updates are generally worth having as they offer improved hardware support, particularly for PCs and laptops that were released after the LTS was.

ARM用にLinuxをビルドする

ここ を参考にした。

必要なパッケージをインストー

$ sudo yum -y groupinstall "development tools"
$ sudo yum -y install tetex gawk sqlite-devel vim-common redhat-lsb xz \
       m4 make wget curl ftp tar bzip2 gzip python-devel \
       unzip perl texinfo texi2html diffstat openjade zlib-devel \
       docbook-style-dsssl sed docbook-style-xsl docbook-dtds \
       docbook-utils bc glibc-devel pcre pcre-devel \
       groff linuxdoc-tools patch cmake \
       tcl-devel gettext ncurses apr \
       SDL-devel mesa-libGL-devel mesa-libGLU-devel gnome-doc-utils \
       autoconf automake libtool xterm

poky落とす

git clone -b jethro git://git.yoctoproject.org/poky.git

バージョン2.0.3 を落とした。
最新の2.2系ではないのは、2.1 以降はhobが無くなって、代わりにtoasterとかいうのになったから。
toaster についての日本語情報は少ないので、hobでいいやという話。

buildtools 実行

こいつらが入ってないといけない。
* Git 1.7.8 以上
* tar 1.24 以上
* Python 2.7.3 以上

入ってないなら、buildtoolsを落として実行する。

# 必要なパッケージのダウンロード
wget http://downloads.yoctoproject.org/releases/yocto/yocto-2.0/buildtools/poky-glibc-x86_64-buildtools-tarball-core2-64-buildtools-nativesdk-standalone-2.0.sh
source poky-glibc-x86_64-buildtools-tarball-core2-64-buildtools-nativesdk-standalone-2.0.sh

# 上記パッケージへのパスを、$PATHの先頭に追加
cd /opt/poky/2.0
source environment-setup-x86_64-pokysdk-linux

結果、一時的に python2.7やらが使えるようになる。 再起動したら元に戻るけど。

[user@yocto_lab buildtools]$ tar --version
tar (GNU tar) 1.28

[user@yocto_lab buildtools]$ git --version
git version 2.5.0

[user@yocto_lab buildtools]$ python -V
Python 2.7.9

環境変数設定スクリプト

パッケージに提供されているスクリプトを使用してシェルの環境変数を設定します。
このスクリプトを実行すると、作業ディレクトリーは build サブディレクトリーとなり、このサブディレクトリーからビルドを実行することができます。

$ cd poky 
$ . ./oe-init-build-env

ビルド設定

build/conf/local.conf にこれを追記。
local.conf は、bitbakeがビルドする時の設定を書いたもの。 ビルド並列実行数は、使ってるCPUコア数にする。

# ビルド中の作業用ディレクトリは削除する
INHERIT += "rm_work"

# アーキテクチャとしてarm64bitを指定
MACHINE ?= "qemuarm64"

# ビルドの並列実行数
BB_NUMBER_THREADS = "2"

ビルド開始

最低限の機能を持ったOSをビルドする。

bitbake core-image-minimal

ビルドしたOSを起動

runqemu 自体は、scriptディレクトリにあるスクリプト
起動後は、ユーザ名root、パスワード無しでログイン可能。

$ runqemu qemuarm64

Poky (Yocto Project Reference Distro) 2.0.3 qemuarm64 /dev/ttyAMA0
qemuarm64 login: 

終わらせる時は、shutdown -h now でいける。

ツール名について

yocto には、pokyやらbitbakeやらhobやらいろんなツールがあって関係がわかりにくい。 自分の理解だと、こんな感じ。

  • poky
    • yocto の機能を提供するパッケージ名前
    • pokyの中に、各種ツールとかが含まれてる。要は、入れ物の名前って感じ?
    • 出来上がるデフォルトのディストリビューションの名前でもある。 ちなみに、GUIを持ったフル機能なOSをビルドするレシピが、core-image-sato

VNCでqemu上のマシンにリモートデスクトップする話

CentOSQEMU上でFreeBSDを動かしている。
それを、Windowsサーバからリモートデスクトップする方法。

CentOS側の準備

VNC Serverを入れる

ここを参考に、VNC Serverを入れる。
VNC Serverを起動できればOK

vncserver設定する

インストール
$ yum -y install tigervnc-server

追記する
$ vi /etc/sysconfig/vncservers
  VNCSERVERS="0:centosのユーザ名"
  VNCSERVERARGS[1]="-geometry 1024x768 -nolisten tcp"

ログインパスワード設定
$ vncpasswd

VNCSERVERS の “0” は、vnc接続番号。
qemu側でOSを起動するとき、このvnc番号を指定することになる。

ファイアウォールでアクセス許可

ここを参照に、ファイアウォールで5900/tcp, 5900/udp のアクセス許可
vnc番号がxの時、対応するポートは、590x になる。

サービス起動

$ service vncserver start

Windows側の準備

  • ここからVNC Clientを落とす
  • vncvc.exeで、さっき設定したパスワードを入力。
  • vncviewer.exe で、ゲストOSのIP:0 を指定して接続

 

 

 

VirtualBoxでは仮想マシンの入れ子がNGな話

Virtual Box 上で動くCentOSで、KVMを使おうと思った。
Linuxkvmを使うためには、下の2つのモジュールをロードする必要がある。

しかし2つ目でエラーが出る。
operation not supported みたいなやつ。

どうやら、Virtual Box では、仮想マシンの入れ子はサポートしてないみたい。
Mac で仮想マシンの入れ子 (Nested Virtualization) をする | CUBE SUGAR STORAGE
VirtualBoxでのNested Virtualizationは無理だったという話 - ひろうぃんの雑記

VMWare ではいけるらしい。
やってみよう! vSphere on VMware Player - Japan Cloud Infrastructure Blog - VMware Blogs

ちなみに、入れ子になった仮想マシンのことを、Nested Virtualization とか Nested VMとか言うらしい。

 

カーネルデバッグ

デバッガの種類

kgdb

デバッグ準備など

ここが詳しい。
Linux のデバッグ手法をマスターする

簡単に書くと、
- カーネルにkgdbを組み込む
– make oldconfig, make xconfig で kernel hacking の kgdb を指定して、make
- その後、いろいろやる

vmlinux と vmlinuz

  • vmlinux
    カーネルのオブジェクトファイルをリンクして、elf化したもの。
    デバッグ用シンボルとか付いてる。
    このままでは、読み込めない。
    あくまで、vmlinuz 生成のための中間ファイル。

  • vmlinuz
    ブート時に実際に読み込まれるファイル。 vmlinux に、各アーキテクチャが読み込む際に必要な情報を付けて、zlib 形式で圧縮したもの。

ここを参照
http://unix.stackexchange.com/questions/5518/what-is-the-difference-between-the-following-kernel-makefile-terms-vmlinux-vml

静的リンク/動的リンク

  • 静的リンク
    オブジェクトファイルのリンク時に、プログラム呼び出しを解決して、1つのファイルに纏めてしまう方法。

  • 動的リンク
    リンク時には、プログラム呼び出しを解決しない。
    呼び出しのたびに、対象のプログラムをロードする。

カーネル再構築メモ

そもそもカーネル再構築ってナニ?

  • カーネルやモジュールを、機能追加や削除するために作り直すこと
    何も考えずに CentOS をイメージからインストールすると、組み込まれていない機能が結構ある。
    それらを後から追加したい時は、カーネル再構築が必要になる。

  • ここで疑問
    CentOSの初回インストール時、追加するコンポーネントを選択する場面がある。
    ここでコンポーネントを全選択することは、OSとカーネルのソースをフルでインストールすることと同じなんだろうか?

再構築の流れ

OSのソースを取ってくる

CentOS であれば、ここから。
http://vault.centos.org
以下は例。

$ rpm -i http://vault.centos.org/7.2.1511/updates/Source/SPackages/kernel-3.10.0-514.6.2.el7.src.rpm

rpmbuild を使う準備をする

適当なディレクトリで、下記を実行。

$ cd ~
$ mkdir -p ~/rpmbuild/{BUILD,BUILDROOT,RPMS,SOURCES,SPECS,SRPMS}     
$ echo '%_topdir %(echo $HOME)/rpmbuild' > ~/.rpmmacros 

CentOSのソースは、src.rpm という形式で配布されています。
これに含まれるソースコードのビルドに使用するのが、rpmbuild です。
ここでは、rpmbuild を使ってOSのソースをビルドするための準備をしています。
RPMファイルやrpmbuild については、この記事に纏めてあります。

パッチファイルをソースに組み込む

下記を実行します。
が、正直言うと、これが何をやってるのか、よくわからんです。。

$ cd =~/rpmbuild/SPECS
$ rpmbuild -bp --target=`uname -m` kernel.spec

.config ファイルを作る

下記を実行します。

$ cd ~/rpmbuild/BUILD
$ mv .config .config.old
$ cp /boot/config-`uname -r` ./.config
$ make oldconfig
$ make xconfig
  • .configファイルとは
    カーネルに組み込む機能やその他設定について記載したファイルのこと。
    カーネル再構築には、このファイルが必要。

  • make oldconfig とは
    ちょっと機能を追加するだけなのに、カーネル全体の構成を書いて1からビルドするのは非効率。
    make oldconfigを使えば、現在動いているカーネルの機能との差分だけを適用できます。
    なので当然、現在動いているカーネルの.configファイルが必要になります。
    上記コードの2行目で、/boot 配下のconfigファイルを持ってきてるのは、そのためです。

  • make xconfig とは
    .config ファイルに機能や設定の情報を手動で入力するのは面倒。
    そのため、.config ファイルを自動で作成してくれるツールが用意されています。
    そのうちの1つが、make xconfig。
    GUI にて、各種設定ができます。
    ちなみに、自分がやった時は、コマンドライン上からだと、「Xwindow に接続できません」的なエラーが出力され、実行できませんでした。
    ランレベルを5 にして、GUI画面から端末を開いたところ、正常に実行できました。

ビルドする

$ make -j[1-9]

.config の用意ができたところで、ビルドします。
ただのmakeでも良いのですが、環境や追加する機能によっては、時間がクソかかります。
この-j オプションを使うと、CPUコア数に応じて、並列処理をしてくれます。

今回、僕は、仮想マシンにCPUを2つ割り当てていました。
1CPUあたりの論理コアが2つであるため、最大4つまで並列処理ができるはずです。
なので、make -j4 としました。

ビルドしたモジュールを /lib/modules に置く

$ make modules_install

ビルドしたモジュールを、規定の場所に置きます。

ビルドしたカーネルを /boot に置く

$ make install

カーネルや初期RAMディスクなどを、/boot 配下に置いてくれます。

と、カーネル再構築の手順は、こんな感じです。

参考URL

http://d.hatena.ne.jp/jitsu102/20100325/1269461776
<https://wiki.centos.org/HowTos/I_need_the_Kernel_Source#head-a8dae925eec15786df9f6f8c918eff16bf67be0d >

RPMファイルとrpmbuildについて

RPMパッケージ

一発でインストールできるようにしたパッケージファイル。

  • 種類は2つある。
    – バイナリパッケージ(RPMファイル)
    – ソースパッケージ(SRPMファイル)

  • バイナリパッケージ
    コンパイル済みのバイナリファイル。拡張子は.rpm

  • ソースパッケージ
    RPMファイルを作るためのもの。
    ソースやバッチファイル、スペックファイルから構成される。
    スペックファイル:バイナリを作るための一連処理が書かれてる。

rpmbuild

  • 役割
    – ソースパッケージをビルドしてrpmファイルにする
    rpmをインストールする

パッチ当てだけやる、それに加えてビルドまでやる、更にそれに加えてインストールまでやる、、、など、どのステージまでやるかをオプションで指定できる。

ここを参考。
http://www.momonga-linux.org/~t/old/linux/redhat-50.html

関数ポインタについて

宣言方法

カッコで括るのは、int * 型変数を返す関数と区別するため。

int (*pfunc)(int a,int b);    // 関数ポインタ
int *pfunc(int a, int b);     // int * 型変数を返す関数

#include <stdio.h>

void add(int i, int j){
    printf("add:%d\n", i + j);
}

void sub(int i, int j){
    printf("sub:%d\n", i - j);
}

int main(){
    void (*funcs[2])(int, int) = {sub, add};
    funcs[0](10, 3);  // 13
    funcs[1](10, 3);  // 7
}

関数ポインタの型は、typdefしておくと楽。

typedef void (*MYFUNC)(int, int);

int main(){
    MYFUNC func[2] = {sub, add};
    func[0](10, 3);
    func[1](10, 3);
}

mmapでファイルとマッピングしたメモリへの書き込み後、msyncは必要か

mmapマッピングされたメモリ領域に対して書き込みをしても、 msyncは絶対必要というわけではない。

書き込みをすれば、それはいずれ(カーネル側の都合の良いタイミングで)、ファイルに反映されるから。

#include <stdlib.h>
#include <fcntl.h>
#include <stdio.h>
#include <sys/mman.h>

int main(int argc, char* argv[])
{
    int fd;
    char *cp;

    fd = open("/home/user/labo/mmap/tmp", O_RDWR);
    cp = mmap(NULL, sizeof(char), PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);

    puts("now read");
    printf("%c\n", *cp);

    *cp = *cp + 1;
    puts("now written");
    printf("%c\n", *cp);

    return 0;
}

以下、結果。 msyncしなくても、ファイル中の値がインクリメントされていくのがわかる。

user @ makeos:~/labo/mmap$ cat tmp
a
user @ makeos:~/labo/mmap$ gcc -o mmap mmap.c
user @ makeos:~/labo/mmap$ echo a > tmp
user @ makeos:~/labo/mmap$ ./mmap 
now read
a
now written
b
user @ makeos:~/labo/mmap$ ./mmap 
now read
b
now written
c