View | Details | Raw Unified | Return to bug 153426
Collapse All | Expand All

(-)sbin/fsck_msdosfs/boot.c (-11 / +71 lines)
Lines 39-63 Link Here
39
#include "ext.h"
39
#include "ext.h"
40
#include "fsutil.h"
40
#include "fsutil.h"
41
41
42
#define	IOSIZE	65536
43
42
int
44
int
43
readboot(int dosfs, struct bootblock *boot)
45
readboot(int dosfs, struct bootblock *boot)
44
{
46
{
47
	u_char ioblock[IOSIZE];
48
	u_char iofsinfo[IOSIZE];
49
	u_char iobackup[IOSIZE];
45
	u_char block[DOSBOOTBLOCKSIZE];
50
	u_char block[DOSBOOTBLOCKSIZE];
46
	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
51
	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
47
	u_char backup[DOSBOOTBLOCKSIZE];
52
	u_char backup[DOSBOOTBLOCKSIZE];
53
	u_char *infop;
54
	size_t iosize;
55
	u_int secsize;
48
	int ret = FSOK;
56
	int ret = FSOK;
49
	int i;
57
	int i;
50
	
58
	
51
	if ((size_t)read(dosfs, block, sizeof block) != sizeof block) {
59
	/* Search for an i/o size that works. */
60
	for (iosize = IOSIZE; iosize >= DOSBOOTBLOCKSIZE; iosize >>= 1) {
61
		if (lseek(dosfs, (off_t)0, SEEK_SET) == 0 &&
62
		   read(dosfs, ioblock, iosize) == (ssize_t)iosize)
63
			break;
64
	}
65
	if (iosize < DOSBOOTBLOCKSIZE) {
52
		perr("could not read boot block");
66
		perr("could not read boot block");
53
		return FSFATAL;
67
		return FSFATAL;
54
	}
68
	}
69
	memcpy(block, ioblock, sizeof block);
55
70
56
	if (block[510] != 0x55 || block[511] != 0xaa) {
71
	/*
57
		pfatal("Invalid signature in boot block: %02x%02x",
72
	 * Preliminary decode to determine where the signature might be.
58
		    block[511], block[510]);
73
	 * It is supposed to be at the end of a 512-block, but we used to
74
	 * put it at the end of a sector.  Accept the latter so as to fix
75
	 * it someday.
76
	 */
77
	secsize = block[11] + (block[12] << 8);
78
	if (secsize < sizeof block || secsize > IOSIZE) {
79
		perror("Preposterous or unsupported sector size");
59
		return FSFATAL;
80
		return FSFATAL;
60
	}
81
	}
82
	if (block[510] != 0x55 || block[511] != 0xaa) {
83
		if (ioblock[secsize - 2] != 0x55 ||
84
		    ioblock[secsize - 1] != 0xaa) {
85
			pfatal("Invalid signature in boot block: %02x%02x",
86
			    block[511], block[510]);
87
			return FSFATAL;
88
		}
89
		pwarn(
90
	"Invalid primary signature in boot block -- using secondary\n");
91
	}
61
92
62
	memset(boot, 0, sizeof *boot);
93
	memset(boot, 0, sizeof *boot);
63
	boot->ValidFat = -1;
94
	boot->ValidFat = -1;
Lines 100-111 Link Here
100
		boot->bpbFSInfo = block[48] + (block[49] << 8);
131
		boot->bpbFSInfo = block[48] + (block[49] << 8);
101
		boot->bpbBackup = block[50] + (block[51] << 8);
132
		boot->bpbBackup = block[50] + (block[51] << 8);
102
133
134
		iosize = (secsize >= sizeof fsinfo) ?  secsize : sizeof fsinfo;
103
		if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec,
135
		if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec,
104
		    SEEK_SET) != boot->bpbFSInfo * boot->bpbBytesPerSec
136
		    SEEK_SET) != boot->bpbFSInfo * boot->bpbBytesPerSec
105
		    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
137
		    || read(dosfs, iofsinfo, iosize) != (ssize_t)iosize) {
106
			perr("could not read fsinfo block");
138
			perr("could not read fsinfo block");
107
			return FSFATAL;
139
			return FSFATAL;
108
		}
140
		}
141
		memcpy(fsinfo, iofsinfo, sizeof fsinfo);
109
		if (memcmp(fsinfo, "RRaA", 4)
142
		if (memcmp(fsinfo, "RRaA", 4)
110
		    || memcmp(fsinfo + 0x1e4, "rrAa", 4)
143
		    || memcmp(fsinfo + 0x1e4, "rrAa", 4)
111
		    || fsinfo[0x1fc]
144
		    || fsinfo[0x1fc]
Lines 116-121 Link Here
116
		    || fsinfo[0x3fd]
149
		    || fsinfo[0x3fd]
117
		    || fsinfo[0x3fe] != 0x55
150
		    || fsinfo[0x3fe] != 0x55
118
		    || fsinfo[0x3ff] != 0xaa) {
151
		    || fsinfo[0x3ff] != 0xaa) {
152
			infop = &iofsinfo[secsize - DOSBOOTBLOCKSIZE];
153
			if (memcmp(fsinfo, "RRaA", 4) == 0 &&
154
			    memcmp(infop + 0x1e4, "rrAa", 4) == 0 &&
155
			    infop[0x1fc] == 0 &&
156
			    infop[0x1fd] == 0 &&
157
			    infop[0x1fe] == 0x55 &&
158
			    infop[0x1ff] == 0xaa) {
159
				pwarn(
160
		    "Invalid signature in fsinfo block -- using secondary\n");
161
				/*
162
				 * Silently fix up the actual fsinfo data
163
				 * (just 2 32-bit words) since this data
164
				 * is advisory and the indentation is
165
				 * already too painful to ask about this.
166
				 */
167
				memcpy(fsinfo + 0x1e8, infop + 0x1e8, 8);
168
				goto over;
169
			}
119
			pwarn("Invalid signature in fsinfo block\n");
170
			pwarn("Invalid signature in fsinfo block\n");
120
			if (ask(0, "Fix")) {
171
			if (ask(0, "Fix")) {
121
				memcpy(fsinfo, "RRaA", 4);
172
				memcpy(fsinfo, "RRaA", 4);
Lines 126-140 Link Here
126
				fsinfo[0x3fc] = fsinfo[0x3fd] = 0;
177
				fsinfo[0x3fc] = fsinfo[0x3fd] = 0;
127
				fsinfo[0x3fe] = 0x55;
178
				fsinfo[0x3fe] = 0x55;
128
				fsinfo[0x3ff] = 0xaa;
179
				fsinfo[0x3ff] = 0xaa;
180
				memcpy(iofsinfo, fsinfo, sizeof fsinfo);
129
				if (lseek(dosfs, boot->bpbFSInfo *
181
				if (lseek(dosfs, boot->bpbFSInfo *
130
				    boot->bpbBytesPerSec, SEEK_SET)
182
				    boot->bpbBytesPerSec, SEEK_SET)
131
				    != boot->bpbFSInfo * boot->bpbBytesPerSec
183
				    != boot->bpbFSInfo * boot->bpbBytesPerSec
132
				    || write(dosfs, fsinfo, sizeof fsinfo)
184
				    || write(dosfs, iofsinfo, iosize)
133
				    != sizeof fsinfo) {
185
				    != (ssize_t)iosize) {
134
					perr("Unable to write bpbFSInfo");
186
					perr("Unable to write bpbFSInfo");
135
					return FSFATAL;
187
					return FSFATAL;
136
				}
188
				}
137
				ret = FSBOOTMOD;
189
				ret = FSBOOTMOD;
190
over: ;
138
			} else
191
			} else
139
				boot->bpbFSInfo = 0;
192
				boot->bpbFSInfo = 0;
140
		}
193
		}
Lines 150-159 Link Here
150
		if (lseek(dosfs, boot->bpbBackup * boot->bpbBytesPerSec,
203
		if (lseek(dosfs, boot->bpbBackup * boot->bpbBytesPerSec,
151
		    SEEK_SET)
204
		    SEEK_SET)
152
		    != boot->bpbBackup * boot->bpbBytesPerSec
205
		    != boot->bpbBackup * boot->bpbBytesPerSec
153
		    || read(dosfs, backup, sizeof backup) != sizeof  backup) {
206
		    || read(dosfs, iobackup, secsize) != (ssize_t)secsize) {
154
			perr("could not read backup bootblock");
207
			perr("could not read backup bootblock");
155
			return FSFATAL;
208
			return FSFATAL;
156
		}
209
		}
210
		memcpy(backup, iobackup, sizeof backup);
157
		backup[65] = block[65];				/* XXX */
211
		backup[65] = block[65];				/* XXX */
158
		if (memcmp(block + 11, backup + 11, 79)) {
212
		if (memcmp(block + 11, backup + 11, 79)) {
159
			/*
213
			/*
Lines 237-250 Link Here
237
int
291
int
238
writefsinfo(int dosfs, struct bootblock *boot)
292
writefsinfo(int dosfs, struct bootblock *boot)
239
{
293
{
294
	u_char iofsinfo[IOSIZE];
240
	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
295
	u_char fsinfo[2 * DOSBOOTBLOCKSIZE];
296
	size_t iosize;
297
	u_int secsize;
241
298
299
	secsize = boot->bpbBytesPerSec;
300
	iosize = (secsize >= sizeof fsinfo) ? secsize : sizeof fsinfo;
242
	if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET)
301
	if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET)
243
	    != boot->bpbFSInfo * boot->bpbBytesPerSec
302
	    != boot->bpbFSInfo * boot->bpbBytesPerSec
244
	    || read(dosfs, fsinfo, sizeof fsinfo) != sizeof fsinfo) {
303
	    || read(dosfs, iofsinfo, iosize) != (ssize_t)iosize) {
245
		perr("could not read fsinfo block");
304
		perr("could not read fsinfo block");
246
		return FSFATAL;
305
		return FSFATAL;
247
	}
306
	}
307
	memcpy(fsinfo, iofsinfo, sizeof fsinfo);
248
	fsinfo[0x1e8] = (u_char)boot->FSFree;
308
	fsinfo[0x1e8] = (u_char)boot->FSFree;
249
	fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8);
309
	fsinfo[0x1e9] = (u_char)(boot->FSFree >> 8);
250
	fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16);
310
	fsinfo[0x1ea] = (u_char)(boot->FSFree >> 16);
Lines 253-262 Link Here
253
	fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8);
313
	fsinfo[0x1ed] = (u_char)(boot->FSNext >> 8);
254
	fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16);
314
	fsinfo[0x1ee] = (u_char)(boot->FSNext >> 16);
255
	fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
315
	fsinfo[0x1ef] = (u_char)(boot->FSNext >> 24);
316
	memcpy(iofsinfo, fsinfo, sizeof fsinfo);
256
	if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET)
317
	if (lseek(dosfs, boot->bpbFSInfo * boot->bpbBytesPerSec, SEEK_SET)
257
	    != boot->bpbFSInfo * boot->bpbBytesPerSec
318
	    != boot->bpbFSInfo * boot->bpbBytesPerSec
258
	    || write(dosfs, fsinfo, sizeof fsinfo)
319
	    || write(dosfs, iofsinfo, iosize) != (ssize_t)iosize) {
259
	    != sizeof fsinfo) {
260
		perr("Unable to write bpbFSInfo");
320
		perr("Unable to write bpbFSInfo");
261
		return FSFATAL;
321
		return FSFATAL;
262
	}
322
	}

Return to bug 153426