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

Function do_mkdir_at

syscall.c:1031–1076  ·  view source on GitHub ↗

Symlink-race-safe variant of do_mkdir() for receiver-side use. See the comment on do_chmod_at() for the threat model and design rationale. mkdir() resolves parent symlinks at every component, so a parent- component swap can place an attacker-named directory outside the module. Defence: open the parent of fname under secure_relative_open() and call mkdirat() against that dirfd. Mutate

Source from the content-addressed store, hash-verified

1029 parent and absolute-path cases.
1030*/
1031int do_mkdir_at(char *path, mode_t mode)
1032{
1033#ifdef AT_FDCWD
1034 extern int am_daemon, am_chrooted;
1035 char dirpath[MAXPATHLEN];
1036 const char *bname;
1037 const char *slash;
1038 int dfd, ret, e;
1039 size_t dlen;
1040
1041 if (dry_run) return 0;
1042 RETURN_ERROR_IF_RO_OR_LO;
1043 trim_trailing_slashes(path);
1044
1045 if (!am_daemon || am_chrooted)
1046 return mkdir(path, mode);
1047
1048 if (!path || !*path || *path == '/')
1049 return mkdir(path, mode);
1050
1051 slash = strrchr(path, '/');
1052 if (!slash)
1053 return mkdir(path, mode);
1054
1055 dlen = slash - path;
1056 if (dlen >= sizeof dirpath) {
1057 errno = ENAMETOOLONG;
1058 return -1;
1059 }
1060 memcpy(dirpath, path, dlen);
1061 dirpath[dlen] = '\0';
1062 bname = slash + 1;
1063
1064 dfd = secure_relative_open(NULL, dirpath, O_RDONLY | O_DIRECTORY, 0);
1065 if (dfd < 0)
1066 return -1;
1067
1068 ret = mkdirat(dfd, bname, mode);
1069 e = errno;
1070 close(dfd);
1071 errno = e;
1072 return ret;
1073#else
1074 return do_mkdir(path, mode);
1075#endif
1076}
1077
1078/* like mkstemp but forces permissions */
1079int do_mkstemp(char *template, mode_t perms)

Callers 3

handle_partial_dirFunction · 0.85
copy_valid_pathFunction · 0.85
recv_generatorFunction · 0.85

Calls 3

trim_trailing_slashesFunction · 0.85
secure_relative_openFunction · 0.85
do_mkdirFunction · 0.85

Tested by

no test coverage detected