honeydのsetrlimitでNOFILEというエラーが出て死ぬ件

honeyd: setrlimit: NOFILE

honeydっていうソフトを動かそうとしたら実行時にsetrlimitでエラー.環境はMac OS 10.5.5

解決

setrlimitというのはプロセスの制限を変更するシステムコール

honeyd.cの461行目あたり(honeyd_init関数の中)にエラーの箇所がある

	/* Raising file descriptor limits */
	rl.rlim_max = RLIM_INFINITY;
	rl.rlim_cur = RLIM_INFINITY;
	if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
		/* Linux does not seem to like this */
		if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
			err(1, "getrlimit: NOFILE");
		rl.rlim_cur = rl.rlim_max;
		if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
			err(1, "setrlimit: NOFILE");

honeydを初期化する段階でgetrlimitでRLIMIT_NOFILEの指定できそうな最大値を取得し,rlim_curにコピーしてその値でsetrlimitをもう一度行なうというコード.

どうやらsetrlimitで大きすぎる値を指定しているらしい.Mac固有の問題っぽいのでぐぐったらhttp://developer.apple.com/jp/qa/qa2001/qa1005.htmlを発見.

サンプルプログラムを走らせたら1万をちょっと越えたあたりでsetrlimitが-1を返すようになったので次のように変更したら動いた.

		rl.rlim_cur = rl.rlim_max > 10000 ? 10000 : rl.rlim_max

つまりhoneyd.cの対応する部分はこんなかんじ

	/* Raising file descriptor limits */
	rl.rlim_max = RLIM_INFINITY;
	rl.rlim_cur = RLIM_INFINITY;
	if (setrlimit(RLIMIT_NOFILE, &rl) == -1) {
		/* Linux does not seem to like this */
		if (getrlimit(RLIMIT_NOFILE, &rl) == -1)
			err(1, "getrlimit: NOFILE");
		rl.rlim_cur = rl.rlim_max > 10000 ? 10000 : rl.rlim_max
		if (setrlimit(RLIMIT_NOFILE, &rl) == -1)
			err(1, "setrlimit: NOFILE");

OSごとにシステムコールの返す値は違うから気をつけましょう,という話でした.

サンプルプログラム

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/time.h>
#include <sys/resource.h>
#include <sys/errno.h>


int main() {
    struct rlimit rl;
    rl.rlim_max = RLIM_INFINITY;
    rl.rlim_cur = RLIM_INFINITY;

    if (getrlimit(RLIMIT_NOFILE, &rl) == -1) {
        fprintf(stderr, "getrlimit failed\n errno %d", errno);
    } else {
        //        rl.rlim_cur = rl.rlim_max;
        rl.rlim_cur = 200;
        while (setrlimit(RLIMIT_NOFILE, &rl) != -1) {
            rl.rlim_cur += 10;
        }
        printf("%ld OK\n", (long)rl.rlim_cur);
    }
    return 0;
}

次は..

設定ファイルをhttp://d.hatena.ne.jp/udamino/20060530を参考にして作成して走らせたけどreplyがかえってこない.

とりあえず下のメッセージが出て起動してるように見える.

~/Desktop/honeyd-1.5c $ sudo /usr/local/bin/honeyd -d -f ./hoge -i en1 192.168.1.25 
Honeyd V1.5c Copyright (c) 2002-2007 Niels Provos
honeyd[23975]: started with -d -f ./hoge -i en1 192.168.1.25
Warning: Impossible SI range in Class fingerprint "IBM OS/400 V4R2M0"
Warning: Impossible SI range in Class fingerprint "Microsoft Windows NT 4.0 SP3"
honeyd[23975]: listening promiscuously on en1: (arp or ip proto 47 or (udp and src port 67 and dst port 68) or (ip and (host 192.168.1.25))) and not ether src 00:1e:c2:b0:25:cd
honeyd[23975]: Demoting process privileges to uid 4294967294, gid 4294967294

でもこのuidとgidはあやしいよなぁ...

 honeyd[23975]: Demoting process privileges to uid 4294967294, gid 4294967294

uidとgidのDemoting

honeyd_init関数の中でgetpwnam('nobody')を使ってnobodyユーザのuser_idとgroup_idを指定している.

~ $ id nobody
uid=4294967294(nobody) gid=4294967294(nobody) groups=4294967294(nobody)

こいつか.-uや-gオプションを指定してもnobodyユーザの権限が優先されるらしい.