From 1ebd2a5620c93ef4698485d392c19ded675412d2 Mon Sep 17 00:00:00 2001 From: Martin Pitt Date: Tue, 5 Oct 2010 17:56:19 +0200 Subject: [PATCH] cdrom_id: Don't read beyond "last track" in TOC Read the first and last track from the TOC header, and do not go beyond that stated number of tracks when reading the TOC. Otherwise we interpret random data which leads to bogus tracks. (Reported on an IronKey, which reported 1 data track, and 4 audio tracks which weren't actually present.) --- extras/cdrom_id/cdrom_id.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/extras/cdrom_id/cdrom_id.c b/extras/cdrom_id/cdrom_id.c index e7a3e40a..1b43fe43 100644 --- a/extras/cdrom_id/cdrom_id.c +++ b/extras/cdrom_id/cdrom_id.c @@ -712,7 +712,7 @@ static int cd_media_toc(struct udev *udev, int fd) struct scsi_cmd sc; unsigned char header[12]; unsigned char toc[2048]; - unsigned int len, i; + unsigned int len, i, num_tracks; unsigned char *p; int err; @@ -728,11 +728,13 @@ static int cd_media_toc(struct udev *udev, int fd) } len = (header[0] << 8 | header[1]) + 2; - info(udev, "READ TOC: len: %d\n", len); + info(udev, "READ TOC: len: %d, start track: %d, end track: %d\n", len, header[2], header[3]); if (len > sizeof(toc)) return -1; if (len < 2) return -1; + /* 2: first track, 3: last track */ + num_tracks = header[3] - header[2] + 1; /* empty media has no tracks */ if (len < 8) @@ -750,7 +752,10 @@ static int cd_media_toc(struct udev *udev, int fd) return -1; } - for (p = toc+4, i = 4; i < len-8; i += 8, p += 8) { + /* Take care to not iterate beyond the last valid track as specified in + * the TOC, but also avoid going beyond the TOC length, just in case + * the last track number is invalidly large */ + for (p = toc+4, i = 4; i < len-8 && num_tracks > 0; i += 8, p += 8, --num_tracks) { unsigned int block; unsigned int is_data_track; -- 2.39.5