梶本@NCNです。

FreeBSD 6.2-RELEASEにて、以下のような環境で表題のようなエラーが発生したのですが、
私のスキル不足のため、システムコールの中まで追いかけることができませんでした。

該当ソース(抜粋)

fd = open(fnbuf, O_WRONLY | O_CREAT, 0600);
if(fd < 0)
{
   return 0
}
off = lseek(fd, 0, SEEK_END);
sts = write(fd, body, len);
if(sts < 0)
{
   syslog(LOG_ERR, "off=%lld", off);
   syslog(LOG_ERR, "len=%d", len);
   syslog(LOG_ERR, "fd=%d", fd);
   syslog(LOG_ERR, "sts = %d", sts);
   syslog(LOG_ERR, "errno = %d:%s", errno, strerror(errno));
   syslog(LOG_ERR, "getuid = %d", getuid());
   syslog(LOG_ERR, "geteuid = %d", geteuid());
}

要はファイルの最後にデータを追記しようとしただけです。

コンパイル後のプログラムは
ownerのuid/gid = 10/10
パーミッション=4755(rws r-x r-x)
としています。

上記プログラムを実行すると、/var/log/messagesに以下のように記録されました。
Jan 20 01:17:25 i2c: off=175883021
Jan 20 01:17:25 i2c: len=12299
Jan 20 01:17:25 i2c: fd=4
Jan 20 01:17:25 i2c: sts = -1
Jan 20 01:17:25 i2c: errno = 13:Permission denied
Jan 20 01:17:25 i2c: getuid = 65534
Jan 20 01:17:25 i2c: geteuid = 10

man 2 writeを参照したところ、ERRORSの項目には[EACCES](errno=13)は記載されていません。

ちなみに、ファイルを削除してあたらしくファイルを作るとエラーにならず、正常に動作します。
(ファイルサイズに依存している?)
また、uid=80(webユーザ)から同じプログラムを起動すると、正常に動作しました。

そこで、詳しい方がいれば教えていただきたいのですが……

uid=65534のユーザーが、setuid-bitを立てたプログラムを実行したときに、
システムコールwriteをコールしたときにわざとエラー13[EACCES]を返すような処理があるのでしょうか。
また、openやlseekではエラーにならないのはなぜでしょうか。

なお、そのような処理がある場合、同様な制限がされているuidはほかにあるのでしょうか。

よろしくお願いします。


メールによる返信