From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from [140.186.70.92] (port=38309 helo=eggs.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1OBZSn-0008Pk-AZ for qemu-devel@nongnu.org; Mon, 10 May 2010 16:20:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.69) (envelope-from ) id 1OBZSi-0000Qv-Dp for qemu-devel@nongnu.org; Mon, 10 May 2010 16:20:26 -0400 Received: from verein.lst.de ([213.95.11.210]:45515) by eggs.gnu.org with esmtp (Exim 4.69) (envelope-from ) id 1OBZSi-0000Qd-3H for qemu-devel@nongnu.org; Mon, 10 May 2010 16:20:24 -0400 Date: Mon, 10 May 2010 22:20:22 +0200 From: Christoph Hellwig Subject: Re: [Qemu-devel] [PATCH 2/3] dmg: use pread Message-ID: <20100510202022.GA26186@lst.de> References: <20100507145519.GA14157@lst.de> <20100507145603.GB14245@lst.de> <4BE7DAEC.4090405@redhat.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <4BE7DAEC.4090405@redhat.com> List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: Kevin Wolf Cc: qemu-devel@nongnu.org On Mon, May 10, 2010 at 12:07:40PM +0200, Kevin Wolf wrote: > > > > - info_begin=read_off(s->fd); > > - if(info_begin==0) > > - goto fail; > > - if(lseek(s->fd,info_begin,SEEK_SET)<0) > > - goto fail; > > We seek to info_begin. > > > - if(read_uint32(s->fd)!=0x100) > > - goto fail; > > Now we are at info_begin + 4 > > > - if((count = read_uint32(s->fd))==0) > > - goto fail; > > info_begin + 8 > > > - info_end = info_begin+count; > > - if(lseek(s->fd,0xf8,SEEK_CUR)<0) > > info_begin + 0x100 > > > + info_begin = read_off(s->fd, offset); > > + if (info_begin == 0) { > > goto fail; > > + } > > + > > + if (read_uint32(s->fd, info_begin) != 0x100) { > > + goto fail; > > + } > > + > > + count = read_uint32(s->fd, info_begin + 4); > > + if (count == 0) { > > + goto fail; > > + } > > + info_end = info_begin + count; > > + > > + offset = info_begin + 0xfc; > > So, wrong offset here? Yeah, should be 0x100. That's what you get for quickly doing hex calculation in your head. > > + if (type == 0x6d697368 && count >= 244) { > > int new_size, chunk_count; > > - if(lseek(s->fd,200,SEEK_CUR)<0) > > - goto fail; > > + > > + offset += 4; > > Isn't this needed in the else case, too? I don't think so. For that case we previously did a lseek(s->fd,count-4,SEEK_CUR) to undo the 4 byte advance done by the read. > > - s->sectors[i] = last_out_offset+read_off(s->fd); > > - s->sectorcounts[i] = read_off(s->fd); > > - s->offsets[i] = last_in_offset+read_off(s->fd); > > - s->lengths[i] = read_off(s->fd); > > + read_uint32(s->fd, offset); > > This read is useless. offset += 4 alone should be enough. Thanks, fixed. > > /* we need to buffer, because only the chunk as whole can be > > * inflated. */ > > i=0; > > do { > > - ret = read(s->fd, s->compressed_chunk+i, s->lengths[chunk]-i); > > + ret = pread(s->fd, s->compressed_chunk+i, s->lengths[chunk]-i, > > + s->offsets[chunk]); > > This is in a loop, whereas the lseek was outside the loop. From the > second iteration on you'll repeat the first read instead of advancing. You're right. The EINTR check confused me an I took this for just retrying reads on EINTR. Now this code i quite nasty for error returns except EINTR because we'll subtract one from the i loop iteration, yikes. I'll just reuse the i variable to keep the same kind of bug for both sides of the equation. God, do I hate this code..