[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#698174: perl: double-free in load subroutine for Digest::SHA



On Tue, Jan 22, 2013 at 11:59:17PM +0000, Dominic Hargreaves wrote:

> Having this fix only
> in one of the two places Digest::SHA appears in wheezy is probably
> a Bad Thing, so maybe we should upload a fix for wheezy/perl after all.

Yes, I think we should (FWIW). Along with that, I suppose we need to update
 Breaks: libdigest-sha-perl (<< 5.61)
in the perl package to read
 Breaks: libdigest-sha-perl (<< 5.71-2)
so that any buggy versions of the libdigest-sha-perl package
can't override the fixed version in the perl package.

While at it, I think the fix for #698320 (signed/unsigned wraparound
on 32-bit platforms) could/should go in too.  Release team, would that
be OK with you?

(Upstream patch attached.)
-- 
Niko Tyni   ntyni@debian.org
>From 94e529cc4d56863d7272c254a29eda2b002a4335 Mon Sep 17 00:00:00 2001
From: Andy Dougherty <doughera@lafayette.edu>
Date: Wed, 16 Jan 2013 12:30:43 -0500
Subject: [PATCH] Avoid wraparound when casting unsigned size_t to signed ssize_t.

Practically, this only affects a perl compiled with 64-bit IVs on a 32-bit
system.  In that instance a value of count >= 2**31 would turn negative
when cast to (ssize_t).
---
 perlio.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/perlio.c b/perlio.c
index 3e6e0a6..5de5e65 100644
--- a/perlio.c
+++ b/perlio.c
@@ -2155,7 +2155,7 @@ PerlIOBase_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
 	    SSize_t avail = PerlIO_get_cnt(f);
 	    SSize_t take = 0;
 	    if (avail > 0)
-		take = ((SSize_t)count < avail) ? (SSize_t)count : avail;
+		take = (((SSize_t) count >= 0) && ((SSize_t)count < avail)) ? (SSize_t)count : avail;
 	    if (take > 0) {
 		STDCHAR *ptr = PerlIO_get_ptr(f);
 		Copy(ptr, buf, take, STDCHAR);
@@ -4086,7 +4086,7 @@ PerlIOBuf_unread(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
 	     */
 	    b->posn -= b->bufsiz;
 	}
-	if (avail > (SSize_t) count) {
+	if ((SSize_t) count >= 0 && avail > (SSize_t) count) {
 	    /*
 	     * If we have space for more than count, just move count
 	     */
@@ -4136,7 +4136,7 @@ PerlIOBuf_write(pTHX_ PerlIO *f, const void *vbuf, Size_t count)
     }
     while (count > 0) {
 	SSize_t avail = b->bufsiz - (b->ptr - b->buf);
-	if ((SSize_t) count < avail)
+	if ((SSize_t) count >= 0 && (SSize_t) count < avail)
 	    avail = count;
 	if (flushptr > buf && flushptr <= buf + avail)
 	    avail = flushptr - buf;
@@ -4411,7 +4411,7 @@ PerlIOPending_read(pTHX_ PerlIO *f, void *vbuf, Size_t count)
 {
     SSize_t avail = PerlIO_get_cnt(f);
     SSize_t got = 0;
-    if ((SSize_t)count < avail)
+    if ((SSize_t) count >= 0 && (SSize_t)count < avail)
 	avail = count;
     if (avail > 0)
 	got = PerlIOBuf_read(aTHX_ f, vbuf, avail);
-- 
1.7.4.1


Reply to: