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

Bug#781653: unblock: libdbd-firebird-perl/1.18-2



Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: unblock

Please unblock package libdbd-firebird-perl

libdbd-firebird-perl (1.18-2) unstable; urgency=high

  * High urgency for security fixes

  [ Salvatore Bonaccorso ]
  * Update Vcs-Browser URL to cgit web frontend

  [ Damyan Ivanov ]
  * Add patch from Stefan Roas fixing potential buffer overflow in certain
    error conditions (CVE-2015-2788)
    (Closes: #780925)
  * add patch from upstream Git replacing all sprintf usage with snprintf

 -- Damyan Ivanov <dmn@debian.org>  Wed, 01 Apr 2015 08:43:03 +0000

I have reviewed the first patch, and authored the second one upstream and am 
confident they don't break anything.

Full source diff attached.

unblock libdbd-firebird-perl/1.18-2

TIA,
    dam
diff -Nru libdbd-firebird-perl-1.18/debian/changelog libdbd-firebird-perl-1.18/debian/changelog
--- libdbd-firebird-perl-1.18/debian/changelog	2014-04-03 08:26:49.000000000 +0300
+++ libdbd-firebird-perl-1.18/debian/changelog	2015-04-01 11:46:26.000000000 +0300
@@ -1,3 +1,18 @@
+libdbd-firebird-perl (1.18-2) unstable; urgency=high
+
+  * High urgency for security fixes
+
+  [ Salvatore Bonaccorso ]
+  * Update Vcs-Browser URL to cgit web frontend
+
+  [ Damyan Ivanov ]
+  * Add patch from Stefan Roas fixing potential buffer overflow in certain
+    error conditions (CVE-2015-2788)
+    (Closes: #780925)
+  * add patch from upstream Git replacing all sprintf usage with snprintf
+
+ -- Damyan Ivanov <dmn@debian.org>  Wed, 01 Apr 2015 08:43:03 +0000
+
 libdbd-firebird-perl (1.18-1) unstable; urgency=medium
 
   [ gregor herrmann ]
diff -Nru libdbd-firebird-perl-1.18/debian/control libdbd-firebird-perl-1.18/debian/control
--- libdbd-firebird-perl-1.18/debian/control	2014-03-04 12:36:13.000000000 +0200
+++ libdbd-firebird-perl-1.18/debian/control	2015-04-01 11:41:53.000000000 +0300
@@ -12,7 +12,7 @@
                libtest-exception-perl (>= 0.31),
                perl
 Standards-Version: 3.9.5
-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-perl/packages/libdbd-firebird-perl.git
+Vcs-Browser: https://anonscm.debian.org/cgit/pkg-perl/packages/libdbd-firebird-perl.git
 Vcs-Git: git://anonscm.debian.org/pkg-perl/packages/libdbd-firebird-perl.git
 Homepage: https://metacpan.org/release/DBD-Firebird
 
diff -Nru libdbd-firebird-perl-1.18/debian/patches/dbdimp-780925-buf-overflow.patch libdbd-firebird-perl-1.18/debian/patches/dbdimp-780925-buf-overflow.patch
--- libdbd-firebird-perl-1.18/debian/patches/dbdimp-780925-buf-overflow.patch	1970-01-01 02:00:00.000000000 +0200
+++ libdbd-firebird-perl-1.18/debian/patches/dbdimp-780925-buf-overflow.patch	2015-04-01 11:41:53.000000000 +0300
@@ -0,0 +1,72 @@
+Bug-Debian: https://bugs.debian.org/780925
+Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/libdbd-firebird-perl/+bug/1431867
+Acked-By: Damyan Ivanov <dmn@debian.org>
+From: Stefan Roas <stefan.roas@fau.de>
+Subject: [Dbd-firebird-devel] Buffer Overflow in dbdimp.c
+To: dbd-firebird-devel@lists.alioth.debian.org
+Date: Fri, 13 Mar 2015 17:36:31 +0100
+
+Hi there,
+
+I found a buffer overflow in dbdimp.c. Error messages in dbdimp.c use
+sprintf to a fix-sized buffer that (quite likely in two cases) might be
+too small to hold the final result.
+
+Attached you find a patch that solves the problem by increasing the size
+of the buffer to a value that should be large enough for every
+conceivable input given the conversion specification and additionally
+use snprintf() instead of sprintf(). As snprintf() is already used
+somewhere else in dbdimp.c I figure there are no portability issues
+involved.
+
+I did not check the other uses of sprintf, although it might be
+worthwhile to do so as a quick check found other locations where a
+fix-sized buffer is involved.
+
+Best regards,
+  Stefan
+
+--- a/dbdimp.c
++++ b/dbdimp.c
+@@ -21,6 +21,8 @@
+ 
+ DBISTATE_DECLARE;
+ 
++#define ERRBUFSIZE  255
++
+ #define IB_SQLtimeformat(xxh, format, sv)                             \
+ do {                                                                  \
+     STRLEN len;                                                       \
+@@ -2237,8 +2239,8 @@ static int ib_fill_isqlda(SV *sth, imp_s
+             /*
+             * User passed an undef to a field that is not nullable.
+             */
+-            char err[80];
+-            sprintf(err, "You have not provided a value for non-nullable parameter #%d.", i);
++            char err[ERRBUFSIZE];
++            snprintf(err, sizeof(err), "You have not provided a value for non-nullable parameter #%d.", i);
+             do_error(sth, 1, err);
+             retval = FALSE;
+             return retval;
+@@ -2278,8 +2280,8 @@ static int ib_fill_isqlda(SV *sth, imp_s
+             string = SvPV(value, len);
+ 
+             if (len > ivar->sqllen) {
+-                char err[80];
+-                sprintf(err, "String truncation (SQL_VARYING): attempted to bind %lu octets to column sized %lu",
++                char err[ERRBUFSIZE];
++                snprintf(err, sizeof(err), "String truncation (SQL_VARYING): attempted to bind %lu octets to column sized %lu",
+                         (long unsigned)len, (long unsigned)(sizeof(char) * (ivar->sqllen)));
+                 break;
+             }
+@@ -2301,8 +2303,8 @@ static int ib_fill_isqlda(SV *sth, imp_s
+             string = SvPV(value, len);
+ 
+             if (len > ivar->sqllen) {
+-                char err[80];
+-                sprintf(err, "String truncation (SQL_TEXT): attempted to bind %lu octets to column sized %lu",
++                char err[ERRBUFSIZE];
++                snprintf(err, sizeof(err), "String truncation (SQL_TEXT): attempted to bind %lu octets to column sized %lu",
+                         (long unsigned)len, (long unsigned)(sizeof(char) * (ivar->sqllen)));
+                 break;
+             }
diff -Nru libdbd-firebird-perl-1.18/debian/patches/series libdbd-firebird-perl-1.18/debian/patches/series
--- libdbd-firebird-perl-1.18/debian/patches/series	1970-01-01 02:00:00.000000000 +0200
+++ libdbd-firebird-perl-1.18/debian/patches/series	2015-04-01 11:41:53.000000000 +0300
@@ -0,0 +1,2 @@
+dbdimp-780925-buf-overflow.patch
+snprintf-everywhere.patch
diff -Nru libdbd-firebird-perl-1.18/debian/patches/snprintf-everywhere.patch libdbd-firebird-perl-1.18/debian/patches/snprintf-everywhere.patch
--- libdbd-firebird-perl-1.18/debian/patches/snprintf-everywhere.patch	1970-01-01 02:00:00.000000000 +0200
+++ libdbd-firebird-perl-1.18/debian/patches/snprintf-everywhere.patch	2015-04-01 11:41:53.000000000 +0300
@@ -0,0 +1,147 @@
+commit 43b9cfac3f09dead772ece59b2d3d5bf8d73d360
+Author: Damyan Ivanov <dmn@debian.org>
+Commit: Damyan Ivanov <dmn@debian.org>
+
+    use snprintf instead of sprintf everywhere
+    
+    this way even if the buffer can't hold all the content, we never
+    overflow it
+
+diff --git a/Firebird.xs b/Firebird.xs
+index 08d17d8..c1c2361 100644
+--- a/Firebird.xs
++++ b/Firebird.xs
+@@ -1646,7 +1646,7 @@ ib_plan(sth)
+     if (plan_buffer[0] == isc_info_sql_get_plan) {
+         short l = (short) isc_vax_integer((char *)plan_buffer + 1, 2);
+ 		Newx(RETVAL, l + 2, char);
+-        sprintf(RETVAL, "%.*s%s", l, plan_buffer + 3, "\n");
++        snprintf(RETVAL, l+2, "%.*s%s", l, plan_buffer + 3, "\n");
+         //PerlIO_printf(PerlIO_stderr(), "Len: %d, orig len: %d\n", strlen(imp_sth->plan), l);
+     }
+ }
+diff --git a/dbdimp.c b/dbdimp.c
+index dbdf8e3..a7574b3 100644
+--- a/dbdimp.c
++++ b/dbdimp.c
+@@ -72,9 +72,10 @@ bool is_ascii_string(const U8 *s, STRLEN len) {
+ int create_cursor_name(SV *sth, imp_sth_t *imp_sth)
+ {
+     ISC_STATUS status[ISC_STATUS_LENGTH];
++#define CURSOR_NAME_LEN 22
+ 
+-    Newxz(imp_sth->cursor_name, 22, char);
+-    sprintf(imp_sth->cursor_name, "perl%16.16X", (uint32_t)imp_sth->stmt);
++    Newxz(imp_sth->cursor_name, CURSOR_NAME_LEN, char);
++    snprintf(imp_sth->cursor_name, CURSOR_NAME_LEN, "perl%16.16X", (uint32_t)imp_sth->stmt);
+     isc_dsql_set_cursor_name(status, &(imp_sth->stmt), imp_sth->cursor_name, 0);
+     if (ib_error_check(sth, status))
+         return FALSE;
+@@ -1494,7 +1495,7 @@ AV *dbd_st_fetch(SV *sth, imp_sth_t *imp_sth)
+                         switch (dtype)
+                         {
+                             case SQL_TIMESTAMP:
+-                                sprintf(buf, "%04d-%02d-%02d %02d:%02d:%02d.%04ld",
++                                snprintf(buf, sizeof(buf), "%04d-%02d-%02d %02d:%02d:%02d.%04ld",
+                                         times.tm_year + 1900,
+                                         times.tm_mon  + 1,
+                                         times.tm_mday,
+@@ -1504,14 +1505,14 @@ AV *dbd_st_fetch(SV *sth, imp_sth_t *imp_sth)
+                                         fpsec);
+                                 break;
+                             case SQL_TYPE_DATE:
+-                                sprintf(buf, "%04d-%02d-%02d",
++                                snprintf(buf, sizeof(buf), "%04d-%02d-%02d",
+                                         times.tm_year + 1900,
+                                         times.tm_mon  + 1,
+                                         times.tm_mday);
+                                 break;
+ 
+                             case SQL_TYPE_TIME:
+-                                sprintf(buf, "%02d:%02d:%02d.%04ld",
++                                snprintf(buf, sizeof(buf), "%02d:%02d:%02d.%04ld",
+                                         times.tm_hour,
+                                         times.tm_min,
+                                         times.tm_sec,
+@@ -1762,7 +1763,7 @@ AV *dbd_st_fetch(SV *sth, imp_sth_t *imp_sth)
+             else
+             {
+                 char s[20];
+-                sprintf(s, "COLUMN%d", i);
++                snprintf(s, sizeof(s), "COLUMN%d", i);
+                 sv_setpvn(sv, s, strlen(s));
+             }
+ */
+@@ -2015,7 +2016,7 @@ SV* dbd_st_FETCH_attrib(SV *sth, imp_sth_t *imp_sth, SV *keysv)
+             else
+             {
+                 char s[20];
+-                sprintf(s, "COLUMN%d", i);
++                snprintf(s, sizeof(s), "COLUMN%d", i);
+                 av_store(av, i, newSVpvn(s, strlen(s)));
+             }
+         }
+@@ -2350,7 +2351,7 @@ static int ib_fill_isqlda(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value,
+                 char *tmp;
+                 char *neg;
+ 
+-                sprintf(format, "%%ld.%%%dld%%1ld", -ivar->sqlscale);
++                snprintf(format, sizeof(format), "%%ld.%%%dld%%1ld", -ivar->sqlscale);
+ 
+                 /* negative -0.x hack */
+                 neg = strchr(svalue, '-');
+@@ -2363,7 +2364,7 @@ static int ib_fill_isqlda(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value,
+                 if (!sscanf(svalue, format, &p, &q, &r))
+                 {
+                     /* here we handle values such as .78 passed as string */
+-                    sprintf(format, ".%%%dld%%1ld", -ivar->sqlscale);
++                    snprintf(format, sizeof(format), ".%%%dld%%1ld", -ivar->sqlscale);
+                     if (!sscanf(svalue, format, &q, &r) && DBIc_WARN(imp_sth))
+                         warn("problem parsing SQL_LONG type");
+                 }
+@@ -2389,11 +2390,11 @@ static int ib_fill_isqlda(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value,
+             {
+                 /* numeric(?,0): scan for one decimal and do rounding*/
+ 
+-                sprintf(format, "%%ld.%%1ld");
++                snprintf(format, sizeof(format), "%%ld.%%1ld");
+ 
+                 if (!sscanf(svalue, format, &p, &r))
+                 {
+-                    sprintf(format, ".%%1ld");
++                    snprintf(format, sizeof(format), ".%%1ld");
+                     if (!sscanf(svalue, format, &r) && DBIc_WARN(imp_sth))
+                         warn("problem parsing SQL_LONG type");
+                 }
+@@ -2481,7 +2482,7 @@ static int ib_fill_isqlda(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value,
+                 char *tmp;
+                 char *neg;
+ 
+-                sprintf(format, S_INT64_FULL, -ivar->sqlscale);
++                snprintf(format, sizeof(format), S_INT64_FULL, -ivar->sqlscale);
+ 
+                 /* negative -0.x hack */
+                 neg = strchr(svalue, '-');
+@@ -2494,7 +2495,7 @@ static int ib_fill_isqlda(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value,
+                 if (!sscanf(svalue, format, &p, &q, &r))
+                 {
+                     /* here we handle values such as .78 passed as string */
+-                    sprintf(format, S_INT64_DEC_FULL, -ivar->sqlscale);
++                    snprintf(format, sizeof(format), S_INT64_DEC_FULL, -ivar->sqlscale);
+                     if (!sscanf(svalue, format, &q, &r) && DBIc_WARN(imp_sth))
+                         warn("problem parsing SQL_INT64 type");
+                 }
+@@ -2520,11 +2521,11 @@ static int ib_fill_isqlda(SV *sth, imp_sth_t *imp_sth, SV *param, SV *value,
+             {
+                 /* numeric(?,0): scan for one decimal and do rounding*/
+ 
+-                sprintf(format, S_INT64_NOSCALE);
++                snprintf(format, sizeof(format), S_INT64_NOSCALE);
+ 
+                 if (!sscanf(svalue, format, &p, &r))
+                 {
+-                    sprintf(format, S_INT64_DEC_NOSCALE);
++                    snprintf(format, sizeof(format), S_INT64_DEC_NOSCALE);
+                     if (!sscanf(svalue, format, &r) && DBIc_WARN(imp_sth))
+                         warn("problem parsing SQL_INT64 type");
+                 }

Reply to: