Skip to content

Commit a59ee88

Browse files
committed
Fix Coverity warning about contrib/pgcrypto's mdc_finish().
Coverity points out that mdc_finish returns a pointer to a local buffer (which of course is gone as soon as the function returns), leaving open a risk of misbehaviors possibly as bad as a stack overwrite. In reality, the only possible call site is in process_data_packets() which does not examine the returned pointer at all. So there's no live bug, but nonetheless the code is confusing and risky. Refactor to avoid the issue by letting process_data_packets() call mdc_finish() directly instead of going through the pullf_read() API. Although this is only cosmetic, it seems good to back-patch so that the logic in pgp-decrypt.c stays in sync across all branches. Marko Kreen
1 parent bd4e2fd commit a59ee88

File tree

1 file changed

+19
-30
lines changed

1 file changed

+19
-30
lines changed

contrib/pgcrypto/pgp-decrypt.c

+19-30
Original file line numberDiff line numberDiff line change
@@ -351,37 +351,33 @@ mdc_free(void *priv)
351351
}
352352

353353
static int
354-
mdc_finish(PGP_Context *ctx, PullFilter *src,
355-
int len, uint8 **data_p)
354+
mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
356355
{
357356
int res;
358357
uint8 hash[20];
359-
uint8 tmpbuf[22];
358+
uint8 tmpbuf[20];
359+
uint8 *data;
360360

361-
if (len + 1 > sizeof(tmpbuf))
361+
/* should not happen */
362+
if (ctx->use_mdcbuf_filter)
362363
return PXE_BUG;
363364

365+
/* It's SHA1 */
366+
if (len != 20)
367+
return PXE_PGP_CORRUPT_DATA;
368+
369+
/* mdc_read should not call md_update */
370+
ctx->in_mdc_pkt = 1;
371+
364372
/* read data */
365-
res = pullf_read_max(src, len + 1, data_p, tmpbuf);
373+
res = pullf_read_max(src, len, &data, tmpbuf);
366374
if (res < 0)
367375
return res;
368376
if (res == 0)
369377
{
370-
if (ctx->mdc_checked == 0)
371-
{
372-
px_debug("no mdc");
373-
return PXE_PGP_CORRUPT_DATA;
374-
}
375-
return 0;
376-
}
377-
378-
/* safety check */
379-
if (ctx->in_mdc_pkt > 1)
380-
{
381-
px_debug("mdc_finish: several times here?");
378+
px_debug("no mdc");
382379
return PXE_PGP_CORRUPT_DATA;
383380
}
384-
ctx->in_mdc_pkt++;
385381

386382
/* is the packet sane? */
387383
if (res != 20)
@@ -394,7 +390,7 @@ mdc_finish(PGP_Context *ctx, PullFilter *src,
394390
* ok, we got the hash, now check
395391
*/
396392
px_md_finish(ctx->mdc_ctx, hash);
397-
res = memcmp(hash, *data_p, 20);
393+
res = memcmp(hash, data, 20);
398394
px_memset(hash, 0, 20);
399395
px_memset(tmpbuf, 0, sizeof(tmpbuf));
400396
if (res != 0)
@@ -403,7 +399,7 @@ mdc_finish(PGP_Context *ctx, PullFilter *src,
403399
return PXE_PGP_CORRUPT_DATA;
404400
}
405401
ctx->mdc_checked = 1;
406-
return len;
402+
return 0;
407403
}
408404

409405
static int
@@ -414,12 +410,9 @@ mdc_read(void *priv, PullFilter *src, int len,
414410
PGP_Context *ctx = priv;
415411

416412
/* skip this filter? */
417-
if (ctx->use_mdcbuf_filter)
413+
if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
418414
return pullf_read(src, len, data_p);
419415

420-
if (ctx->in_mdc_pkt)
421-
return mdc_finish(ctx, src, len, data_p);
422-
423416
res = pullf_read(src, len, data_p);
424417
if (res < 0)
425418
return res;
@@ -878,7 +871,6 @@ process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
878871
int got_data = 0;
879872
int got_mdc = 0;
880873
PullFilter *pkt = NULL;
881-
uint8 *tmp;
882874

883875
while (1)
884876
{
@@ -937,11 +929,8 @@ process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
937929
break;
938930
}
939931

940-
/* notify mdc_filter */
941-
ctx->in_mdc_pkt = 1;
942-
943-
res = pullf_read(pkt, 8192, &tmp);
944-
if (res > 0)
932+
res = mdc_finish(ctx, pkt, len);
933+
if (res >= 0)
945934
got_mdc = 1;
946935
break;
947936
default:

0 commit comments

Comments
 (0)