Commit 69655cb1 authored by Randolph Chung's avatar Randolph Chung Committed by David S. Miller

[COMPAT]: Fix sock_fprog handling.

parent f5d6da7d
...@@ -496,6 +496,7 @@ static int do_set_attach_filter(int fd, int level, int optname, ...@@ -496,6 +496,7 @@ static int do_set_attach_filter(int fd, int level, int optname,
struct sock_fprog kfprog; struct sock_fprog kfprog;
mm_segment_t old_fs; mm_segment_t old_fs;
compat_uptr_t uptr; compat_uptr_t uptr;
unsigned int fsize;
int ret; int ret;
if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) || if (!access_ok(VERIFY_READ, fprog32, sizeof(*fprog32)) ||
...@@ -503,15 +504,14 @@ static int do_set_attach_filter(int fd, int level, int optname, ...@@ -503,15 +504,14 @@ static int do_set_attach_filter(int fd, int level, int optname,
__get_user(uptr, &fprog32->filter)) __get_user(uptr, &fprog32->filter))
return -EFAULT; return -EFAULT;
kfprog.filter = compat_ptr(uptr); fsize = kfprog.len * sizeof(struct sock_filter);
/* kfprog.filter = (struct sock_filter *)kmalloc(fsize, GFP_KERNEL);
* Since struct sock_filter is architecure independent, if (kfprog.filter == NULL)
* we can just do the access_ok check and pass the return -ENOMEM;
* same pointer to the real syscall. if (copy_from_user(kfprog.filter, compat_ptr(uptr), fsize)) {
*/ kfree(kfprog.filter);
if (!access_ok(VERIFY_READ, kfprog.filter,
kfprog.len * sizeof(struct sock_filter)))
return -EFAULT; return -EFAULT;
}
old_fs = get_fs(); old_fs = get_fs();
set_fs(KERNEL_DS); set_fs(KERNEL_DS);
...@@ -519,6 +519,7 @@ static int do_set_attach_filter(int fd, int level, int optname, ...@@ -519,6 +519,7 @@ static int do_set_attach_filter(int fd, int level, int optname,
(char *)&kfprog, sizeof(kfprog)); (char *)&kfprog, sizeof(kfprog));
set_fs(old_fs); set_fs(old_fs);
kfree(kfprog.filter);
return ret; return ret;
} }
......
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