Fail closed on invalid .snapraidignore control files

This commit is contained in:
Andrea Mazzoleni 2026-09-25 09:21:06 +02:00
parent 099f3c7429
commit 13267085d1
5 changed files with 55 additions and 12 deletions

View file

@ -1523,8 +1523,36 @@ static int scan_sub(struct snapraid_scan* scan, int level, int is_diff, char* pa
tommy_list_insert_tail(&list, &entry->node, entry);
/* process ignore files */
if (pathcmp(".snapraidignore", dd->d_name) == 0)
state_load_ignore_file(&scan->local_filter_list, path_next, sub_next);
if (pathcmp(".snapraidignore", dd->d_name) == 0) {
int d_type;
#if HAVE_STRUCT_DIRENT_D_TYPE
d_type = dd->d_type;
#else
d_type = DT_UNKNOWN;
#endif
if (d_type == DT_UNKNOWN) {
struct stat st_ignore;
if (lstat(path_next, &st_ignore) != 0) {
/* LCOV_EXCL_START */
log_fatal(errno, "Error stating the ignore file '%s'. %s.\n", path_next, strerror(errno));
exit(EXIT_FAILURE);
/* LCOV_EXCL_STOP */
}
if (S_ISREG(st_ignore.st_mode))
d_type = DT_REG;
}
if (d_type != DT_REG) {
log_fatal(EUSER, "Ignore file '%s' is not a regular file.\n", path_next);
exit(EXIT_FAILURE);
}
if (state_load_ignore_file(&scan->local_filter_list, path_next, sub_next) != 0)
exit(EXIT_FAILURE);
}
}
if (closedir(d) != 0) {

View file

@ -6695,16 +6695,17 @@ int state_write_barrier(struct snapraid_state* state, struct snapraid_io* io, st
return 0;
}
void state_load_ignore_file(tommy_list* filter_list, const char* path, const char* sub)
int state_load_ignore_file(tommy_list* filter_list, const char* path, const char* sub)
{
STREAM* f;
int line;
int error = 0;
f = sopen_read(path, 0);
f = sopen_read(path, STREAM_FLAGS_NOFOLLOW);
if (!f) {
/* LCOV_EXCL_START */
log_error(errno, "Error opening the ignore file '%s'. %s.\n", path, strerror(errno));
return;
log_fatal(errno, "Error opening the ignore file '%s'. %s.\n", path, strerror(errno));
return -1;
/* LCOV_EXCL_STOP */
}
@ -6721,7 +6722,8 @@ void state_load_ignore_file(tommy_list* filter_list, const char* path, const cha
ret = sgetline(f, buffer, sizeof(buffer));
if (ret < 0) {
/* LCOV_EXCL_START */
log_error(EUSER, "Too long line in '%s' at line %u\n", path, line);
log_fatal(EUSER, "Too long line in '%s' at line %u\n", path, line);
error = 1;
break;
/* LCOV_EXCL_STOP */
}
@ -6736,7 +6738,8 @@ void state_load_ignore_file(tommy_list* filter_list, const char* path, const cha
filter = filter_alloc_file(-1, sub, buffer);
if (!filter) {
/* LCOV_EXCL_START */
log_error(EUSER, "Invalid ignore specification '%s' in '%s' at line %u\n", buffer, path, line);
log_fatal(EUSER, "Invalid ignore specification '%s' in '%s' at line %u\n", buffer, path, line);
error = 1;
break;
/* LCOV_EXCL_STOP */
}
@ -6751,7 +6754,8 @@ void state_load_ignore_file(tommy_list* filter_list, const char* path, const cha
}
if (c != '\n') {
/* LCOV_EXCL_START */
log_error(EUSER, "Extra data in '%s' at line %u\n", path, line);
log_fatal(EUSER, "Extra data in '%s' at line %u\n", path, line);
error = 1;
break;
/* LCOV_EXCL_STOP */
}
@ -6760,11 +6764,19 @@ void state_load_ignore_file(tommy_list* filter_list, const char* path, const cha
if (serror(f)) {
/* LCOV_EXCL_START */
log_error(errno, "Error reading the ignore file '%s' at line %u\n", path, line);
log_fatal(errno, "Error reading the ignore file '%s' at line %u. %s.\n", path, line, strerror(errno));
error = 1;
/* LCOV_EXCL_STOP */
}
sclose(f);
if (sclose(f) != 0) {
/* LCOV_EXCL_START */
log_fatal(errno, "Error closing the ignore file '%s'. %s.\n", path, strerror(errno));
error = 1;
/* LCOV_EXCL_STOP */
}
return error ? -1 : 0;
}
static int state_snapshot_dir(struct fssnapshot_struct* fss, const char* name, struct snapraid_disk* disk)

View file

@ -438,7 +438,7 @@ int state_thermal_begin(struct snapraid_state* state, time_t now);
/**
* Load the ignore file .snapraidignore
*/
void state_load_ignore_file(tommy_list* filter_list, const char* path, const char* sub);
int state_load_ignore_file(tommy_list* filter_list, const char* path, const char* sub);
/**
* Report attributes into the log

View file

@ -25,6 +25,8 @@ STREAM* sopen_read(const char* file, int flags)
advise_init(&s->advise[0], s->flags & STREAM_FLAGS_ADVISE_MASK);
int open_flags = O_RDONLY | O_BINARY | advise_flags(&s->advise[0]);
if ((s->flags & STREAM_FLAGS_NOFOLLOW) != 0)
open_flags |= O_NOFOLLOW;
pathcpy(s->handle[0].path, sizeof(s->handle[0].path), file);
s->handle[0].f = open(file, open_flags);

View file

@ -12,6 +12,7 @@
#define STREAM_FLAGS_ADVISE_MASK 0xFF /**< Low bits containing one of ADVISE_*. */
#define STREAM_FLAGS_CRC 0x100 /**< Enable the CRC computation. */
#define STREAM_FLAGS_NOFOLLOW 0x200 /**< Don't follow the final symbolic link on open. */
/**
* Size of the buffer of the stream.