Skip to content

Commit 017da6f

Browse files
Don Bradybehlendorf
authored andcommitted
Fix for recent zdb -h | -i crashes (seg fault)
Allocating SPA_MAXBLOCKSIZE on the stack is a bad idea (even with the old 128K size). Use malloc instead when allocating temporary block buffer memory. Signed-off-by: Don Brady <don.brady@intel.com> Signed-off-by: Brian Behlendorf <behlendorf1@llnl.gov> Closes #3522
1 parent 784652c commit 017da6f

File tree

2 files changed

+20
-7
lines changed

2 files changed

+20
-7
lines changed

cmd/zdb/zdb.c

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1070,7 +1070,7 @@ static void
10701070
dump_history(spa_t *spa)
10711071
{
10721072
nvlist_t **events = NULL;
1073-
char buf[SPA_MAXBLOCKSIZE];
1073+
char *buf;
10741074
uint64_t resid, len, off = 0;
10751075
uint_t num = 0;
10761076
int error;
@@ -1080,12 +1080,19 @@ dump_history(spa_t *spa)
10801080
char internalstr[MAXPATHLEN];
10811081
int i;
10821082

1083+
if ((buf = malloc(SPA_OLD_MAXBLOCKSIZE)) == NULL) {
1084+
(void) fprintf(stderr, "%s: unable to allocate I/O buffer\n",
1085+
__func__);
1086+
return;
1087+
}
1088+
10831089
do {
1084-
len = sizeof (buf);
1090+
len = SPA_OLD_MAXBLOCKSIZE;
10851091

10861092
if ((error = spa_history_get(spa, &off, &len, buf)) != 0) {
10871093
(void) fprintf(stderr, "Unable to read history: "
10881094
"error %d\n", error);
1095+
free(buf);
10891096
return;
10901097
}
10911098

@@ -1136,6 +1143,7 @@ dump_history(spa_t *spa)
11361143
dump_nvlist(events[i], 2);
11371144
}
11381145
}
1146+
free(buf);
11391147
}
11401148

11411149
/*ARGSUSED*/

cmd/zdb/zdb_il.c

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
124124
char *data, *dlimit;
125125
blkptr_t *bp = &lr->lr_blkptr;
126126
zbookmark_phys_t zb;
127-
char buf[SPA_MAXBLOCKSIZE];
127+
char *buf;
128128
int verbose = MAX(dump_opt['d'], dump_opt['i']);
129129
int error;
130130

@@ -135,6 +135,9 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
135135
if (txtype == TX_WRITE2 || verbose < 5)
136136
return;
137137

138+
if ((buf = malloc(SPA_MAXBLOCKSIZE)) == NULL)
139+
return;
140+
138141
if (lr->lr_common.lrc_reclen == sizeof (lr_write_t)) {
139142
(void) printf("%shas blkptr, %s\n", prefix,
140143
!BP_IS_HOLE(bp) &&
@@ -145,13 +148,13 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
145148
if (BP_IS_HOLE(bp)) {
146149
(void) printf("\t\t\tLSIZE 0x%llx\n",
147150
(u_longlong_t)BP_GET_LSIZE(bp));
148-
bzero(buf, sizeof (buf));
151+
bzero(buf, SPA_MAXBLOCKSIZE);
149152
(void) printf("%s<hole>\n", prefix);
150-
return;
153+
goto exit;
151154
}
152155
if (bp->blk_birth < zilog->zl_header->zh_claim_txg) {
153156
(void) printf("%s<block already committed>\n", prefix);
154-
return;
157+
goto exit;
155158
}
156159

157160
SET_BOOKMARK(&zb, dmu_objset_id(zilog->zl_os),
@@ -162,7 +165,7 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
162165
bp, buf, BP_GET_LSIZE(bp), NULL, NULL,
163166
ZIO_PRIORITY_SYNC_READ, ZIO_FLAG_CANFAIL, &zb));
164167
if (error)
165-
return;
168+
goto exit;
166169
data = buf;
167170
} else {
168171
data = (char *)(lr + 1);
@@ -180,6 +183,8 @@ zil_prt_rec_write(zilog_t *zilog, int txtype, lr_write_t *lr)
180183
data++;
181184
}
182185
(void) printf("\n");
186+
exit:
187+
free(buf);
183188
}
184189

185190
/* ARGSUSED */

0 commit comments

Comments
 (0)