diff --git a/backup_logs/src/backup_engine.c b/backup_logs/src/backup_engine.c index a47af3c2..4486fea9 100644 --- a/backup_logs/src/backup_engine.c +++ b/backup_logs/src/backup_engine.c @@ -402,29 +402,26 @@ int backup_and_recover_logs(const char* source, const char* dest, continue; } - /* Check if it's a regular file (match shell script -type f). - * Use open(O_NOFOLLOW) + fstat() to eliminate TOCTOU (CWE-367): - * opening with O_NOFOLLOW refuses symlinks, and fstat() on the - * resulting fd operates on the same inode already held open, - * so no race window exists between the check and the use. */ + /* Check if it's a regular file or a symlink to a regular file. + * Log files may be symlinks (e.g. last.log, rdk_shell.log). + * Use lstat() to get the link info, then stat() to verify + * the target is a regular file before copying. */ struct stat file_stat; - int check_fd = open(source_file, O_RDONLY | O_NOFOLLOW); - if (check_fd < 0) { - /* Skip if file cannot be opened (e.g. symlink or permission denied) */ + if (lstat(source_file, &file_stat) != 0) { continue; } - if (fstat(check_fd, &file_stat) != 0) { - close(check_fd); - continue; - } - close(check_fd); if (S_ISDIR(file_stat.st_mode)) { /* Skip directories - we don't want to backup directories to PreviousLogs */ RDK_LOG(RDK_LOG_DEBUG, LOG_BACKUP_LOGS, "Skipping directory: %s\n", source_file); continue; } - if (!S_ISREG(file_stat.st_mode)) { - /* Skip non-regular files (symlinks, devices, etc.) */ + if (S_ISLNK(file_stat.st_mode)) { + /* For symlinks, check the target is a regular file */ + if (stat(source_file, &file_stat) != 0 || !S_ISREG(file_stat.st_mode)) { + continue; + } + } else if (!S_ISREG(file_stat.st_mode)) { + /* Skip non-regular, non-symlink files (devices, etc.) */ continue; } diff --git a/uploadstblogs/src/archive_manager.c b/uploadstblogs/src/archive_manager.c index d6253ae0..f22cd315 100755 --- a/uploadstblogs/src/archive_manager.c +++ b/uploadstblogs/src/archive_manager.c @@ -528,14 +528,12 @@ static int add_file_to_tar(gzFile gz, const char* filepath, const char* arcname) { struct stat st; - // Open file first with O_NOFOLLOW to prevent symlink attacks (TOCTOU fix) - int fd = open(filepath, O_RDONLY | O_NOFOLLOW); + // Open file for reading - follow symlinks as log files may be symlinked + int fd = open(filepath, O_RDONLY); if (fd < 0) { - if (errno != ELOOP) { // ELOOP = symlink detected - RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, - "[%s:%d] Failed to open file: %s (errno=%d)\n", - __FUNCTION__, __LINE__, filepath, errno); - } + RDK_LOG(RDK_LOG_ERROR, LOG_UPLOADSTB, + "[%s:%d] Failed to open file: %s (errno=%d)\n", + __FUNCTION__, __LINE__, filepath, errno); return -1; }