2014年2月18日火曜日

SECCON 2013 CTF オンライン予選 数毒 writeup

そもそも修論の追い込みで忙しい時期なので今回参加しないつもりでしたが、蓋を開ければ「解かないとあとで何言われるかわからない」数独があったのでしょうがない、この1問だけやりました。

DEFCON CTF 2013のゲリラプログラミングのスライドパズル同様、過去に自分で作って晒したコードをダウンロードして流用パターンです。

出題サーバにtelnetでアクセスするとこんな問題が表示されます。


'suDOKU(su-poison)' challenge for SECCON 2013.
by KeigoYAMAZAKI, 2013.11.22-


* Stage 1

   1 2 3 4 5 6 7 8 9 
  $-+-+-$-+-+-$-+-+-$
A |8|.|.|.|.|.|.|.|.|
B |.|.|3|6|.|.|.|.|.|
C |.|7|.|.|9|.|X|.|.|
  $-+-+-$-+-+-$-+-+-$
D |.|5|.|.|.|7|.|.|.|
E |.|.|.|.|4|5|7|.|.|
F |.|.|.|1|.|.|.|3|.|
  $-+-+-$-+-+-$-+-+-$
G |.|.|1|.|.|.|.|6|8|
H |.|.|8|5|.|.|.|1|.|
I |.|9|.|.|.|.|4|.|.|
  $-+-+-$-+-+-$-+-+-$

if 'X' is 2, how many solutions does this sudoku have?  => answer: 

注:証拠のデータ残していなかったので、問題は別のやつ貼り付けてます。

数独の問題なんですが中にXってのがあって、Xが2の時解はいくつあるか?って聞いてきます。 1盤面あたり複数この質問が来て、クリアすると次の盤面っていう繰り返しです。

以前、自分で作ったPrologのコードはこんなカンジです。
https://github.com/minetosh/sudoku/tree/master/prolog


sudoku(Rows) :-
    maplist(seigen, Rows), cols(Rows), blks(Rows),
    maplist(fd_labeling, Rows).

cols([[]|L]).
cols(L) :-
    maplist(nth(1), L, X), seigen(X), maplist(delete, L, X, NL), cols(NL).

blks([]).
blks([X, Y, Z|L]) :- blks2(X, Y, Z), blks(L).

blks2([],_,_).
blks2([X1, X2, X3|XL], [Y1, Y2, Y3|YL], [Z1, Z2, Z3|ZL]) :-
    seigen([X1, X2, X3, Y1, Y2, Y3, Z1, Z2, Z3]), blks2(XL, YL, ZL).

seigen(X) :- fd_domain(X, 1, 9), fd_all_different(X).


gprolog --consult-file sudoku.pl で起動した後、問題入力はこうやります。


Row1 = [8, _, _, _, _, _, _, _, _],
Row2 = [_, _, 3, 6, _, _, _, _, _],
Row3 = [_, 7, _, _, 9, _, 2, _, _],
Row4 = [_, 5, _, _, _, 7, _, _, _],
Row5 = [_, _, _, _, 4, 5, 7, _, _],
Row6 = [_, _, _, 1, _, _, _, 3, _],
Row7 = [_, _, 1, _, _, _, _, 6, 8],
Row8 = [_, _, 8, 5, _, _, _, 1, _],
Row9 = [_, 9, _, _, _, _, 4, _, _],
sudoku([Row1, Row2, Row3, Row4, Row5, Row6, Row7, Row8, Row9]).


解は次のように表示されます。


Row1 = [8,1,2,7,5,3,6,4,9]
Row2 = [9,4,3,6,8,2,1,7,5]
Row3 = [6,7,5,4,9,1,2,8,3]
Row4 = [1,5,4,2,3,7,8,9,6]
Row5 = [3,6,9,8,4,5,7,2,1]
Row6 = [2,8,7,1,6,9,5,3,4]
Row7 = [5,2,1,9,7,4,3,6,8]
Row8 = [4,3,8,5,2,6,9,1,7]
Row9 = [7,9,6,3,1,8,4,5,2] ?


検索してこのプログラムにたどり着いても複数解表示させる方法がわからなければ意味ないんですが、Prologで次の解を表示させるには、解を表示した後の?プロンプトに対して;(セミコロン)を入力します。解がある間これを繰り返します。
1問あたり制限時間は3分なので、この間に全解を手動で表示できる程度であれば、問題をこのプログラムの入力形式に変換してコピペ、セミコロンを入力し続けて解の数を数えればおkとなります。

解の数が2桁程度までなら上記方法でも十分間に合いますが3桁以上になったらきついと思うので、その時はjavaでI/O制御するプログラム作るつもりでいました。

とりあえず問題変換&コピペの手法を試すのに、以下のプログラムを作りました。


import java.io.*;

public class P200 {
 public static void main(String args[]) {
  try {
   InputStreamReader isr = null;
   try {
    isr = new InputStreamReader(System.in, "UTF-8");
    BufferedReader br = null;
    try {
     br = new BufferedReader(isr);
     String line = null;
     char c;
     while (true) {
      line = br.readLine();
      if (line.charAt(0) != ' ') {
       System.out.print("Row");
       System.out.print(line.charAt(0) - 'A' + 1);
       System.out.print("=[");
    System.out.print(a(line.charAt(3))); System.out.print(",");
    System.out.print(a(line.charAt(5))); System.out.print(",");
    System.out.print(a(line.charAt(7))); System.out.print(",");
    System.out.print(a(line.charAt(9))); System.out.print(",");
    System.out.print(a(line.charAt(11))); System.out.print(",");
    System.out.print(a(line.charAt(13))); System.out.print(",");
    System.out.print(a(line.charAt(15))); System.out.print(",");
    System.out.print(a(line.charAt(17))); System.out.print(",");
    System.out.print(a(line.charAt(19))); System.out.println("],");
       if (line.charAt(0) == 'I') {
        System.out.println(
 "sudoku([Row1, Row2, Row3, Row4, Row5, Row6, Row7, Row8, Row9])."
        );
       }
      }
     }
    } finally {
     if (br != null) br.close();
    }
   } finally {
    if (isr != null) isr.close();
   }
  } catch (Exception ex) {
   ex.printStackTrace();
  }
 }

 public static char a(char c) {
  if (c == '.')
   return '_';
  else
   return c;
 }
}


このプログラムで、


   1 2 3 4 5 6 7 8 9 
  $-+-+-$-+-+-$-+-+-$
A |8|.|.|.|.|.|.|.|.|
B |.|.|3|6|.|.|.|.|.|
C |.|7|.|.|9|.|X|.|.|
  $-+-+-$-+-+-$-+-+-$
D |.|5|.|.|.|7|.|.|.|
E |.|.|.|.|4|5|7|.|.|
F |.|.|.|1|.|.|.|3|.|
  $-+-+-$-+-+-$-+-+-$
G |.|.|1|.|.|.|.|6|8|
H |.|.|8|5|.|.|.|1|.|
I |.|9|.|.|.|.|4|.|.|
  $-+-+-$-+-+-$-+-+-$


が、


Row1 = [8, _, _, _, _, _, _, _, _],
Row2 = [_, _, 3, 6, _, _, _, _, _],
Row3 = [_, 7, _, _, 9, _, X, _, _],
Row4 = [_, 5, _, _, _, 7, _, _, _],
Row5 = [_, _, _, _, 4, 5, 7, _, _],
Row6 = [_, _, _, 1, _, _, _, 3, _],
Row7 = [_, _, 1, _, _, _, _, 6, 8],
Row8 = [_, _, 8, 5, _, _, _, 1, _],
Row9 = [_, 9, _, _, _, _, 4, _, _],
sudoku([Row1, Row2, Row3, Row4, Row5, Row6, Row7, Row8, Row9]).


