Skip to content

rm: Incomplete safe traversal/access #9542

@julian-klode

Description

@julian-klode

Similar to 9541, the statx() calls are using full paths

$ mkdir x/y/z -p && touch x/y/z/f
$  strace ./target/debug/rm -r x
[...]
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0775, stx_size=15, ...}) = 0
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0775, stx_size=15, ...}) = 0
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0775, stx_size=15, ...}) = 0
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x", AT_STATX_SYNC_AS_STAT|AT_SYMLINK_NOFOLLOW, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFDIR|0775, stx_size=15, ...}) = 0
openat(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 3
dup(3)                                  = 4
fstat(4, {st_mode=S_IFDIR|0775, st_size=15, ...}) = 0
fcntl(4, F_GETFL)                       = 0x18000 (flags O_RDONLY|O_LARGEFILE|O_DIRECTORY)
fcntl(4, F_SETFD, FD_CLOEXEC)           = 0
getdents64(4, 0x5aa3113e8bb0 /* 3 entries */, 32768) = 72
getdents64(4, 0x5aa3113e8bb0 /* 0 entries */, 32768) = 0
lseek(4, 0, SEEK_SET)                   = 0
close(4)                                = 0
newfstatat(3, "y", {st_mode=S_IFDIR|0775, st_size=15, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(3, "y", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 4
dup(4)                                  = 5
fstat(5, {st_mode=S_IFDIR|0775, st_size=15, ...}) = 0
fcntl(5, F_GETFL)                       = 0x18000 (flags O_RDONLY|O_LARGEFILE|O_DIRECTORY)
fcntl(5, F_SETFD, FD_CLOEXEC)           = 0
getdents64(5, 0x5aa3113e8bb0 /* 3 entries */, 32768) = 72
getdents64(5, 0x5aa3113e8bb0 /* 0 entries */, 32768) = 0
lseek(5, 0, SEEK_SET)                   = 0
close(5)                                = 0
newfstatat(4, "z", {st_mode=S_IFDIR|0775, st_size=15, ...}, AT_SYMLINK_NOFOLLOW) = 0
openat(4, "z", O_RDONLY|O_CLOEXEC|O_DIRECTORY) = 5
dup(5)                                  = 6
fstat(6, {st_mode=S_IFDIR|0775, st_size=15, ...}) = 0
fcntl(6, F_GETFL)                       = 0x18000 (flags O_RDONLY|O_LARGEFILE|O_DIRECTORY)
fcntl(6, F_SETFD, FD_CLOEXEC)           = 0
getdents64(6, 0x5aa3113e8bb0 /* 3 entries */, 32768) = 72
getdents64(6, 0x5aa3113e8bb0 /* 0 entries */, 32768) = 0
lseek(6, 0, SEEK_SET)                   = 0
close(6)                                = 0
newfstatat(5, "f", {st_mode=S_IFREG|0664, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x/y/z/f", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0664, stx_size=0, ...}) = 0
ioctl(0, TCGETS2, {c_iflag=ICRNL|IUTF8, c_oflag=NL0|CR0|TAB0|BS0|VT0|FF0|OPOST|ONLCR, c_cflag=B38400|B38400<<IBSHIFT|CS8|CREAD, c_lflag=ISIG|ICANON|ECHO|ECHOE|ECHOK|IEXTEN|ECHOCTL|ECHOKE, ...}) = 0
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x/y/z/f", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0664, stx_size=0, ...}) = 0
statx(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x/y/z/f", AT_STATX_SYNC_AS_STAT, STATX_ALL, {stx_mask=STATX_ALL|STATX_MNT_ID, stx_attributes=0, stx_mode=S_IFREG|0664, stx_size=0, ...}) = 0
unlinkat(5, "f", 0)                     = 0
unlinkat(4, "z", AT_REMOVEDIR)          = 0
fcntl(5, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(5)                                = 0
unlinkat(3, "y", AT_REMOVEDIR)          = 0
fcntl(4, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(4)                                = 0
openat(AT_FDCWD, "/home/jak/Projects/Ubuntu/uutils/x", O_RDONLY|O_NONBLOCK|O_CLOEXEC|O_DIRECTORY) = 4
fstat(4, {st_mode=S_IFDIR|0775, st_size=6, ...}) = 0
getdents64(4, 0x5aa3113eabc0 /* 2 entries */, 32768) = 48
getdents64(4, 0x5aa3113eabc0 /* 0 entries */, 32768) = 0
close(4)                                = 0
rmdir("/home/jak/Projects/Ubuntu/uutils/x") = 0
fcntl(3, F_GETFD)                       = 0x1 (flags FD_CLOEXEC)
close(3)                                = 0
sigaltstack({ss_sp=NULL, ss_flags=SS_DISABLE, ss_size=8192}, NULL) = 0
munmap(0x779d4f0d4000, 12288)           = 0
exit_group(0)                           = ?
+++ exited with 0 +++

One other confusing thing is that the final dir removal is an rmdir() whereas inner removals are unlinkat(3, "y", AT_REMOVEDIR)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions