From: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> Instead of using asprintf(3) and heavy string formatting just manually concatenate the substitution string. Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- v2: add patch --- libselinux/src/label_file.c | 38 +++++++++++++++++++++++++------------ libselinux/src/label_file.h | 1 + 2 files changed, 27 insertions(+), 12 deletions(-) diff --git a/libselinux/src/label_file.c b/libselinux/src/label_file.c index c91a91f7..523968a6 100644 --- a/libselinux/src/label_file.c +++ b/libselinux/src/label_file.c @@ -1130,9 +1130,9 @@ static void selabel_subs_fini(struct selabel_sub *subs, uint32_t num) free(subs); } -static char *selabel_apply_subs(const struct selabel_sub *subs, uint32_t num, const char *src) +static char *selabel_apply_subs(const struct selabel_sub *subs, uint32_t num, const char *src, size_t slen) { - char *dst; + char *dst, *tmp; uint32_t len; for (uint32_t i = 0; i < num; i++) { @@ -1146,8 +1146,14 @@ static char *selabel_apply_subs(const struct selabel_sub *subs, uint32_t num, co len = ptr->slen + 1; else len = ptr->slen; - if (asprintf(&dst, "%s%s", ptr->dst, &src[len]) < 0) + + dst = malloc(ptr->dlen + slen - len + 1); + if (!dst) return NULL; + + tmp = mempcpy(dst, ptr->dst, ptr->dlen); + tmp = mempcpy(tmp, &src[len], slen - len); + *tmp = '\0'; return dst; } } @@ -1183,7 +1189,7 @@ static int selabel_subs_init(const char *path, struct selabel_digest *digest, char *ptr; char *src = buf; char *dst; - size_t len; + size_t slen, dlen; while (*src && isspace((unsigned char)*src)) src++; @@ -1204,8 +1210,14 @@ static int selabel_subs_init(const char *path, struct selabel_digest *digest, if (! *dst) continue; - len = strlen(src); - if (len >= UINT32_MAX) { + slen = strlen(src); + if (slen >= UINT32_MAX) { + errno = EINVAL; + goto err; + } + + dlen = strlen(dst); + if (dlen >= UINT32_MAX) { errno = EINVAL; goto err; } @@ -1224,8 +1236,9 @@ static int selabel_subs_init(const char *path, struct selabel_digest *digest, tmp[tmp_num++] = (struct selabel_sub) { .src = src_cpy, - .slen = len, + .slen = slen, .dst = dst_cpy, + .dlen = dlen, }; src_cpy = NULL; dst_cpy = NULL; @@ -1255,19 +1268,19 @@ err: } #endif -static char *selabel_sub_key(const struct saved_data *data, const char *key) +static char *selabel_sub_key(const struct saved_data *data, const char *key, size_t key_len) { char *ptr, *dptr; - ptr = selabel_apply_subs(data->subs, data->subs_num, key); + ptr = selabel_apply_subs(data->subs, data->subs_num, key, key_len); if (ptr) { - dptr = selabel_apply_subs(data->dist_subs, data->dist_subs_num, ptr); + dptr = selabel_apply_subs(data->dist_subs, data->dist_subs_num, ptr, strlen(ptr)); if (dptr) { free(ptr); ptr = dptr; } } else { - ptr = selabel_apply_subs(data->dist_subs, data->dist_subs_num, key); + ptr = selabel_apply_subs(data->dist_subs, data->dist_subs_num, key, key_len); } return ptr; @@ -1783,9 +1796,10 @@ FUZZ_EXTERN struct lookup_result *lookup_all(struct selabel_handle *rec, clean_key[len - 1] = '\0'; key = clean_key; + len--; } - sub = selabel_sub_key(data, key); + sub = selabel_sub_key(data, key, len); if (sub) key = sub; diff --git a/libselinux/src/label_file.h b/libselinux/src/label_file.h index 436982bf..122894a2 100644 --- a/libselinux/src/label_file.h +++ b/libselinux/src/label_file.h @@ -72,6 +72,7 @@ struct selabel_sub { char *src; /* source path prefix */ char *dst; /* substituted path prefix */ uint32_t slen; /* length of source path prefix */ + uint32_t dlen; /* length of substituted path prefix */ }; /* A regular expression file security context specification */ -- 2.45.2