になるので、X手前までPrologへコピペ、Xのところに示された数字入力、Xより後ろコピペ、セミコロン入力しながら数えて、の繰り返しでクリア出来ました。

結局私がやったときは解の数は0,1,2しかなく結構あっさり終わってしまいました。他の方のWriteupを見ると19っていうのもあったようです。

スコア画面に「あなたが一番最初にこの問題をときました」みたいに表示されていたので、多分そうゆうことなんだと思います。

2013年11月21日木曜日

制約論理プログラミングで数独を解く

GNU Prolog制約論理プログラミングで数独を解くプログラムを作ったところ、ほぼ数独のルールを記述するだけで出来てしまいました。

まずGNU Prologをインストールします。上のGNU Prologのサイトからソースをダウンロードしてインストールします。以下は1.4.4の場合です。

 $ tar zxf gprolog-1.4.4.tar.gz
 $ cd gprolog-1.4.4/src
 $ ./configure
 $ make
 $ sudo make install

次に以下のプログラム、


sudoku(Rows) :-
    Rows = [ % 引数の各行のリストをX11〜X99の変数に分解
        [X11, X12, X13, X14, X15, X16, X17, X18, X19],
        [X21, X22, X23, X24, X25, X26, X27, X28, X29],
        [X31, X32, X33, X34, X35, X36, X37, X38, X39],
        [X41, X42, X43, X44, X45, X46, X47, X48, X49],
        [X51, X52, X53, X54, X55, X56, X57, X58, X59],
        [X61, X62, X63, X64, X65, X66, X67, X68, X69],
        [X71, X72, X73, X74, X75, X76, X77, X78, X79],
        [X81, X82, X83, X84, X85, X86, X87, X88, X89],
        [X91, X92, X93, X94, X95, X96, X97, X98, X99]
    ],
    maplist(seigen, Rows), % 各行について値を制限

    Cols = [    % Colsを各列のリストとして定義
        [X11, X21, X31, X41, X51, X61, X71, X81, X91],
        [X12, X22, X32, X42, X52, X62, X72, X82, X92],
        [X13, X23, X33, X43, X53, X63, X73, X83, X93],
        [X14, X24, X34, X44, X54, X64, X74, X84, X94],
        [X15, X25, X35, X45, X55, X65, X75, X85, X95],
        [X16, X26, X36, X46, X56, X66, X76, X86, X96],
        [X17, X27, X37, X47, X57, X67, X77, X87, X97],
        [X18, X28, X38, X48, X58, X68, X78, X88, X98],
        [X19, X29, X39, X49, X59, X69, X79, X89, X99]
    ],
    maplist(seigen, Cols), % 各列について値を制限

    Blks = [ % Blksを各ブロックのリストとして定義
        [X11, X12, X13, X21, X22, X23, X31, X32, X33],
        [X14, X15, X16, X24, X25, X26, X34, X35, X36],
        [X17, X18, X19, X27, X28, X29, X37, X38, X39],
        [X41, X42, X43, X51, X52, X53, X61, X62, X63],
        [X44, X45, X46, X54, X55, X56, X64, X65, X66],
        [X47, X48, X49, X57, X58, X59, X67, X68, X69],
        [X71, X72, X73, X81, X82, X83, X91, X92, X93],
        [X74, X75, X76, X84, X85, X86, X94, X95, X96],
        [X77, X78, X79, X87, X88, X89, X97, X98, X99]
    ],
    maplist(seigen, Blks), % 各ブロックについて値を制限

    maplist(fd_labeling, Rows). % 各行の値を探索

% リストXの各値の取る値は1から9で、重複なし
seigen(X) :- fd_domain(X,1,9), fd_all_different(X).


をファイル(sudoku.pl)に保存して、以下のようにprologを起動します。

 $ gprolog --consult-file sudoku.pl

