2016年12月7日水曜日

カーネルモジュールを学ぼうとして得たこと

Linux の中核の処理であるタスク切り替え。その切り替えするタスクの情報を構成する task_struct

それをCのプログラムで見れないものか、と調べたらカーネルモジュールでやるんだよ、と突き止めた。

まずはカーネルモジュールを試してみようと思って、"Hello, World" だけを書き出すカーネルモジュールを作ってみた。環境は Ubuntu 16.04 (カーネルバージョンは4.4.0-51)。

Makefile に下記のテキストを書く。makefile にすると、「Makefileが見つからん」とコンパイラがお怒りになる。

obj-m += hello.o

hello.c に下記のコードを書く。

#include <linux/module.h>

int init_module(void)
{
    printk(KERN_ALERT "Hello World!\n");
    return 0;
}

void cleanup_module(void)
{
    return;
} 

次のようにコマンド実行して、コンパイルすると、hello.ko が出来上がった。

$ make -C /lib/modules/4.4.0-51-generic/build SUBDIRS=~/Develop/kernel.modules/hello modules
make: ディレクトリ '/usr/src/linux-headers-4.4.0-51-generic' に入ります
  CC [M]  /home/kernel.modules/hello/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/kernel.modules/hello/hello.mod.o
  LD [M]  /home/kernel.modules/hello/hello.ko
make: ディレクトリ '/usr/src/linux-headers-4.4.0-51-generic' から出ます
$ ls
Makefile        hello.c   hello.mod.c  hello.o
Module.symvers  hello.ko  hello.mod.o  modules.order

そして、この hello.ko を実行しようとして、以下のように蹴られた。

$ sudo insmod hello.ko

insmod: ERROR: could not insert module hello.ko: Required key not available
$ 

こちらのサイトで紹介されているように、カーネルモードで動くマルウェアをインストールさせないために、最近のカーネルバージョンではセキュアブートしているのだという。

今、使用している10インチノートPCは2012年仕様で、BIOSでのセキュアブートができないので困った...。

上記のキーワードで検索すると、mokutil というものを使うことでセキュアブートを無効にできるらしいと、ここから分かった。早速、

$ sudo apt-get install mokutil
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています                
状態情報を読み取っています... 完了
mokutil はすでに最新バージョン (0.3.0-0ubuntu3) です。
アップグレード: 0 個、新規インストール: 0 個、削除: 0 個、保留: 342 個。 

セキュアブート対応のカーネルバージョンを持つ Ubuntu 16.04 にはデフォルトで付いている。ひき続いて、

sudo mokutil --disable-validation

パスワードを求められたので、入力してPCを再起動後、そのパスワードを入力すると、"Booting insecure mode"と表示されて、デスクトップ起動後に以下を実行。

$ sudo insmod hello.ko
[sudo] emeraudequeen のパスワード: 
$ dmesg | tail
[  358.598562] hello: module license 'unspecified' taints kernel.
[  358.598574] Disabling lock debugging due to kernel taint
[  358.598685] hello: module verification failed: signature and/or required key missing - tainting kernel

[  358.599138] Hello World! 

どうやらカーネルモジュールが動いた。これで task_struct を覗いてみる準備が整った。
それはまた後日に、ってところにしておいて、ちょっとおさらい。

カーネルモジュール動作時に dmesg で見た"module verification failed"は、正規のやり方でないので、出るのは当然。Windows でよくフリーのアプリをインストールするときに、「署名されていないパッケージだけどインストールしていいの?」と聞かれてくるものに置き換えると分かりやすいか...。

上記での参照先では「余計なことを」と書いておられるようだが、Linux にも知らない間にバックドアを仕掛けるカーネルレベルのモジュールが入り込むリスクはやはり避けたい。スヌープしたものの送信先が支那や朝鮮であれば、悲惨なことになる。

2016年8月15日月曜日

Ubuntuにクロスコンパイラを構築する方法

ARM用Linuxを構築したいため、Ubuntuにクロスコンパイラを構築する方法をメモっとく。

事前にbuild-essentialtexinfogawkをインストールしておく。

ARM用クロスコンパイラのモジュールのインストール先を$HOME/Programs/armccとするので、ディレクトリと環境変数を作っておく。


$ mkdir -pv $HOME/Programs
$ mkdir -pv $HOME/Programs/armcc
$ export PATH="$HOME/Programs/armcc/bin:$PATH"

binutils-2.25 をビルド
$ wget http://ftp.gnu.org/gnu/binutils/binutils-2.25.tar.bz2
$ tar jxvf binutils-2.25.tar.bz2
$ mkdir -pv binutils-2.25/build
$ cd binutils-2.25/build
$ ../configure --target=arm-linux-gnueabi --prefix=$HOME/Programs/armcc
$ make
$ make install

gcc-4.9.2 をビルド(1回め)
※gmp、mpc、mpfr を一緒にビルドする
$ wget http://ftp.gnu.org/gnu/gcc/gcc-4.9.2/gcc-4.9.2.tar.bz2
$ wget http://ftp.gnu.org/gnu//gmp/gmp-6.0.0a.tar.xz
$ wget http://www.multiprecision.org/mpc/download/mpc-1.0.2.tar.gz
$ wget http://www.mpfr.org/mpfr-3.1.2/mpfr-3.1.2.tar.xz
$ tar jxvf gcc-4.9.2.tar.bz2
$ tar -xf gmp-6.0.0a.tar.xz
$ mv gmp-6.0.0 gcc-4.9.2/gmp
$ tar -xf mpc-1.0.2.tar.gz
$ mv mpc-1.0.2 gcc-4.9.2/mpc
$ tar -xf mpfr-3.1.2.tar.xz
$ mv mpfr-3.1.2 gcc-4.9.2/mpfr
$ mkdir gcc-4.9.2/build1
$ cd gcc-4.9.2/build1
$ ../configure --target=arm-linux-gnueabi --prefix=$HOME/Programs/armcc --with-newlib \
--without-headers --disable-nls --disable-shared --disable-multilib \
--disable-decimal-float --disable-threads --disable-libatomic \
--disable-libgomp --disable-libitm --disable-libquadmath \
--disable-libsanitizer --disable-libssp --disable-libvtv \
--disable-libcilkrts --disable-libstdc++-v3 \
--enable-languages=c,c++
$ make
$ make install

Linux ヘッダインストール
$ wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.19.tar.xz
$ tar -xf linux-3.19.tar.xz
$ cd linux-3.19
$ make mrproper
$ make headers_install ARCH=arm CROSS_COMPILE=arm-linux-gnueabi INSTALL_HDR_PATH=$HOME/Programs/armcc/arm-linux-gnueabi

glibc-2.21 のビルド
$ wget http://ftp.gnu.org/gnu/glibc/glibc-2.21.tar.xz
$ tar -xf glibc-2.21.tar.xz
$ mkdir -pv glibc-2.21/build
$ cd glibc-2.21/build
$ ../configure --prefix=$HOME/Programs/armcc/arm-linux-gnueabi \

  --host=arm-linux-gnueabi --build=$(../scripts/config.guess) \
  --disable-profile --enable-kernel=2.6.32 \
  --with-headers=$HOME/Programs/armcc/arm-linux-gnueabi/include \
  libc_cv_forced_unwind=yes \

  libc_cv_ctors_headers=yes \
  libc_cv_c_cleanup=yes
$ make
$ make install

libstdc++ のビルド
$ mkdir -pv gcc-4.9.2/build_libstdcpp
$ cd gcc-4.9.2/build_libstdcpp
$ ../libstdc++-v3/configure --target=arm-linux-gnueabi \
  --prefix=$HOME/Programs/armcc/arm-linux-gnueabi --disable-multilib \
  --disable-shared --disable-nls --disable-libstdcxx-threads \

  --disable-libstdcxx-pch \
  --with-gxx-include-dir=$HOME/Programs/armcc/arm-linux-gnueabi/include/c++/4.9.2
$ make
$ make install

gcc-4.9.2 のビルド(2回め)
$ mkdir -pv gcc-4.9.2/build2
$ cd gcc-4.9.2/build2
$ ../configure --target=arm-linux-gnueabi --prefix=$HOME/Programs/armcc \

  --disable-nls --disable-shared --disable-multilib \
  --disable-libgomp --disable-threads --enable-languages=c,c++ \
  --disable-libstdcxx-pch --disable-bootstrap
$ make
$ make install

gdb-7.11 のビルド
$ wget http://ftp.gnu.org/gnu/gdb/gdb-7.11.tar.xz $ tar -xf gdb-7.11.tar.xz
$ mkdir -pv gdb-7.11/build
$ cd gdb-7.11/build
$ ../configure --target=arm-linux-gnueabi --prefix=$HOME/Programs/armcc
$ make
$ make install

コンパイルテストする。a.c に以下のコードを書く。
#include <stdio.h>

int main()
{
printf("Hello ARM\n");
return 0;
}

ビルドしたクロスコンパイラでa.cをコンパイルする。
$ arm-linux-gnueabi-gcc a.c -o pa

$ arm-linux-gnueabi-readelf -h pra
ELF ヘッダ:
マジック: 7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
クラス: ELF32
データ: 2 の補数、リトルエンディアン
バージョン: 1 (current)
OS/ABI: UNIX - System V
ABI バージョン: 0
型: EXEC (実行可能ファイル)
マシン: ARM
バージョン: 0x1
エントリポイントアドレス: 0x102c4
プログラムの開始ヘッダ: 52 (バイト)
セクションヘッダ始点: 7520 (バイト)
フラグ: 0x5000202, has entry point, Version5 EABI, soft-float ABI
このヘッダのサイズ: 52 (バイト)
プログラムヘッダサイズ: 32 (バイト)
プログラムヘッダ数: 8
セクションヘッダ: 40 (バイト)
セクションヘッダサイズ: 37
セクションヘッダ文字列表索引: 34

qemu-arm で動かしてみる
$ qemu-arm -L $HOME/Programs/armcc/arm-linux-gnueabi ./pra
Hello ARM

2016年2月20日土曜日

Ubuntuでセキュリティアップデートを自動化する

unattended-upgradesをインストールする。

$ sudo apt-get install unattended-upgrades

/etc/apt/apt.conf.d/50unattended-upgrades のUnattended-Upgrade::Allowed-Origins セクションがセキュリティだけ有効になっていればOK。

Unattended-Upgrade::Allowed-Origins {
        "${distro_id}:${distro_codename}-security";
//      "${distro_id}:${distro_codename}-updates";
//      "${distro_id}:${distro_codename}-proposed";
//      "${distro_id}:${distro_codename}-backports";
};

38行目の通知先メールアドレスを適宜設定する。

Unattended-Upgrade::Mail "hoge@hogehoge"

自動更新を有効にする。

$ sudo dpkg-reconfigure -plow unattended-upgrades # Yesを選択

2016年2月17日に発表されたglibcの脆弱性修正版の自動アップデートを確認する。
/var/log/unattended-upgrades/unattended-upgrades.logにて以下のログがある。

2016-02-17 07:54:40,970 INFO 初期状態でブラックリストにあるパッケージ:
2016-02-17 07:54:40,971 INFO 自動アップグレードスクリプトを開始
2016-02-17 07:54:40,971 INFO 許可されているパッケージ導入元: ['o=Ubuntu,a=trusty-security']
2016-02-17 07:58:07,500 INFO Packages that will be upgraded: fonts-opensymbol libc-bin libc-dev-bin libc6 libc6-dbg libc6-dev libreoffice-avmedia-backend-gstreamer libreoffice-base-core libreoffice-calc libreoffice-common libreoffice-core libreoffice-draw libreoffice-gnome libreoffice-gtk libreoffice-impress libreoffice-math libreoffice-ogltrans libreoffice-pdfimport libreoffice-presentation-minimizer libreoffice-style-human libreoffice-writer libwbclient0 multiarch-support python-samba python3-uno samba samba-common samba-common-bin samba-dsdb-modules samba-libs samba-vfs-modules uno-libs3 ure
2016-02-17 07:58:07,501 INFO dpkg のログを '/var/log/unattended-upgrades/unattended-upgrades-dpkg_2016-02-17_07:58:07.500662.log' に書き込み中
2016-02-17 07:59:19,752 INFO すべてのアップグレードがインストールされました

libc-binのバージョンを表示して、脆弱性修正版を確認した。

$ apt-cache policy libc-bin
libc-bin:
  インストールされているバージョン: 2.19-0ubuntu6.7
  候補:               2.19-0ubuntu6.7
  バージョンテーブル:
 *** 2.19-0ubuntu6.7 0
        500 http://jp.archive.ubuntu.com/ubuntu/ trusty-updates/main amd64 Packages
        500 http://security.ubuntu.com/ubuntu/ trusty-security/main amd64 Packages
        100 /var/lib/dpkg/status
     2.19-0ubuntu6 0
        500 http://jp.archive.ubuntu.com/ubuntu/ trusty/main amd64 Packages

2016年1月17日日曜日

「慰安婦合意は国際法的には国際刑事法違反」とするウリナーラ教授のファッビョーーン症状

「国際法」、これは地球規模の秩序を保つためのものですが、あのウリナラ国では発狂するためのツールでしか無いようです。

ハンギョレ新聞の記事を引用します。

亜洲大法学専門大学院のイ・ユンゼ教授は旧ユーゴ戦犯裁判所で裁判研究官を勤め、大学で国際刑事法を講義しているという。
裁判研究官
そんな職業、初めて聞きましたよ。ググってみると韓国しかヒットしませんが、もしかしてOINK
な職業なのでしょうかね。

日政府の慰安婦関聨合意内容が‘国際犯罪’という側面を排除する非常に深刻な問題があるが、 この部分についてはまともに議論されていない。 
島根県の竹島を不法占拠、靖国神社での爆弾テロなど、「日本で罪を犯している」ことを棚に上げて、 国際犯罪などと抜かすなよ。アホタレが!!

ソース:ハンギョレ新聞(韓国語) [時論]‘慰安婦合意’という国際的逸脱行為/イ・ユンゼ 
http://www.hani.co.kr/arti/opinion/column/725655.html 

2016年1月16日土曜日

munin の壊れたグラフを修復

2015年12月27日にShuttle製ベアボーンDS57Uの2台目を購入し、それをルーター用として稼働させたのね。

1台目のDS57Uに munin をインストールして、モニタリングしとったんやけど、上述のルーター機交換時にこの1台目をシャットダウンさせた、っと。

それからmunin のグラフがこんなんなったのを修復させた、っちゅうお話。


/var/log/munin/munin-update.log にこんなログが出とった。

2016/01/16 07:45:01 [INFO]: Starting munin-update
2016/01/16 07:45:01 [INFO] starting work in 16183 for fender/127.0.0.1:4949.
2016/01/16 07:45:06 [ERROR] In RRD: Error updating /var/lib/munin/fender/fender-sensors_temp-temp8-g.rrd: '/var/lib/munin/fender/fender-sensors_temp-temp8-g.rrd' is not an RRD file
2016/01/16 07:45:06 [ERROR] In RRD: Error updating /var/lib/munin/fender/fender-sensors_temp-temp6-g.rrd: '/var/lib/munin/fender/fender-sensors_temp-temp6-g.rrd' is not an RRD file
2016/01/16 07:45:06 [ERROR] In RRD: Error updating /var/lib/munin/fender/fender-sensors_temp-temp7-g.rrd: '/var/lib/munin/fender/fender-sensors_temp-temp7-g.rrd' is not an RRD file
2016/01/16 07:45:10 [INFO]: Munin-update finished for node fender;fender (8.88 sec)
2016/01/16 07:45:10 [INFO] Reaping Munin::Master::UpdateWorker. Exit value/signal: 0/0
2016/01/16 07:45:10 [INFO]: Munin-update finished (9.00 sec)


RRDを更新できないねん、と言わはっとる。munin の更新が9秒もかかっとることに、ピンときた。

実は冒頭のルーター機交換のときに、シャットダウンしようとして、やけに時間がかかるなっと思い、無理やりPowerOffしたことを思い出した(これは素直に反省するねん)。

munin 更新中に Ubuntu を無理やり落として、RRDが壊れてしまったんだろうと推論して、以前の履歴が消えることを覚悟して、3つのRRDを消してみた。

5分後にこんなログが出て、RRDが作られたっと。

2016/01/16 11:40:01 [INFO]: Starting munin-update
2016/01/16 11:40:01 [INFO] starting work in 19375 for fender/127.0.0.1:4949.
2016/01/16 11:40:01 [INFO] creating rrd-file for sensors_temp->temp7: '/var/lib/munin/fender/fender-sensors_temp-temp7-g.rrd'
2016/01/16 11:40:01 [INFO] creating rrd-file for sensors_temp->temp8: '/var/lib/munin/fender/fender-sensors_temp-temp8-g.rrd'
2016/01/16 11:40:01 [INFO] creating rrd-file for sensors_temp->temp6: '/var/lib/munin/fender/fender-sensors_temp-temp6-g.rrd'
2016/01/16 11:40:10 [INFO]: Munin-update finished for node fender;fender (9.56 sec)
2016/01/16 11:40:10 [INFO] Reaping Munin::Master::UpdateWorker. Exit value/signal: 0/0
2016/01/16 11:40:10 [INFO]: Munin-update finished (9.66 sec)


munin のページを表示したら、あらら、ちゃんと出てきましたよっと。めでたしめでたし。


ちなみにこのマシンは昨年の構築時に4GBのメモリを搭載しとったけど、16GBに増やした。