Date: Sun, 12 Aug 2007 21:00:10 GMT From: Maxim Konovalov <maxim@macomnet.ru> To: freebsd-bugs@FreeBSD.org Subject: Re: bin/115430: rpc.statd core dumps if unable to mmap() /var/db/statd.status file Message-ID: <200708122100.l7CL0AxR090118@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
The following reply was made to PR bin/115430; it has been noted by GNATS. From: Maxim Konovalov <maxim@macomnet.ru> To: "Timur I. Bakeyev" <timur@freebsd.org> Cc: bug-followup@freebsd.org, truckman@freebsd.org Subject: Re: bin/115430: rpc.statd core dumps if unable to mmap() /var/db/statd.status file Date: Mon, 13 Aug 2007 00:23:23 +0400 (MSD) [...] > >Release: FreeBSD 6.2-STABLE i386 > >Organization: > >Environment: > > >Description: > > Somehow with my recent enough build rpc.statd is unable to mmap() "/var/db/statd.status" file and core dumps. Possibly, the failure of mmap() is fixed in latest STABLE, but this problem revealed a race condition in the rpc.statd. Here is the stack trace and piece of offending code: > > timur# gdb `which rpc.statd` rpc.statd.0.1092.core > GNU gdb 6.1.1 [FreeBSD] > Copyright 2004 Free Software Foundation, Inc. > GDB is free software, covered by the GNU General Public License, and you are > welcome to change it and/or distribute copies of it under certain conditions. > Type "show copying" to see the conditions. > There is absolutely no warranty for GDB. Type "show warranty" for details. > This GDB was configured as "i386-marcel-freebsd"... > Core was generated by `rpc.statd'. > Program terminated with signal 11, Segmentation fault. > Reading symbols from /usr/lib/librpcsvc.so.3...done. > Loaded symbols for /usr/lib/librpcsvc.so.3 > Reading symbols from /lib/libc.so.6...done. > Loaded symbols for /lib/libc.so.6 > Reading symbols from /libexec/ld-elf.so.1...done. > Loaded symbols for /libexec/ld-elf.so.1 > #0 0x08049531 in init_file (filename=0x804a880 "/var/db/statd.status") at /usr/src/usr.sbin/rpc.statd/file.c:170 > (gdb) l 150 > 145 > 146 /* try to open existing file - if not present, create one */ > 147 status_fd = open(filename, O_RDWR); > 148 if ((status_fd < 0) && (errno == ENOENT)) > 149 { > 150 status_fd = open(filename, O_RDWR | O_CREAT, 0644); > 151 new_file = TRUE; > 152 } > 153 if (status_fd < 0) > 154 errx(1, "unable to open status file %s", filename); > 155 > 156 /* File now open. mmap() it, with a generous size to allow for */ > 157 /* later growth, where we will extend the file but not re-map it. */ > 158 status_info = (FileLayout *) > 159 mmap(NULL, 0x10000000, PROT_READ | PROT_WRITE, MAP_SHARED, status_fd, 0); > 160 > 161 if (status_info == (FileLayout *) MAP_FAILED) > 162 warn("unable to mmap() status file"); > 163 > 164 status_file_len = lseek(status_fd, 0L, SEEK_END); > 165 > 166 /* If the file was not newly created, validate the contents, and if */ > 167 /* defective, re-create from scratch. */ > 168 if (!new_file) > 169 { > 170 if ((status_file_len < HEADER_LEN) || (status_file_len > 171 < (HEADER_LEN + sizeof(HostInfo) * status_info->noOfHosts)) ) > 172 { > 173 warnx("status file is corrupt"); > 174 new_file = TRUE; > > On line 170 we have a guardian condition: > > 170 if ((status_file_len < HEADER_LEN) || > > But it doesn't work after second invokation of rpc.statd, when status file was already created. > > statd.h:#define HEADER_LEN (sizeof(FileLayout) - sizeof(HostInfo)) > > (gdb) p status_file_len > $1 = 256 > (gdb) p sizeof(FileLayout) - sizeof(HostInfo) > $2 = 256 > > As it's seen on line 161, in case of mmap() failure status_info variable takes special value MAP_FAILED: > > mman.h:#define MAP_FAILED ((void *)-1) > > And a warning issued. Possibly, such a failure shouldn't be a fatal event, we just loose some speed in processing. But the fact of a failure isn't taken into account on line 171, when we try to dereference status_info unconditionally: > > sizeof(HostInfo) * status_info->noOfHosts > > which leads to the core dump. I don't think, this bug is > exploitable, but definetly, it have to be fixed one way or another. > > >How-To-Repeat: > > I wish I know what's wrong with mmap() functino in my build. If it > is reproduced then rpc.statd will crash for sure. But the bug is > visible on a first glance. > Could it be fixed by the latest truckman@ work? -- Maxim Konovalov
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200708122100.l7CL0AxR090118>