#ifndef __NR_ia32_linkat
#define __NR_ia32_linkat 303
#endif
+#ifndef __NR_ia32_mkdirat
+#define __NR_ia32_mkdirat 296
+#endif
+#ifndef __NR_ia32_open
+#define __NR_ia32_open 5
+#endif
#ifndef __NR_ia32_pipe2
#define __NR_ia32_pipe2 331
#endif
#ifndef __NR_ia32_readlinkat
#define __NR_ia32_readlinkat 305
#endif
+#ifndef __NR_ia32_renameat
+#define __NR_ia32_renameat 302
+#endif
#ifndef __NR_ia32_rt_sigprocmask
#define __NR_ia32_rt_sigprocmask 175
#endif
#define __NR_compat_getpgid __NR_ia32_getpgid
#define __NR_compat_inotify_init1 __NR_ia32_inotify_init1
#define __NR_compat_linkat __NR_ia32_linkat
+#define __NR_compat_mkdirat __NR_ia32_mkdirat
+#define __NR_compat_open __NR_ia32_open
#define __NR_compat_pipe2 __NR_ia32_pipe2
#define __NR_compat_readlinkat __NR_ia32_readlinkat
+#define __NR_compat_renameat __NR_ia32_renameat
#define __NR_compat_rt_sigprocmask __NR_ia32_rt_sigprocmask
#define __NR_compat_symlinkat __NR_ia32_symlinkat
#define __NR_compat_umount2 __NR_ia32_umount2
#define __NR_compat_getpgid __NR_getpgid
#define __NR_compat_inotify_init1 __NR_inotify_init1
#define __NR_compat_linkat __NR_linkat
+#define __NR_compat_mkdirat __NR_mkdirat
+#define __NR_compat_open __NR_open
#define __NR_compat_pipe2 __NR_pipe2
#define __NR_compat_readlinkat __NR_readlinkat
+#define __NR_compat_renameat __NR_renameat
#define __NR_compat_rt_sigprocmask __NR_rt_sigprocmask
#define __NR_compat_symlinkat __NR_symlinkat
#define __NR_compat_umount2 __NR_umount2
# long sys_mkdirat(int dfd, const char __user *pathname, int mode)
probe nd_syscall.mkdirat = kprobe.function("sys_mkdirat") ?
{
+ @__syscall_compat_gate(%{ __NR_mkdirat %}, %{ __NR_compat_mkdirat %})
name = "mkdirat"
// dirfd = $dfd
// pathname = user_string($pathname)
}
probe nd_syscall.mkdirat.return = kprobe.function("sys_mkdirat").return ?
{
+ @__syscall_compat_gate(%{ __NR_mkdirat %}, %{ __NR_compat_mkdirat %})
name = "mkdirat"
retstr = returnstr(1)
}
kprobe.function("sys32_open") ?,
kprobe.function("sys_open") ?
{
+ @__syscall_compat_gate(%{ __NR_open %}, %{ __NR_compat_open %})
name = "open"
// filename = user_string($filename)
// flags = $flags
kprobe.function("sys32_open").return ?,
kprobe.function("sys_open").return ?
{
+ @__syscall_compat_gate(%{ __NR_open %}, %{ __NR_compat_open %})
name = "open"
retstr = returnstr(1)
}
# int newdfd, const char __user *newname)
probe nd_syscall.renameat = kprobe.function("sys_renameat") ?
{
+ @__syscall_compat_gate(%{ __NR_renameat %}, %{ __NR_compat_renameat %})
name = "renameat"
// olddfd = $olddfd
// olddfd_str = _dfd_str($olddfd)
}
probe nd_syscall.renameat.return = kprobe.function("sys_renameat").return ?
{
+ @__syscall_compat_gate(%{ __NR_renameat %}, %{ __NR_compat_renameat %})
name = "renameat"
retstr = returnstr(1)
}
# long sys_mkdirat(int dfd, const char __user *pathname, int mode)
probe syscall.mkdirat = kernel.function("sys_mkdirat").call ?
{
+ @__syscall_compat_gate(%{ __NR_mkdirat %}, %{ __NR_compat_mkdirat %})
name = "mkdirat"
dirfd = $dfd
pathname = user_string_quoted($pathname)
}
probe syscall.mkdirat.return = kernel.function("sys_mkdirat").return ?
{
+ @__syscall_compat_gate(%{ __NR_mkdirat %}, %{ __NR_compat_mkdirat %})
name = "mkdirat"
retstr = return_str(1, $return)
}
#
probe syscall.open = __syscall.compat_open ?, __syscall.open
{
+ @__syscall_compat_gate(%{ __NR_open %}, %{ __NR_compat_open %})
name = "open"
flags = $flags
if ($flags & 64)
kernel.function("sys32_open").return ?,
kernel.function("sys_open").return ?
{
+ @__syscall_compat_gate(%{ __NR_open %}, %{ __NR_compat_open %})
name = "open"
retstr = return_str(1, $return)
}
# int newdfd, const char __user *newname)
probe syscall.renameat = kernel.function("sys_renameat").call ?
{
+ @__syscall_compat_gate(%{ __NR_renameat %}, %{ __NR_compat_renameat %})
name = "renameat"
olddfd = $olddfd
olddfd_str = _dfd_str($olddfd)
}
probe syscall.renameat.return = kernel.function("sys_renameat").return ?
{
+ @__syscall_compat_gate(%{ __NR_renameat %}, %{ __NR_compat_renameat %})
name = "renameat"
retstr = return_str(1, $return)
}
--- /dev/null
+/* COVERAGE: rename renameat */
+
+#include <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+
+// To test for glibc support for renameat():
+//
+// Since glibc 2.10:
+// _XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L
+// Before glibc 2.10:
+// _ATFILE_SOURCE
+
+#define GLIBC_SUPPORT \
+ (_XOPEN_SOURCE >= 700 || _POSIX_C_SOURCE >= 200809L \
+ || defined(_ATFILE_SOURCE))
+
+int main()
+{
+ int fd1;
+
+ fd1 = creat("file1", S_IREAD|S_IWRITE);
+ close (fd1);
+
+ mkdir("dir1", S_IREAD|S_IWRITE|S_IEXEC);
+ mkdir("dir3", S_IREAD|S_IWRITE|S_IEXEC);
+
+ fd1 = creat("dir3/file", S_IREAD|S_IWRITE);
+ close (fd1);
+
+ rename("file1", "file2");
+ //staptest// rename ("file1", "file2") = 0
+
+ rename("dir1", "dir2");
+ //staptest// rename ("dir1", "dir2") = 0
+
+ // This will fail since the target isn't empty.
+ rename("dir2", "dir3");
+ //staptest// rename ("dir2", "dir3") = -NNNN (ENOTEMPTY!!!!EEXIST)
+
+ // This will fail since you can't rename a file to a directory.
+ rename("file2", "dir2");
+ //staptest// rename ("file2", "dir2") = -NNNN (EISDIR)
+
+ // You can't rename a directory to a subdirectory of itself.
+ rename("dir2", "dir2/dir4");
+ //staptest// rename ("dir2", "dir2/dir4") = -NNNN (EINVAL)
+
+ // You can't rename a directory to a file.
+ rename("dir2", "file2");
+ //staptest// rename ("dir2", "file2") = -NNNN (ENOTDIR)
+
+ rename("file2", (char *)-1);
+ //staptest// rename ("file2", XXXX) = -NNNN (EFAULT)
+
+#if GLIBC_SUPPORT
+ renameat(AT_FDCWD, "file2", AT_FDCWD, "file1");
+ //staptest// renameat (AT_FDCWD, "file2", AT_FDCWD, "file1") = 0
+
+ renameat(AT_FDCWD, "dir2", AT_FDCWD, "dir1");
+ //staptest// renameat (AT_FDCWD, "dir2", AT_FDCWD, "dir1") = 0
+
+ // This will fail since the target isn't empty.
+ renameat(AT_FDCWD, "dir1", AT_FDCWD, "dir3");
+ //staptest// rename (AT_FDCWD, "dir1", AT_FDCWD, "dir3") = -NNNN (ENOTEMPTY!!!!EEXIST)
+
+ // This will fail since you can't rename a file to a directory.
+ renameat(AT_FDCWD, "file1", AT_FDCWD, "dir1");
+ //staptest// renameat (AT_FDCWD, "file1", AT_FDCWD, "dir1") = -NNNN (EISDIR)
+
+ // You can't rename a directory to a subdirectory of itself.
+ renameat(AT_FDCWD, "dir1", AT_FDCWD, "dir1/dir4");
+ //staptest// renameat (AT_FDCWD, "dir1", AT_FDCWD, "dir1/dir4") = -NNNN (EINVAL)
+
+ // You can't rename a directory to a file.
+ renameat(AT_FDCWD, "dir1", AT_FDCWD, "file1");
+ //staptest// renameat (AT_FDCWD, "dir1", AT_FDCWD, "file1") = -NNNN (ENOTDIR)
+
+ renameat(AT_FDCWD, "file1", AT_FDCWD, (char *)-1);
+ //staptest// renameat (AT_FDCWD, "file1", AT_FDCWD, XXXX) = -NNNN (EFAULT)
+
+#endif
+ return 0;
+}