From patchwork Mon Oct 26 03:49:30 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paul Pluzhnikov X-Patchwork-Id: 9374 Received: (qmail 21665 invoked by alias); 26 Oct 2015 03:50:07 -0000 Mailing-List: contact libc-alpha-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: libc-alpha-owner@sourceware.org Delivered-To: mailing list libc-alpha@sourceware.org Received: (qmail 21647 invoked by uid 89); 26 Oct 2015 03:50:06 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=AWL, BAYES_00, RCVD_IN_DNSWL_LOW, RP_MATCHES_RCVD, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-wi0-f172.google.com X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to :content-type; bh=ukYsmSl0GDOsLXA1VZUHOerGkRvjtsjEUHF55Gif3w0=; b=dfXc1+l3iGV/LL9U24RK5bR9jU+sgEn0Y80aPOH6DR7kmfZX42ERw0wUl+X6COxwWi N4uktWCE/P8tzrDtQZ8GcMgGdKSYyT+P57C7RGfBNQGS71nqKz60ShqDQnsBuyZa+rp0 hQTeGuypqTbOAkl2vjTFi6KNIFOXpwwe+f8IZ0kjDZmAkRzFE9OwvNJAnKd/c1iGBJtS nqrr+iJCrsTkef75i0wEgqJc1QAykaN0NNI7nzMCdHZlCFS5AfA+eaXcJKJO+t1vICV7 DVBU7AC32YIceGsd14MAT5j6yedTYev5dL9yZXO8J+A4ujzK75m1P3kWs0KRKohIjP7D hGJQ== X-Gm-Message-State: ALoCoQkFmB3SjNITSIUJadek6XTGeMJiObgMOSlAU1sXM0EQ8dH5G/+3GKwSXL2Ypl6hE7tfTLzR X-Received: by 10.194.71.84 with SMTP id s20mr17940495wju.89.1445831400171; Sun, 25 Oct 2015 20:50:00 -0700 (PDT) MIME-Version: 1.0 From: Paul Pluzhnikov Date: Sun, 25 Oct 2015 20:49:30 -0700 Message-ID: Subject: [patch] Fix BZ 19165 -- overflow in fread / fwrite To: GLIBC Devel Greetings, Attached patch fixes BZ 19165 by failing fwrite when the byte count is impossibly large, and by returning actual count from fread, instead of approximation of it. Tested on Linux/x86_64, no new failures. 2015-10-25 Paul Pluzhnikov [BZ #19165] * libio/iofread.c (_IO_fread): Return correct count. * ibio/iofread_u.c (__fread_unlocked): Likewise. * libio/iofwrite.c (_IO_fwrite): Error on overflow. * libio/iofwrite_u.c (fwrite_unlocked): Likewise. diff --git a/libio/iofread.c b/libio/iofread.c index eb69b05..a8ea391 100644 --- a/libio/iofread.c +++ b/libio/iofread.c @@ -37,7 +37,7 @@ _IO_fread (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) _IO_acquire_lock (fp); bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested); _IO_release_lock (fp); - return bytes_requested == bytes_read ? count : bytes_read / size; + return bytes_read / size; } libc_hidden_def (_IO_fread) diff --git a/libio/iofread_u.c b/libio/iofread_u.c index 997b714..28651bf 100644 --- a/libio/iofread_u.c +++ b/libio/iofread_u.c @@ -38,7 +38,7 @@ __fread_unlocked (void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) if (bytes_requested == 0) return 0; bytes_read = _IO_sgetn (fp, (char *) buf, bytes_requested); - return bytes_requested == bytes_read ? count : bytes_read / size; + return bytes_read / size; } libc_hidden_def (__fread_unlocked) weak_alias (__fread_unlocked, fread_unlocked) diff --git a/libio/iofwrite.c b/libio/iofwrite.c index 48ad4bc..4f6c29c 100644 --- a/libio/iofwrite.c +++ b/libio/iofwrite.c @@ -34,6 +34,11 @@ _IO_fwrite (const void *buf, _IO_size_t size, _IO_size_t count, _IO_FILE *fp) CHECK_FILE (fp, 0); if (request == 0) return 0; + if (count > SIZE_MAX / size) + { + __set_errno(EOVERFLOW); + return 0; + } _IO_acquire_lock (fp); if (_IO_vtable_offset (fp) != 0 || _IO_fwide (fp, -1) == -1) written = _IO_sputn (fp, (const char *) buf, request); diff --git a/libio/iofwrite_u.c b/libio/iofwrite_u.c index 2b1c47a..f818aec 100644 --- a/libio/iofwrite_u.c +++ b/libio/iofwrite_u.c @@ -38,6 +38,11 @@ fwrite_unlocked (const void *buf, _IO_size_t size, _IO_size_t count, CHECK_FILE (fp, 0); if (request == 0) return 0; + if (count > SIZE_MAX / size) + { + __set_errno(EOVERFLOW); + return 0; + } if (_IO_fwide (fp, -1) == -1) { written = _IO_sputn (fp, (const char *) buf, request);