Avoid false positive out-of-bounds in writeForgottenNodePingExt#11053
Avoid false positive out-of-bounds in writeForgottenNodePingExt#11053madolson merged 5 commits intoredis:unstablefrom
Conversation
In clusterMsgPingExtForgottenNode, sizeof(name) is CLUSTER_NAMELEN, and sizeof(clusterMsgPingExtForgottenNode) is > CLUSTER_NAMELEN. Doing a (name + sizeof(clusterMsgPingExtForgottenNode)) sanitizer generates an out-of-bounds error which is a false positive in here.
|
a full daily CI: https://github.com/enjoy-binbin/redis/actions/runs/2750957825 |
|
there's something i'm still missing. we're talking of this line, right: *cursor = (clusterMsgPingExt *) (ext->name + sizeof(clusterMsgPingExtForgottenNode));
typedef struct {
char name[CLUSTER_NAMELEN]; /* Node name. */
uint64_t ttl; /* Remaining time to blacklist the node, in seconds. */
} clusterMsgPingExtForgottenNode;so if @madolson please have a look. |
|
ohh, i missed the fact it is casted to well, maybe we can declare a struct for all of that instead messing with offsets? |
|
@enjoy-binbin can you check if doing this will also solve the problem (i.e. avoid using *cursor = (clusterMsgPingExt *) (ext + sizeof(clusterMsgPingExtForgottenNode));i rather not silence warnings in that area since it has a chance to hide other issues, and that code seems dangerous so i rather not do that. |
agree. my first thinking is also use ext, but I don't really want to modify the code, it is following the writeHostnamePingExt. int writeHostnamePingExt(clusterMsgPingExt **cursor) {
/* If hostname is not set, we don't send this extension */
if (sdslen(myself->hostname) == 0) return 0;
/* Add the hostname information at the extension cursor */
clusterMsgPingExtHostname *ext = &(*cursor)->ext[0].hostname;
memcpy(ext->hostname, myself->hostname, sdslen(myself->hostname));
uint32_t extension_size = getHostnamePingExtSize();
/* Move the write cursor */
(*cursor)->type = htons(CLUSTERMSG_EXT_TYPE_HOSTNAME);
(*cursor)->length = htonl(extension_size);
/* Make sure the string is NULL terminated by adding 1 */
*cursor = (clusterMsgPingExt *) (ext->hostname + EIGHT_BYTE_ALIGN(sdslen(myself->hostname) + 1));
return extension_size;
} |
|
testing the final thing with sanitizers: |
madolson
left a comment
There was a problem hiding this comment.
Yeah, this code could probably use 1) More documentation or 2) a better approach to making sure the offsets are correct. This does look OK.
…s#11053) In clusterMsgPingExtForgottenNode, sizeof(name) is CLUSTER_NAMELEN, and sizeof(clusterMsgPingExtForgottenNode) is > CLUSTER_NAMELEN. Doing a (name + sizeof(clusterMsgPingExtForgottenNode)) sanitizer generates an out-of-bounds error which is a false positive in here
In clusterMsgPingExtForgottenNode, sizeof(name) is CLUSTER_NAMELEN,
and sizeof(clusterMsgPingExtForgottenNode) is > CLUSTER_NAMELEN.
Doing a (name + sizeof(clusterMsgPingExtForgottenNode)) sanitizer
generates an out-of-bounds error which is a false positive in here.
Reported in test-sanitizer-undefined (clang):
In this fix, we are using ext+1 instead of ext->name+sizeof(clusterMsgPingExtForgottenNode)
to avoid false positive sanitizer out-of-bounds error. Also convert writeHostnamePingExt.
introduced in #10869