Bugfix/validate-user-provided-file-object-paths (#1197)

* Fixed BACnet file object path name unintended path traversals by optionally restricting path name content with BACNET_FILE_PATH_RESTRICTED define.

* Added POSIX file path name checking for AtomicReadFile and AtomicWriteFile example applications. Prohibits use of relative and absolute file paths when BACNET_FILE_PATH_RESTRICTED is non-zero.
This commit is contained in:
Steve Karg
2026-01-05 11:19:52 -06:00
committed by GitHub
parent 715e45eb5c
commit c5dc00a77b
11 changed files with 151 additions and 16 deletions
+13 -10
View File
@@ -13,11 +13,14 @@
#include <string.h>
/* BACnet Stack defines - first */
#include "bacnet/bacdef.h"
#include "bacnet/basic/sys/debug.h"
#include "bacnet/basic/object/bacfile.h"
#include "bacnet/basic/sys/debug.h"
#include "bacnet/basic/sys/filename.h"
/* me! */
#include "bacfile-posix.h"
#ifndef FILE_RECORD_SIZE
#define FILE_RECORD_SIZE MAX_OCTET_STRING_BYTES
#ifndef BACNET_FILE_POSIX_RECORD_SIZE
#define BACNET_FILE_POSIX_RECORD_SIZE MAX_OCTET_STRING_BYTES
#endif
/**
@@ -50,7 +53,7 @@ size_t bacfile_posix_file_size(const char *pathname)
long file_position = 0;
size_t file_size = 0;
if (pathname) {
if (filename_path_valid(pathname)) {
pFile = fopen(pathname, "rb");
if (pFile) {
file_position = fsize(pFile);
@@ -100,7 +103,7 @@ size_t bacfile_posix_read_stream_data(
FILE *pFile = NULL;
size_t len = 0;
if (pathname) {
if (filename_path_valid(pathname)) {
pFile = fopen(pathname, "rb");
if (pFile) {
(void)fseek(pFile, fileStartPosition, SEEK_SET);
@@ -131,7 +134,7 @@ size_t bacfile_posix_write_stream_data(
size_t bytes_written = 0;
FILE *pFile = NULL;
if (pathname) {
if (filename_path_valid(pathname)) {
if (fileStartPosition == 0) {
/* open the file as a clean slate when starting at 0 */
pFile = fopen(pathname, "wb");
@@ -177,11 +180,11 @@ bool bacfile_posix_write_record_data(
bool status = false;
FILE *pFile = NULL;
uint32_t i = 0;
char dummy_data[FILE_RECORD_SIZE];
char dummy_data[BACNET_FILE_POSIX_RECORD_SIZE];
const char *pData = NULL;
size_t fileSeekRecord = 0;
if (pathname) {
if (filename_path_valid(pathname)) {
if (fileStartRecord == 0) {
/* open the file as a clean slate when starting at 0 */
pFile = fopen(pathname, "wb");
@@ -238,11 +241,11 @@ bool bacfile_posix_read_record_data(
bool status = false;
FILE *pFile = NULL;
uint32_t i = 0;
char dummy_data[FILE_RECORD_SIZE] = { 0 };
char dummy_data[BACNET_FILE_POSIX_RECORD_SIZE] = { 0 };
const char *pData = NULL;
size_t fileSeekRecord = 0;
if (pathname) {
if (filename_path_valid(pathname)) {
pFile = fopen(pathname, "rb");
if (pFile) {
fileSeekRecord = fileStartRecord + fileIndexRecord;