Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP1:GA
fdupes.33850
toctou-race-allows-arbitrary-file-deletion.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File toctou-race-allows-arbitrary-file-deletion.patch of Package fdupes.33850
From 85680897148f1ac33b55418e00334116e419717f Mon Sep 17 00:00:00 2001 From: Adrian Lopez <adrianlopezroche@gmail.com> Date: Tue, 16 Aug 2022 14:39:18 -0400 Subject: [PATCH] Call stat() before deleting any file to ensure it's still the same file. --- Makefile.am | 4 ++++ fdupes.c | 11 +++++++---- ncurses-commands.c | 3 ++- removeifnotchanged.c | 41 +++++++++++++++++++++++++++++++++++++++++ removeifnotchanged.h | 8 ++++++++ 5 files changed, 62 insertions(+), 5 deletions(-) create mode 100644 removeifnotchanged.c create mode 100644 removeifnotchanged.h Index: fdupes-1.6.1/fdupes.c =================================================================== --- fdupes-1.6.1.orig/fdupes.c 2016-08-21 04:54:46.000000000 +0000 +++ fdupes-1.6.1/fdupes.c 2024-04-25 09:13:19.407546801 +0000 @@ -109,6 +109,42 @@ typedef struct _filetree { struct _filetree *right; } filetree_t; +int removeifnotchanged(const file_t *file, char **errorstring) +{ + int result; + struct stat st; + + static char *filechanged = "File contents changed during processing"; + static char *unknownerror = "Unknown error"; + + stat(file->d_name, &st); + + if (file->device != st.st_dev || + file->inode != st.st_ino || + file->mtime != st.st_mtime || + file->size != st.st_size) + { + if (errorstring != 0) + *errorstring = filechanged; + + return -2; + } + else + { + result = remove(file->d_name); + + if (result != 0 && errorstring != 0) + { + *errorstring = strerror(errno); + + if (*errorstring == 0) + *errorstring = unknownerror; + } + + return result; + } +} + void errormsg(char *message, ...) { va_list ap; @@ -773,6 +809,7 @@ void deletefiles(file_t *files, int prom int max = 0; int x; int i; + char *errorstring; curfile = files; @@ -884,11 +921,11 @@ void deletefiles(file_t *files, int prom if (preserve[x]) printf(" [+] %s\n", dupelist[x]->d_name); else { - if (remove(dupelist[x]->d_name) == 0) { + if (removeifnotchanged(dupelist[x], &errorstring) == 0) { printf(" [-] %s\n", dupelist[x]->d_name); } else { printf(" [!] %s ", dupelist[x]->d_name); - printf("-- unable to delete file!\n"); + printf("-- unable to delete file: %s!\n", errorstring); } } } @@ -977,6 +1014,7 @@ void deletesuccessor(file_t **existing, { file_t *to_keep; file_t *to_delete; + char *errorstring; if (comparef(duplicate, *existing) >= 0) { @@ -994,11 +1032,11 @@ void deletesuccessor(file_t **existing, if (!ISFLAG(flags, F_HIDEPROGRESS)) fprintf(stderr, "\r%40s\r", " "); printf(" [+] %s\n", to_keep->d_name); - if (remove(to_delete->d_name) == 0) { + if (removeifnotchanged(to_delete, &errorstring) == 0) { printf(" [-] %s\n", to_delete->d_name); } else { printf(" [!] %s ", to_delete->d_name); - printf("-- unable to delete file!\n"); + printf("-- unable to delete file: %s!\n", errorstring); } printf("\n");
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor