Commit d92cfbf0 authored by Linus Torvalds's avatar Linus Torvalds Committed by Linus Torvalds

Add user pointer annotations to socket, file IO and signal

handling.

This pointed out a bug in x86 sys_rt_sigreturn(), btw.
parent 20ca5ae1
......@@ -116,7 +116,7 @@ sys_sigaction(int sig, const struct old_sigaction __user *act,
}
asmlinkage int
sys_sigaltstack(const stack_t *uss, stack_t *uoss)
sys_sigaltstack(const stack_t __user *uss, stack_t __user *uoss)
{
struct pt_regs *regs = (struct pt_regs *) &uss;
return do_sigaltstack(uss, uoss, regs->esp);
......@@ -244,6 +244,11 @@ asmlinkage int sys_rt_sigreturn(unsigned long __unused)
goto badframe;
/* It is more difficult to avoid calling this function than to
call it and ignore errors. */
/*
* THIS CANNOT WORK! "&st" is a kernel address, and "do_sigaltstack()"
* takes a user address (and verifies that it is a user address). End
* result: it does exactly _nothing_.
*/
do_sigaltstack(&st, NULL, regs->esp);
return eax;
......
......@@ -61,7 +61,7 @@ static inline unsigned long ptep_to_address(pte_t * ptep)
return page->index + low_bits;
}
#if CONFIG_HIGHPTE
#ifdef CONFIG_HIGHPTE
static inline pte_addr_t ptep_to_paddr(pte_t *ptep)
{
pte_addr_t paddr;
......
......@@ -14,6 +14,7 @@
#define _LINUX_CAPABILITY_H
#include <linux/types.h>
#include <linux/compiler.h>
/* User-level do most of the mapping between kernel and user
capabilities based on the version tag given by the kernel. The
......@@ -31,13 +32,13 @@
typedef struct __user_cap_header_struct {
__u32 version;
int pid;
} *cap_user_header_t;
} __user *cap_user_header_t;
typedef struct __user_cap_data_struct {
__u32 effective;
__u32 permitted;
__u32 inheritable;
} *cap_user_data_t;
} __user *cap_user_data_t;
#ifdef __KERNEL__
......
......@@ -691,7 +691,7 @@ struct block_device_operations {
typedef struct {
size_t written;
size_t count;
char * buf;
char __user * buf;
int error;
} read_descriptor_t;
......@@ -722,7 +722,7 @@ struct file_operations {
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *, unsigned long, loff_t *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t, read_actor_t, void __user *);
ssize_t (*sendpage) (struct file *, struct page *, int, size_t, loff_t *, int);
unsigned long (*get_unmapped_area)(struct file *, unsigned long, unsigned long, unsigned long, unsigned long);
};
......@@ -1207,15 +1207,15 @@ extern ssize_t generic_file_read(struct file *, char __user *, size_t, loff_t *)
int generic_write_checks(struct inode *inode, struct file *file,
loff_t *pos, size_t *count, int isblk);
extern ssize_t generic_file_write(struct file *, const char __user *, size_t, loff_t *);
extern ssize_t generic_file_aio_read(struct kiocb *, char *, size_t, loff_t);
extern ssize_t generic_file_aio_write(struct kiocb *, const char *, size_t, loff_t);
extern ssize_t generic_file_aio_read(struct kiocb *, char __user *, size_t, loff_t);
extern ssize_t generic_file_aio_write(struct kiocb *, const char __user *, size_t, loff_t);
extern ssize_t generic_file_aio_write_nolock(struct kiocb *, const struct iovec *,
unsigned long, loff_t *);
extern ssize_t do_sync_read(struct file *filp, char __user *buf, size_t len, loff_t *ppos);
extern ssize_t do_sync_write(struct file *filp, const char __user *buf, size_t len, loff_t *ppos);
ssize_t generic_file_write_nolock(struct file *file, const struct iovec *iov,
unsigned long nr_segs, loff_t *ppos);
extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void *);
extern ssize_t generic_file_sendfile(struct file *, loff_t *, size_t, read_actor_t, void __user *);
extern void do_generic_mapping_read(struct address_space *, struct file_ra_state *, struct file *,
loff_t *, read_descriptor_t *, read_actor_t);
extern void
......
......@@ -6,6 +6,6 @@
#define FUTEX_WAKE (1)
#define FUTEX_FD (2)
extern asmlinkage long sys_futex(u32 *uaddr, int op, int val, struct timespec *utime);
extern asmlinkage long sys_futex(u32 __user *uaddr, int op, int val, struct timespec __user *utime);
#endif
......@@ -96,18 +96,18 @@ struct proto_ops {
struct module *owner;
int (*release) (struct socket *sock);
int (*bind) (struct socket *sock,
struct sockaddr *umyaddr,
struct sockaddr *myaddr,
int sockaddr_len);
int (*connect) (struct socket *sock,
struct sockaddr *uservaddr,
struct sockaddr *vaddr,
int sockaddr_len, int flags);
int (*socketpair)(struct socket *sock1,
struct socket *sock2);
int (*accept) (struct socket *sock,
struct socket *newsock, int flags);
int (*getname) (struct socket *sock,
struct sockaddr *uaddr,
int *usockaddr_len, int peer);
struct sockaddr *addr,
int *sockaddr_len, int peer);
unsigned int (*poll) (struct file *file, struct socket *sock,
struct poll_table_struct *wait);
int (*ioctl) (struct socket *sock, unsigned int cmd,
......@@ -115,9 +115,9 @@ struct proto_ops {
int (*listen) (struct socket *sock, int len);
int (*shutdown) (struct socket *sock, int flags);
int (*setsockopt)(struct socket *sock, int level,
int optname, char *optval, int optlen);
int optname, char __user *optval, int optlen);
int (*getsockopt)(struct socket *sock, int level,
int optname, char *optval, int *optlen);
int optname, char __user *optval, int __user *optlen);
int (*sendmsg) (struct kiocb *iocb, struct socket *sock,
struct msghdr *m, int total_len);
int (*recvmsg) (struct kiocb *iocb, struct socket *sock,
......
......@@ -172,7 +172,7 @@ extern void end_page_writeback(struct page *page);
* This assumes that two userspace pages are always sufficient. That's
* not true if PAGE_CACHE_SIZE > PAGE_SIZE.
*/
static inline int fault_in_pages_writeable(char *uaddr, int size)
static inline int fault_in_pages_writeable(char __user *uaddr, int size)
{
int ret;
......@@ -182,7 +182,7 @@ static inline int fault_in_pages_writeable(char *uaddr, int size)
*/
ret = __put_user(0, uaddr);
if (ret == 0) {
char *end = uaddr + size - 1;
char __user *end = uaddr + size - 1;
/*
* If the page was already mapped, this will get a cache miss
......@@ -195,14 +195,14 @@ static inline int fault_in_pages_writeable(char *uaddr, int size)
return ret;
}
static inline void fault_in_pages_readable(const char *uaddr, int size)
static inline void fault_in_pages_readable(const char __user *uaddr, int size)
{
volatile char c;
int ret;
ret = __get_user(c, (char *)uaddr);
if (ret == 0) {
const char *end = uaddr + size - 1;
const char __user *end = uaddr + size - 1;
if (((unsigned long)uaddr & PAGE_MASK) !=
((unsigned long)end & PAGE_MASK))
......
......@@ -69,8 +69,8 @@
#include <linux/compiler.h> /* For unlikely. */
#include <linux/sched.h> /* For struct task_struct. */
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char * src, unsigned long dst, int len);
extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
extern int ptrace_attach(struct task_struct *tsk);
extern int ptrace_detach(struct task_struct *, unsigned int);
extern void ptrace_disable(struct task_struct *);
......
......@@ -371,8 +371,8 @@ struct task_struct {
wait_queue_head_t wait_chldexit; /* for wait4() */
struct completion *vfork_done; /* for vfork() */
int *set_child_tid; /* CLONE_CHILD_SETTID */
int *clear_child_tid; /* CLONE_CHILD_CLEARTID */
int __user *set_child_tid; /* CLONE_CHILD_SETTID */
int __user *clear_child_tid; /* CLONE_CHILD_CLEARTID */
unsigned long rt_priority;
unsigned long it_real_value, it_prof_value, it_virt_value;
......@@ -563,7 +563,7 @@ extern int kill_pg(pid_t, int, int);
extern int kill_sl(pid_t, int, int);
extern int kill_proc(pid_t, int, int);
extern int do_sigaction(int, const struct k_sigaction *, struct k_sigaction *);
extern int do_sigaltstack(const stack_t *, stack_t *, unsigned long);
extern int do_sigaltstack(const stack_t __user *, stack_t __user *, unsigned long);
/* These can be the second arg to send_sig_info/send_group_sig_info. */
#define SEND_SIG_NOINFO ((struct siginfo *) 0)
......@@ -636,7 +636,7 @@ extern int allow_signal(int);
extern task_t *child_reaper;
extern int do_execve(char *, char __user * __user *, char __user * __user *, struct pt_regs *);
extern struct task_struct *do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int *, int *);
extern struct task_struct *do_fork(unsigned long, unsigned long, struct pt_regs *, unsigned long, int __user *, int __user *);
#ifdef CONFIG_SMP
extern void wait_task_inactive(task_t * p);
......
......@@ -201,7 +201,7 @@ static inline void init_sigpending(struct sigpending *sig)
sig->tail = &sig->head;
}
extern long do_sigpending(void *, unsigned long);
extern long do_sigpending(void __user *, unsigned long);
extern int sigprocmask(int, sigset_t *, sigset_t *);
#ifndef HAVE_ARCH_GET_SIGNAL_TO_DELIVER
......
......@@ -9,6 +9,7 @@
#include <linux/sockios.h> /* the SIOCxxx I/O controls */
#include <linux/uio.h> /* iovec support */
#include <linux/types.h> /* pid_t */
#include <linux/compiler.h> /* __user */
typedef unsigned short sa_family_t;
......@@ -242,8 +243,8 @@ struct ucred {
#define MSG_CMSG_COMPAT 0 /* We never have 32 bit fixups */
#endif
extern asmlinkage long sys_sendmsg(int fd, struct msghdr *msg, unsigned flags);
extern asmlinkage long sys_recvmsg(int fd, struct msghdr *msg, unsigned flags);
extern asmlinkage long sys_sendmsg(int fd, struct msghdr __user *msg, unsigned flags);
extern asmlinkage long sys_recvmsg(int fd, struct msghdr __user *msg, unsigned flags);
......@@ -285,8 +286,8 @@ extern int csum_partial_copy_fromiovecend(unsigned char *kdata,
extern int verify_iovec(struct msghdr *m, struct iovec *iov, char *address, int mode);
extern int memcpy_toiovec(struct iovec *v, unsigned char *kdata, int len);
extern void memcpy_tokerneliovec(struct iovec *iov, unsigned char *kdata, int len);
extern int move_addr_to_user(void *kaddr, int klen, void *uaddr, int *ulen);
extern int move_addr_to_kernel(void *uaddr, int ulen, void *kaddr);
extern int move_addr_to_user(void *kaddr, int klen, void __user *uaddr, int __user *ulen);
extern int move_addr_to_kernel(void __user *uaddr, int ulen, void *kaddr);
extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
#endif
......
......@@ -27,7 +27,7 @@ struct compat_cmsghdr {
#define compat_msghdr msghdr /* to avoid compiler warnings */
#endif /* defined(CONFIG_COMPAT) */
extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr *);
extern int get_compat_msghdr(struct msghdr *, struct compat_msghdr __user *);
extern int verify_compat_iovec(struct msghdr *, struct iovec *, char *, int);
extern asmlinkage long compat_sys_sendmsg(int,struct compat_msghdr *,unsigned);
extern asmlinkage long compat_sys_recvmsg(int,struct compat_msghdr *,unsigned);
......
......@@ -450,7 +450,7 @@ void mm_release(struct task_struct *tsk, struct mm_struct *mm)
complete(vfork_done);
}
if (tsk->clear_child_tid && atomic_read(&mm->mm_users) > 1) {
u32 * tidptr = tsk->clear_child_tid;
u32 __user * tidptr = tsk->clear_child_tid;
tsk->clear_child_tid = NULL;
/*
......@@ -738,7 +738,7 @@ static inline void copy_flags(unsigned long clone_flags, struct task_struct *p)
p->flags = new_flags;
}
asmlinkage long sys_set_tid_address(int *tidptr)
asmlinkage long sys_set_tid_address(int __user *tidptr)
{
current->clear_child_tid = tidptr;
......@@ -757,8 +757,8 @@ static struct task_struct *copy_process(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int *parent_tidptr,
int *child_tidptr)
int __user *parent_tidptr,
int __user *child_tidptr)
{
int retval;
struct task_struct *p = NULL;
......@@ -1073,8 +1073,8 @@ struct task_struct *do_fork(unsigned long clone_flags,
unsigned long stack_start,
struct pt_regs *regs,
unsigned long stack_size,
int *parent_tidptr,
int *child_tidptr)
int __user *parent_tidptr,
int __user *child_tidptr)
{
struct task_struct *p;
int trace = 0;
......
......@@ -311,7 +311,7 @@ void __init reserve_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsi
void __init free_bootmem_node (pg_data_t *pgdat, unsigned long physaddr, unsigned long size)
{
return(free_bootmem_core(pgdat->bdata, physaddr, size));
free_bootmem_core(pgdat->bdata, physaddr, size);
}
unsigned long __init free_all_bootmem_node (pg_data_t *pgdat)
......@@ -336,7 +336,7 @@ void __init reserve_bootmem (unsigned long addr, unsigned long size)
void __init free_bootmem (unsigned long addr, unsigned long size)
{
return(free_bootmem_core(contig_page_data.bdata, addr, size));
free_bootmem_core(contig_page_data.bdata, addr, size);
}
unsigned long __init free_all_bootmem (void)
......
......@@ -802,7 +802,7 @@ __generic_file_aio_read(struct kiocb *iocb, const struct iovec *iov,
}
ssize_t
generic_file_aio_read(struct kiocb *iocb, char *buf, size_t count, loff_t pos)
generic_file_aio_read(struct kiocb *iocb, char __user *buf, size_t count, loff_t pos)
{
struct iovec local_iov = { .iov_base = buf, .iov_len = count };
......@@ -812,7 +812,7 @@ generic_file_aio_read(struct kiocb *iocb, char *buf, size_t count, loff_t pos)
EXPORT_SYMBOL(generic_file_aio_read);
ssize_t
generic_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
generic_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
struct iovec local_iov = { .iov_base = buf, .iov_len = count };
struct kiocb kiocb;
......@@ -846,7 +846,7 @@ int file_send_actor(read_descriptor_t * desc, struct page *page, unsigned long o
}
ssize_t generic_file_sendfile(struct file *in_file, loff_t *ppos,
size_t count, read_actor_t actor, void *target)
size_t count, read_actor_t actor, void __user *target)
{
read_descriptor_t desc;
......@@ -1412,7 +1412,7 @@ void remove_suid(struct dentry *dentry)
static inline int
filemap_copy_from_user(struct page *page, unsigned long offset,
const char *buf, unsigned bytes)
const char __user *buf, unsigned bytes)
{
char *kaddr;
int left;
......@@ -1437,7 +1437,7 @@ __filemap_copy_from_user_iovec(char *vaddr,
int left = 0;
while (bytes) {
char *buf = iov->iov_base + base;
char __user *buf = iov->iov_base + base;
int copy = min(bytes, iov->iov_len - base);
base = 0;
if ((left = __copy_from_user(vaddr, buf, copy)))
......@@ -1601,7 +1601,7 @@ generic_file_aio_write_nolock(struct kiocb *iocb, const struct iovec *iov,
const struct iovec *cur_iov = iov; /* current iovec */
size_t iov_base = 0; /* offset in the current iovec */
unsigned long seg;
char *buf;
char __user *buf;
ocount = 0;
for (seg = 0; seg < nr_segs; seg++) {
......@@ -1775,13 +1775,13 @@ generic_file_write_nolock(struct file *file, const struct iovec *iov,
return ret;
}
ssize_t generic_file_aio_write(struct kiocb *iocb, const char *buf,
ssize_t generic_file_aio_write(struct kiocb *iocb, const char __user *buf,
size_t count, loff_t pos)
{
struct file *file = iocb->ki_filp;
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
ssize_t err;
struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
BUG_ON(iocb->ki_pos != pos);
......@@ -1795,12 +1795,12 @@ ssize_t generic_file_aio_write(struct kiocb *iocb, const char *buf,
EXPORT_SYMBOL(generic_file_aio_write);
EXPORT_SYMBOL(generic_file_aio_write_nolock);
ssize_t generic_file_write(struct file *file, const char *buf,
ssize_t generic_file_write(struct file *file, const char __user *buf,
size_t count, loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode->i_mapping->host;
ssize_t err;
struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
struct iovec local_iov = { .iov_base = (void __user *)buf, .iov_len = count };
down(&inode->i_sem);
err = generic_file_write_nolock(file, &local_iov, 1, ppos);
......
......@@ -39,7 +39,7 @@ static unsigned char mincore_page(struct vm_area_struct * vma,
}
static long mincore_vma(struct vm_area_struct * vma,
unsigned long start, unsigned long end, unsigned char * vec)
unsigned long start, unsigned long end, unsigned char __user * vec)
{
long error, i, remaining;
unsigned char * tmp;
......@@ -106,7 +106,7 @@ static long mincore_vma(struct vm_area_struct * vma,
* -EAGAIN - A kernel resource was temporarily unavailable.
*/
asmlinkage long sys_mincore(unsigned long start, size_t len,
unsigned char * vec)
unsigned char __user * vec)
{
int index = 0;
unsigned long end;
......
......@@ -1114,7 +1114,7 @@ shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsig
}
static ssize_t
shmem_file_write(struct file *file, const char *buf, size_t count, loff_t *ppos)
shmem_file_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos)
{
struct inode *inode = file->f_dentry->d_inode;
loff_t pos;
......@@ -1310,7 +1310,7 @@ static void do_shmem_file_read(struct file *filp, loff_t *ppos, read_descriptor_
update_atime(inode);
}
static ssize_t shmem_file_read(struct file *filp, char *buf, size_t count, loff_t *ppos)
static ssize_t shmem_file_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos)
{
read_descriptor_t desc;
......@@ -1333,7 +1333,7 @@ static ssize_t shmem_file_read(struct file *filp, char *buf, size_t count, loff_
}
static ssize_t shmem_file_sendfile(struct file *in_file, loff_t *ppos,
size_t count, read_actor_t actor, void *target)
size_t count, read_actor_t actor, void __user *target)
{
read_descriptor_t desc;
......@@ -1519,7 +1519,7 @@ static int shmem_symlink(struct inode *dir, struct dentry *dentry, const char *s
return 0;
}
static int shmem_readlink_inline(struct dentry *dentry, char *buffer, int buflen)
static int shmem_readlink_inline(struct dentry *dentry, char __user *buffer, int buflen)
{
return vfs_readlink(dentry, buffer, buflen, (const char *)SHMEM_I(dentry->d_inode));
}
......@@ -1529,7 +1529,7 @@ static int shmem_follow_link_inline(struct dentry *dentry, struct nameidata *nd)
return vfs_follow_link(nd, (const char *)SHMEM_I(dentry->d_inode));
}
static int shmem_readlink(struct dentry *dentry, char *buffer, int buflen)
static int shmem_readlink(struct dentry *dentry, char __user *buffer, int buflen)
{
struct page *page = NULL;
int res = shmem_getpage(dentry->d_inode, 0, &page, SGP_READ);
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment