简体   繁体   English

strncpy被__strncpy_chk替换并失败

[英]strncpy is replaced by __strncpy_chk and fails

I have a statement 我有一个声明

strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);

in my application which itself is fine and works well. 在我的应用程序中,它本身很好并且运行良好。 Here data->m_bin->data is a char where the calling application ensures it is followed by a datablock which is large enough to keep all the data handed over by strncpy(). 这里data-> m_bin-> data是一个char,调用应用程序确保它后跟一个数据块,该数据块足够大,可以保留strncpy()移交的所有数据。

But when I build this as release using GCC/Linux, this function crashes in __strncpy_chk(). 但是,当我使用GCC / Linux构建此版本时,此函数在__strncpy_chk()中崩溃。 So it seems my strncpy() was replaced by __strncpy_chk() using a wrong length for parameter s1. 因此,似乎我的strncpy()被__strncpy_chk()替换为参数s1使用了错误的长度。

So how can I ensure __strncpy_chk() is called with the correct length for s1? 那么如何确保使用正确的s1长度调用__strncpy_chk()?

Thanks! 谢谢!

Here data->m_bin->data is a char where the calling application ensures it is followed by a datablock which is large enough to keep all the data handed over by strncpy(). 这里data-> m_bin-> data是一个char,调用应用程序确保它后跟一个数据块,该数据块足够大,可以保留strncpy()移交的所有数据。

It is unusual that this results in a valid C program. 这导致有效的C程序是不寻常的。 Pointer provenance rules usually imply that this leads to undefined behavior. 指针出处规则通常意味着这会导致未定义的行为。

If the char is at the end of a struct, it may be possible to use a flexible array member, to make it clearer to the compiler what the intent is. 如果char位于结构的末尾,则可以使用灵活的数组成员,以使编译器更清楚意图是什么。

If you do not want to change your sources, you can compile with -U_FORTIFY_SOURCE or -D_FORTIFY_SOURCE=0 . 如果您不想更改源,可以使用-U_FORTIFY_SOURCE-D_FORTIFY_SOURCE=0进行编译。 This will disable the replacement of strncpy with the fortified version. 这将禁用强化版本替换strncpy

strncpy(&data->m_bin->data,versionStr,data->m_bin->sizeData);

The address of operator looks suspicious to me. 操作员的address of对我来说很可疑。 I would expect something like: 我希望有类似的东西:

strncpy(data->m_bin->data,versionStr,data->m_bin->sizeData);

Or maybe: 或者可能:

strncpy(&data->m_bin->data[0],versionStr,data->m_bin->sizeData);

how can I ensure __strncpy_chk() is called with the correct length for s1? 如何确保使用正确的s1长度调用__strncpy_chk()

Well, you can't per se . 好吧,你本身不能。 This is part of FORTIFY_SOURCE and object size checking, and the destination buffer size is used when the compiler can deduce it. 这是FORTIFY_SOURCE和对象大小检查的一部分,并且在编译器可以推导出目标缓冲区大小时使用。

You could possibly do something like the following, assuming data is an array of size sizeData . 您可以执行以下操作,假设data是size sizeData数组。

/* avoid undefined behavior */
ASSERT(data->m_bin->data != NULL);
ASSERT(versionStr != NULL);
ASSERT(data->m_bin->sizeData > 0);

size_t l1 = data->m_bin->sizeData;
size_t l2 = strlen(versionStr);

/* min function */
size_t len = l1 < l2 ? l1 : l2;

/* if versionStr is shorter than len, then data will be backfilled */
strncpy(data->m_bin->data, versionStr, len);

/* NULL terminate, even if it truncates */
data->m_bin->data[data->m_bin->sizeData-1] = '\0';

You should probably turn on warnings with -Wall . 您可能应该使用-Wall打开警告。 I suspect you should get one for using the address of operator. 我怀疑你应该得到一个使用运营商的address of

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM