MCPcopy Index your code
hub / github.com/RsyncProject/rsync / secure_basis_open

Function secure_basis_open

receiver.c:100–143  ·  view source on GitHub ↗

Open a basis/output path that may legitimately be an operator-trusted * ABSOLUTE path -- e.g. an absolute --partial-dir ("a directory reserved for * partial-dir work") or --backup-dir. secure_relative_open() deliberately * rejects an absolute relpath, so feeding it the whole absolute partialptr * (with a NULL basedir) returns EINVAL: the basis fd is then -1, no basis is * mapped, and receive_

Source from the content-addressed store, hash-verified

98 * open already trusts an absolute basedir while O_NOFOLLOW-confining the leaf.
99 * Anything else is a straight pass-through that preserves the strict contract. */
100static int secure_basis_open(const char *basedir, const char *relpath, int flags, mode_t mode)
101{
102 extern int am_daemon, am_chrooted;
103
104 /* The confined resolver is only needed for the sanitizing daemon
105 * (am_daemon && !am_chrooted, i.e. use_secure_symlinks). Local /
106 * remote-shell mode has no module boundary, and "use chroot = yes" makes
107 * the kernel root the boundary, so there an alt-dest basis like
108 * --link-dest=../01 must resolve against the cwd as a bare open did before
109 * the hardening (confining it would reject the legitimate sibling "..",
110 * #915). */
111 if (!am_daemon || am_chrooted) {
112 if (basedir) {
113 char fullpath[MAXPATHLEN];
114 if (pathjoin(fullpath, sizeof fullpath, basedir, relpath) >= sizeof fullpath) {
115 errno = ENAMETOOLONG;
116 return -1;
117 }
118 return do_open(fullpath, flags, mode);
119 }
120 return do_open(relpath, flags, mode);
121 }
122
123 if (!basedir && relpath && *relpath == '/') {
124 const char *slash = strrchr(relpath, '/');
125 const char *leaf = slash + 1;
126 char dirbuf[MAXPATHLEN];
127 const char *dir;
128 if (slash == relpath)
129 dir = "/";
130 else {
131 size_t dlen = slash - relpath;
132 if (dlen >= sizeof dirbuf) {
133 errno = ENAMETOOLONG;
134 return -1;
135 }
136 memcpy(dirbuf, relpath, dlen);
137 dirbuf[dlen] = '\0';
138 dir = dirbuf;
139 }
140 return secure_relative_open(dir, leaf, flags, mode);
141 }
142 return secure_relative_open(basedir, relpath, flags, mode);
143}
144
145/* get_tmpname() - create a tmp filename for a given filename
146 *

Callers 1

recv_filesFunction · 0.85

Calls 3

pathjoinFunction · 0.85
do_openFunction · 0.85
secure_relative_openFunction · 0.85

Tested by

no test coverage detected