Last active
December 2, 2021 10:04
-
-
Save paranlee/07d7636e9c5adb705f1a23ae72edfba6 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| /* arm64/include/asm/unistd32.h::__SYSCALL */ | |
| #undef __SYSCALL | |
| #define __SYSCALL(nr, sym) asmlinkage long __arm64_##sym(const struct pt_regs *); | |
| #include <asm/unistd.h> | |
| #undef __SYSCALL | |
| #define __SYSCALL(nr, sym) [nr] = __arm64_##sym, | |
| /* arch/arm64/include/asm/unistd32.h::__NR_open */ | |
| #define __NR_open 5 | |
| __SYSCALL(__NR_open, compat_sys_open) | |
| /* include/linux/compat.h::compat_sys_open */ | |
| asmlinkage long compat_sys_open(const char __user *filename, int flags, | |
| umode_t mode); | |
| /* arch/arm64/include/asm/syscall_wrapper.h */ | |
| #define __SYSCALL_DEFINEx(x, name, ...) \ | |
| asmlinkage long __arm64_sys##name(const struct pt_regs *regs); \ | |
| ALLOW_ERROR_INJECTION(__arm64_sys##name, ERRNO); \ | |
| static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)); \ | |
| static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)); \ | |
| asmlinkage long __arm64_sys##name(const struct pt_regs *regs) \ | |
| { \ | |
| return __se_sys##name(SC_ARM64_REGS_TO_ARGS(x,__VA_ARGS__)); \ | |
| } \ | |
| static long __se_sys##name(__MAP(x,__SC_LONG,__VA_ARGS__)) \ | |
| { \ | |
| long ret = __do_sys##name(__MAP(x,__SC_CAST,__VA_ARGS__)); \ | |
| __MAP(x,__SC_TEST,__VA_ARGS__); \ | |
| __PROTECT(x, ret,__MAP(x,__SC_ARGS,__VA_ARGS__)); \ | |
| return ret; \ | |
| } \ | |
| static inline long __do_sys##name(__MAP(x,__SC_DECL,__VA_ARGS__)) | |
| /* include/linux/syscalls.h */ | |
| /* | |
| * __MAP - apply a macro to syscall arguments | |
| * __MAP(n, m, t1, a1, t2, a2, ..., tn, an) will expand to | |
| * m(t1, a1), m(t2, a2), ..., m(tn, an) | |
| * The first argument must be equal to the amount of type/name | |
| * pairs given. Note that this list of pairs (i.e. the arguments | |
| * of __MAP starting at the third one) is in the same format as | |
| * for SYSCALL_DEFINE<n>/COMPAT_SYSCALL_DEFINE<n> | |
| */ | |
| #define __MAP0(m,...) | |
| #define __MAP1(m,t,a,...) m(t,a) | |
| #define __MAP2(m,t,a,...) m(t,a), __MAP1(m,__VA_ARGS__) | |
| #define __MAP3(m,t,a,...) m(t,a), __MAP2(m,__VA_ARGS__) | |
| #define __MAP4(m,t,a,...) m(t,a), __MAP3(m,__VA_ARGS__) | |
| #define __MAP5(m,t,a,...) m(t,a), __MAP4(m,__VA_ARGS__) | |
| #define __MAP6(m,t,a,...) m(t,a), __MAP5(m,__VA_ARGS__) | |
| #define __MAP(n,...) __MAP##n(__VA_ARGS__) | |
| /* https://elixir.bootlin.com/linux/v5.14.21/source/fs/open.c#L1228 */ | |
| /* fs/open.c::do_sys_open() */ | |
| long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) | |
| { | |
| struct open_how how = build_open_how(flags, mode); | |
| return do_sys_openat2(dfd, filename, &how); | |
| } | |
| /* fs/open.c::do_sys_openat2() */ | |
| static long do_sys_openat2(int dfd, const char __user *filename, | |
| struct open_how *how) | |
| { | |
| struct open_flags op; | |
| int fd = build_open_flags(how, &op); | |
| struct filename *tmp; | |
| if (fd) | |
| return fd; | |
| tmp = getname(filename); | |
| if (IS_ERR(tmp)) | |
| return PTR_ERR(tmp); | |
| fd = get_unused_fd_flags(how->flags); | |
| if (fd >= 0) { | |
| struct file *f = do_filp_open(dfd, tmp, &op); | |
| if (IS_ERR(f)) { | |
| put_unused_fd(fd); | |
| fd = PTR_ERR(f); | |
| } else { | |
| fsnotify_open(f); | |
| fd_install(fd, f); | |
| } | |
| } | |
| putname(tmp); | |
| return fd; | |
| } | |
| /* fs/namei.c::do_o_path() */ | |
| static int do_o_path(struct nameidata *nd, unsigned flags, struct file *file) | |
| { | |
| struct path path; | |
| int error = path_lookupat(nd, flags, &path); | |
| if (!error) { | |
| audit_inode(nd->name, path.dentry, 0); | |
| error = vfs_open(&path, file); | |
| path_put(&path); | |
| } | |
| return error; | |
| } | |
| /** | |
| * fs/open.c::vfs_open() | |
| * -> fs/open.c::do_dentry_open() | |
| * => each handle for FMODE_XXXXX | |
| */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment