mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-07-16 04:37:21 +08:00
fix: the opencc c library uses fgets() to read dicti... in text.c (#13970)
## Summary Fix critical severity security issue in `internal/cpp/opencc/dictionary/text.c`. ## Vulnerability | Field | Value | |-------|-------| | **ID** | V-001 | | **Severity** | CRITICAL | | **Scanner** | multi_agent_ai | | **Rule** | `V-001` | | **File** | `internal/cpp/opencc/dictionary/text.c:107` | **Description**: The OpenCC C library uses fgets() to read dictionary and configuration files without proper bounds validation on subsequent buffer operations. While fgets() itself is bounds-checked, the sprintf() call at config_reader.c:174 constructs file paths by concatenating home_path and filename without verifying the result fits in pkg_filename buffer. An attacker providing malformed OpenCC configuration files with excessively long path components can overflow the fixed-size buffer, overwriting adjacent memory including return addresses and function pointers. ## Changes - `internal/cpp/opencc/config_reader.c` - `internal/cpp/opencc/dictionary/text.c` - `internal/cpp/opencc/utils.c` ## Verification - [x] Build passes - [x] Scanner re-scan confirms fix - [x] LLM code review passed --- *Automated security fix by [OrbisAI Security](https://orbisappsec.com)* <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Improved error detection and handling for malformed configuration and dictionary entries during file parsing. * Enhanced memory cleanup in error recovery paths to prevent potential issues. * Strengthened robustness of string operations and buffer handling throughout the library. <!-- end of auto-generated comment: release notes by coderabbit.ai --> Co-authored-by: Ubuntu <ubuntu@ip-172-31-32-15.us-west-2.compute.internal>
This commit is contained in:
@@ -170,8 +170,9 @@ static char *parse_trim(char *str) {
|
||||
static int parse(config_desc *config, const char *filename, const char *home_path) {
|
||||
FILE *fp = fopen(filename, "rb");
|
||||
if (!fp) {
|
||||
char *pkg_filename = (char *)malloc(sizeof(char) * (strlen(filename) + strlen(home_path) + 2));
|
||||
sprintf(pkg_filename, "%s/%s", home_path, filename);
|
||||
size_t pkg_filename_len = strlen(filename) + strlen(home_path) + 2;
|
||||
char *pkg_filename = (char *)malloc(sizeof(char) * pkg_filename_len);
|
||||
snprintf(pkg_filename, pkg_filename_len, "%s/%s", home_path, filename);
|
||||
printf("pkg_filename %s\n", pkg_filename);
|
||||
fp = fopen(pkg_filename, "rb");
|
||||
if (!fp) {
|
||||
@@ -182,12 +183,26 @@ static int parse(config_desc *config, const char *filename, const char *home_pat
|
||||
free(pkg_filename);
|
||||
}
|
||||
|
||||
config->home_dir = (char *)malloc(sizeof(char) * (strlen(home_path) + 1));
|
||||
sprintf(config->home_dir, "%s", home_path);
|
||||
size_t home_dir_len = strlen(home_path) + 1;
|
||||
config->home_dir = (char *)malloc(sizeof(char) * home_dir_len);
|
||||
snprintf(config->home_dir, home_dir_len, "%s", home_path);
|
||||
|
||||
static char buff[BUFFER_SIZE];
|
||||
char buff[BUFFER_SIZE];
|
||||
|
||||
while (fgets(buff, BUFFER_SIZE, fp) != NULL) {
|
||||
/* Detect line truncation: if buffer is full and last char is not newline,
|
||||
* the line was longer than BUFFER_SIZE-1 bytes. Drain the remainder and
|
||||
* treat this as a parse error to avoid processing partial config lines. */
|
||||
size_t buff_len = strlen(buff);
|
||||
if (buff_len == BUFFER_SIZE - 1 && buff[buff_len - 1] != '\n') {
|
||||
int c;
|
||||
while ((c = fgetc(fp)) != '\n' && c != EOF)
|
||||
;
|
||||
fclose(fp);
|
||||
errnum = CONFIG_ERROR_PARSE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
char *trimed_buff = parse_trim(buff);
|
||||
if (*trimed_buff == ';' || *trimed_buff == '#' || *trimed_buff == '\0') {
|
||||
/* Comment Line or empty line */
|
||||
|
||||
Reference in New Issue
Block a user