diff options
| author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2026-09-04 00:00:00 +0000 |
|---|---|---|
| committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2026-09-04 12:17:40 +0500 |
| commit | 0766b733fe3e06dd2a7f9a3cfbf2108ac73abd17 (patch) | |
| tree | 3a8ca8ef8e855c41476499484ae3f3596e842ac2 /CPP/Windows/FileDir.cpp | |
| parent | f9d78aff31a5f2521ae7ddbdc97c4a8855808959 (diff) | |
| download | 7zip-0766b733fe3e06dd2a7f9a3cfbf2108ac73abd17.tar.gz 7zip-0766b733fe3e06dd2a7f9a3cfbf2108ac73abd17.tar.bz2 7zip-0766b733fe3e06dd2a7f9a3cfbf2108ac73abd17.zip | |
Diffstat (limited to 'CPP/Windows/FileDir.cpp')
| -rw-r--r-- | CPP/Windows/FileDir.cpp | 102 |
1 files changed, 64 insertions, 38 deletions
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp index ad0d8c9..bf77c15 100644 --- a/CPP/Windows/FileDir.cpp +++ b/CPP/Windows/FileDir.cpp | |||
| @@ -34,7 +34,9 @@ using namespace NName; | |||
| 34 | 34 | ||
| 35 | #ifndef _WIN32 | 35 | #ifndef _WIN32 |
| 36 | 36 | ||
| 37 | static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts) | 37 | extern |
| 38 | bool FiTime_To_timespec(const CFiTime *ft, timespec &ts); | ||
| 39 | bool FiTime_To_timespec(const CFiTime *ft, timespec &ts) | ||
| 38 | { | 40 | { |
| 39 | if (ft) | 41 | if (ft) |
| 40 | { | 42 | { |
| @@ -51,7 +53,7 @@ static bool FiTime_To_timespec(const CFiTime *ft, timespec &ts) | |||
| 51 | ts.tv_sec = 0; | 53 | ts.tv_sec = 0; |
| 52 | ts.tv_nsec = | 54 | ts.tv_nsec = |
| 53 | #ifdef UTIME_OMIT | 55 | #ifdef UTIME_OMIT |
| 54 | UTIME_OMIT; // -2 keep old timesptamp | 56 | UTIME_OMIT; // -2 keep old timestamp |
| 55 | #else | 57 | #else |
| 56 | // UTIME_NOW; -1 // set to the current time | 58 | // UTIME_NOW; -1 // set to the current time |
| 57 | 0; | 59 | 0; |
| @@ -170,6 +172,10 @@ bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, con | |||
| 170 | 172 | ||
| 171 | bool SetFileAttrib(CFSTR path, DWORD attrib) | 173 | bool SetFileAttrib(CFSTR path, DWORD attrib) |
| 172 | { | 174 | { |
| 175 | /* win10: | ||
| 176 | if (attrib == 0), it sets (FILE_ATTRIBUTE_NORMAL) attribute | ||
| 177 | (FILE_ATTRIBUTE_DIRECTORY and some another attributes are ignored for files). | ||
| 178 | */ | ||
| 173 | #ifndef _UNICODE | 179 | #ifndef _UNICODE |
| 174 | if (!g_IsNT) | 180 | if (!g_IsNT) |
| 175 | { | 181 | { |
| @@ -1078,7 +1084,7 @@ static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile, ICopyFileProgress *progres | |||
| 1078 | } | 1084 | } |
| 1079 | // There is file IO error or process was interrupted by user. | 1085 | // There is file IO error or process was interrupted by user. |
| 1080 | // We close output file and delete it. | 1086 | // We close output file and delete it. |
| 1081 | // DeleteFileAlways doesn't change errno (if successed), but we restore errno. | 1087 | // DeleteFileAlways doesn't change errno (if succeed), but we restore errno. |
| 1082 | const int errno_save = errno; | 1088 | const int errno_save = errno; |
| 1083 | DeleteFileAlways(newFile); | 1089 | DeleteFileAlways(newFile); |
| 1084 | errno = errno_save; | 1090 | errno = errno_save; |
| @@ -1240,26 +1246,34 @@ bool SetLinkFileTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, con | |||
| 1240 | } | 1246 | } |
| 1241 | 1247 | ||
| 1242 | 1248 | ||
| 1243 | struct C_umask | 1249 | C_umask::C_umask() |
| 1244 | { | 1250 | { |
| 1245 | mode_t mask; | 1251 | /* |
| 1246 | 1252 | For security purposes, we restrict the file (mode) attributes | |
| 1247 | C_umask() | 1253 | using the process's file mode creation mask (umask). |
| 1248 | { | 1254 | System's umask is used by open(), mkdir(), and other system calls |
| 1249 | /* by security reasons we restrict attributes according | 1255 | that create files to modify the permissions placed on newly |
| 1250 | with process's file mode creation mask (umask) */ | 1256 | created files or directories. |
| 1251 | const mode_t um = umask(0); // octal :0022 is expected | 1257 | We use (g_umask.mask) for any function that changes the file's access |
| 1252 | mask = 0777 & (~um); // octal: 0755 is expected | 1258 | mode but is not affected by the system's umask. |
| 1253 | umask(um); // restore the umask | 1259 | We use additional mask restiction 0777 for security purposes. |
| 1254 | // printf("\n umask = 0%03o mask = 0%03o\n", um, mask); | 1260 | So we don't create the following mode bits for files and directories: |
| 1255 | 1261 | S_ISUID 04000 set-user-ID bit | |
| 1256 | // mask = 0777; // debug we can disable the restriction: | 1262 | S_ISGID 02000 set-group-ID bit |
| 1257 | } | 1263 | S_ISVTX 01000 sticky bit |
| 1258 | }; | 1264 | system's open(), mkdir() also can have similar 0777 restiction for some cases. |
| 1265 | */ | ||
| 1266 | const mode_t um = umask(0); // um = 0022 (octal) is expected | ||
| 1267 | mask = ~um | ||
| 1268 | & 0777; // 0777 is our additional mode restruction : is secure | ||
| 1269 | // & 07777; // for debug : 07777 to support all mode bits : is not secure | ||
| 1270 | // mask = 07777; // for debug : to restore all mode bits | ||
| 1271 | umask(um); // restore original umask that was changed by umask(0) in code above | ||
| 1272 | } | ||
| 1259 | 1273 | ||
| 1260 | static C_umask g_umask; | 1274 | C_umask g_umask; |
| 1261 | 1275 | ||
| 1262 | // #define PRF(x) x; | 1276 | // #define PRF(x) x |
| 1263 | #define PRF(x) | 1277 | #define PRF(x) |
| 1264 | 1278 | ||
| 1265 | #define TRACE_SetFileAttrib(msg) \ | 1279 | #define TRACE_SetFileAttrib(msg) \ |
| @@ -1273,12 +1287,17 @@ int my_chown(CFSTR path, uid_t owner, gid_t group) | |||
| 1273 | return chown(path, owner, group); | 1287 | return chown(path, owner, group); |
| 1274 | } | 1288 | } |
| 1275 | 1289 | ||
| 1290 | int my_chown_Link(CFSTR path, uid_t owner, gid_t group) | ||
| 1291 | { | ||
| 1292 | return lchown(path, owner, group); | ||
| 1293 | // return fchownat(AT_FDCWD, path, owner, group, AT_SYMLINK_NOFOLLOW); | ||
| 1294 | } | ||
| 1295 | |||
| 1276 | bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | 1296 | bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) |
| 1277 | { | 1297 | { |
| 1278 | TRACE_SetFileAttrib("") | 1298 | TRACE_SetFileAttrib("") |
| 1279 | 1299 | mode_t mode; | |
| 1280 | struct stat st; | 1300 | struct stat st; |
| 1281 | |||
| 1282 | bool use_lstat = true; | 1301 | bool use_lstat = true; |
| 1283 | if (use_lstat) | 1302 | if (use_lstat) |
| 1284 | { | 1303 | { |
| @@ -1297,20 +1316,26 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
| 1297 | return false; | 1316 | return false; |
| 1298 | } | 1317 | } |
| 1299 | } | 1318 | } |
| 1300 | 1319 | mode = st.st_mode; | |
| 1320 | |||
| 1301 | if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) | 1321 | if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) |
| 1302 | { | 1322 | { |
| 1303 | TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION") | 1323 | TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION") |
| 1304 | st.st_mode = attrib >> 16; | 1324 | mode = attrib >> 16; |
| 1305 | if (S_ISDIR(st.st_mode)) | 1325 | if (S_ISDIR(mode)) |
| 1306 | { | 1326 | { |
| 1327 | if (!S_ISDIR(st.st_mode)) | ||
| 1328 | return true; | ||
| 1307 | // user/7z must be able to create files in this directory | 1329 | // user/7z must be able to create files in this directory |
| 1308 | st.st_mode |= (S_IRUSR | S_IWUSR | S_IXUSR); | 1330 | mode |= (S_IRUSR | S_IWUSR | S_IXUSR); |
| 1331 | } | ||
| 1332 | else | ||
| 1333 | { | ||
| 1334 | if (!S_ISREG(mode) || !S_ISREG(st.st_mode)) | ||
| 1335 | return true; | ||
| 1309 | } | 1336 | } |
| 1310 | else if (!S_ISREG(st.st_mode)) | ||
| 1311 | return true; | ||
| 1312 | } | 1337 | } |
| 1313 | else if (S_ISLNK(st.st_mode)) | 1338 | else if (S_ISLNK(mode)) |
| 1314 | { | 1339 | { |
| 1315 | /* for most systems: permissions for symlinks are fixed to rwxrwxrwx. | 1340 | /* for most systems: permissions for symlinks are fixed to rwxrwxrwx. |
| 1316 | so we don't need chmod() for symlinks. */ | 1341 | so we don't need chmod() for symlinks. */ |
| @@ -1322,27 +1347,28 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
| 1322 | { | 1347 | { |
| 1323 | TRACE_SetFileAttrib("Only Windows Attributes") | 1348 | TRACE_SetFileAttrib("Only Windows Attributes") |
| 1324 | // Only Windows Attributes | 1349 | // Only Windows Attributes |
| 1325 | if (S_ISDIR(st.st_mode) | 1350 | if (S_ISDIR(mode) |
| 1326 | || (attrib & FILE_ATTRIBUTE_READONLY) == 0) | 1351 | || (attrib & FILE_ATTRIBUTE_READONLY) == 0) |
| 1327 | return true; | 1352 | return true; |
| 1328 | st.st_mode &= ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH); // octal: ~0222; // disable write permissions | 1353 | mode &= ~(mode_t)(S_IWUSR | S_IWGRP | S_IWOTH); // octal: ~0222; // disable write permissions |
| 1329 | } | 1354 | } |
| 1330 | 1355 | ||
| 1331 | int res; | 1356 | int res; |
| 1357 | mode &= g_umask.mask; | ||
| 1332 | /* | 1358 | /* |
| 1333 | if (S_ISLNK(st.st_mode)) | 1359 | if (S_ISLNK(mode)) |
| 1334 | { | 1360 | { |
| 1335 | printf("\nfchmodat()\n"); | 1361 | printf("\nfchmodat()\n"); |
| 1336 | TRACE_chmod(path, (st.st_mode) & g_umask.mask) | 1362 | TRACE_chmod(path, (mode)) |
| 1337 | // AT_SYMLINK_NOFOLLOW is not implemted still in Linux. | 1363 | // AT_SYMLINK_NOFOLLOW is not implemented still in Linux. |
| 1338 | res = fchmodat(AT_FDCWD, path, (st.st_mode) & g_umask.mask, | 1364 | res = fchmodat(AT_FDCWD, path, (mode), |
| 1339 | S_ISLNK(st.st_mode) ? AT_SYMLINK_NOFOLLOW : 0); | 1365 | S_ISLNK(mode) ? AT_SYMLINK_NOFOLLOW : 0); |
| 1340 | } | 1366 | } |
| 1341 | else | 1367 | else |
| 1342 | */ | 1368 | */ |
| 1343 | { | 1369 | { |
| 1344 | TRACE_chmod(path, (st.st_mode) & g_umask.mask) | 1370 | TRACE_chmod(path, mode) |
| 1345 | res = chmod(path, (st.st_mode) & g_umask.mask); | 1371 | res = chmod(path, mode); |
| 1346 | } | 1372 | } |
| 1347 | // TRACE_SetFileAttrib("End") | 1373 | // TRACE_SetFileAttrib("End") |
| 1348 | return (res == 0); | 1374 | return (res == 0); |
