summaryrefslogtreecommitdiff
path: root/libc
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2003-11-02 10:00:45 +0000
committerEric Andersen <andersen@codepoet.org>2003-11-02 10:00:45 +0000
commit1167efa4afe9828a6185c39a5982f446a9c75276 (patch)
treec55549d2a052dec5fb678bee122275707c0bad6a /libc
parentc94d3fd8f78053c49e0329de473631a1bfa52d37 (diff)
Be extra careful to check uid and gid converstions to kernel types
Diffstat (limited to 'libc')
-rw-r--r--libc/sysdeps/linux/common/syscalls.c91
1 files changed, 74 insertions, 17 deletions
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 <sys/ptrace.h>
-#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 <sys/stat.h>
#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