From 7be73826410a8c78e4eca30ae1e4b590cadb5a2b Mon Sep 17 00:00:00 2001 From: Sebastian Andrzej Siewior Date: Mon, 31 Oct 2016 21:08:27 +0100 Subject: [PATCH 3/3] use int32_t instead off_t for file size Bug: https://bugs.debian.org/632585 Using off_t (64bit) is kinda waste. With last change we only need 16x the size of the old file. So for a 2GiB - 1 file we would allocate almost 32GiB (the content of the old file would be loaded on demand from disk). This is a lot. Since the file size is less than 2GiB we leave the upper 4 bytes unused. With this change the max file size is limitted to 2GiB - 1 and we require 8x the size of the oldfile which makes almost 16GiB. When we assume a virtual address space of 3GiB on a 32bit then the max oldsize increased from about ~180MiB to ~341MiB. _If_ some sees this as a regression because files >2GiB can not be used anymore please provide another binary with -DUSE_OFF_T. The binary has less than 20KiB. Signed-off-by: Sebastian Andrzej Siewior --- bsdiff.c | 62 ++++++++++++++++++++++++++++++++++++++++---------------------- 1 file changed, 40 insertions(+), 22 deletions(-) diff --git a/bsdiff.c b/bsdiff.c index f975e3722cba..997c87b01f56 100644 --- a/bsdiff.c +++ b/bsdiff.c @@ -39,11 +39,24 @@ __FBSDID("$FreeBSD: src/usr.bin/bsdiff/bsdiff/bsdiff.c,v 1.1 2005/08/06 01:59:05 #include #include +#include + +#ifdef USE_OFF_T + +#define t_off off_t +#define t_off_max LLONG_MAX + +#else + +#define t_off int32_t +#define t_off_max INT_MAX +#endif + #define MIN(x,y) (((x)<(y)) ? (x) : (y)) -static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h) +static void split(t_off *I,t_off *V,t_off start,t_off len,t_off h) { - off_t i,j,k,x,tmp,jj,kk; + t_off i,j,k,x,tmp,jj,kk; if(len<16) { for(k=start;kkk) split(I,V,kk,start+len-kk,h); } -static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize) +static void qsufsort(t_off *I,t_off *V,u_char *old,t_off oldsize) { - off_t buckets[256]; - off_t i,h,len; + t_off buckets[256]; + t_off i,h,len; for(i=0;i<256;i++) buckets[i]=0; for(i=0;i t_off_max) + err(1, "file too large %s", argv[1]); old = mmap(NULL, oldsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); if (old == MAP_FAILED) err(1, "mmap() %s", argv[1]); close(fd); - if(((I=malloc((oldsize+1)*sizeof(off_t)))==NULL) || - ((V=malloc((oldsize+1)*sizeof(off_t)))==NULL)) err(1,NULL); + if(((I=malloc((oldsize+1)*sizeof(t_off)))==NULL) || + ((V=malloc((oldsize+1)*sizeof(t_off)))==NULL)) err(1,NULL); qsufsort(I,V,old,oldsize); @@ -244,6 +259,9 @@ int main(int argc,char *argv[]) newsize = lseek(fd, 0, SEEK_END); if (newsize == -1) err(1, "lseek %s", argv[2]); + if (newsize > t_off_max) + err(1, "file too large %s", argv[2]); + new = mmap(NULL, newsize, PROT_READ, MAP_SHARED | MAP_POPULATE, fd, 0); if (new == MAP_FAILED) err(1, "mmap %s", argv[2]); -- 2.9.3