From 48b03eb888a1178f8b31b7ab17351ccaee2d533c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?P=C3=A1draig=20Brady?=
Date: Sat, 19 Nov 2022 17:09:17 +0000
Subject: [PATCH] copy: constrain buffer size to a reasonable value
Remove use of buffer_lcm() to determine a buffer_size to use,
and instead just pick the largest io_blksize()
for the src and dst file, which in turn is constrained
to a reasonable value of 32MiB currently.
* bootstrap.conf: Remove buffer-lcm module.
* gl/lib/buffer-lcm.c: Likewise.
* gl/lib/buffer-lcm.h: Likewise.
* gl/modules/buffer-lcm: Likewise.
* src/copy.c: Pick a buffer value as per the above description.
* src/ioblksize.h: Constrain io_blksize() to 32MiB,
* NEWS: Mention the fix.
to avoid any subsequent memory or type overflow issues.
Fixes https://bugs.gnu.org/59382
---
bootstrap.conf | 1 -
gl/lib/buffer-lcm.c | 59 -------------------------------------------
gl/lib/buffer-lcm.h | 2 --
gl/modules/buffer-lcm | 23 -----------------
src/copy.c | 18 +++++--------
src/ioblksize.h | 10 +++++---
6 files changed, 14 insertions(+), 99 deletions(-)
delete mode 100644 gl/lib/buffer-lcm.c
delete mode 100644 gl/lib/buffer-lcm.h
delete mode 100644 gl/modules/buffer-lcm
diff --git a/bootstrap.conf b/bootstrap.conf
index 8e257a254..f37ac4e47 100644
--- a/bootstrap.conf
+++ b/bootstrap.conf
@@ -42,7 +42,6 @@ gnulib_modules="
base32
base64
btowc
- buffer-lcm
byteswap
c-strcase
cl-strtod
diff --git a/gl/lib/buffer-lcm.c b/gl/lib/buffer-lcm.c
deleted file mode 100644
index 392dcb753..000000000
--- a/gl/lib/buffer-lcm.c
+++ /dev/null
@@ -1,59 +0,0 @@
-/* buffer-lcm.c - compute a good buffer size for dealing with two files
-
- Copyright (C) 2002-2022 Free Software Foundation, Inc.
-
- This program is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program. If not, see . */
-
-/* Written by Paul Eggert. */
-
-#include
-#include "buffer-lcm.h"
-
-/* Return a buffer size suitable for doing I/O with files whose block
- sizes are A and B. However, never return a value greater than
- LCM_MAX. */
-
-size_t
-buffer_lcm (size_t a, size_t b, size_t lcm_max)
-{
- size_t size;
-
- /* Use reasonable values if buffer sizes are zero. */
- if (!a)
- size = b ? b : 8 * 1024;
- else
- {
- if (b)
- {
- /* Return lcm (A, B) if it is in range; otherwise, fall back
- on A. */
-
- size_t lcm, m, n, q, r;
-
- /* N = gcd (A, B). */
- for (m = a, n = b; (r = m % n) != 0; m = n, n = r)
- continue;
-
- /* LCM = lcm (A, B), if in range. */
- q = a / n;
- lcm = q * b;
- if (lcm <= lcm_max && lcm / b == q)
- return lcm;
- }
-
- size = a;
- }
-
- return size <= lcm_max ? size : lcm_max;
-}
diff --git a/gl/lib/buffer-lcm.h b/gl/lib/buffer-lcm.h
deleted file mode 100644
index 454c65be8..000000000
--- a/gl/lib/buffer-lcm.h
+++ /dev/null
@@ -1,2 +0,0 @@
-#include
-size_t buffer_lcm (size_t, size_t, size_t) _GL_ATTRIBUTE_CONST;
diff --git a/gl/modules/buffer-lcm b/gl/modules/buffer-lcm
deleted file mode 100644
index 1d86f715e..000000000
--- a/gl/modules/buffer-lcm
+++ /dev/null
@@ -1,23 +0,0 @@
-Description:
-Compute a good buffer size for dealing with two files.
-
-Files:
-lib/buffer-lcm.c
-lib/buffer-lcm.h
-
-Depends-on:
-stddef
-
-configure.ac:
-
-Makefile.am:
-lib_SOURCES += buffer-lcm.c buffer-lcm.h
-
-Include:
-"buffer-lcm.h"
-
-License:
-GPL
-
-Maintainer:
-Paul Eggert
diff --git a/src/copy.c b/src/copy.c
index e465271ef..5ccac99d5 100644
--- a/src/copy.c
+++ b/src/copy.c
@@ -34,7 +34,6 @@
#include "acl.h"
#include "alignalloc.h"
#include "backupfile.h"
-#include "buffer-lcm.h"
#include "canonicalize.h"
#include "copy.h"
#include "cp-hash.h"
@@ -1342,22 +1341,19 @@ copy_reg (char const *src_name, char const *dst_name,
{
/* Compute the least common multiple of the input and output
buffer sizes, adjusting for outlandish values. */
- size_t blcm_max = MIN (SIZE_MAX, SSIZE_MAX);
- size_t blcm = buffer_lcm (io_blksize (src_open_sb), buf_size,
- blcm_max);
+ size_t bmax = MAX (io_blksize (src_open_sb), buf_size);
/* Do not bother with a buffer larger than the input file, plus one
byte to make sure the file has not grown while reading it. */
if (S_ISREG (src_open_sb.st_mode) && src_open_sb.st_size < buf_size)
buf_size = src_open_sb.st_size + 1;
- /* However, stick with a block size that is a positive multiple of
- blcm, overriding the above adjustments. Watch out for
- overflow. */
- buf_size += blcm - 1;
- buf_size -= buf_size % blcm;
- if (buf_size == 0 || blcm_max < buf_size)
- buf_size = blcm;
+ /* However, stick with a buffer size that is a positive multiple of
+ bmax, overriding the above adjustments. Watch out for overflow. */
+ buf_size += bmax - 1;
+ buf_size -= buf_size % bmax;
+ if (buf_size == 0 || IO_BUFSIZE_MAX < buf_size)
+ buf_size = bmax;
}
off_t n_read;
diff --git a/src/ioblksize.h b/src/ioblksize.h
index 8bd18ba05..b8e9ebf32 100644
--- a/src/ioblksize.h
+++ b/src/ioblksize.h
@@ -17,6 +17,7 @@
/* Include this file _after_ system headers if possible. */
/* sys/stat.h and minmax.h will already have been included by system.h. */
+#include
#include "idx.h"
#include "stat-size.h"
@@ -72,11 +73,14 @@
and default to io_blksize() if not.
*/
enum { IO_BUFSIZE = 128 * 1024 };
+
+/* Set a max constraint to avoid excessive mem usage or type overflow. */
+enum { IO_BUFSIZE_MAX = 128 * IO_BUFSIZE };
+static_assert (IO_BUFSIZE_MAX <= MIN (IDX_MAX, SIZE_MAX) / 2 + 1);
+
static inline idx_t
io_blksize (struct stat sb)
{
- /* Don’t go above the largest power of two that fits in idx_t and size_t,
- as that is asking for trouble. */
- return MIN (MIN (IDX_MAX, SIZE_MAX) / 2 + 1,
+ return MIN (IO_BUFSIZE_MAX,
MAX (IO_BUFSIZE, ST_BLKSIZE (sb)));
}
--
2.26.2