From 080e3ee7c7f412f48fadab503791974b5ae79c53 Mon Sep 17 00:00:00 2001 From: bobijam Date: Thu, 27 Sep 2007 02:57:15 +0000 Subject: [PATCH] Branch HEAD b=12948 i=wangdi, johann Description: buffer overruns could theoretically occur Details : llapi_semantic_traverse() modifies the "path" argument by appending values to the end of the origin string, and a buffer overrun may occur. Adding buffer overrun check in liblustreapi. --- lustre/ChangeLog | 7 +++++ lustre/utils/liblustreapi.c | 73 +++++++++++++++++++++++++++++++++++++-------- 2 files changed, 67 insertions(+), 13 deletions(-) diff --git a/lustre/ChangeLog b/lustre/ChangeLog index 9a8c352..be94848 100644 --- a/lustre/ChangeLog +++ b/lustre/ChangeLog @@ -324,6 +324,13 @@ Description: Fix warning idr_remove called for id=.. which is not Details : Last kernels save old s_dev before kill super and not allow to restore from callback - restore it before call kill_anon_super. +Severity : minor +Bugzilla : 12948 +Description: buffer overruns could theoretically occur +Details : llapi_semantic_traverse() modifies the "path" argument by + appending values to the end of the origin string, and a + overrun may occur. Adding buffer overrun check in liblustreapi. + -------------------------------------------------------------------------------- 2007-08-10 Cluster File Systems, Inc. diff --git a/lustre/utils/liblustreapi.c b/lustre/utils/liblustreapi.c index 1386608..a6ddb9d 100644 --- a/lustre/utils/liblustreapi.c +++ b/lustre/utils/liblustreapi.c @@ -525,7 +525,7 @@ static DIR *opendir_parent(char *path) return parent; } -static int llapi_semantic_traverse(char *path, DIR *parent, +static int llapi_semantic_traverse(char *path, int size, DIR *parent, semantic_func_t sem_init, semantic_func_t sem_fini, void *data) { @@ -559,6 +559,12 @@ static int llapi_semantic_traverse(char *path, DIR *parent, continue; path[len] = 0; + if ((len + dent->d_reclen + 2) > size) { + fprintf(stderr, + "error: %s: string buffer is too small\n", + __FUNCTION__); + break; + } strcat(path, "/"); strcat(path, dent->d_name); @@ -575,7 +581,7 @@ static int llapi_semantic_traverse(char *path, DIR *parent, * tool only makes sense for lustre filesystems. */ break; case DT_DIR: - ret = llapi_semantic_traverse(path, d, sem_init, + ret = llapi_semantic_traverse(path, size, d, sem_init, sem_fini, data); if (ret < 0) goto out; @@ -887,21 +893,33 @@ static int cb_common_fini(char *path, DIR *parent, DIR *d, void *data) int llapi_find(char *path, struct find_param *param) { - char buf[PATH_MAX + 1]; - int ret; + char *buf; + int ret, len = strlen(path); + + if (len > PATH_MAX) { + fprintf(stderr, "%s: Path name '%s' is too long.\n", + __FUNCTION__, path); + return -EINVAL; + } + + buf = (char *)malloc(PATH_MAX + 1); + if (!buf) + return -ENOMEM; ret = common_param_init(param); - if (ret) + if (ret) { + free(buf); return ret; + } param->depth = 0; - strncpy(buf, path, strlen(path)); - buf[strlen(path)] = '\0'; - ret = llapi_semantic_traverse(buf, NULL, cb_find_init, + strncpy(buf, path, PATH_MAX + 1); + ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_find_init, cb_common_fini, param); find_param_fini(param); + free(buf); return ret < 0 ? ret : 0; } @@ -960,16 +978,32 @@ out: int llapi_getstripe(char *path, struct find_param *param) { - int ret = 0; + char *buf; + int ret = 0, len = strlen(path); + + if (len > PATH_MAX) { + fprintf(stderr, "%s: Path name '%s' is too long.\n", + __FUNCTION__, path); + return -EINVAL; + } + + buf = (char *)malloc(PATH_MAX + 1); + if (!buf) + return -ENOMEM; ret = common_param_init(param); - if (ret) + if (ret) { + free(buf); return ret; + } param->depth = 0; - ret = llapi_semantic_traverse(path, NULL, cb_getstripe, + + strncpy(buf, path, PATH_MAX + 1); + ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_getstripe, cb_common_fini, param); find_param_fini(param); + free(buf); return ret < 0 ? ret : 0; } @@ -1280,7 +1314,18 @@ static int cb_quotachown(char *path, DIR *parent, DIR *d, void *data) int llapi_quotachown(char *path, int flag) { struct find_param param; - int ret = 0; + char *buf; + int ret = 0, len = strlen(path); + + if (len > PATH_MAX) { + fprintf(stderr, "%s: Path name '%s' is too long.\n", + __FUNCTION__, path); + return -EINVAL; + } + + buf = (char *)malloc(PATH_MAX + 1); + if (!buf) + return -ENOMEM; memset(¶m, 0, sizeof(param)); param.recursive = 1; @@ -1291,10 +1336,12 @@ int llapi_quotachown(char *path, int flag) if (ret) goto out; - ret = llapi_semantic_traverse(path, NULL, cb_quotachown, + strncpy(buf, path, PATH_MAX + 1); + ret = llapi_semantic_traverse(buf, PATH_MAX + 1, NULL, cb_quotachown, NULL, ¶m); out: find_param_fini(¶m); + free(buf); return ret; } -- 1.8.3.1