首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Puredata的OAuth实现

Puredata的OAuth实现
EN

Code Review用户
提问于 2022-05-05 21:24:31
回答 1查看 38关注 0票数 0

我正在为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。

代码语言:javascript
复制
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");标记为可能的缓冲区溢出,但我在这里看不到可能的溢出。我遗漏了什么?

我不能通过包含任何-、空格或其他任何组合的任意数据来触发缓冲区溢出。

EN

回答 1

Code Review用户

回答已采纳

发布于 2022-05-05 21:35:02

几乎可以肯定的是,Coverity只是在寻找strcatstrcpysprintf等的所有用途,并将它们标记为“潜在的缓冲区溢出”,而不管上下文如何。您可以通过向项目中添加一些代码来检查这些代码,这些代码可以执行一些简单且明显正确的操作,例如

代码语言:javascript
复制
char *p = malloc(10);
strcpy(p, "12345");
strcat(p, "6789");
free(p);

代码语言:javascript
复制
char *mystrdupdot(const char *s) {
    char *p = malloc(strlen(s) + 2);
    strcpy(p, s);
    return strcat(p, ".");
}

如果Coverity将strcpys或strcats标记为缓冲区溢出,那么您就得到了答案。

代码语言:javascript
复制
memset(oauth->oauth.rsa_key + strlen(oauth->oauth.rsa_key) - 1, 0x00, 1);

这是一种非常奇怪的说法

代码语言:javascript
复制
oauth->oauth.rsa_key[strlen(oauth->oauth.rsa_key)-1] = '\0';

此外,您可能应该寻找一种方法来停止每次通过这个循环重新计算strlen

票数 1
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/276336

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档