我正在为Puredata ( Pd )管理一个OAuth实现,它是用C编写的。OAuth可以接受OAuth密钥,但是Pd不能用换行符发送消息,所以放置私钥将以字符串列表的形式出现,空格充当分隔符。
基本上,这个函数查看块的不同部分,并在末尾添加一个换行符或空格,这样-----BEGIN PRIVATE KEY-----将在一行中结束,而A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d 7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ将在单独的行中结束。
这里使用的一些函数、类型和常量:MAXPDSTRING:字符串的最大长度,t_atom:message part,atom_string(*t_atom src, *char dest, size_t max_length):用max_length将src转换为dest。
static char *string_create(size_t *const newl, const size_t strl) {
char *gen;
/* newl is not the length of the string, but the memory size */
(*newl) = 1 + strl;
gen = getbytes((*newl) * sizeof(char));
if (gen == NULL) {
pd_error(0, "not enough memory.");
return gen;
}
return memset(gen, 0x00, (*newl));
}
static void oauth_set_rsa_key(t_oauth *const oauth, const int argc, t_atom *const argv) {
char temp[MAXPDSTRING];
size_t rsa_key_len = 1; /* Accomodate NULL terminator */
short use_newline = 0;
for (int i = 1; i < argc; i++) {
atom_string(argv + i, temp, MAXPDSTRING);
rsa_key_len += strlen(temp) + 1; /* Each section + 1 for space or newline */
}
oauth->oauth.rsa_key = string_create(&oauth->oauth.rsa_key_len, rsa_key_len);
for (int i = 1; i < argc; i++) {
atom_string(argv + i, temp, MAXPDSTRING);
if (strncmp(temp, "-----", 5) == 0 && strlen(oauth->oauth.rsa_key) > 1) {
/* Cutoff trailing space and add newline */
memset(oauth->oauth.rsa_key + strlen(oauth->oauth.rsa_key) - 1, 0x00, 1);
strcat(oauth->oauth.rsa_key, "\n");
use_newline = 0;
}
if (strlen(temp) >= 5 && strncmp(temp + strlen(temp) - 5, "-----", 5) == 0) {
use_newline = 1;
}
strcat(oauth->oauth.rsa_key, temp);
if (i < argc - 1) {
if (use_newline == 1) {
/* This gets flagged as possible buffer overflow */
strcat(oauth->oauth.rsa_key, "\n");
} else {
/* This also */
strcat(oauth->oauth.rsa_key, " ");
}
}
}
}Coverity中的静态分析确实将strcat(oauth->oauth.rsa_key, "\n");标记为可能的缓冲区溢出,但我在这里看不到可能的溢出。我遗漏了什么?
我不能通过包含任何-、空格或其他任何组合的任意数据来触发缓冲区溢出。
发布于 2022-05-05 21:35:02
几乎可以肯定的是,Coverity只是在寻找strcat、strcpy、sprintf等的所有用途,并将它们标记为“潜在的缓冲区溢出”,而不管上下文如何。您可以通过向项目中添加一些代码来检查这些代码,这些代码可以执行一些简单且明显正确的操作,例如
char *p = malloc(10);
strcpy(p, "12345");
strcat(p, "6789");
free(p);或
char *mystrdupdot(const char *s) {
char *p = malloc(strlen(s) + 2);
strcpy(p, s);
return strcat(p, ".");
}如果Coverity将strcpys或strcats标记为缓冲区溢出,那么您就得到了答案。
memset(oauth->oauth.rsa_key + strlen(oauth->oauth.rsa_key) - 1, 0x00, 1);这是一种非常奇怪的说法
oauth->oauth.rsa_key[strlen(oauth->oauth.rsa_key)-1] = '\0';此外,您可能应该寻找一种方法来停止每次通过这个循环重新计算strlen。
https://codereview.stackexchange.com/questions/276336
复制相似问题