@@ -166,7 +166,10 @@ void Machine::setup_linux_system_calls()
166
166
Machine::install_syscall_handler (
167
167
SYS_lseek, [] (vCPU& cpu) { // LSEEK
168
168
auto & regs = cpu.registers ();
169
- const int fd = cpu.machine ().fds ().translate (regs.rdi );
169
+ int fd = regs.rdi ;
170
+ if (fd > 2 ) {
171
+ fd = cpu.machine ().fds ().translate (regs.rdi );
172
+ }
170
173
regs.rax = lseek (fd, regs.rsi , regs.rdx );
171
174
cpu.set_registers (regs);
172
175
});
@@ -611,6 +614,27 @@ void Machine::setup_linux_system_calls()
611
614
}
612
615
cpu.set_registers (regs);
613
616
});
617
+ Machine::install_syscall_handler (
618
+ SYS_dup, [](vCPU& cpu) { // DUP
619
+ auto & regs = cpu.registers ();
620
+ int fd = regs.rdi ;
621
+ if (fd > 2 )
622
+ {
623
+ fd = cpu.machine ().fds ().translate (fd);
624
+ }
625
+ const int new_fd = dup (fd);
626
+ if (new_fd < 0 )
627
+ {
628
+ regs.rax = -errno;
629
+ }
630
+ else
631
+ {
632
+ regs.rax = cpu.machine ().fds ().manage (new_fd, false , false );
633
+ }
634
+ SYSPRINT (" dup(vfd=%lld fd=%d) = %lld\n " ,
635
+ regs.rdi , fd, regs.rax );
636
+ cpu.set_registers (regs);
637
+ });
614
638
Machine::install_syscall_handler (
615
639
SYS_nanosleep, [](vCPU& cpu) { // nanosleep
616
640
auto & regs = cpu.registers ();
@@ -665,7 +689,14 @@ void Machine::setup_linux_system_calls()
665
689
Machine::install_syscall_handler (
666
690
SYS_fcntl, [](vCPU& cpu) { // FCNTL
667
691
auto & regs = cpu.registers ();
692
+ const int fd = cpu.machine ().fds ().translate (regs.rdi );
693
+ const int cmd = regs.rsi ;
668
694
regs.rax = 0 ;
695
+ if (cmd == F_GETFD)
696
+ {
697
+ // const int flags = fcntl(fd, cmd);
698
+ regs.rax = 0x1 ;
699
+ }
669
700
SYSPRINT (" fcntl(...) = %lld\n " ,
670
701
regs.rax );
671
702
cpu.set_registers (regs);
@@ -871,40 +902,38 @@ void Machine::setup_linux_system_calls()
871
902
auto & regs = cpu.registers ();
872
903
const auto vpath = regs.rsi ;
873
904
const auto buffer = regs.rdx ;
874
- const int flags = regs.r8 ;
905
+ const int flags = 0 ; // regs.r10 ;
875
906
int fd = AT_FDCWD;
876
907
std::string path;
877
908
878
909
try {
879
910
path = cpu.machine ().memcstring (vpath, PATH_MAX);
880
911
881
- if (regs.rdi != AT_FDCWD ) {
912
+ if (int ( regs.rdi ) >= 0 ) {
882
913
// Use existing vfd
883
- fd = cpu.machine ().fds ().translate (regs.rdi );
914
+ fd = cpu.machine ().fds ().translate (int (regs.rdi ));
915
+ } else {
916
+ // Use AT_FDCWD
917
+ fd = AT_FDCWD;
918
+ }
884
919
920
+ if (!cpu.machine ().fds ().is_readable_path (path)) {
921
+ regs.rax = -EPERM;
922
+ } else {
885
923
struct stat64 vstat;
886
- // We don't use path here, as a security measure
887
- regs.rax = fstatat64 (fd, " " , &vstat, flags);
924
+ // Path is in allow-list
925
+ regs.rax = fstatat64 (fd, path. c_str () , &vstat, flags);
888
926
if (regs.rax == 0 ) {
889
927
cpu.machine ().copy_to_guest (buffer, &vstat, sizeof (vstat));
890
- }
891
- } else {
892
- if (!cpu.machine ().fds ().is_readable_path (path)) {
893
- regs.rax = -EPERM;
894
928
} else {
895
- struct stat64 vstat;
896
- // Path is in allow-list
897
- regs.rax = fstatat64 (AT_FDCWD, path.c_str (), &vstat, flags);
898
- if (regs.rax == 0 ) {
899
- cpu.machine ().copy_to_guest (buffer, &vstat, sizeof (vstat));
900
- }
929
+ regs.rax = -errno;
901
930
}
902
931
}
903
932
} catch (...) {
904
933
regs.rax = -1 ;
905
934
}
906
935
907
- SYSPRINT (" NEWFSTATAT to vfd=%lld, vfd =%d, path=%s, data=0x%llX, flags=0x%X = %lld\n " ,
936
+ SYSPRINT (" NEWFSTATAT to vfd=%lld, fd =%d, path=%s, data=0x%llX, flags=0x%X = %lld\n " ,
908
937
regs.rdi , fd, path.c_str (), buffer, flags, regs.rax );
909
938
cpu.set_registers (regs);
910
939
});
@@ -1048,26 +1077,22 @@ void Machine::setup_linux_system_calls()
1048
1077
Machine::install_syscall_handler (
1049
1078
SYS_readlinkat, [](vCPU& cpu) { // READLINKAT
1050
1079
auto & regs = cpu.registers ();
1080
+ const int vfd = regs.rdi ;
1051
1081
const auto vpath = regs.rsi ;
1052
1082
const auto g_buffer = regs.rdx ;
1053
1083
const int flags = regs.r8 ;
1054
- int fd = AT_FDCWD;
1055
1084
std::string path;
1056
1085
try {
1057
1086
path = cpu.machine ().memcstring (vpath, PATH_MAX);
1058
1087
if (!cpu.machine ().fds ().is_readable_path (path)) {
1059
- fd = cpu.machine ().fds ().translate (regs.rdi );
1060
-
1061
- char buffer[PATH_MAX];
1062
- regs.rax = readlinkat (fd, " " , buffer, sizeof (buffer));
1063
- if (regs.rax > 0 ) {
1064
- cpu.machine ().copy_to_guest (g_buffer, buffer, regs.rax );
1065
- } else {
1066
- regs.rax = -errno;
1067
- }
1088
+ regs.rax = -EPERM;
1068
1089
} else {
1090
+ int fd = vfd;
1091
+ // Translate from vfd when fd != AT_FDCWD
1092
+ if (vfd != AT_FDCWD)
1093
+ fd = cpu.machine ().fds ().translate (vfd);
1069
1094
// Path is in allow-list
1070
- regs.rax = readlinkat (AT_FDCWD , path.c_str (), (char *)g_buffer, regs.rdx );
1095
+ regs.rax = readlinkat (fd , path.c_str (), (char *)g_buffer, regs.rdx );
1071
1096
if (regs.rax > 0 ) {
1072
1097
cpu.machine ().copy_to_guest (g_buffer, path.c_str (), regs.rax );
1073
1098
} else {
0 commit comments