プロンプト(?-)が表示されたところで、以下のように問題データをセットして呼び出します。


Row1 = [8, _, _, _, _, _, _, _, _],
Row2 = [_, _, 3, 6, _, _, _, _, _],
Row3 = [_, 7, _, _, 9, _, 2, _, _],
Row4 = [_, 5, _, _, _, 7, _, _, _],
Row5 = [_, _, _, _, 4, 5, 7, _, _],
Row6 = [_, _, _, 1, _, _, _, 3, _],
Row7 = [_, _, 1, _, _, _, _, 6, 8],
Row8 = [_, _, 8, 5, _, _, _, 1, _],
Row9 = [_, 9, _, _, _, _, 4, _, _],
sudoku([Row1, Row2, Row3, Row4, Row5, Row6, Row7, Row8, Row9]).


多分、瞬殺で解答が返ってくると思います。問題はこちらのサイトから世界一難しい数独問題を拝借しました。


Row1 = [8,1,2,7,5,3,6,4,9]
Row2 = [9,4,3,6,8,2,1,7,5]
Row3 = [6,7,5,4,9,1,2,8,3]
Row4 = [1,5,4,2,3,7,8,9,6]
Row5 = [3,6,9,8,4,5,7,2,1]
Row6 = [2,8,7,1,6,9,5,3,4]
Row7 = [5,2,1,9,7,4,3,6,8]
Row8 = [4,3,8,5,2,6,9,1,7]
Row9 = [7,9,6,3,1,8,4,5,2] ?


プログラム、というかルール記述は至って単純で、
 Rows = [[X11, ... , X19], ... [X91, ... , X99],
で引数で渡されたRowsの各行を変数X11〜X99に分解、
 maplist(seigen, Rows),
で数独による各行の値のルールを指定しています。maplistは2つ目の引数のリストの各要素について1つ目の引数の関数(Prologでは通常は関数と呼ばないようですが)を呼び出します。Rowsの各行についてseigenを呼び出していますが、これは最後の行で以下のように定義されています。
 seigen(X) :- fd_domain(X,1,9), fd_all_different(X).
fd_domainで各要素の値の取りうる値を1から9に制限し、fd_all_differentで各要素で重複する値を持つことがない、としています。
 Cols = [...

 Blks = [...
で各列と各ブロックのリストを構成する変数を定義し、同じようにseigenを呼び出しています。

以上、ここまでは文字通り数独のルール記述だけになっています。

 maplist(fd_labeling, Rows).

この行で各行のリストの持つ変数、すなわちX11〜X99すべてについて探索開始を指示しています。

問題を設定するところでわざわざRows1〜Rows9のリストとしているのは、結果の表示を見やすくするためです。

こんなに簡単にいけると思わかなった。。。

2013/11/21追記
 
以下が私の考える最短ソース。ここまで行くとProlog読めないと意味不明。
https://github.com/minetosh/sudoku/tree/master/prolog


sudoku(Rows) :-
    maplist(seigen, Rows), cols(Rows), blks(Rows),
    maplist(fd_labeling, Rows).

cols([[]|L]).
cols(L) :-
    maplist(nth(1), L, X), seigen(X), maplist(delete, L, X, NL), cols(NL).

blks([]).
blks([X, Y, Z|L]) :- blks2(X, Y, Z), blks(L).

blks2([],_,_).
blks2([X1, X2, X3|XL], [Y1, Y2, Y3|YL], [Z1, Z2, Z3|ZL]) :-
    seigen([X1, X2, X3, Y1, Y2, Y3, Z1, Z2, Z3]), blks2(XL, YL, ZL).

seigen(X) :- fd_domain(X, 1, 9), fd_all_different(X).

2013年11月9日土曜日

Linuxで一つのネットワークインターフェースに複数IPアドレス設定する方法

CentOS6から複数IPアドレス設定の方法か変わったらしい、件で書いた、IPエイリアスを使わない方法はUbuntuでも行けました。しかもGUI上一つしか設定できないように見える8.04で。



# ip addr add 192.168.224.132/24 dev eth0

で設定できて、pingが通りました。ifconfigではやっぱり出て来ません。

全部試したわけじゃないけど、きっとLinux共通なんでしょーねー。
自分が知らなかっただけか。

2013年10月31日木曜日

CentOS6から複数IPアドレス設定の方法が変わったらしい、件

UNIX系OSにおいて、1つの物理ネットワークインターフェースで複数のIPアドレスを使うのに、eth0:0といった仮想?インターフェースを定義して別のアドレスを振る、ってのがここ20年近く使われてきた常套手段だと思いますが、どうも最近のCentOSには別の方法があるようです。

 CentOSでIPアドレスを固定にしようと思いGUIメニューから、システム→設定→ネットワーク接続、でネットワークインターフェースを選択して編集をクリック、IPv4のセッティングタブを開くと、IPアドレスを複数設定できるように見えます。


おそらく最初のIPがeth0に割り当てられ、2つ目がeth0:0、3つ目がeth0:1、と言った具合に続くと予想していました。仕事で複数IP振る必要があったので、早速試してみました。

下のように192.168.100.101と192.168.100.102を設定して、


ifconfigで確認したところ、アドレス192.168.100.102は出てきません。


bash-4.1$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr 08:00:27:DC:58:77
          inet addr:192.168.100.101  Bcast:192.168.100.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fedc:5877/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:25 errors:0 dropped:0 overruns:0 frame:0
          TX packets:47 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:12297 (12.0 KiB)  TX bytes:3305 (3.2 KiB)
          Interrupt:10 Base address:0xd020

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)


しかし、他のマシンからpingを打つとちゃんと帰ってきます。pingを打ったマシンでarpを見ると、ちゃんと複数IPアドレスが同一MACアドレスにリンクされています。


$ arp -a
? (192.168.100.101) at 8:0:27:dc:58:77 on en1 ifscope [ethernet]
? (192.168.100.102) at 8:0:27:dc:58:77 on en1 ifscope [ethernet]


どゆこと???
(◕‿‿◕)わけがわからないよ。

意図した通りに動いているけど原理がまったくわからない。
「CentOS6+複数IPアドレス」で検索しても、従来の方法しか見つかりませんでしたが、「RedHat6+複数IPアドレス」でようやくこのページにたどり着きました。

RHEL6: ifconfig is obsolete!

このページによると、ifconfigは廃止なんだそうで、今後はip addrを使えってことでした。早速やってみると、


bash-4.1$ ip addr
1: lo:  mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 08:00:27:dc:58:77 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.101/24 brd 192.168.100.255 scope global eth0
    inet 192.168.100.102/24 brd 192.168.100.255 scope global secondary eth0
    inet6 fe80::a00:27ff:fedc:5877/64 scope link
       valid_lft forever preferred_lft forever


でてきました。 どうやら最近のRedHat系OSは1つのインターフェースに仮想インターフェースを追加することなくフツーに複数IPアドレス設定できるようになっているようです。従来のifconfigではこの設定を見ることはできず、ip addrでないと見れない。

設定ファイルの中は、以下の通り2つ目以降のアドレスをIPADDR2等で設定しています。


bash-4.1$ cat /etc/sysconfig/network-scripts/ifcfg-Auto_eth0
TYPE=Ethernet
BOOTPROTO=none
IPADDR=192.168.100.101
PREFIX=24
GATEWAY=192.168.100.254
DNS1=192.168.100.254
DOMAIN=burger.jp
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="Auto eth0"
UUID=e35c20d7-be0a-44e4-bdea-a3f20d6a9165
ONBOOT=yes
IPADDR2=192.168.100.102
PREFIX2=24
HWADDR=08:00:27:DC:58:77
LAST_CONNECT=1383196516


ずいぶん簡単にできるようになりました。が、このリンク先にもある通り、仮想インターフェース方式ならup/downを別にできる(ip addr add/delでできそうなので削除)、webminが複数IPアドレス方式だと認識できない、といったこともあるようなので、用途によってどちらを使うか考える必要があります。Apahce2.2は問題なく動きました。

ためしにこの状態で仮想インターフェースも使えるかやってみました。/etc/sysconfig/network-scripts/ifcfg-eth0:0を以下のように用意します。192.168.100.103を仮想IPアドレスにします。


bash-4.1$ cat /etc/sysconfig/network-scripts/ifcfg-eth0:0
TYPE=Ethernet
BOOTPROTO=none
IPADDR=192.168.100.103
PREFIX=24
GATEWAY=192.168.100.254
ONBOOT=yes


リブート後ifconfigで確認すると、192.168.100.102は相変わらず出ませんがeth0:0で192.168.100.103が出てきました。


bash-4.1$ ifconfig -a
eth0      Link encap:Ethernet  HWaddr 08:00:27:DC:58:77
          inet addr:192.168.100.101  Bcast:192.168.100.255  Mask:255.255.255.0
          inet6 addr: fe80::a00:27ff:fedc:5877/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:23 errors:0 dropped:0 overruns:0 frame:0
          TX packets:45 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:12171 (11.8 KiB)  TX bytes:3221 (3.1 KiB)
          Interrupt:10 Base address:0xd020

eth0:0    Link encap:Ethernet  HWaddr 08:00:27:DC:58:77
          inet addr:192.168.100.103  Bcast:192.168.100.255  Mask:255.255.255.0
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          Interrupt:10 Base address:0xd020

lo        Link encap:Local Loopback
          inet addr:127.0.0.1  Mask:255.0.0.0
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:8 errors:0 dropped:0 overruns:0 frame:0
          TX packets:8 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:480 (480.0 b)  TX bytes:480 (480.0 b)


ip addrはこんなカンジです。


bash-4.1$ ip addr
1: lo:  mtu 16436 qdisc noqueue state UNKNOWN
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
    inet6 ::1/128 scope host
       valid_lft forever preferred_lft forever
2: eth0:  mtu 1500 qdisc pfifo_fast state UNKNOWN qlen 1000
    link/ether 08:00:27:dc:58:77 brd ff:ff:ff:ff:ff:ff
    inet 192.168.100.101/24 brd 192.168.100.255 scope global eth0
    inet 192.168.100.102/24 brd 192.168.100.255 scope global secondary eth0
    inet 192.168.100.103/24 brd 192.168.100.255 scope global secondary eth0:0
    inet6 fe80::a00:27ff:fedc:5877/64 scope link


他のマシンからはすべて問題なくpingが通りました。

2013年7月23日火曜日

VMWare Player上のUbuntu13.04でVMWare Toolsのhgfsのコンパイルがコケる件


VMWare Player上のUbuntu13.04でVMWare Toolsをインストールしようとすると、ホストOSとゲストOSでディレクトリを共有するためのファイルシステムhgfs(Host-Guest Filesystem)のコンパイルに失敗します。


The VMware Host-Guest Filesystem allows for shared folders between the host OS
and the guest OS in a Fusion or Workstation virtual environment.  Do you wish
to enable this feature? [yes]

Using 2.6.x kernel build system.
make: ディレクトリ `/tmp/modconfig-fMqXb3/vmci-only' に入ります
/usr/bin/make -C /lib/modules/3.8.0-23-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. \
      MODULEBUILDDIR= modules
make[1]: ディレクトリ `/usr/src/linux-headers-3.8.0-23-generic' に入ります
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/linux/driver.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/linux/vmciKernelIf.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciContext.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciDatagram.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciDoorbell.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciDriver.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciEvent.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciHashtable.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciQPair.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciQueuePair.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciResource.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/common/vmciRoute.o
  CC [M]  /tmp/modconfig-fMqXb3/vmci-only/driverLog.o
  LD [M]  /tmp/modconfig-fMqXb3/vmci-only/vmci.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /tmp/modconfig-fMqXb3/vmci-only/vmci.mod.o
  LD [M]  /tmp/modconfig-fMqXb3/vmci-only/vmci.ko
make[1]: ディレクトリ `/usr/src/linux-headers-3.8.0-23-generic' から出ます
/usr/bin/make -C $PWD SRCROOT=$PWD/. \
      MODULEBUILDDIR= postbuild
make[1]: ディレクトリ `/tmp/modconfig-fMqXb3/vmci-only' に入ります
make[1]: `postbuild' は更新済みです
make[1]: ディレクトリ `/tmp/modconfig-fMqXb3/vmci-only' から出ます
cp -f vmci.ko ./../vmci.o
make: ディレクトリ `/tmp/modconfig-fMqXb3/vmci-only' から出ます
Using 2.6.x kernel build system.
make: ディレクトリ `/tmp/modconfig-fMqXb3/vmhgfs-only' に入ります
/usr/bin/make -C /lib/modules/3.8.0-23-generic/build/include/.. SUBDIRS=$PWD SRCROOT=$PWD/. \
      MODULEBUILDDIR= modules
make[1]: ディレクトリ `/usr/src/linux-headers-3.8.0-23-generic' に入ります
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/backdoor.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/backdoorGcc32.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/bdhandler.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/cpName.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/cpNameLinux.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/cpNameLite.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/dentry.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/dir.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/file.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/filesystem.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/fsutil.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/hgfsBd.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/hgfsEscape.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/hgfsUtil.o
  CC [M]  /tmp/modconfig-fMqXb3/vmhgfs-only/inode.o
/tmp/modconfig-fMqXb3/vmhgfs-only/inode.c: 関数 ‘HgfsTruncatePages’ 内:
/tmp/modconfig-fMqXb3/vmhgfs-only/inode.c:888:4: エラー: 関数 ‘vmtruncate’ の暗黙的な宣言です [-Werror=implicit-function-declaration]
cc1: some warnings being treated as errors
make[2]: *** [/tmp/modconfig-fMqXb3/vmhgfs-only/inode.o] エラー 1
make[1]: *** [_module_/tmp/modconfig-fMqXb3/vmhgfs-only] エラー 2
make[1]: ディレクトリ `/usr/src/linux-headers-3.8.0-23-generic' から出ます
make: *** [vmhgfs.ko] エラー 2
make: ディレクトリ `/tmp/modconfig-fMqXb3/vmhgfs-only' から出ます

The filesystem driver (vmhgfs module) is used only for the shared folder
feature. The rest of the software provided by VMware Tools is designed to work
independently of this feature.

If you wish to have the shared folders feature, you can install the driver by
running vmware-config-tools.pl again after making sure that gcc, binutils, make
and the kernel sources for your running kernel are installed on your machine.
These packages are available on your distribution's installation CD.


これネットで検索するとエラーの出た該当行、vmware-tools-distrib/lib/modules/source/vmhgfs.tar内のvmhgfs-only/inode.cの888行目


result = compat_vmtruncate(inode, newSize);





result = 0;


に変えろっていうのが大多数なんですが、ホントにtruncateとかしなくていいのか疑問だったので、調べて見ました。

まずこのcompat_vmtruncateは、vmhgfs-only/shared/compat_mm.hでdefineされていました。


/*
 * In 2.4.10, vmtruncate was changed from returning void to returning int.
 */
#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 10)
#define compat_vmtruncate(inode, size)                                        \
({                                                                            \
   int result = 0;                                                            \
   vmtruncate(inode, size);                                                   \
   result;                                                                    \
})
#else
#define compat_vmtruncate(inode, size) vmtruncate(inode, size)
#endif


カーネルバージョン2.4.10より前ならvoid型をint型に変えて、それ以降ならvmtruncateに書き換えるだけ。で、Ubuntu13.04のカーネルバージョンは3.8.0なんですが、カーネルソースダウンロードしてきて探してもありません。Ubuntu12.10の3.5.0で探してみたらありました。mm/truncate.cに。


/**
 * vmtruncate - unmap mappings "freed" by truncate() syscall
 * @inode: inode of the file used
 * @newsize: file offset to start truncating
 *
 * This function is deprecated and truncate_setsize or truncate_pagecache
 * should be used instead, together with filesystem specific block truncation.
 */
int vmtruncate(struct inode *inode, loff_t newsize)
{
        int error;

        error = inode_newsize_ok(inode, newsize);
        if (error)
                return error;

        truncate_setsize(inode, newsize);
        if (inode->i_op->truncate)
                inode->i_op->truncate(inode);
        return 0;
}


コメントの2ブロック目、ようはもうvmtruncate使うな、ってことのようです。
ちなみにinode->i_op->truncateがあれば呼び出すようになっていますが、3.8.0ではこのメンバはありません。

ということで私なりにですが、バージョン3.8.0より前ならそのまま、それ以降ならcompat_vmtruncateを上記のコードに近い形で置き換える、という方法を取りました。

以下その手順です。


# cd vmware-tools-distrib/lib/modules/source
# tar xf vmhgfs.tar
# vi vmhgfs-only/shared/compat_mm.h


103行目の


#define compat_vmtruncate(inode, size) vmtruncate(inode, size)


を以下のように変更。


#  if LINUX_VERSION_CODE < KERNEL_VERSION(3, 8, 0)
#     define compat_vmtruncate(inode, size) vmtruncate(inode, size)
#  else
#     define compat_vmtruncate(inode, size)                                   \
({                                                                            \
   int error = inode_newsize_ok(inode, size);                                 \
   if (!error)                                                                \
      truncate_setsize(inode, size);                                          \
   error;                                                                     \
})
#  endif


で、


# tar cf vmhgfs.tar vmhgfs-only
# cd ../../../
# ./vmware-install.pl


なんかWarningでましたが一応コンパイルは通って動くようになりました。


 CC [M]  /tmp/modconfig-z3oAcX/vmhgfs-only/inode.o
/tmp/modconfig-z3oAcX/vmhgfs-only/inode.c: 関数 ‘HgfsPermission’ 内:
/tmp/modconfig-z3oAcX/vmhgfs-only/inode.c:1755:8: 警告: ‘dentry’ はこの関数内初期化されずに使用されるかもしれません [-Wmaybe-uninitialized]
/tmp/modconfig-z3oAcX/vmhgfs-only/inode.c:1813:22: 備考: ‘dentry’ はここで定義されています


当然ですが、ここで紹介した方法によって何が起きても責任は負えませんので。

2013年7月11日木曜日

メモ。iPadとかでdnsだます方法。

Windows7で管理者権限でコマンドプロンプト起動。
> netsh wlan set hostednetwork mode=allow
> netsh wlan set hostednetwork ssid=hogehogeap
> netsh wlan set hostednetwork key=nyarlathotep keyusage=persistent
> netsh wlan start hostednetwork
確認は
> netsh wlan show hostednetwork
停止は
> netsh wlan stop hostednetwork

ローカルエリアネットワークでインターネット接続の共有

Ubuntuで/etc/hostsにだましたいURL入れる。
# dnsmasq

Windows7でDNSを上のUbuntuに変更。
iPadでhogehogeapに接続。

2013年7月6日土曜日

Ubuntu12.10にSELinux

メモ。
# apt-get install selinux
# apt-get install selinux-policy-src
# apt-get install selinux-policy-dev
リブート。