From 1167efa4afe9828a6185c39a5982f446a9c75276 Mon Sep 17 00:00:00 2001 From: Eric Andersen Date: Sun, 2 Nov 2003 10:00:45 +0000 Subject: Be extra careful to check uid and gid converstions to kernel types --- libc/sysdeps/linux/common/syscalls.c | 91 +++++++++++++++++++++++++++++------- 1 file changed, 74 insertions(+), 17 deletions(-) (limited to 'libc/sysdeps') diff --git a/libc/sysdeps/linux/common/syscalls.c b/libc/sysdeps/linux/common/syscalls.c index b4ee02338..53506636a 100644 --- a/libc/sysdeps/linux/common/syscalls.c +++ b/libc/sysdeps/linux/common/syscalls.c @@ -84,11 +84,13 @@ static inline _syscall3(int, __syscall_open, const char *, fn, int, flags, __kernel_mode_t, mode); int __libc_open (const char * fn, int flags, ...) { - va_list ap; mode_t mode; - va_start(ap, flags); - mode = va_arg(ap, mode_t); - va_end(ap); + if (flags & O_CREAT) { + va_list ap; + va_start(ap, flags); + mode = va_arg(ap, mode_t); + va_end(ap); + } return __syscall_open(fn, flags, mode); } @@ -114,7 +116,7 @@ weak_alias(__libc_close, close) _syscall2(int, __syscall_creat, const char *, file, __kernel_mode_t, mode); int creat (const char *file, mode_t mode) { - return __syscall_creat (file, mode); + return __syscall_creat (file, mode); } #else extern int __libc_open (const char *file, int flags, mode_t mode); @@ -177,8 +179,8 @@ time_t time (time_t *t) _syscall3(int, __syscall_mknod, const char *, path, __kernel_mode_t, mode, __kernel_dev_t, dev); int mknod(const char *path, mode_t mode, dev_t dev) { - __kernel_dev_t k_dev; /* We must convert the dev_t value to a __kernel_dev_t */ + __kernel_dev_t k_dev; k_dev = ((major(dev) & 0xff) << 8) | (minor(dev) & 0xff); return __syscall_mknod(path, mode, k_dev); } @@ -211,6 +213,12 @@ static inline _syscall3(int, __syscall_lchown, const char *, path, __kernel_uid_t, owner, __kernel_gid_t, group); int lchown(const char *path, uid_t owner, gid_t group) { + if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U)) + || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } return __syscall_lchown(path, owner, group); } #endif @@ -262,7 +270,7 @@ static inline _syscall1(int, __syscall_setuid, __kernel_uid_t, uid); int setuid(uid_t uid) { - if (uid == (uid_t) ~0 || uid != (uid_t) ((int) uid)) { + if (uid == (uid_t) ~0 || uid != (uid_t) ((__kernel_uid_t) uid)) { __set_errno (EINVAL); return -1; } @@ -304,12 +312,7 @@ int stime(const time_t *when) #endif //#define __NR_ptrace 26 -#ifdef L___ptrace -#include -#define __NR___ptrace __NR_ptrace -_syscall4(long, __ptrace, enum __ptrace_request, request, __kernel_pid_t, pid, - void*, addr, void*, data); -#endif +//See ptrace.c //#define __NR_alarm 27 @@ -521,6 +524,12 @@ static inline _syscall1(int, __syscall_setgid, __kernel_gid_t, gid); int setgid(gid_t gid) { + if (gid == (gid_t) ~0 + || gid != (gid_t) ((__kernel_gid_t) gid)) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_setgid(gid)); } #endif @@ -665,10 +674,10 @@ int setpgid(pid_t pid, pid_t pgid) #include #define __NR___syscall_umask __NR_umask static inline -_syscall1(__kernel_mode_t, __syscall_umask, __kernel_mode_t, mask); -mode_t umask(mode_t mask) +_syscall1(__kernel_mode_t, __syscall_umask, __kernel_mode_t, mode); +mode_t umask(mode_t mode) { - return(__syscall_umask(mask)); + return(__syscall_umask(mode)); } #endif @@ -686,8 +695,8 @@ static inline _syscall2(int, __syscall_ustat, unsigned short int, kdev_t, struct ustat *, ubuf); int ustat(dev_t dev, struct ustat *ubuf) { - __kernel_dev_t k_dev; /* We must convert the dev_t value to a __kernel_dev_t */ + __kernel_dev_t k_dev; k_dev = ((major(dev) & 0xff) << 8) | (minor(dev) & 0xff); return __syscall_ustat(k_dev, ubuf); } @@ -748,6 +757,12 @@ static inline _syscall2(int, __syscall_setreuid, __kernel_uid_t, ruid, __kernel_uid_t, euid); int setreuid(uid_t ruid, uid_t euid) { + if (((ruid + 1) > (uid_t) ((__kernel_uid_t) -1U)) + || ((euid + 1) > (uid_t) ((__kernel_uid_t) -1U))) + { + __set_errno(EINVAL); + return -1; + } return(__syscall_setreuid(ruid, euid)); } #endif @@ -760,6 +775,12 @@ static inline _syscall2(int, __syscall_setregid, __kernel_gid_t, rgid, __kernel_gid_t, egid); int setregid(gid_t rgid, gid_t egid) { + if (((rgid + 1) > (gid_t) ((__kernel_gid_t) -1U)) + || ((egid + 1) > (gid_t) ((__kernel_gid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_setregid(rgid, egid)); } #endif @@ -1040,6 +1061,12 @@ static inline _syscall3(int, __syscall_fchown, int, fd, __kernel_uid_t, owner, __kernel_gid_t, group); int fchown(int fd, uid_t owner, gid_t group) { + if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U)) + || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_fchown(fd, owner, group)); } #endif @@ -1404,6 +1431,11 @@ static inline _syscall1(int, __syscall_setfsuid, __kernel_uid_t, uid); int setfsuid(uid_t uid) { + if (uid != (uid_t) ((__kernel_uid_t) uid)) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_setfsuid(uid)); } #endif @@ -1418,6 +1450,11 @@ static inline _syscall1(int, __syscall_setfsgid, __kernel_gid_t, gid); int setfsgid(gid_t gid) { + if (gid != (gid_t) ((__kernel_gid_t) gid)) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_setfsgid(gid)); } #endif @@ -1677,6 +1714,13 @@ static inline _syscall3(int, __syscall_setresuid, __kernel_uid_t, rgid, __kernel_uid_t, egid, __kernel_uid_t, sgid); int setresuid(uid_t ruid, uid_t euid, uid_t suid) { + if (((ruid + 1) > (uid_t) ((__kernel_uid_t) -1U)) + || ((euid + 1) > (uid_t) ((__kernel_uid_t) -1U)) + || ((suid + 1) > (uid_t) ((__kernel_uid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_setresuid(ruid, euid, suid)); } #endif @@ -1742,6 +1786,13 @@ static inline _syscall3(int, __syscall_setresgid, __kernel_gid_t, rgid, __kernel_gid_t, egid, __kernel_gid_t, sgid); int setresgid(gid_t rgid, gid_t egid, gid_t sgid) { + if (((rgid + 1) > (gid_t) ((__kernel_gid_t) -1U)) + || ((egid + 1) > (gid_t) ((__kernel_gid_t) -1U)) + || ((sgid + 1) > (gid_t) ((__kernel_gid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_setresgid(rgid, egid, sgid)); } #endif @@ -1891,6 +1942,12 @@ static inline _syscall3(int, __syscall_chown, const char *, path, __kernel_uid_t, owner, __kernel_gid_t, group); int chown(const char * path, uid_t owner, gid_t group) { + if (((owner + 1) > (uid_t) ((__kernel_uid_t) -1U)) + || ((group + 1) > (gid_t) ((__kernel_gid_t) -1U))) + { + __set_errno (EINVAL); + return -1; + } return(__syscall_chown(path, owner, group)); } #endif -- cgit v1.2.3