@@ -856,20 +856,19 @@ void Machine::setup_linux_system_calls()
856856 if (addrlen > sizeof (addr))
857857 {
858858 regs.rax = -EINVAL;
859- cpu.set_registers (regs);
860- return ;
861- }
862- cpu.machine ().copy_from_guest (&addr, g_addr, addrlen);
863- // Validate the address
864- if (!cpu.machine ().fds ().validate_socket_address (fd, addr))
865- {
866- regs.rax = -EPERM;
867859 } else {
868- if (connect (fd, &addr, addrlen) < 0 ) {
869- regs.rax = -errno;
870- }
871- else {
872- regs.rax = 0 ;
860+ cpu.machine ().copy_from_guest (&addr, g_addr, addrlen);
861+ // Validate the address
862+ if (!cpu.machine ().fds ().validate_socket_address (fd, addr))
863+ {
864+ regs.rax = -EPERM;
865+ } else {
866+ if (connect (fd, &addr, addrlen) < 0 ) {
867+ regs.rax = -errno;
868+ }
869+ else {
870+ regs.rax = 0 ;
871+ }
873872 }
874873 }
875874 SYSPRINT (" connect(fd=%d, addr=0x%lX, addrlen=%zu) = %lld\n " ,
@@ -1156,7 +1155,7 @@ void Machine::setup_linux_system_calls()
11561155 }
11571156 cpu.machine ().copy_to_guest (iov.iov_base , buf.data () + offset, len_remaining);
11581157 offset += iov.iov_len ;
1159- if (offset >= result) {
1158+ if (offset >= size_t ( result) ) {
11601159 break ;
11611160 }
11621161 }
@@ -1439,21 +1438,26 @@ void Machine::setup_linux_system_calls()
14391438 Machine::install_syscall_handler (
14401439 SYS_openat, [] (vCPU& cpu) { // OPENAT
14411440 auto & regs = cpu.registers ();
1442-
1441+ const int vfd = regs. rdi ;
14431442 const auto vpath = regs.rsi ;
1444- const int flags = regs.rdx ;
1443+ int flags = regs.rdx | AT_SYMLINK_NOFOLLOW ;
14451444
14461445 std::string path = cpu.machine ().memcstring (vpath, PATH_MAX);
1446+ std::string real_path;
14471447 bool write_flags = (flags & (O_WRONLY | O_RDWR)) != 0x0 ;
14481448 if (!write_flags)
14491449 {
14501450 try {
1451- std::string real_path = path;
1451+ int pfd = AT_FDCWD;
1452+ if (vfd != AT_FDCWD) {
1453+ pfd = cpu.machine ().fds ().translate (vfd);
1454+ }
1455+ real_path = path;
14521456 if (!cpu.machine ().fds ().is_readable_path (real_path)) {
14531457 throw std::runtime_error (" Path not readable: " + real_path);
14541458 }
14551459
1456- int fd = openat (AT_FDCWD , real_path.c_str (), flags);
1460+ int fd = openat (pfd , real_path.c_str (), flags);
14571461 if (fd > 0 ) {
14581462 regs.rax = cpu.machine ().fds ().manage (fd, false );
14591463 } else {
@@ -1473,12 +1477,18 @@ void Machine::setup_linux_system_calls()
14731477 if (write_flags || regs.rax == (__u64)-1 )
14741478 {
14751479 try {
1476- std::string real_path = path;
1480+ int pfd = AT_FDCWD;
1481+ if (vfd != AT_FDCWD) {
1482+ pfd = cpu.machine ().fds ().translate (vfd);
1483+ }
1484+
1485+ real_path = path;
14771486 if (!cpu.machine ().fds ().is_writable_path (real_path)) {
1487+ SYSPRINT (" OPENAT path was not writable: %s\n " , real_path.c_str ());
14781488 throw std::runtime_error (" Path not writable: " + real_path);
14791489 }
14801490
1481- int fd = openat (AT_FDCWD , real_path.c_str (), flags, S_IWUSR | S_IRUSR);
1491+ int fd = openat (pfd , real_path.c_str (), flags, S_IWUSR | S_IRUSR);
14821492 SYSPRINT (" OPENAT where=%lld path=%s (real_path=%s) flags=%X = fd %d\n " ,
14831493 regs.rdi , path.c_str (), real_path.c_str (), flags, fd);
14841494
@@ -1498,7 +1508,7 @@ void Machine::setup_linux_system_calls()
14981508 auto & regs = cpu.registers ();
14991509 const auto vpath = regs.rsi ;
15001510 const auto buffer = regs.rdx ;
1501- int flags = 0 ; // regs.r10;
1511+ int flags = AT_SYMLINK_NOFOLLOW ; // regs.r10;
15021512 int fd = AT_FDCWD;
15031513 std::string path;
15041514
@@ -1822,31 +1832,32 @@ void Machine::setup_linux_system_calls()
18221832 auto & regs = cpu.registers ();
18231833 const int vfd = regs.rdi ;
18241834 const auto vpath = regs.rsi ;
1825- const auto flags = regs.rdx ;
1835+ const auto flags = regs.rdx | AT_SYMLINK_NOFOLLOW ;
18261836 const auto mask = regs.r10 ;
18271837 const auto buffer = regs.r8 ;
18281838 std::string path;
18291839 int fd = AT_FDCWD;
18301840
18311841 try {
18321842 path = cpu.machine ().memcstring (vpath, PATH_MAX);
1833- if (!cpu.machine ().fds ().is_readable_path (path)) {
1834- regs.rax = -EPERM;
1835- } else {
1836- // Translate from vfd when fd != AT_FDCWD
1837- if (vfd != AT_FDCWD)
1838- fd = cpu.machine ().fds ().translate (vfd);
1839-
1840- struct statx vstat;
1841- const int result =
1842- statx (fd, path.c_str (), flags, mask, &vstat);
1843- if (result == 0 ) {
1844- cpu.machine ().copy_to_guest (buffer, &vstat, sizeof (vstat));
1845- regs.rax = 0 ;
1846- } else {
1847- regs.rax = -errno;
1843+ if (!path.empty ()) {
1844+ if (!cpu.machine ().fds ().is_readable_path (path)) {
1845+ regs.rax = -EPERM;
18481846 }
18491847 }
1848+ // Translate from vfd when fd != AT_FDCWD
1849+ if (vfd != AT_FDCWD)
1850+ fd = cpu.machine ().fds ().translate (vfd);
1851+
1852+ struct statx vstat;
1853+ const int result =
1854+ statx (fd, path.c_str (), flags, mask, &vstat);
1855+ if (result == 0 ) {
1856+ cpu.machine ().copy_to_guest (buffer, &vstat, sizeof (vstat));
1857+ regs.rax = 0 ;
1858+ } else {
1859+ regs.rax = -errno;
1860+ }
18501861 } catch (...) {
18511862 regs.rax = -1 ;
18521863 }
0 commit comments