已合并
Replace unsafe functions: memset and memcpy #74
yuhaiyan8创建于 2025年8月5日
Replace unsafe functions: memset and memcpy #74
已合并
从refs/pull/74/head合入到master
共 21 个文件变更+137-83
| @@ -10,3 +10,6 @@ | |||
| 10 | [submodule "third_party/libnop"] | 10 | [submodule "third_party/libnop"] |
| 11 | path = third_party/libnop | 11 | path = third_party/libnop |
| 12 | url = https://gitee.com/mirrors/libnop.git | 12 | url = https://gitee.com/mirrors/libnop.git |
| 13 | +[submodule "third_party/secure_c"] | ||
| 14 | + path = third_party/secure_c | ||
| 15 | + url = https://gitee.com/openeuler/libboundscheck.git | ||
Y | |||
| @@ -130,6 +130,20 @@ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND | |||
| 130 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | 130 | IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, |
| 131 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 131 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 132 | 132 | ||
| 133 | +Software: openEuler:libboundscheck master | ||
| 134 | + | ||
| 135 | +Copyright notice: | ||
| 136 | +Copyright (c) Huawei Technologies Co., Ltd. 2014-2021 | ||
| 137 | + | ||
| 138 | +License: MulanPSL-2.0 License | ||
| 139 | +You can use this software according to the terms and conditions of the Mulan PSL v2. | ||
| 140 | +You may obtain a copy of Mulan PSL v2 at: | ||
| 141 | + http://license.coscl.org.cn/MulanPSL2 | ||
| 142 | +THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, | ||
| 143 | +EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, | ||
| 144 | +MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE. | ||
| 145 | +See the Mulan PSL v2 for more details. | ||
| 146 | + | ||
| 133 | Written Offer | 147 | Written Offer |
| 134 | This product contains software whose rights holders license it on the terms of the GNU General Public License, version 2 (GPLv2) and/or other open source software licenses. We will provide you and any third party with the source code of the software licensed under an open source software license if you send us a written request by mail or email to the following addresses: | 148 | This product contains software whose rights holders license it on the terms of the GNU General Public License, version 2 (GPLv2) and/or other open source software licenses. We will provide you and any third party with the source code of the software licensed under an open source software license if you send us a written request by mail or email to the following addresses: |
| 135 | foss@huawei.com | 149 | foss@huawei.com |
| @@ -139,3 +153,4 @@ Please note you need to make a payment before you obtain the complete Correspond | |||
| 139 | This offer is valid to anyone in receipt of this information. | 153 | This offer is valid to anyone in receipt of this information. |
| 140 | 154 | ||
| 141 | THIS OFFER IS VALID FOR THREE YEARS FROM THE MOMENT WE DISTRIBUTED THE PRODUCT OR FIRMWARE. | 155 | THIS OFFER IS VALID FOR THREE YEARS FROM THE MOMENT WE DISTRIBUTED THE PRODUCT OR FIRMWARE. |
| 156 | + | ||
| @@ -15,4 +15,5 @@ | |||
| 15 | | 开发引入 | 不涉及 | .gitmodules | https://gitee.com/mirrors/googletest.git | 依赖的开源代码仓 | | 15 | | 开发引入 | 不涉及 | .gitmodules | https://gitee.com/mirrors/googletest.git | 依赖的开源代码仓 | |
| 16 | | 开发引入 | 不涉及 | .gitmodules | https://gitee.com/mirrors/libnop.git | 依赖的开源代码仓 | | 16 | | 开发引入 | 不涉及 | .gitmodules | https://gitee.com/mirrors/libnop.git | 依赖的开源代码仓 | |
| 17 | | 开发引入 | 不涉及 | cmake/FindPackageHandleStandardArgs.cmake | https://cmake.org/licensing | 保留原始版权声明和链接,确保许可证信息完整 | | 17 | | 开发引入 | 不涉及 | cmake/FindPackageHandleStandardArgs.cmake | https://cmake.org/licensing | 保留原始版权声明和链接,确保许可证信息完整 | |
| 18 | -| 开发引入 | 不涉及 | cmake/FindPackageMessage.cmake | https://cmake.org/licensing | 保留原始版权声明和链接,确保许可证信息完整 | | 18 | +| 开发引入 | 不涉及 | cmake/FindPackageMessage.cmake | https://cmake.org/licensing | 保留原始版权声明和链接,确保许可证信息完整 | |
| 19 | +| 开发引入 | 不涉及 | .gitmoudles | https://gitee.com/openeuler/libboundscheck.git | 依赖的开源代码仓 | | ||
| @@ -180,6 +180,15 @@ if(TP_ENABLE_IBV) | |||
| 180 | set(TENSORPIPE_HAS_IBV_TRANSPORT 1) | 180 | set(TENSORPIPE_HAS_IBV_TRANSPORT 1) |
| 181 | endif() | 181 | endif() |
| 182 | 182 | ||
| 183 | +# secure_c | ||
| 184 | +include_directories(${PROJECT_SOURCE_DIR}/third_party/secure_c/include) | ||
| 185 | +list(APPEND TP_SRCS | ||
| 186 | + ${PROJECT_SOURCE_DIR}/third_party/secure_c/src/memcpy_s.c | ||
| 187 | + ${PROJECT_SOURCE_DIR}/third_party/secure_c/src/memset_s.c | ||
| 188 | +) | ||
| 189 | +list(APPEND TP_PUBLIC_HDRS | ||
| 190 | + ${PROJECT_SOURCE_DIR}/third_party/secure_c/include/securec.h | ||
| 191 | +) | ||
| 183 | 192 | ||
| 184 | ## MAC OS specific library deps | 193 | ## MAC OS specific library deps |
| 185 | 194 | ||
| @@ -18,6 +18,7 @@ | |||
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| 21 | + | ||
| 21 | 22 | ||
| 22 | 23 | ||
| 23 | 24 | ||
| @@ -115,8 +116,9 @@ void ContextImpl::handleCopyRequests() { | |||
| 115 | // Don't even call memcpy on a length of 0 to avoid issues with the pointer | 116 | // Don't even call memcpy on a length of 0 to avoid issues with the pointer |
| 116 | // possibly being null. | 117 | // possibly being null. |
| 117 | if (request.length > 0) { | 118 | if (request.length > 0) { |
| 118 | - // Perform copy. | 119 | + // Perform copy. |
| 119 | - std::memcpy(request.localPtr, request.remotePtr, request.length); | 120 | + const auto ret = memcpy_s(request.localPtr, request.length, request.remotePtr, request.length); |
| 121 | + TP_THROW_ASSERT_IF(ret != EOK) << "context_impl.cc handleCopyRequests memcpy_s is failed!"; | ||
| 120 | } | 122 | } |
| 121 | 123 | ||
| 122 | request.callback(Error::kSuccess); | 124 | request.callback(Error::kSuccess); |
| @@ -11,6 +11,7 @@ | |||
| 11 | 11 | ||
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | + | ||
DY torch_npu和op-plugin后续也需要引入吗? ![]() ![]() | |||
| 14 | 15 | ||
| 15 | namespace tensorpipe_npu { | 16 | namespace tensorpipe_npu { |
| 16 | 17 | ||
| @@ -43,13 +44,13 @@ struct IbvAddress makeIbvAddress( | |||
| 43 | uint8_t portNum, | 44 | uint8_t portNum, |
| 44 | uint8_t globalIdentifierIndex) { | 45 | uint8_t globalIdentifierIndex) { |
| 45 | struct IbvAddress addr; | 46 | struct IbvAddress addr; |
| 46 | - std::memset(&addr, 0, sizeof(addr)); | 47 | + memset_s(&addr, sizeof(addr), 0, sizeof(addr)); |
| 47 | 48 | ||
| 48 | addr.portNum = portNum; | 49 | addr.portNum = portNum; |
| 49 | addr.globalIdentifierIndex = globalIdentifierIndex; | 50 | addr.globalIdentifierIndex = globalIdentifierIndex; |
| 50 | 51 | ||
| 51 | IbvLib::port_attr portAttr; | 52 | IbvLib::port_attr portAttr; |
| 52 | - std::memset(&portAttr, 0, sizeof(portAttr)); | 53 | + memset_s(&portAttr, sizeof(portAttr), 0, sizeof(portAttr)); |
| 53 | TP_CHECK_IBV_INT(ibvLib.query_port(context.get(), portNum, &portAttr)); | 54 | TP_CHECK_IBV_INT(ibvLib.query_port(context.get(), portNum, &portAttr)); |
| 54 | addr.localIdentifier = portAttr.lid; | 55 | addr.localIdentifier = portAttr.lid; |
| 55 | addr.maximumTransmissionUnit = portAttr.active_mtu; | 56 | addr.maximumTransmissionUnit = portAttr.active_mtu; |
| @@ -65,7 +66,7 @@ struct IbvSetupInformation makeIbvSetupInformation( | |||
| 65 | const IbvAddress& addr, | 66 | const IbvAddress& addr, |
| 66 | const IbvQueuePair& qp) { | 67 | const IbvQueuePair& qp) { |
| 67 | struct IbvSetupInformation info; | 68 | struct IbvSetupInformation info; |
| 68 | - std::memset(&info, 0, sizeof(info)); | 69 | + memset_s(&info, sizeof(info), 0, sizeof(info)); |
| 69 | 70 | ||
| 70 | info.localIdentifier = addr.localIdentifier; | 71 | info.localIdentifier = addr.localIdentifier; |
| 71 | info.globalIdentifier = addr.globalIdentifier; | 72 | info.globalIdentifier = addr.globalIdentifier; |
| @@ -81,7 +82,7 @@ void transitionIbvQueuePairToInit( | |||
| 81 | IbvQueuePair& qp, | 82 | IbvQueuePair& qp, |
| 82 | const IbvAddress& selfAddr) { | 83 | const IbvAddress& selfAddr) { |
| 83 | IbvLib::qp_attr attr; | 84 | IbvLib::qp_attr attr; |
| 84 | - std::memset(&attr, 0, sizeof(attr)); | 85 | + memset_s(&attr, sizeof(attr), 0, sizeof(attr)); |
| 85 | int attrMask = 0; | 86 | int attrMask = 0; |
| 86 | 87 | ||
| 87 | attrMask |= IbvLib::QP_STATE; | 88 | attrMask |= IbvLib::QP_STATE; |
| @@ -109,7 +110,7 @@ void transitionIbvQueuePairToReadyToReceive( | |||
| 109 | const IbvAddress& selfAddr, | 110 | const IbvAddress& selfAddr, |
| 110 | const IbvSetupInformation& destinationInfo) { | 111 | const IbvSetupInformation& destinationInfo) { |
| 111 | IbvLib::qp_attr attr; | 112 | IbvLib::qp_attr attr; |
| 112 | - std::memset(&attr, 0, sizeof(attr)); | 113 | + memset_s(&attr, sizeof(attr), 0, sizeof(attr)); |
| 113 | int attrMask = 0; | 114 | int attrMask = 0; |
| 114 | 115 | ||
| 115 | attrMask |= IbvLib::QP_STATE; | 116 | attrMask |= IbvLib::QP_STATE; |
| @@ -154,7 +155,7 @@ void transitionIbvQueuePairToReadyToSend( | |||
| 154 | const IbvLib& ibvLib, | 155 | const IbvLib& ibvLib, |
| 155 | IbvQueuePair& qp) { | 156 | IbvQueuePair& qp) { |
| 156 | IbvLib::qp_attr attr; | 157 | IbvLib::qp_attr attr; |
| 157 | - std::memset(&attr, 0, sizeof(attr)); | 158 | + memset_s(&attr, sizeof(attr), 0, sizeof(attr)); |
| 158 | int attrMask = 0; | 159 | int attrMask = 0; |
| 159 | 160 | ||
| 160 | attrMask |= IbvLib::QP_STATE; | 161 | attrMask |= IbvLib::QP_STATE; |
| @@ -182,7 +183,7 @@ void transitionIbvQueuePairToReadyToSend( | |||
| 182 | 183 | ||
| 183 | void transitionIbvQueuePairToError(const IbvLib& ibvLib, IbvQueuePair& qp) { | 184 | void transitionIbvQueuePairToError(const IbvLib& ibvLib, IbvQueuePair& qp) { |
| 184 | IbvLib::qp_attr attr; | 185 | IbvLib::qp_attr attr; |
| 185 | - std::memset(&attr, 0, sizeof(attr)); | 186 | + memset_s(&attr, sizeof(attr), 0, sizeof(attr)); |
| 186 | int attrMask = 0; | 187 | int attrMask = 0; |
| 187 | 188 | ||
| 188 | attrMask |= IbvLib::QP_STATE; | 189 | attrMask |= IbvLib::QP_STATE; |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| @@ -94,18 +94,22 @@ class NopReader final { | |||
| 94 | reinterpret_cast<uint8_t*>(end) - reinterpret_cast<uint8_t*>(begin); | 94 | reinterpret_cast<uint8_t*>(end) - reinterpret_cast<uint8_t*>(begin); |
| 95 | 95 | ||
| 96 | if (unlikely(len1_ < size)) { | 96 | if (unlikely(len1_ < size)) { |
| 97 | - std::memcpy(begin, ptr1_, len1_); | 97 | + const auto ret = memcpy_s(begin, len1_, ptr1_, len1_); |
| 98 | - begin = reinterpret_cast<uint8_t*>(begin) + len1_; | 98 | + TP_THROW_ASSERT_IF(ret != EOK) << " nop.h Read memcpy_s is failed!"; |
| 99 | - size -= len1_; | 99 | + begin = reinterpret_cast<uint8_t*>(begin) + len1_; |
| 100 | - ptr1_ = ptr2_; | 100 | + size -= len1_; |
| 101 | - len1_ = len2_; | 101 | + ptr1_ = ptr2_; |
| 102 | - ptr2_ = nullptr; | 102 | + len1_ = len2_; |
| 103 | - len2_ = 0; | 103 | + ptr2_ = nullptr; |
| 104 | + len2_ = 0; | ||
| 104 | } | 105 | } |
| 105 | 106 | ||
| 106 | TP_THROW_ASSERT_IF(size > len1_) << "Buffer underflow: no data available to read."; | 107 | TP_THROW_ASSERT_IF(size > len1_) << "Buffer underflow: no data available to read."; |
| 107 | 108 | ||
| 108 | - std::memcpy(begin, ptr1_, size); | 109 | + const auto ret = memcpy_s(begin, len1_, ptr1_, size); |
| 110 | + if (len1_ != 0) { | ||
| 111 | + TP_THROW_ASSERT_IF(ret != EOK) << " nop.h Read memcpy_s is failed!"; | ||
| 112 | + } | ||
| 109 | ptr1_ += size; | 113 | ptr1_ += size; |
| 110 | len1_ -= size; | 114 | len1_ -= size; |
| 111 | return nop::ErrorStatus::None; | 115 | return nop::ErrorStatus::None; |
| @@ -175,18 +179,22 @@ class NopWriter final { | |||
| 175 | reinterpret_cast<const uint8_t*>(begin); | 179 | reinterpret_cast<const uint8_t*>(begin); |
| 176 | 180 | ||
| 177 | if (unlikely(len1_ < size)) { | 181 | if (unlikely(len1_ < size)) { |
| 178 | - std::memcpy(ptr1_, begin, len1_); | 182 | + const auto ret = memcpy_s(ptr1_, len1_, begin, len1_); |
| 179 | - begin = reinterpret_cast<const uint8_t*>(begin) + len1_; | 183 | + TP_THROW_ASSERT_IF(ret != EOK) << " nop.h Write memcpy_s is failed!"; |
| 180 | - size -= len1_; | 184 | + begin = reinterpret_cast<const uint8_t*>(begin) + len1_; |
| 181 | - ptr1_ = ptr2_; | 185 | + size -= len1_; |
| 182 | - len1_ = len2_; | 186 | + ptr1_ = ptr2_; |
| 183 | - ptr2_ = nullptr; | 187 | + len1_ = len2_; |
| 184 | - len2_ = 0; | 188 | + ptr2_ = nullptr; |
| 189 | + len2_ = 0; | ||
| 185 | } | 190 | } |
| 186 | 191 | ||
| 187 | TP_THROW_ASSERT_IF(size > len1_) << "Buffer overflow: no space available to write."; | 192 | TP_THROW_ASSERT_IF(size > len1_) << "Buffer overflow: no space available to write."; |
| 188 | 193 | ||
| 189 | - std::memcpy(ptr1_, begin, size); | 194 | + const auto ret = memcpy_s(ptr1_, len1_, begin, size); |
| 195 | + if (len1_ != 0) { | ||
| 196 | + TP_THROW_ASSERT_IF(ret != EOK) << " nop.h Write memcpy_s is failed!"; | ||
| 197 | + } | ||
| 190 | ptr1_ += size; | 198 | ptr1_ += size; |
| 191 | len1_ -= size; | 199 | len1_ -= size; |
| 192 | return nop::ErrorStatus::None; | 200 | return nop::ErrorStatus::None; |
| @@ -195,17 +203,17 @@ class NopWriter final { | |||
| 195 | // NOLINTNEXTLINE(readability-identifier-naming) | 203 | // NOLINTNEXTLINE(readability-identifier-naming) |
| 196 | nop::Status<void> Skip(size_t paddingBytes, uint8_t paddingValue) { | 204 | nop::Status<void> Skip(size_t paddingBytes, uint8_t paddingValue) { |
| 197 | if (unlikely(len1_ < paddingBytes)) { | 205 | if (unlikely(len1_ < paddingBytes)) { |
| 198 | - std::memset(ptr1_, paddingValue, paddingBytes); | 206 | + memset_s(ptr1_, len1_, paddingValue, paddingBytes); |
| 199 | - paddingBytes -= len1_; | 207 | + paddingBytes -= len1_; |
| 200 | - ptr1_ = ptr2_; | 208 | + ptr1_ = ptr2_; |
| 201 | - len1_ = len2_; | 209 | + len1_ = len2_; |
| 202 | - ptr2_ = nullptr; | 210 | + ptr2_ = nullptr; |
| 203 | - len2_ = 0; | 211 | + len2_ = 0; |
| 204 | } | 212 | } |
| 205 | 213 | ||
| 206 | TP_THROW_ASSERT_IF(paddingBytes > len1_) << "Buffer overflow: no space available to skip."; | 214 | TP_THROW_ASSERT_IF(paddingBytes > len1_) << "Buffer overflow: no space available to skip."; |
| 207 | 215 | ||
| 208 | - std::memset(ptr1_, paddingValue, paddingBytes); | 216 | + memset_s(ptr1_, len1_, paddingValue, paddingBytes); |
| 209 | ptr1_ += paddingBytes; | 217 | ptr1_ += paddingBytes; |
| 210 | len1_ -= paddingBytes; | 218 | len1_ -= paddingBytes; |
| 211 | return nop::ErrorStatus::None; | 219 | return nop::ErrorStatus::None; |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | namespace tensorpipe_npu { | 19 | namespace tensorpipe_npu { |
| @@ -179,15 +179,19 @@ class RingBufferRole { | |||
| 179 | // Nothing to do. | 179 | // Nothing to do. |
| 180 | return 0; | 180 | return 0; |
| 181 | } else if (likely(numBuffers == 1)) { | 181 | } else if (likely(numBuffers == 1)) { |
| 182 | - std::memcpy(buffer, buffers[0].ptr, buffers[0].len); | 182 | + const auto ret = memcpy_s(buffer, buffers[0].len, buffers[0].ptr, buffers[0].len); |
| 183 | - return buffers[0].len; | 183 | + TP_THROW_ASSERT_IF(ret != EOK) << " ringbuffer_role.h RingBufferRole#1 memcpy_s is failed!"; |
| 184 | + return buffers[0].len; | ||
| 184 | } else if (likely(numBuffers == 2)) { | 185 | } else if (likely(numBuffers == 2)) { |
| 185 | - std::memcpy(buffer, buffers[0].ptr, buffers[0].len); | 186 | + auto ret = memcpy_s(buffer, buffers[0].len, buffers[0].ptr, buffers[0].len); |
| 186 | - std::memcpy( | 187 | + TP_THROW_ASSERT_IF(ret != EOK) << " ringbuffer_role.h RingBufferRole#2 memcpy_s is failed!"; |
| 187 | - reinterpret_cast<uint8_t*>(buffer) + buffers[0].len, | 188 | + ret = memcpy_s( |
| 188 | - buffers[1].ptr, | 189 | + reinterpret_cast<uint8_t*>(buffer) + buffers[0].len, |
| 189 | - buffers[1].len); | 190 | + buffers[1].len, |
| 190 | - return buffers[0].len + buffers[1].len; | 191 | + buffers[1].ptr, |
| 192 | + buffers[1].len); | ||
| 193 | + TP_THROW_ASSERT_IF(ret != EOK) << " ringbuffer_role.h RingBufferRole#3 memcpy_s is failed!"; | ||
| 194 | + return buffers[0].len + buffers[1].len; | ||
| 191 | } else { | 195 | } else { |
| 192 | TP_THROW_ASSERT() << "Bad number of buffers: " << numBuffers; | 196 | TP_THROW_ASSERT() << "Bad number of buffers: " << numBuffers; |
| 193 | // Dummy return to make the compiler happy. | 197 | // Dummy return to make the compiler happy. |
| @@ -213,14 +217,18 @@ class RingBufferRole { | |||
| 213 | // Nothing to do. | 217 | // Nothing to do. |
| 214 | return 0; | 218 | return 0; |
| 215 | } else if (likely(numBuffers == 1)) { | 219 | } else if (likely(numBuffers == 1)) { |
| 216 | - std::memcpy(buffers[0].ptr, buffer, buffers[0].len); | 220 | + const auto ret = memcpy_s(buffers[0].ptr, buffers[0].len, buffer, buffers[0].len); |
| 221 | + TP_THROW_ASSERT_IF(ret != EOK) << " ringbuffer_role.h RingBufferRole#4 memcpy_s is failed!"; | ||
| 217 | return buffers[0].len; | 222 | return buffers[0].len; |
| 218 | } else if (likely(numBuffers == 2)) { | 223 | } else if (likely(numBuffers == 2)) { |
| 219 | - std::memcpy(buffers[0].ptr, buffer, buffers[0].len); | 224 | + auto ret = memcpy_s(buffers[0].ptr, buffers[0].len, buffer, buffers[0].len); |
| 220 | - std::memcpy( | 225 | + TP_THROW_ASSERT_IF(ret != EOK) << " ringbuffer_role.h RingBufferRole#5 memcpy_s is failed!"; |
| 226 | + ret = memcpy_s( | ||
| 221 | buffers[1].ptr, | 227 | buffers[1].ptr, |
| 228 | + buffers[1].len, | ||
| 222 | reinterpret_cast<const uint8_t*>(buffer) + buffers[0].len, | 229 | reinterpret_cast<const uint8_t*>(buffer) + buffers[0].len, |
| 223 | buffers[1].len); | 230 | buffers[1].len); |
| 231 | + TP_THROW_ASSERT_IF(ret != EOK) << " ringbuffer_role.h RingBufferRole#6 memcpy_s is failed!"; | ||
| 224 | TP_THROW_ASSERT_IF(buffers[0].len > SIZE_MAX - buffers[1].len) << "Integer overflow in calculation."; | 232 | TP_THROW_ASSERT_IF(buffers[0].len > SIZE_MAX - buffers[1].len) << "Integer overflow in calculation."; |
| 225 | return buffers[0].len + buffers[1].len; | 233 | return buffers[0].len + buffers[1].len; |
| 226 | } else { | 234 | } else { |
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | - | 17 | +#include <securec.h> |
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | 20 | ||
| @@ -37,7 +37,7 @@ int main(int argc, char* argv[]) { | |||
| 37 | TP_THROW_SYSTEM_IF(fd < 0, errno); | 37 | TP_THROW_SYSTEM_IF(fd < 0, errno); |
| 38 | 38 | ||
| 39 | struct sockaddr_un socketAddr; | 39 | struct sockaddr_un socketAddr; |
| 40 | - std::memset(&socketAddr, 0, sizeof(struct sockaddr_un)); | 40 | + memset_s(&socketAddr, sizeof(socketAddr), 0, sizeof(struct sockaddr_un)); |
| 41 | socketAddr.sun_family = AF_UNIX; | 41 | socketAddr.sun_family = AF_UNIX; |
| 42 | std::strcpy(socketAddr.sun_path, argv[2]); | 42 | std::strcpy(socketAddr.sun_path, argv[2]); |
| 43 | 43 | ||
| @@ -73,7 +73,7 @@ int main(int argc, char* argv[]) { | |||
| 73 | } | 73 | } |
| 74 | 74 | ||
| 75 | struct ucred peerCreds; | 75 | struct ucred peerCreds; |
| 76 | - std::memset(&peerCreds, 0, sizeof(struct ucred)); | 76 | + memset_s(&peerCreds, sizeof(peerCreds), 0, sizeof(struct ucred)); |
| 77 | socklen_t peerCredsLen = sizeof(struct ucred); | 77 | socklen_t peerCredsLen = sizeof(struct ucred); |
| 78 | rv = ::getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peerCreds, &peerCredsLen); | 78 | rv = ::getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &peerCreds, &peerCredsLen); |
| 79 | 79 | ||
| @@ -100,11 +100,11 @@ int main(int argc, char* argv[]) { | |||
| 100 | 100 | ||
| 101 | uint64_t inbox; | 101 | uint64_t inbox; |
| 102 | struct iovec localIov; | 102 | struct iovec localIov; |
| 103 | - std::memset(&localIov, 0, sizeof(struct iovec)); | 103 | + memset_s(&localIov, sizeof(localIov), 0, sizeof(struct iovec)); |
| 104 | localIov.iov_base = &inbox; | 104 | localIov.iov_base = &inbox; |
| 105 | localIov.iov_len = sizeof(uint64_t); | 105 | localIov.iov_len = sizeof(uint64_t); |
| 106 | struct iovec remoteIov; | 106 | struct iovec remoteIov; |
| 107 | - std::memset(&remoteIov, 0, sizeof(struct iovec)); | 107 | + memset_s(&remoteIov, sizeof(remoteIov), 0, sizeof(struct iovec)); |
| 108 | remoteIov.iov_base = peerOutboxPtr; | 108 | remoteIov.iov_base = peerOutboxPtr; |
| 109 | remoteIov.iov_len = sizeof(uint64_t); | 109 | remoteIov.iov_len = sizeof(uint64_t); |
| 110 | 110 | ||
| @@ -13,6 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | + | ||
| 16 | 17 | ||
| 17 | 18 | ||
| 18 | 19 | ||
| @@ -55,7 +56,8 @@ inline std::pair<tensorpipe_npu::Message, Storage> makeMessage( | |||
| 55 | size_t length = payload.data.length(); | 56 | size_t length = payload.data.length(); |
| 56 | auto data = std::unique_ptr<uint8_t, std::default_delete<uint8_t[]>>( | 57 | auto data = std::unique_ptr<uint8_t, std::default_delete<uint8_t[]>>( |
| 57 | new uint8_t[length]); | 58 | new uint8_t[length]); |
| 58 | - std::memcpy(data.get(), &payload.data[0], length); | 59 | + const auto ret = memcpy_s(data.get(), length, &payload.data[0], length); |
| 60 | + TP_THROW_ASSERT_IF(ret != EOK) << " pipe_test.h makeMessage#1 memcpy_s is failed!"; | ||
| 59 | message.payloads.push_back({ | 61 | message.payloads.push_back({ |
| 60 | .data = data.get(), | 62 | .data = data.get(), |
| 61 | .length = length, | 63 | .length = length, |
| @@ -69,10 +71,11 @@ inline std::pair<tensorpipe_npu::Message, Storage> makeMessage( | |||
| 69 | tensorpipe_npu::Buffer buffer; | 71 | tensorpipe_npu::Buffer buffer; |
| 70 | std::shared_ptr<void> data; | 72 | std::shared_ptr<void> data; |
| 71 | if (tensor.device.type == tensorpipe_npu::kCpuDeviceType) { | 73 | if (tensor.device.type == tensorpipe_npu::kCpuDeviceType) { |
| 72 | - data = std::unique_ptr<uint8_t, std::default_delete<uint8_t[]>>( | 74 | + data = std::unique_ptr<uint8_t, std::default_delete<uint8_t[]>>( |
| 73 | - new uint8_t[length]); | 75 | + new uint8_t[length]); |
| 74 | - std::memcpy(data.get(), &tensor.data[0], length); | 76 | + const auto ret = memcpy_s(data.get(), length, &tensor.data[0], length); |
| 75 | - buffer = tensorpipe_npu::CpuBuffer{.ptr = data.get()}; | 77 | + TP_THROW_ASSERT_IF(ret != EOK) << " pipe_test.h makeMessage#2 memcpy_s is failed!"; |
| 78 | + buffer = tensorpipe_npu::CpuBuffer{.ptr = data.get()}; | ||
| 76 | } else { | 79 | } else { |
| 77 | ADD_FAILURE() << "Unexpected source device: " << tensor.device.toString(); | 80 | ADD_FAILURE() << "Unexpected source device: " << tensor.device.toString(); |
| 78 | } | 81 | } |
| @@ -9,7 +9,7 @@ | |||
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | 11 | ||
| 12 | - | 12 | +#include <securec.h> |
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | using namespace tensorpipe_npu::transport; | 15 | using namespace tensorpipe_npu::transport; |
| @@ -116,7 +116,7 @@ TEST(IbvSockaddr, Inet6) { | |||
| 116 | 116 | ||
| 117 | { | 117 | { |
| 118 | sockaddr_in6 sa; | 118 | sockaddr_in6 sa; |
| 119 | - std::memset(&sa, 0, sizeof(sa)); | 119 | + memset_s(&sa, sizeof(sa), 0, sizeof(sa)); |
| 120 | sa.sin6_family = AF_INET6; | 120 | sa.sin6_family = AF_INET6; |
| 121 | sa.sin6_port = ntohs(42); | 121 | sa.sin6_port = ntohs(42); |
| 122 | sa.sin6_flowinfo = 0; | 122 | sa.sin6_flowinfo = 0; |
| @@ -116,7 +116,7 @@ TEST(UvSockaddr, Inet6) { | |||
| 116 | 116 | ||
| 117 | { | 117 | { |
| 118 | sockaddr_in6 sa; | 118 | sockaddr_in6 sa; |
| 119 | - std::memset(&sa, 0, sizeof(sa)); | 119 | + memset_s(&sa, sizeof(sa), 0, sizeof(sa)); |
| 120 | sa.sin6_family = AF_INET6; | 120 | sa.sin6_family = AF_INET6; |
| 121 | sa.sin6_port = ntohs(42); | 121 | sa.sin6_port = ntohs(42); |
| 122 | sa.sin6_flowinfo = 0; | 122 | sa.sin6_flowinfo = 0; |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| @@ -132,7 +132,7 @@ void ConnectionImpl::initImplFromLoop() { | |||
| 132 | // Create and init queue pair. | 132 | // Create and init queue pair. |
| 133 | { | 133 | { |
| 134 | IbvLib::qp_init_attr initAttr; | 134 | IbvLib::qp_init_attr initAttr; |
| 135 | - std::memset(&initAttr, 0, sizeof(initAttr)); | 135 | + memset_s(&initAttr, sizeof(initAttr), 0, sizeof(initAttr)); |
| 136 | initAttr.qp_type = IbvLib::QPT_RC; | 136 | initAttr.qp_type = IbvLib::QPT_RC; |
| 137 | initAttr.send_cq = context_->getReactor().getIbvCq().get(); | 137 | initAttr.send_cq = context_->getReactor().getIbvCq().get(); |
| 138 | initAttr.recv_cq = context_->getReactor().getIbvCq().get(); | 138 | initAttr.recv_cq = context_->getReactor().getIbvCq().get(); |
| @@ -8,7 +8,7 @@ | |||
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | 10 | ||
| 11 | - | 11 | +#include <securec.h> |
| 12 | 12 | ||
| 13 | 13 | ||
| 14 | 14 | ||
| @@ -30,7 +30,7 @@ Reactor::Reactor(IbvLib ibvLib, IbvDeviceList deviceList) | |||
| 30 | /*comp_vector=*/0); | 30 | /*comp_vector=*/0); |
| 31 | 31 | ||
| 32 | IbvLib::srq_init_attr srqInitAttr; | 32 | IbvLib::srq_init_attr srqInitAttr; |
| 33 | - std::memset(&srqInitAttr, 0, sizeof(srqInitAttr)); | 33 | + memset_s(&srqInitAttr, sizeof(srqInitAttr), 0, sizeof(srqInitAttr)); |
| 34 | srqInitAttr.attr.max_wr = kNumPendingRecvReqs; | 34 | srqInitAttr.attr.max_wr = kNumPendingRecvReqs; |
| 35 | srq_ = createIbvSharedReceiveQueue(getIbvLib(), pd_, srqInitAttr); | 35 | srq_ = createIbvSharedReceiveQueue(getIbvLib(), pd_, srqInitAttr); |
| 36 | 36 | ||
| @@ -45,7 +45,7 @@ void Reactor::postRecvRequestsOnSRQ(int num) { | |||
| 45 | while (num > 0) { | 45 | while (num > 0) { |
| 46 | IbvLib::recv_wr* badRecvWr = nullptr; | 46 | IbvLib::recv_wr* badRecvWr = nullptr; |
| 47 | std::array<IbvLib::recv_wr, kNumPolledWorkCompletions> wrs; | 47 | std::array<IbvLib::recv_wr, kNumPolledWorkCompletions> wrs; |
| 48 | - std::memset(wrs.data(), 0, sizeof(wrs)); | 48 | + memset_s(wrs.data(), sizeof(wrs), 0, sizeof(wrs)); |
| 49 | for (int i = 0; i < std::min(num, kNumPolledWorkCompletions) - 1; i++) { | 49 | for (int i = 0; i < std::min(num, kNumPolledWorkCompletions) - 1; i++) { |
| 50 | wrs[i].next = &wrs[i + 1]; | 50 | wrs[i].next = &wrs[i + 1]; |
| 51 | } | 51 | } |
| @@ -177,7 +177,7 @@ void Reactor::postWrite(IbvQueuePair& qp, WriteInfo info) { | |||
| 177 | list.lkey = info.lkey; | 177 | list.lkey = info.lkey; |
| 178 | 178 | ||
| 179 | IbvLib::send_wr wr; | 179 | IbvLib::send_wr wr; |
| 180 | - std::memset(&wr, 0, sizeof(wr)); | 180 | + memset_s(&wr, sizeof(wr), 0, sizeof(wr)); |
| 181 | wr.wr_id = kWriteRequestId; | 181 | wr.wr_id = kWriteRequestId; |
| 182 | wr.sg_list = &list; | 182 | wr.sg_list = &list; |
| 183 | wr.num_sge = 1; | 183 | wr.num_sge = 1; |
| @@ -202,7 +202,7 @@ void Reactor::postWrite(IbvQueuePair& qp, WriteInfo info) { | |||
| 202 | void Reactor::postAck(IbvQueuePair& qp, AckInfo info) { | 202 | void Reactor::postAck(IbvQueuePair& qp, AckInfo info) { |
| 203 | if (numAvailableAcks_ > 0) { | 203 | if (numAvailableAcks_ > 0) { |
| 204 | IbvLib::send_wr wr; | 204 | IbvLib::send_wr wr; |
| 205 | - std::memset(&wr, 0, sizeof(wr)); | 205 | + memset_s(&wr, sizeof(wr), 0, sizeof(wr)); |
| 206 | wr.wr_id = kAckRequestId; | 206 | wr.wr_id = kAckRequestId; |
| 207 | wr.opcode = IbvLib::WR_SEND_WITH_IMM; | 207 | wr.opcode = IbvLib::WR_SEND_WITH_IMM; |
| 208 | wr.imm_data = info.length; | 208 | wr.imm_data = info.length; |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| @@ -69,7 +69,7 @@ Sockaddr Sockaddr::createInetSockAddr(const std::string& str) { | |||
| 69 | // Try to convert an IPv4 address. | 69 | // Try to convert an IPv4 address. |
| 70 | { | 70 | { |
| 71 | struct sockaddr_in addr; | 71 | struct sockaddr_in addr; |
| 72 | - std::memset(&addr, 0, sizeof(addr)); | 72 | + memset_s(&addr, sizeof(addr), 0, sizeof(addr)); |
| 73 | auto rv = inet_pton(AF_INET, addrStr.c_str(), &addr.sin_addr); | 73 | auto rv = inet_pton(AF_INET, addrStr.c_str(), &addr.sin_addr); |
| 74 | TP_THROW_SYSTEM_IF(rv < 0, errno); | 74 | TP_THROW_SYSTEM_IF(rv < 0, errno); |
| 75 | if (rv == 1) { | 75 | if (rv == 1) { |
| @@ -82,7 +82,7 @@ Sockaddr Sockaddr::createInetSockAddr(const std::string& str) { | |||
| 82 | // Try to convert an IPv6 address. | 82 | // Try to convert an IPv6 address. |
| 83 | { | 83 | { |
| 84 | struct sockaddr_in6 addr; | 84 | struct sockaddr_in6 addr; |
| 85 | - std::memset(&addr, 0, sizeof(addr)); | 85 | + memset_s(&addr, sizeof(addr), 0, sizeof(addr)); |
| 86 | 86 | ||
| 87 | auto interfacePos = addrStr.find('%'); | 87 | auto interfacePos = addrStr.find('%'); |
| 88 | if (interfacePos != std::string::npos) { | 88 | if (interfacePos != std::string::npos) { |
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | namespace tensorpipe_npu { | 19 | namespace tensorpipe_npu { |
| @@ -29,8 +29,9 @@ class Sockaddr final : public tensorpipe_npu::Sockaddr { | |||
| 29 | TP_ARG_CHECK_LE(addrlen, sizeof(addr_)); | 29 | TP_ARG_CHECK_LE(addrlen, sizeof(addr_)); |
| 30 | // Ensure the sockaddr_storage is zeroed, because we don't always | 30 | // Ensure the sockaddr_storage is zeroed, because we don't always |
| 31 | // write to all fields in the `sockaddr_[in|in6]` structures. | 31 | // write to all fields in the `sockaddr_[in|in6]` structures. |
| 32 | - std::memset(&addr_, 0, sizeof(addr_)); | 32 | + memset_s(&addr_, sizeof(addr_), 0, sizeof(addr_)); |
| 33 | - std::memcpy(&addr_, addr, addrlen); | 33 | + const auto ret = memcpy_s(&addr_, sizeof(addr_), addr, addrlen); |
| 34 | + TP_THROW_ASSERT_IF(ret != EOK) << " sockaddr.h Sockaddr memcpy_s is failed!"; | ||
| 34 | addrlen_ = addrlen; | 35 | addrlen_ = addrlen; |
| 35 | } | 36 | } |
| 36 | 37 | ||
| @@ -24,7 +24,7 @@ | |||
| 24 | 24 | ||
| 25 | 25 | ||
| 26 | 26 | ||
| 27 | - | 27 | +#include <securec.h> |
| 28 | 28 | ||
| 29 | 29 | ||
| 30 | 30 | ||
| @@ -76,7 +76,7 @@ using AddressInfo = std::unique_ptr<struct addrinfo, AddressInfoDeleter>; | |||
| 76 | 76 | ||
| 77 | std::tuple<Error, AddressInfo> createAddressInfo(std::string host) { | 77 | std::tuple<Error, AddressInfo> createAddressInfo(std::string host) { |
| 78 | struct addrinfo hints; | 78 | struct addrinfo hints; |
| 79 | - std::memset(&hints, 0, sizeof(hints)); | 79 | + memset_s(&hints, sizeof(hints), 0, sizeof(hints)); |
| 80 | hints.ai_family = AF_UNSPEC; | 80 | hints.ai_family = AF_UNSPEC; |
| 81 | hints.ai_socktype = SOCK_STREAM; | 81 | hints.ai_socktype = SOCK_STREAM; |
| 82 | hints.ai_protocol = IPPROTO_TCP; | 82 | hints.ai_protocol = IPPROTO_TCP; |
| @@ -14,7 +14,7 @@ | |||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | - | 17 | +#include <securec.h> |
| 18 | 18 | ||
| 19 | 19 | ||
| 20 | namespace tensorpipe_npu { | 20 | namespace tensorpipe_npu { |
| @@ -24,7 +24,7 @@ namespace shm { | |||
| 24 | Sockaddr Sockaddr::createAbstractUnixAddr(const std::string& name) { | 24 | Sockaddr Sockaddr::createAbstractUnixAddr(const std::string& name) { |
| 25 | struct sockaddr_un sun; | 25 | struct sockaddr_un sun; |
| 26 | sun.sun_family = AF_UNIX; | 26 | sun.sun_family = AF_UNIX; |
| 27 | - std::memset(&sun.sun_path, 0, sizeof(sun.sun_path)); | 27 | + memset_s(&sun.sun_path, sizeof(sun.sun_path), 0, sizeof(sun.sun_path)); |
| 28 | // There are three "modes" for binding UNIX domain sockets: | 28 | // There are three "modes" for binding UNIX domain sockets: |
| 29 | // - if len(path) == 0: it autobinds to an abstract address | 29 | // - if len(path) == 0: it autobinds to an abstract address |
| 30 | // - if len(path) > 0 and path[0] == 0: it uses an explicit abstract address | 30 | // - if len(path) > 0 and path[0] == 0: it uses an explicit abstract address |
| @@ -51,8 +51,9 @@ Sockaddr Sockaddr::createAbstractUnixAddr(const std::string& name) { | |||
| 51 | Sockaddr::Sockaddr(const struct sockaddr* addr, socklen_t addrlen) { | 51 | Sockaddr::Sockaddr(const struct sockaddr* addr, socklen_t addrlen) { |
| 52 | TP_ARG_CHECK(addr != nullptr); | 52 | TP_ARG_CHECK(addr != nullptr); |
| 53 | TP_ARG_CHECK_LE(addrlen, sizeof(addr_)); | 53 | TP_ARG_CHECK_LE(addrlen, sizeof(addr_)); |
| 54 | - std::memset(&addr_, 0, sizeof(addr_)); | 54 | + memset_s(&addr_, sizeof(addr_), 0, sizeof(addr_)); |
| 55 | - std::memcpy(&addr_, addr, addrlen); | 55 | + const auto ret = memcpy_s(&addr_, sizeof(addr_), addr, addrlen); |
| 56 | + TP_THROW_ASSERT_IF(ret != EOK) << "sockaddr.cc Sockaddr memcpy_s is failed!"; | ||
| 56 | addrlen_ = addrlen; | 57 | addrlen_ = addrlen; |
| 57 | } | 58 | } |
| 58 | 59 | ||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | namespace tensorpipe_npu { | 19 | namespace tensorpipe_npu { |
| @@ -29,8 +29,9 @@ class Sockaddr final : public tensorpipe_npu::Sockaddr { | |||
| 29 | TP_ARG_CHECK_LE(addrlen, sizeof(addr_)); | 29 | TP_ARG_CHECK_LE(addrlen, sizeof(addr_)); |
| 30 | // Ensure the sockaddr_storage is zeroed, because we don't always | 30 | // Ensure the sockaddr_storage is zeroed, because we don't always |
| 31 | // write to all fields in the `sockaddr_[in|in6]` structures. | 31 | // write to all fields in the `sockaddr_[in|in6]` structures. |
| 32 | - std::memset(&addr_, 0, sizeof(addr_)); | 32 | + memset_s(&addr_, sizeof(addr_), 0, sizeof(addr_)); |
| 33 | - std::memcpy(&addr_, addr, addrlen); | 33 | + const auto ret = memcpy_s(&addr_, sizeof(addr_), addr, addrlen); |
| 34 | + TP_THROW_ASSERT_IF(ret != EOK) << "sockaddr.h Sockaddr memcpy_s is failed!"; | ||
| 34 | addrlen_ = addrlen; | 35 | addrlen_ = addrlen; |
| 35 | } | 36 | } |
| 36 | 37 | ||
| @@ -13,7 +13,7 @@ | |||
| 13 | 13 | ||
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | - | 16 | +#include <securec.h> |
| 17 | 17 | ||
| 18 | 18 | ||
| 19 | 19 | ||
| @@ -311,7 +311,7 @@ inline std::tuple<int, Addrinfo> getAddrinfoFromLoop( | |||
| 311 | uv_loop_t* loop, | 311 | uv_loop_t* loop, |
| 312 | std::string hostname) { | 312 | std::string hostname) { |
| 313 | struct addrinfo hints; | 313 | struct addrinfo hints; |
| 314 | - std::memset(&hints, 0, sizeof(hints)); | 314 | + memset_s(&hints, sizeof(hints), 0, sizeof(hints)); |
| 315 | hints.ai_family = AF_UNSPEC; | 315 | hints.ai_family = AF_UNSPEC; |
| 316 | hints.ai_socktype = SOCK_STREAM; | 316 | hints.ai_socktype = SOCK_STREAM; |
| 317 | hints.ai_protocol = IPPROTO_TCP; | 317 | hints.ai_protocol = IPPROTO_TCP; |


已修改