From 703e98c1f5e545a4f4a908d8f11d9eff4439ec32 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 13 Jun 2015 07:13:20 +0200 Subject: [PATCH] Added patch to implement fallback to system ping command when CAP_NET_RAW is not available. --- README.md | 3 +- debian/changelog | 2 + ...k-to-system-ping-when-ICMP-permissio.patch | 339 ++++++++++++++++++ patches/iphlpapi-System_Ping/definition | 1 + patches/patchinstall.sh | 121 ++++--- 5 files changed, 414 insertions(+), 52 deletions(-) create mode 100644 patches/iphlpapi-System_Ping/0001-iphlpapi-Fallback-to-system-ping-when-ICMP-permissio.patch create mode 100644 patches/iphlpapi-System_Ping/definition diff --git a/README.md b/README.md index 885d14c2..1560cb27 100644 --- a/README.md +++ b/README.md @@ -39,7 +39,7 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [20]:** +**Bug fixes and features included in the next upcoming release [21]:** * Add implementation for kernel32.GetNumaProcessorNode ([Wine Bug #38660](https://bugs.winehq.org/show_bug.cgi?id=38660)) * Add semi-stub for FileFsVolumeInformation information class ([Wine Bug #21466](https://bugs.winehq.org/show_bug.cgi?id=21466)) @@ -47,6 +47,7 @@ Included bug fixes and improvements * Allow to enable/disable InsertMode in wineconsole settings ([Wine Bug #38697](https://bugs.winehq.org/show_bug.cgi?id=38697)) * Allow to set pixel format for desktop window * Ensure console InsertMode changes take effect immediately +* Fallback to system ping command when CAP_NET_RAW is not available ([Wine Bug #8332](https://bugs.winehq.org/show_bug.cgi?id=8332)) * Fix endless loop in regedit when importing files with very long lines * Fix link notification conditions for riched20 ([Wine Bug #35949](https://bugs.winehq.org/show_bug.cgi?id=35949)) * Forward GIF encoder requests to windowscodecs ([Wine Bug #34356](https://bugs.winehq.org/show_bug.cgi?id=34356)) diff --git a/debian/changelog b/debian/changelog index b485f3a8..4e2fc51c 100644 --- a/debian/changelog +++ b/debian/changelog @@ -44,6 +44,8 @@ wine-staging (1.7.45) UNRELEASED; urgency=low * Added patch to ensure console InsertMode changes take effect immediately. * Added patch to send WM_DROPFILES only when OLE dnd fails. * Added patch with stub for winscard.SCardListReadersA/W. + * Added patch to implement fallback to system ping command when CAP_NET_RAW is + not available. * Removed patch to handle '\r' as whitespace in wbemprox queries (accepted upstream). * Removed patch to make sure OpenClipboard with current owner doesn't fail diff --git a/patches/iphlpapi-System_Ping/0001-iphlpapi-Fallback-to-system-ping-when-ICMP-permissio.patch b/patches/iphlpapi-System_Ping/0001-iphlpapi-Fallback-to-system-ping-when-ICMP-permissio.patch new file mode 100644 index 00000000..ca3bafc9 --- /dev/null +++ b/patches/iphlpapi-System_Ping/0001-iphlpapi-Fallback-to-system-ping-when-ICMP-permissio.patch @@ -0,0 +1,339 @@ +From 9cd3bea619679a76467705957d9b9f9d4d888a1c Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 13 Jun 2015 05:03:54 +0200 +Subject: iphlpapi: Fallback to system ping when ICMP permissions are not + present. + +Based on an idea by Bruno Jesus. +--- + dlls/iphlpapi/icmp.c | 256 +++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 250 insertions(+), 6 deletions(-) + +diff --git a/dlls/iphlpapi/icmp.c b/dlls/iphlpapi/icmp.c +index ebc2f2b..330dd73a 100644 +--- a/dlls/iphlpapi/icmp.c ++++ b/dlls/iphlpapi/icmp.c +@@ -5,6 +5,7 @@ + * RW Hall, 1999, based on public domain code PING.C by Mike Muus (1983) + * and later works (c) 1989 Regents of Univ. of California - see copyright + * notice at end of source-code. ++ * Copyright 2015 Sebastian Lackner + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public +@@ -32,6 +33,7 @@ + */ + + #include "config.h" ++#include "wine/port.h" + + #include + #ifdef HAVE_SYS_SOCKET_H +@@ -52,7 +54,9 @@ + #endif + #include + #include ++#include + #include ++#include + #ifdef HAVE_UNISTD_H + # include + #endif +@@ -62,6 +66,9 @@ + #ifdef HAVE_SYS_POLL_H + # include + #endif ++#ifdef HAVE_SYS_WAIT_H ++# include ++#endif + + #define USE_WS_PREFIX + +@@ -209,6 +216,7 @@ DWORD WINAPI Icmp6SendEcho2( + */ + HANDLE WINAPI IcmpCreateFile(VOID) + { ++ static int once; + icmp_t* icp; + + int sid=socket(AF_INET,SOCK_RAW,IPPROTO_ICMP); +@@ -217,15 +225,14 @@ HANDLE WINAPI IcmpCreateFile(VOID) + /* Mac OS X supports non-privileged ICMP via SOCK_DGRAM type. */ + sid=socket(AF_INET,SOCK_DGRAM,IPPROTO_ICMP); + } +- if (sid < 0) { +- ERR_(winediag)("Failed to use ICMP (network ping), this requires special permissions.\n"); +- SetLastError(ERROR_ACCESS_DENIED); +- return INVALID_HANDLE_VALUE; ++ if (sid < 0 && !once++) { ++ FIXME_(winediag)("Failed to use ICMP (network ping), this requires special permissions.\n"); ++ FIXME_(winediag)("Falling back to system 'ping' command as a workaround.\n"); + } + + icp=HeapAlloc(GetProcessHeap(), 0, sizeof(*icp)); + if (icp==NULL) { +- close(sid); ++ if (sid >= 0) close(sid); + SetLastError(IP_NO_RESOURCES); + return INVALID_HANDLE_VALUE; + } +@@ -247,11 +254,242 @@ BOOL WINAPI IcmpCloseHandle(HANDLE IcmpHandle) + return FALSE; + } + +- close( icp->sid ); ++ if (icp->sid >= 0) close(icp->sid); + HeapFree(GetProcessHeap (), 0, icp); + return TRUE; + } + ++static DWORD system_icmp( ++ IPAddr DestinationAddress, ++ LPVOID RequestData, ++ WORD RequestSize, ++ PIP_OPTION_INFORMATION RequestOptions, ++ LPVOID ReplyBuffer, ++ DWORD ReplySize, ++ DWORD Timeout ++ ) ++{ ++#ifdef HAVE_FORK ++ ICMP_ECHO_REPLY *reply = ReplyBuffer; ++ char ntoa_buffer[16]; /* 4*3 digits + 3 '.' + 1 '\0' */ ++ char size_buffer[6]; /* 5 digits + '\0' */ ++ char tos_buffer[4]; /* 3 digits + '\0' */ ++ char ttl_buffer[4]; /* 3 digits + '\0' */ ++ char time_buffer[11]; /* 10 digits + '\0' */ ++ int i, pos, res, status, argc; ++ const char *argv[20]; ++ struct in_addr addr; ++ int pipe_out[2]; ++ pid_t pid, wpid; ++ char *ptr, *eol; ++ char buf[127]; ++ ++ /* Assemble the ping commandline */ ++ argc = 0; ++ argv[argc++] = "ping"; ++ argv[argc++] = "-c"; /* only send a single ping */ ++ argv[argc++] = "1"; ++ argv[argc++] = "-n"; /* numeric output only */ ++ argv[argc++] = "-s"; /* request size */ ++ sprintf(size_buffer, "%u", (RequestSize >= 16) ? RequestSize : 16); ++ argv[argc++] = size_buffer; ++ argv[argc++] = "-W"; /* timeout */ ++#ifdef __linux__ ++ /* The linux 'ping' utlity expects a time in seconds */ ++ Timeout = (Timeout + 999) / 1000; ++#endif ++ sprintf(time_buffer, "%u", Timeout); ++ argv[argc++] = time_buffer; ++ ++ if (RequestOptions) ++ { ++ #ifdef __linux__ ++ argv[argc++] = "-Q"; /* tos option */ ++ #else ++ argv[argc++] = "-z"; /* tos option */ ++ #endif ++ sprintf(tos_buffer, "%u", RequestOptions->Tos); ++ argv[argc++] = tos_buffer; ++ #ifdef __linux__ ++ /* TTL can only be specified for multicast addresses on FreeBSD/MacOS */ ++ argv[argc++] = "-t"; /* ttl option */ ++ sprintf(ttl_buffer, "%u", RequestOptions->Ttl); ++ argv[argc++] = ttl_buffer; ++ #endif ++ } ++ ++ addr.s_addr = DestinationAddress; ++ if (!(ptr = inet_ntoa(addr))) ++ { ++ SetLastError(ERROR_INVALID_PARAMETER); ++ return 0; ++ } ++ strcpy(ntoa_buffer, ptr); ++ argv[argc++] = ntoa_buffer; ++ argv[argc] = NULL; ++ ++ /* Dump commandline for debugging purposes */ ++ TRACE("Ping commandline: "); ++ for (i = 0; i < argc; i++) ++ { ++ TRACE("%s ", debugstr_a(argv[i])); ++ } ++ TRACE("\n"); ++ ++ /* Prefill the reply struct with fallback values */ ++ memset(reply, 0, sizeof(*reply)); ++ reply->Address = DestinationAddress; ++ reply->RoundTripTime = 40; ++ reply->Options.Ttl = 120; ++ ++ /* Create communication pipes */ ++#ifdef HAVE_PIPE2 ++ if (pipe2(pipe_out, O_CLOEXEC) < 0) ++#endif ++ { ++ if (pipe(pipe_out) < 0) ++ { ++ SetLastError(ERROR_OUTOFMEMORY); ++ return 0; ++ } ++ fcntl(pipe_out[0], F_SETFD, FD_CLOEXEC); ++ fcntl(pipe_out[1], F_SETFD, FD_CLOEXEC); ++ } ++ ++ /* Fork child process */ ++ pid = fork(); ++ if (pid == -1) ++ { ++ close(pipe_out[0]); ++ close(pipe_out[1]); ++ SetLastError(ERROR_OUTOFMEMORY); ++ return 0; ++ } ++ ++ /* Child process */ ++ if (pid == 0) ++ { ++ static char lang_env[] = "LANG=C"; ++ ++ dup2(pipe_out[1], 1); ++ close(pipe_out[0]); ++ close(pipe_out[1]); ++ close(0); ++ close(2); ++ ++ putenv(lang_env); ++ execvp(argv[0], (char **)argv); ++ _exit(1); ++ } ++ ++ close(pipe_out[1]); ++ ++ /* Wait for child and read output */ ++ pos = 0; ++ do ++ { ++ if (pos >= sizeof(buf) - 1) ++ { ++ ERR("line too long, dropping buffer\n"); ++ pos = 0; ++ } ++ ++ /* read next block */ ++ do ++ { ++ res = read(pipe_out[0], &buf[pos], (sizeof(buf) - 1) - pos); ++ } ++ while (res < 0 && errno == EINTR); ++ if (res < 0) ++ { ++ ERR("read failed: %s\n", strerror(errno)); ++ break; ++ } ++ ++ pos += res; ++ while (pos) ++ { ++ eol = memchr(buf, '\n', pos); ++ if (!eol) break; ++ *eol = 0; ++ ++ TRACE("Received line: %s\n", debugstr_a(buf)); ++ ++ /* Interpret address */ ++ if ((ptr = strstr(buf, "from "))) ++ { ++ int a, b, c, d; ++ if (sscanf(ptr + 5, "%u.%u.%u.%u", &a, &b, &c, &d) >= 4) ++ { ++ reply->Address = a | (b << 8) | (c << 16) | (d << 24); ++ addr.s_addr = reply->Address; ++ TRACE("Got address %s\n", inet_ntoa(addr)); ++ } ++ } ++ ++ /* Interpret ttl */ ++ if ((ptr = strstr(buf, "ttl="))) ++ { ++ int val; ++ if (sscanf(ptr + 4, "%u", &val) >= 1) ++ { ++ reply->Options.Ttl = val; ++ TRACE("Got ttl %u\n", val); ++ } ++ } ++ ++ /* Interpret time */ ++ if ((ptr = strstr(buf, "time="))) ++ { ++ float val; ++ if (sscanf(ptr + 5, "%f", &val) >= 1) ++ { ++ reply->RoundTripTime = (unsigned int)(val + 0.5); ++ TRACE("Got rtt = %u\n", reply->RoundTripTime); ++ } ++ } ++ ++ memmove(buf, eol + 1, pos - (eol + 1 - buf)); ++ pos -= (eol + 1 - buf); ++ } ++ } ++ while (res > 0); ++ close(pipe_out[0]); ++ ++ /* reap the child process */ ++ do ++ { ++ wpid = waitpid(pid, &status, 0); ++ } ++ while (wpid < 0 && errno == EINTR); ++ ++ /* fill out remaining struct fields */ ++ if (wpid >= 0 && WIFEXITED(status) && WEXITSTATUS(status) == 0) ++ { ++ if (ReplySize < RequestSize + sizeof(*reply)) ++ { ++ reply->Status = IP_BUF_TOO_SMALL; ++ reply->DataSize = 0; ++ reply->Data = NULL; ++ } ++ else ++ { ++ reply->Status = 0; ++ reply->DataSize = RequestSize; ++ reply->Data = (char *)reply + sizeof(*reply); ++ memcpy(reply->Data, RequestData, RequestSize); ++ } ++ return 1; ++ } ++ ++ SetLastError(IP_REQ_TIMED_OUT); ++ return 0; ++#else ++ ERR("no fork support on this platform\n"); ++ SetLastError(ERROR_NOT_SUPPORTED); ++ return 0; ++#endif ++} + + /*********************************************************************** + * IcmpSendEcho (IPHLPAPI.@) +@@ -301,6 +539,12 @@ DWORD WINAPI IcmpSendEcho( + return 0; + } + ++ if (icp->sid < 0) { ++ WARN("using system ping command since SOCK_RAW was not supported.\n"); ++ return system_icmp(DestinationAddress, RequestData, RequestSize, ++ RequestOptions, ReplyBuffer, ReplySize, Timeout); ++ } ++ + /* Prepare the request */ + id=getpid() & 0xFFFF; + seq=InterlockedIncrement(&icmp_sequence) & 0xFFFF; +-- +2.4.2 + diff --git a/patches/iphlpapi-System_Ping/definition b/patches/iphlpapi-System_Ping/definition new file mode 100644 index 00000000..aaeeb2fe --- /dev/null +++ b/patches/iphlpapi-System_Ping/definition @@ -0,0 +1 @@ +Fixes: [8332] Fallback to system ping command when CAP_NET_RAW is not available diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 70e07aea..756a4b68 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -127,6 +127,7 @@ patch_enable_all () enable_imagehlp_BindImageEx="$1" enable_imagehlp_ImageLoad="$1" enable_inetcpl_Default_Home="$1" + enable_iphlpapi_System_Ping="$1" enable_iphlpapi_TCP_Table="$1" enable_kernel32_CompareStringEx="$1" enable_kernel32_CopyFileEx="$1" @@ -461,6 +462,9 @@ patch_enable () inetcpl-Default_Home) enable_inetcpl_Default_Home="$2" ;; + iphlpapi-System_Ping) + enable_iphlpapi_System_Ping="$2" + ;; iphlpapi-TCP_Table) enable_iphlpapi_TCP_Table="$2" ;; @@ -2891,6 +2895,21 @@ if test "$enable_inetcpl_Default_Home" -eq 1; then ) >> "$patchlist" fi +# Patchset iphlpapi-System_Ping +# | +# | This patchset fixes the following Wine bugs: +# | * [#8332] Fallback to system ping command when CAP_NET_RAW is not available +# | +# | Modified files: +# | * dlls/iphlpapi/icmp.c +# | +if test "$enable_iphlpapi_System_Ping" -eq 1; then + patch_apply iphlpapi-System_Ping/0001-iphlpapi-Fallback-to-system-ping-when-ICMP-permissio.patch + ( + echo '+ { "Sebastian Lackner", "iphlpapi: Fallback to system ping when ICMP permissions are not present.", 1 },'; + ) >> "$patchlist" +fi + # Patchset iphlpapi-TCP_Table # | # | This patchset fixes the following Wine bugs: @@ -5058,57 +5077,6 @@ if test "$enable_wined3d_CSMT_Helper" -eq 1; then ) >> "$patchlist" fi -# Patchset wined3d-UnhandledBlendFactor -# | -# | Modified files: -# | * dlls/wined3d/state.c -# | -if test "$enable_wined3d_UnhandledBlendFactor" -eq 1; then - patch_apply wined3d-UnhandledBlendFactor/0001-wined3d-Silence-repeated-Unhandled-blend-factor-0-me.patch - ( - echo '+ { "Sebastian Lackner", "wined3d: Silence repeated '\''Unhandled blend factor 0'\'' messages.", 1 },'; - ) >> "$patchlist" -fi - -# Patchset wined3d-wined3d_swapchain_present -# | -# | Modified files: -# | * dlls/wined3d/swapchain.c -# | -if test "$enable_wined3d_wined3d_swapchain_present" -eq 1; then - patch_apply wined3d-wined3d_swapchain_present/0001-wined3d-Silence-repeated-wined3d_swapchain_present-F.patch - ( - echo '+ { "Sebastian Lackner", "wined3d: Silence repeated wined3d_swapchain_present FIXME.", 1 },'; - ) >> "$patchlist" -fi - -# Patchset wined3d-resource_check_usage -# | -# | Modified files: -# | * dlls/wined3d/resource.c -# | -if test "$enable_wined3d_resource_check_usage" -eq 1; then - patch_apply wined3d-resource_check_usage/0001-wined3d-Silence-repeated-resource_check_usage-FIXME.patch - ( - echo '+ { "Erich E. Hoover", "wined3d: Silence repeated resource_check_usage FIXME.", 2 },'; - ) >> "$patchlist" -fi - -# Patchset wined3d-Multisampling -# | -# | This patchset fixes the following Wine bugs: -# | * [#12652] Allow to override number of quality levels for D3DMULTISAMPLE_NONMASKABLE. -# | -# | Modified files: -# | * dlls/wined3d/directx.c, dlls/wined3d/wined3d_main.c, dlls/wined3d/wined3d_private.h -# | -if test "$enable_wined3d_Multisampling" -eq 1; then - patch_apply wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch - ( - echo '+ { "Austin English", "wined3d: Allow to specify multisampling AA quality levels via registry.", 1 },'; - ) >> "$patchlist" -fi - # Patchset wined3d-Revert_PixelFormat # | # | This patchset fixes the following Wine bugs: @@ -5143,6 +5111,57 @@ if test "$enable_wined3d_Revert_PixelFormat" -eq 1; then ) >> "$patchlist" fi +# Patchset wined3d-resource_check_usage +# | +# | Modified files: +# | * dlls/wined3d/resource.c +# | +if test "$enable_wined3d_resource_check_usage" -eq 1; then + patch_apply wined3d-resource_check_usage/0001-wined3d-Silence-repeated-resource_check_usage-FIXME.patch + ( + echo '+ { "Erich E. Hoover", "wined3d: Silence repeated resource_check_usage FIXME.", 2 },'; + ) >> "$patchlist" +fi + +# Patchset wined3d-UnhandledBlendFactor +# | +# | Modified files: +# | * dlls/wined3d/state.c +# | +if test "$enable_wined3d_UnhandledBlendFactor" -eq 1; then + patch_apply wined3d-UnhandledBlendFactor/0001-wined3d-Silence-repeated-Unhandled-blend-factor-0-me.patch + ( + echo '+ { "Sebastian Lackner", "wined3d: Silence repeated '\''Unhandled blend factor 0'\'' messages.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset wined3d-wined3d_swapchain_present +# | +# | Modified files: +# | * dlls/wined3d/swapchain.c +# | +if test "$enable_wined3d_wined3d_swapchain_present" -eq 1; then + patch_apply wined3d-wined3d_swapchain_present/0001-wined3d-Silence-repeated-wined3d_swapchain_present-F.patch + ( + echo '+ { "Sebastian Lackner", "wined3d: Silence repeated wined3d_swapchain_present FIXME.", 1 },'; + ) >> "$patchlist" +fi + +# Patchset wined3d-Multisampling +# | +# | This patchset fixes the following Wine bugs: +# | * [#12652] Allow to override number of quality levels for D3DMULTISAMPLE_NONMASKABLE. +# | +# | Modified files: +# | * dlls/wined3d/directx.c, dlls/wined3d/wined3d_main.c, dlls/wined3d/wined3d_private.h +# | +if test "$enable_wined3d_Multisampling" -eq 1; then + patch_apply wined3d-Multisampling/0001-wined3d-Allow-to-specify-multisampling-AA-quality-le.patch + ( + echo '+ { "Austin English", "wined3d: Allow to specify multisampling AA quality levels via registry.", 1 },'; + ) >> "$patchlist" +fi + # Patchset wined3d-CSMT_Main # | # | This patchset fixes the following Wine bugs: