Hi, I found a bug in extlinux/main.c. Writing a bootloader on a file mounted via /dev/mapper in Lunix it crashed on me with a segment fault. The bug is here: if (!ioctl(devfd, HDIO_GETGEO, &geo)) { Since we are already called with geo as a pointer the & is wrong as the pointer itself will be overwritten. This works: int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo) { struct floppy_struct fd_str; struct loop_info li; struct loop_info64 li64; const struct geometry_table *gp; int rv = 0; memset(geo, 0, sizeof *geo); if (!ioctl(devfd, HDIO_GETGEO, geo)) { goto ok; If someone can incorporate this in a future version I would be happy. V4.03 and V4.04 have the same issue, I did not look at another version. Jur van der Burg.
Geert Stappers
2011-Jul-16 16:12 UTC
[syslinux] crash in extlinux/main (already fixed in "git")
On Sat, Jul 16, 2011 at 03:10:35PM +0200, Jur van der Burg wrote:> Hi, > > I found a bug in extlinux/main.c. Writing a bootloader on a file mounted via > /dev/mapper in Lunix it crashed on me with a segment fault. > > The bug is here: > > if (!ioctl(devfd, HDIO_GETGEO, &geo)) { > > Since we are already called with geo as a pointer the & is wrong as the > pointer itself will be overwritten.Thanks for reporting> This works: ><snip> fix </snip>> > If someone can incorporate this in a future version I would be happy.It is already in master branch of the source code management system 'git' Cheers Geert Stappers -- | commit 73cd9bf26066cad0d4a483e31e1d89802a7ca1f9 | Author: Gene Cumm <gene.cumm at gmail.com> | Date: Wed May 11 12:03:30 2011 -0400 | | extlinux/main.c: Fix geometry handling | | 1) ioctl HDIO_GETGEO expects a pointer to a struct hd_geometry | 2) struct stat's st_dev is the parent file used; st_rdev is what we want | | Reported-by: Michael Tokarev <mjt at tls.msk.ru> | Tested-By: Michael Tokarev <mjt at tls.msk.ru> | Signed-off-by: Gene Cumm <gene.cumm at gmail.com> | | diff --git a/extlinux/main.c b/extlinux/main.c | index e5212a9..6aa6202 100755 | --- a/extlinux/main.c | +++ b/extlinux/main.c | @@ -112,7 +112,7 @@ static int sysfs_get_offset(int devfd, unsigned long *start) | | if ((size_t)snprintf(sysfs_name, sizeof sysfs_name, | "/sys/dev/block/%u:%u/start", | - major(st.st_dev), minor(st.st_dev)) | + major(st.st_rdev), minor(st.st_rdev)) | >= sizeof sysfs_name) | return -1; | | @@ -153,7 +153,7 @@ int get_geometry(int devfd, uint64_t totalbytes, struct hd_geometry *geo) | | memset(geo, 0, sizeof *geo); | | - if (!ioctl(devfd, HDIO_GETGEO, &geo)) { | + if (!ioctl(devfd, HDIO_GETGEO, geo)) { | goto ok; | } else if (!ioctl(devfd, FDGETPRM, &fd_str)) { | geo->heads = fd_str.head;