File: 32-bug-632585-use-int32_t-instead-off_t-for-file-size.patch

package info (click to toggle)
bsdiff 4.3-21
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 192 kB
  • sloc: ansic: 1,473; makefile: 43
file content (164 lines) | stat: -rw-r--r-- 4,871 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
From 7be73826410a8c78e4eca30ae1e4b590cadb5a2b Mon Sep 17 00:00:00 2001
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
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 <sebastian@breakpoint.cc>
---
 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 <unistd.h>
 #include <sys/mman.h>
 
+#include <limits.h>
+
+#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;k<start+len;k+=j) {
@@ -102,10 +115,10 @@ static void split(off_t *I,off_t *V,off_t start,off_t len,off_t h)
 	if(start+len>kk) 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<oldsize;i++) buckets[old[i]]++;
@@ -140,9 +153,9 @@ static void qsufsort(off_t *I,off_t *V,u_char *old,off_t oldsize)
 	for(i=0;i<oldsize+1;i++) I[V[i]]=i;
 }
 
-static off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
+static t_off matchlen(u_char *old,t_off oldsize,u_char *new,t_off newsize)
 {
-	off_t i;
+	t_off i;
 
 	for(i=0;(i<oldsize)&&(i<newsize);i++)
 		if(old[i]!=new[i]) break;
@@ -150,10 +163,10 @@ static off_t matchlen(u_char *old,off_t oldsize,u_char *new,off_t newsize)
 	return i;
 }
 
-static off_t search(off_t *I,u_char *old,off_t oldsize,
-		u_char *new,off_t newsize,off_t st,off_t en,off_t *pos)
+static t_off search(t_off *I,u_char *old,t_off oldsize,
+		u_char *new,t_off newsize,t_off st,t_off en,t_off *pos)
 {
-	off_t x,y;
+	t_off x,y;
 
 	if(en-st<2) {
 		x=matchlen(old+I[st],oldsize-I[st],new,newsize);
@@ -176,9 +189,9 @@ static off_t search(off_t *I,u_char *old,off_t oldsize,
 	};
 }
 
-static void offtout(off_t x,u_char *buf)
+static void offtout(t_off x,u_char *buf)
 {
-	off_t y;
+	t_off y;
 
 	if(x<0) y=-x; else y=x;
 
@@ -199,14 +212,14 @@ int main(int argc,char *argv[])
 	int fd;
 	u_char *old,*new;
 	off_t oldsize,newsize;
-	off_t *I,*V;
-	off_t scan,pos,len;
-	off_t lastscan,lastpos,lastoffset;
-	off_t oldscore,scsc;
-	off_t s,Sf,lenf,Sb,lenb;
-	off_t overlap,Ss,lens;
-	off_t i;
-	off_t dblen,eblen;
+	t_off *I,*V;
+	t_off scan,pos,len;
+	t_off lastscan,lastpos,lastoffset;
+	t_off oldscore,scsc;
+	t_off s,Sf,lenf,Sb,lenb;
+	t_off overlap,Ss,lens;
+	t_off i;
+	t_off dblen,eblen;
 	u_char *db,*eb;
 	u_char buf[8];
 	u_char header[32];
@@ -223,14 +236,16 @@ int main(int argc,char *argv[])
 	oldsize = lseek(fd, 0, SEEK_END);
 	if (oldsize < 0)
 		err(1, "seek %s", argv[1]);
+	if (oldsize > 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