]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
lib: use wrapper for curl_mime_data fseek callback
authorNatanael Copa <ncopa@alpinelinux.org>
Fri, 22 Sep 2023 13:58:49 +0000 (13:58 +0000)
committerDaniel Stenberg <daniel@haxx.se>
Mon, 25 Sep 2023 18:03:09 +0000 (20:03 +0200)
fseek uses long offset which does not match with curl_off_t. This leads
to undefined behavior when calling the callback and caused failure on
arm 32 bit.

Use a wrapper to solve this and use fseeko which uses off_t instead of
long.

Thanks to the nice people at Libera IRC #musl for helping finding this
out.

Fixes #11882
Fixes #11900
Closes #11918

CMakeLists.txt
configure.ac
lib/formdata.c

index 0b3aed90627b1614a0fed0767bb146289bdec2ef..84774dc1db043ef432bf15f5e9c2f46de9f59f9a 100644 (file)
@@ -1037,6 +1037,7 @@ check_include_file_concat("signal.h"         HAVE_SIGNAL_H)
 check_include_file_concat("stdatomic.h"      HAVE_STDATOMIC_H)
 check_include_file_concat("stdbool.h"        HAVE_STDBOOL_H)
 check_include_file_concat("stdint.h"         HAVE_STDINT_H)
+check_include_file_concat("stdio.h"          HAVE_STDIO_H)
 check_include_file_concat("stdlib.h"         HAVE_STDLIB_H)
 check_include_file_concat("string.h"         HAVE_STRING_H)
 check_include_file_concat("strings.h"        HAVE_STRINGS_H)
@@ -1122,6 +1123,8 @@ endif()
 check_symbol_exists(freeaddrinfo   "${CURL_INCLUDES}" HAVE_FREEADDRINFO)
 check_symbol_exists(pipe           "${CURL_INCLUDES}" HAVE_PIPE)
 check_symbol_exists(ftruncate      "${CURL_INCLUDES}" HAVE_FTRUNCATE)
+check_symbol_exists(fseeko         "${CURL_INCLUDES}" HAVE_FSEEKO)
+check_symbol_exists(_fseeki64      "${CURL_INCLUDES}" HAVE__FSEEKI64)
 check_symbol_exists(getpeername    "${CURL_INCLUDES}" HAVE_GETPEERNAME)
 check_symbol_exists(getsockname    "${CURL_INCLUDES}" HAVE_GETSOCKNAME)
 check_symbol_exists(if_nametoindex "${CURL_INCLUDES}" HAVE_IF_NAMETOINDEX)
index a6f9066a133a41b9913c007dd4016af9cf334889..5fa7c45c474304271364150807528189dc02e9f3 100644 (file)
@@ -3584,10 +3584,12 @@ AC_CHECK_DECLS([getpwuid_r], [], [AC_DEFINE(HAVE_DECL_GETPWUID_R_MISSING, 1, "Se
 
 
 AC_CHECK_FUNCS([\
+  _fseeki64 \
   arc4random \
   fchmod \
   fnmatch \
   fork \
+  fseeko \
   geteuid \
   getpass_r \
   getppid \
index 8984b63223cc0e64fafa3a59bfc7714d2da80eb9..f370ce6854b5f9eccda0a6410b0fd47155acc40d 100644 (file)
@@ -789,6 +789,20 @@ static CURLcode setname(curl_mimepart *part, const char *name, size_t len)
   return res;
 }
 
+/* wrap call to fseeko so it matches the calling convetion of callback */
+static int fseeko_wrapper(void *stream, curl_off_t offset, int whence)
+{
+#if defined(HAVE_FSEEKO)
+  return fseeko(stream, (off_t)offset, whence);
+#elif defined(HAVE__FSEEKI64)
+  return _fseeki64(stream, (__int64)offset, whence);
+#else
+  if(offset > LONG_MAX)
+    return -1;
+  return fseek(stream, (long)offset, whence);
+#endif
+}
+
 /*
  * Curl_getformdata() converts a linked list of "meta data" into a mime
  * structure. The input list is in 'post', while the output is stored in
@@ -874,8 +888,7 @@ CURLcode Curl_getformdata(struct Curl_easy *data,
                compatibility: use of "-" pseudo file name should be avoided. */
             result = curl_mime_data_cb(part, (curl_off_t) -1,
                                        (curl_read_callback) fread,
-                                       CURLX_FUNCTION_CAST(curl_seek_callback,
-                                                           fseek),
+                                       fseeko_wrapper,
                                        NULL, (void *) stdin);
           }
           else