MCPcopy Create free account
hub / github.com/RsyncProject/rsync / do_utimensat_at

Function do_utimensat_at

syscall.c:1386–1444  ·  view source on GitHub ↗

Symlink-race-safe variant of do_utimensat() for receiver-side use. See the comment on do_chmod_at() for the threat model. utimes() resolves parent components and follows a final-component symlink; lutimes() doesn't follow the final component but still resolves parents. Either way, a parent-symlink swap can redirect the timestamp update outside the module. Defence: open the parent of pa

Source from the content-addressed store, hash-verified

1384 (caller is expected to fall back to the legacy tier walk).
1385*/
1386int do_utimensat_at(const char *path, STRUCT_STAT *stp)
1387{
1388#ifdef AT_FDCWD
1389 extern int am_daemon, am_chrooted;
1390 struct timespec t[2];
1391 char dirpath[MAXPATHLEN];
1392 const char *bname;
1393 const char *slash;
1394 int dfd, ret, e;
1395 size_t dlen;
1396
1397 if (dry_run) return 0;
1398 RETURN_ERROR_IF_RO_OR_LO;
1399
1400 if (!am_daemon || am_chrooted)
1401 return do_utimensat(path, stp);
1402
1403 if (!path || !*path || *path == '/')
1404 return do_utimensat(path, stp);
1405
1406 slash = strrchr(path, '/');
1407 if (!slash)
1408 return do_utimensat(path, stp);
1409
1410 dlen = slash - path;
1411 if (dlen >= sizeof dirpath) {
1412 errno = ENAMETOOLONG;
1413 return -1;
1414 }
1415 memcpy(dirpath, path, dlen);
1416 dirpath[dlen] = '\0';
1417 bname = slash + 1;
1418
1419 t[0].tv_sec = stp->st_atime;
1420#ifdef ST_ATIME_NSEC
1421 t[0].tv_nsec = stp->ST_ATIME_NSEC;
1422#else
1423 t[0].tv_nsec = 0;
1424#endif
1425 t[1].tv_sec = stp->st_mtime;
1426#ifdef ST_MTIME_NSEC
1427 t[1].tv_nsec = stp->ST_MTIME_NSEC;
1428#else
1429 t[1].tv_nsec = 0;
1430#endif
1431
1432 dfd = secure_relative_open(NULL, dirpath, O_RDONLY | O_DIRECTORY, 0);
1433 if (dfd < 0)
1434 return -1;
1435
1436 ret = utimensat(dfd, bname, t, AT_SYMLINK_NOFOLLOW);
1437 e = errno;
1438 close(dfd);
1439 errno = e;
1440 return ret;
1441#else
1442 return do_utimensat(path, stp);
1443#endif

Callers 1

set_timesFunction · 0.85

Calls 2

do_utimensatFunction · 0.85
secure_relative_openFunction · 0.85

Tested by

no test coverage detected