cp: Don't copy the set-uid or set-gid bits

Also simplify the file copying logic a bit to avoid two syscalls
per file. We now create the file with the right mode right away
instead of creating it first, and then fchmod'ing it later.

Fixes #4479.
This commit is contained in:
Andreas Kling 2020-12-23 01:02:04 +01:00
parent 75da835ffb
commit 8653128ca8
Notes: sideshowbarker 2024-07-19 00:39:50 +09:00

View file

@ -37,9 +37,11 @@
#include <unistd.h>
bool copy_file_or_directory(String, String, bool);
bool copy_file(String, String, struct stat, int);
bool copy_file(String, String, const struct stat&, int);
bool copy_directory(String, String);
static mode_t my_umask = 0;
int main(int argc, char** argv)
{
if (pledge("stdio rpath wpath cpath fattr", nullptr) < 0) {
@ -59,6 +61,9 @@ int main(int argc, char** argv)
args_parser.add_positional_argument(destination, "Destination file path", "destination");
args_parser.parse(argc, argv);
auto my_umask = umask(0);
umask(my_umask);
for (auto& source : sources) {
bool ok = copy_file_or_directory(source, destination, recursion_allowed);
if (!ok)
@ -106,9 +111,12 @@ bool copy_file_or_directory(String src_path, String dst_path, bool recursion_all
*
* To avoid repeated work, the source file's stat and file descriptor are required.
*/
bool copy_file(String src_path, String dst_path, struct stat src_stat, int src_fd)
bool copy_file(String src_path, String dst_path, const struct stat& src_stat, int src_fd)
{
int dst_fd = creat(dst_path.characters(), 0666);
// NOTE: We don't copy the set-uid and set-gid bits.
mode_t mode = (src_stat.st_mode & ~my_umask) & ~06000;
int dst_fd = creat(dst_path.characters(), mode);
if (dst_fd < 0) {
if (errno != EISDIR) {
perror("open dst");
@ -156,14 +164,6 @@ bool copy_file(String src_path, String dst_path, struct stat src_stat, int src_f
}
}
auto my_umask = umask(0);
umask(my_umask);
int rc = fchmod(dst_fd, src_stat.st_mode & ~my_umask);
if (rc < 0) {
perror("fchmod dst");
return false;
}
close(src_fd);
close(dst_fd);
return true;