1 /* SPDX-License-Identifier: LGPL-2.1-or-later */
2 
3 #include <errno.h>
4 #include <fcntl.h>
5 #include <stddef.h>
6 #include <stdio.h>
7 #include <stdlib.h>
8 #include <sys/sendfile.h>
9 #include <sys/xattr.h>
10 #include <unistd.h>
11 
12 #include "alloc-util.h"
13 #include "btrfs-util.h"
14 #include "chattr-util.h"
15 #include "copy.h"
16 #include "dirent-util.h"
17 #include "fd-util.h"
18 #include "fileio.h"
19 #include "fs-util.h"
20 #include "io-util.h"
21 #include "macro.h"
22 #include "missing_syscall.h"
23 #include "mkdir-label.h"
24 #include "mountpoint-util.h"
25 #include "nulstr-util.h"
26 #include "rm-rf.h"
27 #include "selinux-util.h"
28 #include "signal-util.h"
29 #include "stat-util.h"
30 #include "stdio-util.h"
31 #include "string-util.h"
32 #include "strv.h"
33 #include "sync-util.h"
34 #include "time-util.h"
35 #include "tmpfile-util.h"
36 #include "umask-util.h"
37 #include "user-util.h"
38 #include "xattr-util.h"
39 
40 #define COPY_BUFFER_SIZE (16U*1024U)
41 
42 /* A safety net for descending recursively into file system trees to copy. On Linux PATH_MAX is 4096, which means the
43  * deepest valid path one can build is around 2048, which we hence use as a safety net here, to not spin endlessly in
44  * case of bind mount cycles and suchlike. */
45 #define COPY_DEPTH_MAX 2048U
46 
try_copy_file_range(int fd_in,loff_t * off_in,int fd_out,loff_t * off_out,size_t len,unsigned flags)47 static ssize_t try_copy_file_range(
48                 int fd_in, loff_t *off_in,
49                 int fd_out, loff_t *off_out,
50                 size_t len,
51                 unsigned flags) {
52 
53         static int have = -1;
54         ssize_t r;
55 
56         if (have == 0)
57                 return -ENOSYS;
58 
59         r = copy_file_range(fd_in, off_in, fd_out, off_out, len, flags);
60         if (have < 0)
61                 have = r >= 0 || errno != ENOSYS;
62         if (r < 0)
63                 return -errno;
64 
65         return r;
66 }
67 
68 enum {
69         FD_IS_NO_PIPE,
70         FD_IS_BLOCKING_PIPE,
71         FD_IS_NONBLOCKING_PIPE,
72 };
73 
fd_is_nonblock_pipe(int fd)74 static int fd_is_nonblock_pipe(int fd) {
75         struct stat st;
76         int flags;
77 
78         /* Checks whether the specified file descriptor refers to a pipe, and if so if O_NONBLOCK is set. */
79 
80         if (fstat(fd, &st) < 0)
81                 return -errno;
82 
83         if (!S_ISFIFO(st.st_mode))
84                 return FD_IS_NO_PIPE;
85 
86         flags = fcntl(fd, F_GETFL);
87         if (flags < 0)
88                 return -errno;
89 
90         return FLAGS_SET(flags, O_NONBLOCK) ? FD_IS_NONBLOCKING_PIPE : FD_IS_BLOCKING_PIPE;
91 }
92 
look_for_signals(CopyFlags copy_flags)93 static int look_for_signals(CopyFlags copy_flags) {
94         int r;
95 
96         if ((copy_flags & (COPY_SIGINT|COPY_SIGTERM)) == 0)
97                 return 0;
98 
99         r = pop_pending_signal(copy_flags & COPY_SIGINT ? SIGINT : 0,
100                                copy_flags & COPY_SIGTERM ? SIGTERM : 0);
101         if (r < 0)
102                 return r;
103         if (r != 0)
104                 return log_debug_errno(SYNTHETIC_ERRNO(EINTR),
105                                        "Got %s, cancelling copy operation.", signal_to_string(r));
106 
107         return 0;
108 }
109 
create_hole(int fd,off_t size)110 static int create_hole(int fd, off_t size) {
111         off_t offset;
112         off_t end;
113 
114         offset = lseek(fd, 0, SEEK_CUR);
115         if (offset < 0)
116                 return -errno;
117 
118         end = lseek(fd, 0, SEEK_END);
119         if (end < 0)
120                 return -errno;
121 
122         /* If we're not at the end of the target file, try to punch a hole in the existing space using fallocate(). */
123 
124         if (offset < end &&
125             fallocate(fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE, offset, MIN(size, end - offset)) < 0 &&
126             !ERRNO_IS_NOT_SUPPORTED(errno))
127                 return -errno;
128 
129         if (end - offset >= size) {
130                 /* If we've created the full hole, set the file pointer to the end of the hole we created and exit. */
131                 if (lseek(fd, offset + size, SEEK_SET) < 0)
132                         return -errno;
133 
134                 return 0;
135         }
136 
137         /* If we haven't created the full hole, use ftruncate() to grow the file (and the hole) to the
138          * required size and move the file pointer to the end of the file. */
139 
140         size -= end - offset;
141 
142         if (ftruncate(fd, end + size) < 0)
143                 return -errno;
144 
145         if (lseek(fd, 0, SEEK_END) < 0)
146                 return -errno;
147 
148         return 0;
149 }
150 
copy_bytes_full(int fdf,int fdt,uint64_t max_bytes,CopyFlags copy_flags,void ** ret_remains,size_t * ret_remains_size,copy_progress_bytes_t progress,void * userdata)151 int copy_bytes_full(
152                 int fdf, int fdt,
153                 uint64_t max_bytes,
154                 CopyFlags copy_flags,
155                 void **ret_remains,
156                 size_t *ret_remains_size,
157                 copy_progress_bytes_t progress,
158                 void *userdata) {
159 
160         bool try_cfr = true, try_sendfile = true, try_splice = true, copied_something = false;
161         int r, nonblock_pipe = -1;
162         size_t m = SSIZE_MAX; /* that is the maximum that sendfile and c_f_r accept */
163 
164         assert(fdf >= 0);
165         assert(fdt >= 0);
166 
167         /* Tries to copy bytes from the file descriptor 'fdf' to 'fdt' in the smartest possible way. Copies a maximum
168          * of 'max_bytes', which may be specified as UINT64_MAX, in which no maximum is applied. Returns negative on
169          * error, zero if EOF is hit before the bytes limit is hit and positive otherwise. If the copy fails for some
170          * reason but we read but didn't yet write some data an ret_remains/ret_remains_size is not NULL, then it will
171          * be initialized with an allocated buffer containing this "remaining" data. Note that these two parameters are
172          * initialized with a valid buffer only on failure and only if there's actually data already read. Otherwise
173          * these parameters if non-NULL are set to NULL. */
174 
175         if (ret_remains)
176                 *ret_remains = NULL;
177         if (ret_remains_size)
178                 *ret_remains_size = 0;
179 
180         /* Try btrfs reflinks first. This only works on regular, seekable files, hence let's check the file offsets of
181          * source and destination first. */
182         if ((copy_flags & COPY_REFLINK)) {
183                 off_t foffset;
184 
185                 foffset = lseek(fdf, 0, SEEK_CUR);
186                 if (foffset >= 0) {
187                         off_t toffset;
188 
189                         toffset = lseek(fdt, 0, SEEK_CUR);
190                         if (toffset >= 0) {
191 
192                                 if (foffset == 0 && toffset == 0 && max_bytes == UINT64_MAX)
193                                         r = btrfs_reflink(fdf, fdt); /* full file reflink */
194                                 else
195                                         r = btrfs_clone_range(fdf, foffset, fdt, toffset, max_bytes == UINT64_MAX ? 0 : max_bytes); /* partial reflink */
196                                 if (r >= 0) {
197                                         off_t t;
198 
199                                         /* This worked, yay! Now — to be fully correct — let's adjust the file pointers */
200                                         if (max_bytes == UINT64_MAX) {
201 
202                                                 /* We cloned to the end of the source file, let's position the read
203                                                  * pointer there, and query it at the same time. */
204                                                 t = lseek(fdf, 0, SEEK_END);
205                                                 if (t < 0)
206                                                         return -errno;
207                                                 if (t < foffset)
208                                                         return -ESPIPE;
209 
210                                                 /* Let's adjust the destination file write pointer by the same number
211                                                  * of bytes. */
212                                                 t = lseek(fdt, toffset + (t - foffset), SEEK_SET);
213                                                 if (t < 0)
214                                                         return -errno;
215 
216                                                 return 0; /* we copied the whole thing, hence hit EOF, return 0 */
217                                         } else {
218                                                 t = lseek(fdf, foffset + max_bytes, SEEK_SET);
219                                                 if (t < 0)
220                                                         return -errno;
221 
222                                                 t = lseek(fdt, toffset + max_bytes, SEEK_SET);
223                                                 if (t < 0)
224                                                         return -errno;
225 
226                                                 return 1; /* we copied only some number of bytes, which worked, but this means we didn't hit EOF, return 1 */
227                                         }
228                                 }
229                         }
230                 }
231         }
232 
233         for (;;) {
234                 ssize_t n;
235 
236                 if (max_bytes <= 0)
237                         return 1; /* return > 0 if we hit the max_bytes limit */
238 
239                 r = look_for_signals(copy_flags);
240                 if (r < 0)
241                         return r;
242 
243                 if (max_bytes != UINT64_MAX && m > max_bytes)
244                         m = max_bytes;
245 
246                 if (copy_flags & COPY_HOLES) {
247                         off_t c, e;
248 
249                         c = lseek(fdf, 0, SEEK_CUR);
250                         if (c < 0)
251                                 return -errno;
252 
253                         /* To see if we're in a hole, we search for the next data offset. */
254                         e = lseek(fdf, c, SEEK_DATA);
255                         if (e < 0 && errno == ENXIO)
256                                 /* If errno == ENXIO, that means we've reached the final hole of the file and
257                                 * that hole isn't followed by more data. */
258                                 e = lseek(fdf, 0, SEEK_END);
259                         if (e < 0)
260                                 return -errno;
261 
262                         /* If we're in a hole (current offset is not a data offset), create a hole of the
263                          * same size in the target file. */
264                         if (e > c) {
265                                 r = create_hole(fdt, e - c);
266                                 if (r < 0)
267                                         return r;
268                         }
269 
270                         c = e; /* Set c to the start of the data segment. */
271 
272                         /* After copying a potential hole, find the end of the data segment by looking for
273                          * the next hole. If we get ENXIO, we're at EOF. */
274                         e = lseek(fdf, c, SEEK_HOLE);
275                         if (e < 0) {
276                                 if (errno == ENXIO)
277                                         break;
278                                 return -errno;
279                         }
280 
281                         /* SEEK_HOLE modifies the file offset so we need to move back to the initial offset. */
282                         if (lseek(fdf, c, SEEK_SET) < 0)
283                                 return -errno;
284 
285                         /* Make sure we're not copying more than the current data segment. */
286                         m = MIN(m, (size_t) e - c);
287                 }
288 
289                 /* First try copy_file_range(), unless we already tried */
290                 if (try_cfr) {
291                         n = try_copy_file_range(fdf, NULL, fdt, NULL, m, 0u);
292                         if (n < 0) {
293                                 if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV, -EBADF))
294                                         return n;
295 
296                                 try_cfr = false;
297                                 /* use fallback below */
298                         } else if (n == 0) { /* likely EOF */
299 
300                                 if (copied_something)
301                                         break;
302 
303                                 /* So, we hit EOF immediately, without having copied a single byte. This
304                                  * could indicate two things: the file is actually empty, or we are on some
305                                  * virtual file system such as procfs/sysfs where the syscall actually
306                                  * doesn't work but doesn't return an error. Try to handle that, by falling
307                                  * back to simple read()s in case we encounter empty files.
308                                  *
309                                  * See: https://lwn.net/Articles/846403/ */
310                                 try_cfr = try_sendfile = try_splice = false;
311                         } else
312                                 /* Success! */
313                                 goto next;
314                 }
315 
316                 /* First try sendfile(), unless we already tried */
317                 if (try_sendfile) {
318                         n = sendfile(fdt, fdf, NULL, m);
319                         if (n < 0) {
320                                 if (!IN_SET(errno, EINVAL, ENOSYS))
321                                         return -errno;
322 
323                                 try_sendfile = false;
324                                 /* use fallback below */
325                         } else if (n == 0) { /* likely EOF */
326 
327                                 if (copied_something)
328                                         break;
329 
330                                 try_sendfile = try_splice = false; /* same logic as above for copy_file_range() */
331                         } else
332                                 /* Success! */
333                                 goto next;
334                 }
335 
336                 /* Then try splice, unless we already tried. */
337                 if (try_splice) {
338 
339                         /* splice()'s asynchronous I/O support is a bit weird. When it encounters a pipe file
340                          * descriptor, then it will ignore its O_NONBLOCK flag and instead only honour the
341                          * SPLICE_F_NONBLOCK flag specified in its flag parameter. Let's hide this behaviour
342                          * here, and check if either of the specified fds are a pipe, and if so, let's pass
343                          * the flag automatically, depending on O_NONBLOCK being set.
344                          *
345                          * Here's a twist though: when we use it to move data between two pipes of which one
346                          * has O_NONBLOCK set and the other has not, then we have no individual control over
347                          * O_NONBLOCK behaviour. Hence in that case we can't use splice() and still guarantee
348                          * systematic O_NONBLOCK behaviour, hence don't. */
349 
350                         if (nonblock_pipe < 0) {
351                                 int a, b;
352 
353                                 /* Check if either of these fds is a pipe, and if so non-blocking or not */
354                                 a = fd_is_nonblock_pipe(fdf);
355                                 if (a < 0)
356                                         return a;
357 
358                                 b = fd_is_nonblock_pipe(fdt);
359                                 if (b < 0)
360                                         return b;
361 
362                                 if ((a == FD_IS_NO_PIPE && b == FD_IS_NO_PIPE) ||
363                                     (a == FD_IS_BLOCKING_PIPE && b == FD_IS_NONBLOCKING_PIPE) ||
364                                     (a == FD_IS_NONBLOCKING_PIPE && b == FD_IS_BLOCKING_PIPE))
365 
366                                         /* splice() only works if one of the fds is a pipe. If neither is,
367                                          * let's skip this step right-away. As mentioned above, if one of the
368                                          * two fds refers to a blocking pipe and the other to a non-blocking
369                                          * pipe, we can't use splice() either, hence don't try either. This
370                                          * hence means we can only use splice() if either only one of the two
371                                          * fds is a pipe, or if both are pipes with the same nonblocking flag
372                                          * setting. */
373 
374                                         try_splice = false;
375                                 else
376                                         nonblock_pipe = a == FD_IS_NONBLOCKING_PIPE || b == FD_IS_NONBLOCKING_PIPE;
377                         }
378                 }
379 
380                 if (try_splice) {
381                         n = splice(fdf, NULL, fdt, NULL, m, nonblock_pipe ? SPLICE_F_NONBLOCK : 0);
382                         if (n < 0) {
383                                 if (!IN_SET(errno, EINVAL, ENOSYS))
384                                         return -errno;
385 
386                                 try_splice = false;
387                                 /* use fallback below */
388                         } else if (n == 0) { /* likely EOF */
389 
390                                 if (copied_something)
391                                         break;
392 
393                                 try_splice = false; /* same logic as above for copy_file_range() + sendfile() */
394                         } else
395                                 /* Success! */
396                                 goto next;
397                 }
398 
399                 /* As a fallback just copy bits by hand */
400                 {
401                         uint8_t buf[MIN(m, COPY_BUFFER_SIZE)], *p = buf;
402                         ssize_t z;
403 
404                         n = read(fdf, buf, sizeof buf);
405                         if (n < 0)
406                                 return -errno;
407                         if (n == 0) /* EOF */
408                                 break;
409 
410                         z = (size_t) n;
411                         do {
412                                 ssize_t k;
413 
414                                 k = write(fdt, p, z);
415                                 if (k < 0) {
416                                         r = -errno;
417 
418                                         if (ret_remains) {
419                                                 void *copy;
420 
421                                                 copy = memdup(p, z);
422                                                 if (!copy)
423                                                         return -ENOMEM;
424 
425                                                 *ret_remains = copy;
426                                         }
427 
428                                         if (ret_remains_size)
429                                                 *ret_remains_size = z;
430 
431                                         return r;
432                                 }
433 
434                                 assert(k <= z);
435                                 z -= k;
436                                 p += k;
437                         } while (z > 0);
438                 }
439 
440         next:
441                 if (progress) {
442                         r = progress(n, userdata);
443                         if (r < 0)
444                                 return r;
445                 }
446 
447                 if (max_bytes != UINT64_MAX) {
448                         assert(max_bytes >= (uint64_t) n);
449                         max_bytes -= n;
450                 }
451 
452                 /* sendfile accepts at most SSIZE_MAX-offset bytes to copy, so reduce our maximum by the
453                  * amount we already copied, but don't go below our copy buffer size, unless we are close the
454                  * limit of bytes we are allowed to copy. */
455                 m = MAX(MIN(COPY_BUFFER_SIZE, max_bytes), m - n);
456 
457                 copied_something = true;
458         }
459 
460         return 0; /* return 0 if we hit EOF earlier than the size limit */
461 }
462 
fd_copy_symlink(int df,const char * from,const struct stat * st,int dt,const char * to,uid_t override_uid,gid_t override_gid,CopyFlags copy_flags)463 static int fd_copy_symlink(
464                 int df,
465                 const char *from,
466                 const struct stat *st,
467                 int dt,
468                 const char *to,
469                 uid_t override_uid,
470                 gid_t override_gid,
471                 CopyFlags copy_flags) {
472 
473         _cleanup_free_ char *target = NULL;
474         int r;
475 
476         assert(from);
477         assert(st);
478         assert(to);
479 
480         r = readlinkat_malloc(df, from, &target);
481         if (r < 0)
482                 return r;
483 
484         if (copy_flags & COPY_MAC_CREATE) {
485                 r = mac_selinux_create_file_prepare_at(dt, to, S_IFLNK);
486                 if (r < 0)
487                         return r;
488         }
489         r = symlinkat(target, dt, to);
490         if (copy_flags & COPY_MAC_CREATE)
491                 mac_selinux_create_file_clear();
492         if (r < 0)
493                 return -errno;
494 
495         if (fchownat(dt, to,
496                      uid_is_valid(override_uid) ? override_uid : st->st_uid,
497                      gid_is_valid(override_gid) ? override_gid : st->st_gid,
498                      AT_SYMLINK_NOFOLLOW) < 0)
499                 r = -errno;
500 
501         (void) utimensat(dt, to, (struct timespec[]) { st->st_atim, st->st_mtim }, AT_SYMLINK_NOFOLLOW);
502         return r;
503 }
504 
505 /* Encapsulates the database we store potential hardlink targets in */
506 typedef struct HardlinkContext {
507         int dir_fd;    /* An fd to the directory we use as lookup table. Never AT_FDCWD. Lazily created, when
508                         * we add the first entry. */
509 
510         /* These two fields are used to create the hardlink repository directory above — via
511          * mkdirat(parent_fd, subdir) — and are kept so that we can automatically remove the directory again
512          * when we are done. */
513         int parent_fd; /* Possibly AT_FDCWD */
514         char *subdir;
515 } HardlinkContext;
516 
hardlink_context_setup(HardlinkContext * c,int dt,const char * to,CopyFlags copy_flags)517 static int hardlink_context_setup(
518                 HardlinkContext *c,
519                 int dt,
520                 const char *to,
521                 CopyFlags copy_flags) {
522 
523         _cleanup_close_ int dt_copy = -1;
524         int r;
525 
526         assert(c);
527         assert(c->dir_fd < 0 && c->dir_fd != AT_FDCWD);
528         assert(c->parent_fd < 0);
529         assert(!c->subdir);
530 
531         /* If hardlink recreation is requested we have to maintain a database of inodes that are potential
532          * hardlink sources. Given that generally disk sizes have to be assumed to be larger than what fits
533          * into physical RAM we cannot maintain that database in dynamic memory alone. Here we opt to
534          * maintain it on disk, to simplify things: inside the destination directory we'll maintain a
535          * temporary directory consisting of hardlinks of every inode we copied that might be subject of
536          * hardlinks. We can then use that as hardlink source later on. Yes, this means additional disk IO
537          * but thankfully Linux is optimized for this kind of thing. If this ever becomes a performance
538          * bottleneck we can certainly place an in-memory hash table in front of this, but for the beginning,
539          * let's keep things simple, and just use the disk as lookup table for inodes.
540          *
541          * Note that this should have zero performance impact as long as .n_link of all files copied remains
542          * <= 0, because in that case we will not actually allocate the hardlink inode lookup table directory
543          * on disk (we do so lazily, when the first candidate with .n_link > 1 is seen). This means, in the
544          * common case where hardlinks are not used at all or only for few files the fact that we store the
545          * table on disk shouldn't matter perfomance-wise. */
546 
547         if (!FLAGS_SET(copy_flags, COPY_HARDLINKS))
548                 return 0;
549 
550         if (dt == AT_FDCWD)
551                 dt_copy = AT_FDCWD;
552         else if (dt < 0)
553                 return -EBADF;
554         else {
555                 dt_copy = fcntl(dt, F_DUPFD_CLOEXEC, 3);
556                 if (dt_copy < 0)
557                         return -errno;
558         }
559 
560         r = tempfn_random_child(to, "hardlink", &c->subdir);
561         if (r < 0)
562                 return r;
563 
564         c->parent_fd = TAKE_FD(dt_copy);
565 
566         /* We don't actually create the directory we keep the table in here, that's done on-demand when the
567          * first entry is added, using hardlink_context_realize() below. */
568         return 1;
569 }
570 
hardlink_context_realize(HardlinkContext * c)571 static int hardlink_context_realize(HardlinkContext *c) {
572         if (!c)
573                 return 0;
574 
575         if (c->dir_fd >= 0) /* Already realized */
576                 return 1;
577 
578         if (c->parent_fd < 0 && c->parent_fd != AT_FDCWD) /* Not configured */
579                 return 0;
580 
581         assert(c->subdir);
582 
583         c->dir_fd = open_mkdir_at(c->parent_fd, c->subdir, O_EXCL|O_CLOEXEC, 0700);
584         if (c->dir_fd < 0)
585                 return c->dir_fd;
586 
587         return 1;
588 }
589 
hardlink_context_destroy(HardlinkContext * c)590 static void hardlink_context_destroy(HardlinkContext *c) {
591         int r;
592 
593         assert(c);
594 
595         /* Automatically remove the hardlink lookup table directory again after we are done. This is used via
596          * _cleanup_() so that we really delete this, even on failure. */
597 
598         if (c->dir_fd >= 0) {
599                 r = rm_rf_children(TAKE_FD(c->dir_fd), REMOVE_PHYSICAL, NULL); /* consumes dir_fd in all cases, even on failure */
600                 if (r < 0)
601                         log_debug_errno(r, "Failed to remove hardlink store (%s) contents, ignoring: %m", c->subdir);
602 
603                 assert(c->parent_fd >= 0 || c->parent_fd == AT_FDCWD);
604                 assert(c->subdir);
605 
606                 if (unlinkat(c->parent_fd, c->subdir, AT_REMOVEDIR) < 0)
607                         log_debug_errno(errno, "Failed to remove hardlink store (%s) directory, ignoring: %m", c->subdir);
608         }
609 
610         assert_cc(AT_FDCWD < 0);
611         c->parent_fd = safe_close(c->parent_fd);
612 
613         c->subdir = mfree(c->subdir);
614 }
615 
try_hardlink(HardlinkContext * c,const struct stat * st,int dt,const char * to)616 static int try_hardlink(
617                 HardlinkContext *c,
618                 const struct stat *st,
619                 int dt,
620                 const char *to) {
621 
622         char dev_ino[DECIMAL_STR_MAX(dev_t)*2 + DECIMAL_STR_MAX(uint64_t) + 4];
623 
624         assert(st);
625         assert(dt >= 0 || dt == AT_FDCWD);
626         assert(to);
627 
628         if (!c) /* No temporary hardlink directory, don't bother */
629                 return 0;
630 
631         if (st->st_nlink <= 1) /* Source not hardlinked, don't bother */
632                 return 0;
633 
634         if (c->dir_fd < 0) /* not yet realized, hence empty */
635                 return 0;
636 
637         xsprintf(dev_ino, "%u:%u:%" PRIu64, major(st->st_dev), minor(st->st_dev), (uint64_t) st->st_ino);
638         if (linkat(c->dir_fd, dev_ino, dt, to, 0) < 0)  {
639                 if (errno != ENOENT) /* doesn't exist in store yet */
640                         log_debug_errno(errno, "Failed to hardlink %s to %s, ignoring: %m", dev_ino, to);
641                 return 0;
642         }
643 
644         return 1;
645 }
646 
memorize_hardlink(HardlinkContext * c,const struct stat * st,int dt,const char * to)647 static int memorize_hardlink(
648                 HardlinkContext *c,
649                 const struct stat *st,
650                 int dt,
651                 const char *to) {
652 
653         char dev_ino[DECIMAL_STR_MAX(dev_t)*2 + DECIMAL_STR_MAX(uint64_t) + 4];
654         int r;
655 
656         assert(st);
657         assert(dt >= 0 || dt == AT_FDCWD);
658         assert(to);
659 
660         if (!c) /* No temporary hardlink directory, don't bother */
661                 return 0;
662 
663         if (st->st_nlink <= 1) /* Source not hardlinked, don't bother */
664                 return 0;
665 
666         r = hardlink_context_realize(c); /* Create the hardlink store lazily */
667         if (r < 0)
668                 return r;
669 
670         xsprintf(dev_ino, "%u:%u:%" PRIu64, major(st->st_dev), minor(st->st_dev), (uint64_t) st->st_ino);
671         if (linkat(dt, to, c->dir_fd, dev_ino, 0) < 0) {
672                 log_debug_errno(errno, "Failed to hardlink %s to %s, ignoring: %m", to, dev_ino);
673                 return 0;
674         }
675 
676         return 1;
677 }
678 
fd_copy_regular(int df,const char * from,const struct stat * st,int dt,const char * to,uid_t override_uid,gid_t override_gid,CopyFlags copy_flags,HardlinkContext * hardlink_context,copy_progress_bytes_t progress,void * userdata)679 static int fd_copy_regular(
680                 int df,
681                 const char *from,
682                 const struct stat *st,
683                 int dt,
684                 const char *to,
685                 uid_t override_uid,
686                 gid_t override_gid,
687                 CopyFlags copy_flags,
688                 HardlinkContext *hardlink_context,
689                 copy_progress_bytes_t progress,
690                 void *userdata) {
691 
692         _cleanup_close_ int fdf = -1, fdt = -1;
693         int r, q;
694 
695         assert(from);
696         assert(st);
697         assert(to);
698 
699         r = try_hardlink(hardlink_context, st, dt, to);
700         if (r < 0)
701                 return r;
702         if (r > 0) /* worked! */
703                 return 0;
704 
705         fdf = openat(df, from, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
706         if (fdf < 0)
707                 return -errno;
708 
709         if (copy_flags & COPY_MAC_CREATE) {
710                 r = mac_selinux_create_file_prepare_at(dt, to, S_IFREG);
711                 if (r < 0)
712                         return r;
713         }
714         fdt = openat(dt, to, O_WRONLY|O_CREAT|O_EXCL|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, st->st_mode & 07777);
715         if (copy_flags & COPY_MAC_CREATE)
716                 mac_selinux_create_file_clear();
717         if (fdt < 0)
718                 return -errno;
719 
720         r = copy_bytes_full(fdf, fdt, UINT64_MAX, copy_flags, NULL, NULL, progress, userdata);
721         if (r < 0)
722                 goto fail;
723 
724         if (fchown(fdt,
725                    uid_is_valid(override_uid) ? override_uid : st->st_uid,
726                    gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
727                 r = -errno;
728 
729         if (fchmod(fdt, st->st_mode & 07777) < 0)
730                 r = -errno;
731 
732         (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
733         (void) copy_xattr(fdf, fdt, copy_flags);
734 
735         if (copy_flags & COPY_FSYNC) {
736                 if (fsync(fdt) < 0) {
737                         r = -errno;
738                         goto fail;
739                 }
740         }
741 
742         q = close_nointr(TAKE_FD(fdt)); /* even if this fails, the fd is now invalidated */
743         if (q < 0) {
744                 r = q;
745                 goto fail;
746         }
747 
748         (void) memorize_hardlink(hardlink_context, st, dt, to);
749         return r;
750 
751 fail:
752         (void) unlinkat(dt, to, 0);
753         return r;
754 }
755 
fd_copy_fifo(int df,const char * from,const struct stat * st,int dt,const char * to,uid_t override_uid,gid_t override_gid,CopyFlags copy_flags,HardlinkContext * hardlink_context)756 static int fd_copy_fifo(
757                 int df,
758                 const char *from,
759                 const struct stat *st,
760                 int dt,
761                 const char *to,
762                 uid_t override_uid,
763                 gid_t override_gid,
764                 CopyFlags copy_flags,
765                 HardlinkContext *hardlink_context) {
766         int r;
767 
768         assert(from);
769         assert(st);
770         assert(to);
771 
772         r = try_hardlink(hardlink_context, st, dt, to);
773         if (r < 0)
774                 return r;
775         if (r > 0) /* worked! */
776                 return 0;
777 
778         if (copy_flags & COPY_MAC_CREATE) {
779                 r = mac_selinux_create_file_prepare_at(dt, to, S_IFIFO);
780                 if (r < 0)
781                         return r;
782         }
783         r = mkfifoat(dt, to, st->st_mode & 07777);
784         if (copy_flags & COPY_MAC_CREATE)
785                 mac_selinux_create_file_clear();
786         if (r < 0)
787                 return -errno;
788 
789         if (fchownat(dt, to,
790                      uid_is_valid(override_uid) ? override_uid : st->st_uid,
791                      gid_is_valid(override_gid) ? override_gid : st->st_gid,
792                      AT_SYMLINK_NOFOLLOW) < 0)
793                 r = -errno;
794 
795         if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
796                 r = -errno;
797 
798         (void) utimensat(dt, to, (struct timespec[]) { st->st_atim, st->st_mtim }, AT_SYMLINK_NOFOLLOW);
799 
800         (void) memorize_hardlink(hardlink_context, st, dt, to);
801         return r;
802 }
803 
fd_copy_node(int df,const char * from,const struct stat * st,int dt,const char * to,uid_t override_uid,gid_t override_gid,CopyFlags copy_flags,HardlinkContext * hardlink_context)804 static int fd_copy_node(
805                 int df,
806                 const char *from,
807                 const struct stat *st,
808                 int dt,
809                 const char *to,
810                 uid_t override_uid,
811                 gid_t override_gid,
812                 CopyFlags copy_flags,
813                 HardlinkContext *hardlink_context) {
814         int r;
815 
816         assert(from);
817         assert(st);
818         assert(to);
819 
820         r = try_hardlink(hardlink_context, st, dt, to);
821         if (r < 0)
822                 return r;
823         if (r > 0) /* worked! */
824                 return 0;
825 
826         if (copy_flags & COPY_MAC_CREATE) {
827                 r = mac_selinux_create_file_prepare_at(dt, to, st->st_mode & S_IFMT);
828                 if (r < 0)
829                         return r;
830         }
831         r = mknodat(dt, to, st->st_mode, st->st_rdev);
832         if (copy_flags & COPY_MAC_CREATE)
833                 mac_selinux_create_file_clear();
834         if (r < 0)
835                 return -errno;
836 
837         if (fchownat(dt, to,
838                      uid_is_valid(override_uid) ? override_uid : st->st_uid,
839                      gid_is_valid(override_gid) ? override_gid : st->st_gid,
840                      AT_SYMLINK_NOFOLLOW) < 0)
841                 r = -errno;
842 
843         if (fchmodat(dt, to, st->st_mode & 07777, 0) < 0)
844                 r = -errno;
845 
846         (void) utimensat(dt, to, (struct timespec[]) { st->st_atim, st->st_mtim }, AT_SYMLINK_NOFOLLOW);
847 
848         (void) memorize_hardlink(hardlink_context, st, dt, to);
849         return r;
850 }
851 
fd_copy_directory(int df,const char * from,const struct stat * st,int dt,const char * to,dev_t original_device,unsigned depth_left,uid_t override_uid,gid_t override_gid,CopyFlags copy_flags,HardlinkContext * hardlink_context,const char * display_path,copy_progress_path_t progress_path,copy_progress_bytes_t progress_bytes,void * userdata)852 static int fd_copy_directory(
853                 int df,
854                 const char *from,
855                 const struct stat *st,
856                 int dt,
857                 const char *to,
858                 dev_t original_device,
859                 unsigned depth_left,
860                 uid_t override_uid,
861                 gid_t override_gid,
862                 CopyFlags copy_flags,
863                 HardlinkContext *hardlink_context,
864                 const char *display_path,
865                 copy_progress_path_t progress_path,
866                 copy_progress_bytes_t progress_bytes,
867                 void *userdata) {
868 
869         _cleanup_(hardlink_context_destroy) HardlinkContext our_hardlink_context = {
870                 .dir_fd = -1,
871                 .parent_fd = -1,
872         };
873 
874         _cleanup_close_ int fdf = -1, fdt = -1;
875         _cleanup_closedir_ DIR *d = NULL;
876         bool exists, created;
877         int r;
878 
879         assert(st);
880         assert(to);
881 
882         if (depth_left == 0)
883                 return -ENAMETOOLONG;
884 
885         if (from)
886                 fdf = openat(df, from, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
887         else
888                 fdf = fcntl(df, F_DUPFD_CLOEXEC, 3);
889         if (fdf < 0)
890                 return -errno;
891 
892         if (!hardlink_context) {
893                 /* If recreating hardlinks is requested let's set up a context for that now. */
894                 r = hardlink_context_setup(&our_hardlink_context, dt, to, copy_flags);
895                 if (r < 0)
896                         return r;
897                 if (r > 0) /* It's enabled and allocated, let's now use the same context for all recursive
898                             * invocations from here down */
899                         hardlink_context = &our_hardlink_context;
900         }
901 
902         d = take_fdopendir(&fdf);
903         if (!d)
904                 return -errno;
905 
906         exists = false;
907         if (copy_flags & COPY_MERGE_EMPTY) {
908                 r = dir_is_empty_at(dt, to, /* ignore_hidden_or_backup= */ false);
909                 if (r < 0 && r != -ENOENT)
910                         return r;
911                 else if (r == 1)
912                         exists = true;
913         }
914 
915         if (exists)
916                 created = false;
917         else {
918                 if (copy_flags & COPY_MAC_CREATE)
919                         r = mkdirat_label(dt, to, st->st_mode & 07777);
920                 else
921                         r = mkdirat(dt, to, st->st_mode & 07777);
922                 if (r >= 0)
923                         created = true;
924                 else if (errno == EEXIST && (copy_flags & COPY_MERGE))
925                         created = false;
926                 else
927                         return -errno;
928         }
929 
930         fdt = openat(dt, to, O_RDONLY|O_DIRECTORY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
931         if (fdt < 0)
932                 return -errno;
933 
934         r = 0;
935 
936         FOREACH_DIRENT_ALL(de, d, return -errno) {
937                 const char *child_display_path = NULL;
938                 _cleanup_free_ char *dp = NULL;
939                 struct stat buf;
940                 int q;
941 
942                 if (dot_or_dot_dot(de->d_name))
943                         continue;
944 
945                 r = look_for_signals(copy_flags);
946                 if (r < 0)
947                         return r;
948 
949                 if (fstatat(dirfd(d), de->d_name, &buf, AT_SYMLINK_NOFOLLOW) < 0) {
950                         r = -errno;
951                         continue;
952                 }
953 
954                 if (progress_path) {
955                         if (display_path)
956                                 child_display_path = dp = path_join(display_path, de->d_name);
957                         else
958                                 child_display_path = de->d_name;
959 
960                         r = progress_path(child_display_path, &buf, userdata);
961                         if (r < 0)
962                                 return r;
963                 }
964 
965                 if (S_ISDIR(buf.st_mode)) {
966                         /*
967                          * Don't descend into directories on other file systems, if this is requested. We do a simple
968                          * .st_dev check here, which basically comes for free. Note that we do this check only on
969                          * directories, not other kind of file system objects, for two reason:
970                          *
971                          * • The kernel's overlayfs pseudo file system that overlays multiple real file systems
972                          *   propagates the .st_dev field of the file system a file originates from all the way up
973                          *   through the stack to stat(). It doesn't do that for directories however. This means that
974                          *   comparing .st_dev on non-directories suggests that they all are mount points. To avoid
975                          *   confusion we hence avoid relying on this check for regular files.
976                          *
977                          * • The main reason we do this check at all is to protect ourselves from bind mount cycles,
978                          *   where we really want to avoid descending down in all eternity. However the .st_dev check
979                          *   is usually not sufficient for this protection anyway, as bind mount cycles from the same
980                          *   file system onto itself can't be detected that way. (Note we also do a recursion depth
981                          *   check, which is probably the better protection in this regard, which is why
982                          *   COPY_SAME_MOUNT is optional).
983                          */
984 
985                         if (FLAGS_SET(copy_flags, COPY_SAME_MOUNT)) {
986                                 if (buf.st_dev != original_device)
987                                         continue;
988 
989                                 r = fd_is_mount_point(dirfd(d), de->d_name, 0);
990                                 if (r < 0)
991                                         return r;
992                                 if (r > 0)
993                                         continue;
994                         }
995 
996                         q = fd_copy_directory(dirfd(d), de->d_name, &buf, fdt, de->d_name, original_device, depth_left-1, override_uid, override_gid, copy_flags, hardlink_context, child_display_path, progress_path, progress_bytes, userdata);
997                 } else if (S_ISREG(buf.st_mode))
998                         q = fd_copy_regular(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, hardlink_context, progress_bytes, userdata);
999                 else if (S_ISLNK(buf.st_mode))
1000                         q = fd_copy_symlink(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags);
1001                 else if (S_ISFIFO(buf.st_mode))
1002                         q = fd_copy_fifo(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, hardlink_context);
1003                 else if (S_ISBLK(buf.st_mode) || S_ISCHR(buf.st_mode) || S_ISSOCK(buf.st_mode))
1004                         q = fd_copy_node(dirfd(d), de->d_name, &buf, fdt, de->d_name, override_uid, override_gid, copy_flags, hardlink_context);
1005                 else
1006                         q = -EOPNOTSUPP;
1007 
1008                 if (q == -EINTR) /* Propagate SIGINT/SIGTERM up instantly */
1009                         return q;
1010                 if (q == -EEXIST && (copy_flags & COPY_MERGE))
1011                         q = 0;
1012                 if (q < 0)
1013                         r = q;
1014         }
1015 
1016         if (created) {
1017                 if (fchown(fdt,
1018                            uid_is_valid(override_uid) ? override_uid : st->st_uid,
1019                            gid_is_valid(override_gid) ? override_gid : st->st_gid) < 0)
1020                         r = -errno;
1021 
1022                 if (fchmod(fdt, st->st_mode & 07777) < 0)
1023                         r = -errno;
1024 
1025                 (void) copy_xattr(dirfd(d), fdt, copy_flags);
1026                 (void) futimens(fdt, (struct timespec[]) { st->st_atim, st->st_mtim });
1027         }
1028 
1029         if (copy_flags & COPY_FSYNC_FULL) {
1030                 if (fsync(fdt) < 0)
1031                         return -errno;
1032         }
1033 
1034         return r;
1035 }
1036 
copy_tree_at_full(int fdf,const char * from,int fdt,const char * to,uid_t override_uid,gid_t override_gid,CopyFlags copy_flags,copy_progress_path_t progress_path,copy_progress_bytes_t progress_bytes,void * userdata)1037 int copy_tree_at_full(
1038                 int fdf,
1039                 const char *from,
1040                 int fdt,
1041                 const char *to,
1042                 uid_t override_uid,
1043                 gid_t override_gid,
1044                 CopyFlags copy_flags,
1045                 copy_progress_path_t progress_path,
1046                 copy_progress_bytes_t progress_bytes,
1047                 void *userdata) {
1048 
1049         struct stat st;
1050         int r;
1051 
1052         assert(from);
1053         assert(to);
1054 
1055         if (fstatat(fdf, from, &st, AT_SYMLINK_NOFOLLOW) < 0)
1056                 return -errno;
1057 
1058         if (S_ISREG(st.st_mode))
1059                 r = fd_copy_regular(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL, progress_bytes, userdata);
1060         else if (S_ISDIR(st.st_mode))
1061                 r = fd_copy_directory(fdf, from, &st, fdt, to, st.st_dev, COPY_DEPTH_MAX, override_uid, override_gid, copy_flags, NULL, NULL, progress_path, progress_bytes, userdata);
1062         else if (S_ISLNK(st.st_mode))
1063                 r = fd_copy_symlink(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags);
1064         else if (S_ISFIFO(st.st_mode))
1065                 r = fd_copy_fifo(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
1066         else if (S_ISBLK(st.st_mode) || S_ISCHR(st.st_mode) || S_ISSOCK(st.st_mode))
1067                 r = fd_copy_node(fdf, from, &st, fdt, to, override_uid, override_gid, copy_flags, NULL);
1068         else
1069                 return -EOPNOTSUPP;
1070         if (r < 0)
1071                 return r;
1072 
1073         if (S_ISDIR(st.st_mode) && (copy_flags & COPY_SYNCFS)) {
1074                 /* If the top-level inode is a directory run syncfs() now. */
1075                 r = syncfs_path(fdt, to);
1076                 if (r < 0)
1077                         return r;
1078         } else if ((copy_flags & (COPY_FSYNC_FULL|COPY_SYNCFS)) != 0) {
1079                 /* fsync() the parent dir of what we just copied if COPY_FSYNC_FULL is set. Also do this in
1080                  * case COPY_SYNCFS is set but the top-level inode wasn't actually a directory. We do this so that
1081                  * COPY_SYNCFS provides reasonable synchronization semantics on any kind of inode: when the
1082                  * copy operation is done the whole inode — regardless of its type — and all its children
1083                  * will be synchronized to disk. */
1084                 r = fsync_parent_at(fdt, to);
1085                 if (r < 0)
1086                         return r;
1087         }
1088 
1089         return 0;
1090 }
1091 
sync_dir_by_flags(const char * path,CopyFlags copy_flags)1092 static int sync_dir_by_flags(const char *path, CopyFlags copy_flags) {
1093 
1094         if (copy_flags & COPY_SYNCFS)
1095                 return syncfs_path(AT_FDCWD, path);
1096         if (copy_flags & COPY_FSYNC_FULL)
1097                 return fsync_parent_at(AT_FDCWD, path);
1098 
1099         return 0;
1100 }
1101 
copy_directory_fd_full(int dirfd,const char * to,CopyFlags copy_flags,copy_progress_path_t progress_path,copy_progress_bytes_t progress_bytes,void * userdata)1102 int copy_directory_fd_full(
1103                 int dirfd,
1104                 const char *to,
1105                 CopyFlags copy_flags,
1106                 copy_progress_path_t progress_path,
1107                 copy_progress_bytes_t progress_bytes,
1108                 void *userdata) {
1109 
1110         struct stat st;
1111         int r;
1112 
1113         assert(dirfd >= 0);
1114         assert(to);
1115 
1116         if (fstat(dirfd, &st) < 0)
1117                 return -errno;
1118 
1119         r = stat_verify_directory(&st);
1120         if (r < 0)
1121                 return r;
1122 
1123         r = fd_copy_directory(
1124                         dirfd, NULL,
1125                         &st,
1126                         AT_FDCWD, to,
1127                         st.st_dev,
1128                         COPY_DEPTH_MAX,
1129                         UID_INVALID, GID_INVALID,
1130                         copy_flags,
1131                         NULL, NULL,
1132                         progress_path,
1133                         progress_bytes,
1134                         userdata);
1135         if (r < 0)
1136                 return r;
1137 
1138         r = sync_dir_by_flags(to, copy_flags);
1139         if (r < 0)
1140                 return r;
1141 
1142         return 0;
1143 }
1144 
copy_directory_full(const char * from,const char * to,CopyFlags copy_flags,copy_progress_path_t progress_path,copy_progress_bytes_t progress_bytes,void * userdata)1145 int copy_directory_full(
1146                 const char *from,
1147                 const char *to,
1148                 CopyFlags copy_flags,
1149                 copy_progress_path_t progress_path,
1150                 copy_progress_bytes_t progress_bytes,
1151                 void *userdata) {
1152 
1153         struct stat st;
1154         int r;
1155 
1156         assert(from);
1157         assert(to);
1158 
1159         if (lstat(from, &st) < 0)
1160                 return -errno;
1161 
1162         r = stat_verify_directory(&st);
1163         if (r < 0)
1164                 return r;
1165 
1166         r = fd_copy_directory(
1167                         AT_FDCWD, from,
1168                         &st,
1169                         AT_FDCWD, to,
1170                         st.st_dev,
1171                         COPY_DEPTH_MAX,
1172                         UID_INVALID, GID_INVALID,
1173                         copy_flags,
1174                         NULL, NULL,
1175                         progress_path,
1176                         progress_bytes,
1177                         userdata);
1178         if (r < 0)
1179                 return r;
1180 
1181         r = sync_dir_by_flags(to, copy_flags);
1182         if (r < 0)
1183                 return r;
1184 
1185         return 0;
1186 }
1187 
copy_file_fd_full(const char * from,int fdt,CopyFlags copy_flags,copy_progress_bytes_t progress_bytes,void * userdata)1188 int copy_file_fd_full(
1189                 const char *from,
1190                 int fdt,
1191                 CopyFlags copy_flags,
1192                 copy_progress_bytes_t progress_bytes,
1193                 void *userdata) {
1194 
1195         _cleanup_close_ int fdf = -1;
1196         struct stat st;
1197         int r;
1198 
1199         assert(from);
1200         assert(fdt >= 0);
1201 
1202         fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
1203         if (fdf < 0)
1204                 return -errno;
1205 
1206         r = fd_verify_regular(fdf);
1207         if (r < 0)
1208                 return r;
1209 
1210         if (fstat(fdt, &st) < 0)
1211                 return -errno;
1212 
1213         r = copy_bytes_full(fdf, fdt, UINT64_MAX, copy_flags, NULL, NULL, progress_bytes, userdata);
1214         if (r < 0)
1215                 return r;
1216 
1217         /* Make sure to copy file attributes only over if target is a regular
1218          * file (so that copying a file to /dev/null won't alter the access
1219          * mode/ownership of that device node...) */
1220         if (S_ISREG(st.st_mode)) {
1221                 (void) copy_times(fdf, fdt, copy_flags);
1222                 (void) copy_xattr(fdf, fdt, copy_flags);
1223         }
1224 
1225         if (copy_flags & COPY_FSYNC_FULL) {
1226                 r = fsync_full(fdt);
1227                 if (r < 0)
1228                         return r;
1229         } else if (copy_flags & COPY_FSYNC) {
1230                 if (fsync(fdt) < 0)
1231                         return -errno;
1232         }
1233 
1234         return 0;
1235 }
1236 
copy_file_full(const char * from,const char * to,int flags,mode_t mode,unsigned chattr_flags,unsigned chattr_mask,CopyFlags copy_flags,copy_progress_bytes_t progress_bytes,void * userdata)1237 int copy_file_full(
1238                 const char *from,
1239                 const char *to,
1240                 int flags,
1241                 mode_t mode,
1242                 unsigned chattr_flags,
1243                 unsigned chattr_mask,
1244                 CopyFlags copy_flags,
1245                 copy_progress_bytes_t progress_bytes,
1246                 void *userdata) {
1247 
1248         _cleanup_close_ int fdf = -1, fdt = -1;
1249         struct stat st;
1250         int r;
1251 
1252         assert(from);
1253         assert(to);
1254 
1255         fdf = open(from, O_RDONLY|O_CLOEXEC|O_NOCTTY);
1256         if (fdf < 0)
1257                 return -errno;
1258 
1259         if (fstat(fdf, &st) < 0)
1260                 return -errno;
1261 
1262         r = stat_verify_regular(&st);
1263         if (r < 0)
1264                 return r;
1265 
1266         RUN_WITH_UMASK(0000) {
1267                 if (copy_flags & COPY_MAC_CREATE) {
1268                         r = mac_selinux_create_file_prepare(to, S_IFREG);
1269                         if (r < 0)
1270                                 return r;
1271                 }
1272                 fdt = open(to, flags|O_WRONLY|O_CREAT|O_CLOEXEC|O_NOCTTY,
1273                            mode != MODE_INVALID ? mode : st.st_mode);
1274                 if (copy_flags & COPY_MAC_CREATE)
1275                         mac_selinux_create_file_clear();
1276                 if (fdt < 0)
1277                         return -errno;
1278         }
1279 
1280         if (!FLAGS_SET(flags, O_EXCL)) { /* if O_EXCL was used we created the thing as regular file, no need to check again */
1281                 r = fd_verify_regular(fdt);
1282                 if (r < 0)
1283                         goto fail;
1284         }
1285 
1286         if (chattr_mask != 0)
1287                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
1288 
1289         r = copy_bytes_full(fdf, fdt, UINT64_MAX, copy_flags, NULL, NULL, progress_bytes, userdata);
1290         if (r < 0)
1291                 goto fail;
1292 
1293         (void) copy_times(fdf, fdt, copy_flags);
1294         (void) copy_xattr(fdf, fdt, copy_flags);
1295 
1296         if (chattr_mask != 0)
1297                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
1298 
1299         if (copy_flags & (COPY_FSYNC|COPY_FSYNC_FULL)) {
1300                 if (fsync(fdt) < 0) {
1301                         r = -errno;
1302                         goto fail;
1303                 }
1304         }
1305 
1306         r = close_nointr(TAKE_FD(fdt)); /* even if this fails, the fd is now invalidated */
1307         if (r < 0)
1308                 goto fail;
1309 
1310         if (copy_flags & COPY_FSYNC_FULL) {
1311                 r = fsync_parent_at(AT_FDCWD, to);
1312                 if (r < 0)
1313                         goto fail;
1314         }
1315 
1316         return 0;
1317 
1318 fail:
1319         /* Only unlink if we definitely are the ones who created the file */
1320         if (FLAGS_SET(flags, O_EXCL))
1321                 (void) unlink(to);
1322 
1323         return r;
1324 }
1325 
copy_file_atomic_full(const char * from,const char * to,mode_t mode,unsigned chattr_flags,unsigned chattr_mask,CopyFlags copy_flags,copy_progress_bytes_t progress_bytes,void * userdata)1326 int copy_file_atomic_full(
1327                 const char *from,
1328                 const char *to,
1329                 mode_t mode,
1330                 unsigned chattr_flags,
1331                 unsigned chattr_mask,
1332                 CopyFlags copy_flags,
1333                 copy_progress_bytes_t progress_bytes,
1334                 void *userdata) {
1335 
1336         _cleanup_(unlink_and_freep) char *t = NULL;
1337         _cleanup_close_ int fdt = -1;
1338         int r;
1339 
1340         assert(from);
1341         assert(to);
1342 
1343         /* We try to use O_TMPFILE here to create the file if we can. Note that this only works if COPY_REPLACE is not
1344          * set though as we need to use linkat() for linking the O_TMPFILE file into the file system but that system
1345          * call can't replace existing files. Hence, if COPY_REPLACE is set we create a temporary name in the file
1346          * system right-away and unconditionally which we then can renameat() to the right name after we completed
1347          * writing it. */
1348 
1349         if (copy_flags & COPY_REPLACE) {
1350                 _cleanup_free_ char *f = NULL;
1351 
1352                 r = tempfn_random(to, NULL, &f);
1353                 if (r < 0)
1354                         return r;
1355 
1356                 if (copy_flags & COPY_MAC_CREATE) {
1357                         r = mac_selinux_create_file_prepare(to, S_IFREG);
1358                         if (r < 0)
1359                                 return r;
1360                 }
1361                 fdt = open(f, O_CREAT|O_EXCL|O_NOFOLLOW|O_NOCTTY|O_WRONLY|O_CLOEXEC, 0600);
1362                 if (copy_flags & COPY_MAC_CREATE)
1363                         mac_selinux_create_file_clear();
1364                 if (fdt < 0)
1365                         return -errno;
1366 
1367                 t = TAKE_PTR(f);
1368         } else {
1369                 if (copy_flags & COPY_MAC_CREATE) {
1370                         r = mac_selinux_create_file_prepare(to, S_IFREG);
1371                         if (r < 0)
1372                                 return r;
1373                 }
1374                 fdt = open_tmpfile_linkable(to, O_WRONLY|O_CLOEXEC, &t);
1375                 if (copy_flags & COPY_MAC_CREATE)
1376                         mac_selinux_create_file_clear();
1377                 if (fdt < 0)
1378                         return fdt;
1379         }
1380 
1381         if (chattr_mask != 0)
1382                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & CHATTR_EARLY_FL, NULL);
1383 
1384         r = copy_file_fd_full(from, fdt, copy_flags, progress_bytes, userdata);
1385         if (r < 0)
1386                 return r;
1387 
1388         if (fchmod(fdt, mode) < 0)
1389                 return -errno;
1390 
1391         if ((copy_flags & (COPY_FSYNC|COPY_FSYNC_FULL))) {
1392                 /* Sync the file */
1393                 if (fsync(fdt) < 0)
1394                         return -errno;
1395         }
1396 
1397         if (copy_flags & COPY_REPLACE) {
1398                 if (renameat(AT_FDCWD, t, AT_FDCWD, to) < 0)
1399                         return -errno;
1400         } else {
1401                 r = link_tmpfile(fdt, t, to);
1402                 if (r < 0)
1403                         return r;
1404         }
1405 
1406         t = mfree(t);
1407 
1408         if (chattr_mask != 0)
1409                 (void) chattr_fd(fdt, chattr_flags, chattr_mask & ~CHATTR_EARLY_FL, NULL);
1410 
1411         r = close_nointr(TAKE_FD(fdt)); /* even if this fails, the fd is now invalidated */
1412         if (r < 0)
1413                 goto fail;
1414 
1415         if (copy_flags & COPY_FSYNC_FULL) {
1416                 /* Sync the parent directory */
1417                 r = fsync_parent_at(AT_FDCWD, to);
1418                 if (r < 0)
1419                         goto fail;
1420         }
1421 
1422         return 0;
1423 
1424 fail:
1425         (void) unlink(to);
1426         return r;
1427 }
1428 
copy_times(int fdf,int fdt,CopyFlags flags)1429 int copy_times(int fdf, int fdt, CopyFlags flags) {
1430         struct stat st;
1431 
1432         assert(fdf >= 0);
1433         assert(fdt >= 0);
1434 
1435         if (fstat(fdf, &st) < 0)
1436                 return -errno;
1437 
1438         if (futimens(fdt, (struct timespec[2]) { st.st_atim, st.st_mtim }) < 0)
1439                 return -errno;
1440 
1441         if (FLAGS_SET(flags, COPY_CRTIME)) {
1442                 usec_t crtime;
1443 
1444                 if (fd_getcrtime(fdf, &crtime) >= 0)
1445                         (void) fd_setcrtime(fdt, crtime);
1446         }
1447 
1448         return 0;
1449 }
1450 
copy_access(int fdf,int fdt)1451 int copy_access(int fdf, int fdt) {
1452         struct stat st;
1453 
1454         assert(fdf >= 0);
1455         assert(fdt >= 0);
1456 
1457         /* Copies just the access mode (and not the ownership) from fdf to fdt */
1458 
1459         if (fstat(fdf, &st) < 0)
1460                 return -errno;
1461 
1462         return RET_NERRNO(fchmod(fdt, st.st_mode & 07777));
1463 }
1464 
copy_rights_with_fallback(int fdf,int fdt,const char * patht)1465 int copy_rights_with_fallback(int fdf, int fdt, const char *patht) {
1466         struct stat st;
1467 
1468         assert(fdf >= 0);
1469         assert(fdt >= 0);
1470 
1471         /* Copies both access mode and ownership from fdf to fdt */
1472 
1473         if (fstat(fdf, &st) < 0)
1474                 return -errno;
1475 
1476         return fchmod_and_chown_with_fallback(fdt, patht, st.st_mode & 07777, st.st_uid, st.st_gid);
1477 }
1478 
copy_xattr(int fdf,int fdt,CopyFlags copy_flags)1479 int copy_xattr(int fdf, int fdt, CopyFlags copy_flags) {
1480         _cleanup_free_ char *names = NULL;
1481         int ret = 0, r;
1482         const char *p;
1483 
1484         r = flistxattr_malloc(fdf, &names);
1485         if (r < 0)
1486                 return r;
1487 
1488         NULSTR_FOREACH(p, names) {
1489                 _cleanup_free_ char *value = NULL;
1490 
1491                 if (!FLAGS_SET(copy_flags, COPY_ALL_XATTRS) && !startswith(p, "user."))
1492                         continue;
1493 
1494                 r = fgetxattr_malloc(fdf, p, &value);
1495                 if (r == -ENODATA)
1496                         continue; /* gone by now */
1497                 if (r < 0)
1498                         return r;
1499 
1500                 if (fsetxattr(fdt, p, value, r, 0) < 0)
1501                         ret = -errno;
1502         }
1503 
1504         return ret;
1505 }
1506