[Openvpn-devel] Limit file size assignment to safe size_t range.

Message ID 4fc05e83-ba18-49e7-904c-cc3182980652@gmx.de
State New
Headers
Series [Openvpn-devel] Limit file size assignment to safe size_t range. |

Commit Message

Matthias Andree July 1, 2026, 6:31 p.m. UTC
  Some operating systems (FreeBSD 14 on i386) have
sizeof(size_t) == 4 (which is used for object sizes)
sizeof(off_t)  == 8 (which is used for file sizes),
so assigning a file size obtained from stat to a size_t
causes justified compiler warnings about a narrowing
conversion.

It is safe to assume a 32-bit platform will not want
to load a >= 4 GB file there, so let's just ASSERT()
that the off_t we are about to assign fits into
a size_t object.

Signed-off-by: Matthias Andree <matthias.andree@gmx.de>
---
  src/openvpn/buffer.c | 5 ++++-
  1 file changed, 4 insertions(+), 1 deletion(-)

      size_t read_size = fread(BPTR(&ret), 1, size, fp);
      if (read_size == 0)
  

Comments

Matthias Andree July 1, 2026, 6:40 p.m. UTC | #1
Please disregard this one, this has protected spaces, I have already 
resent with git send-email.

Am 01.07.26 um 20:31 schrieb Matthias Andree via Openvpn-devel:
> Some operating systems (FreeBSD 14 on i386) have
> sizeof(size_t) == 4 (which is used for object sizes)
> sizeof(off_t)  == 8 (which is used for file sizes),
> so assigning a file size obtained from stat to a size_t
> causes justified compiler warnings about a narrowing
> conversion.
>
> It is safe to assume a 32-bit platform will not want
> to load a >= 4 GB file there, so let's just ASSERT()
> that the off_t we are about to assign fits into
> a size_t object.
>
> Signed-off-by: Matthias Andree <matthias.andree@gmx.de>
> ---
>  src/openvpn/buffer.c | 5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
>
> diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c
> index 5f2b2338..4b6acb36 100644
> --- a/src/openvpn/buffer.c
> +++ b/src/openvpn/buffer.c
> @@ -1391,7 +1391,10 @@ buffer_read_from_file(const char *filename, 
> struct gc_arena *gc)
>          return ret;
>      }
>
> -    const size_t size = file_stat.st_size;
> +    /* for some systems, off_t is 63 bits wide + sign bit and size_t 
> is 32 bits
> +     * wide, and we need to avoid negative garbage wrapping around */
> +    ASSERT(file_stat.st_size >= 0 && file_stat.st_size <= SIZE_MAX);
> +    const size_t size = (size_t)file_stat.st_size;
>      ret = alloc_buf_gc(size + 1, gc); /* space for trailing \0 */
>      size_t read_size = fread(BPTR(&ret), 1, size, fp);
>      if (read_size == 0)
  

Patch

diff --git a/src/openvpn/buffer.c b/src/openvpn/buffer.c
index 5f2b2338..4b6acb36 100644
--- a/src/openvpn/buffer.c
+++ b/src/openvpn/buffer.c
@@ -1391,7 +1391,10 @@  buffer_read_from_file(const char *filename, 
struct gc_arena *gc)
          return ret;
      }

-    const size_t size = file_stat.st_size;
+    /* for some systems, off_t is 63 bits wide + sign bit and size_t is 
32 bits
+     * wide, and we need to avoid negative garbage wrapping around */
+    ASSERT(file_stat.st_size >= 0 && file_stat.st_size <= SIZE_MAX);
+    const size_t size = (size_t)file_stat.st_size;
      ret = alloc_buf_gc(size + 1, gc); /* space for trailing \0 */