mirror of
https://github.com/Divested-Mobile/DivestOS-Build.git
synced 2024-12-29 01:16:26 -05:00
Add patches for many Linux CVEs, and overhaul script paths
This commit is contained in:
parent
8c8dc284c9
commit
75099b9404
34
Patches/Linux_CVEs/CVE-2012-6657/0.patch
Normal file
34
Patches/Linux_CVEs/CVE-2012-6657/0.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From 3e10986d1d698140747fcfc2761ec9cb64c1d582 Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Mon, 24 Sep 2012 07:00:11 +0000
|
||||
Subject: net: guard tcp_set_keepalive() to tcp sockets
|
||||
|
||||
Its possible to use RAW sockets to get a crash in
|
||||
tcp_set_keepalive() / sk_reset_timer()
|
||||
|
||||
Fix is to make sure socket is a SOCK_STREAM one.
|
||||
|
||||
Reported-by: Dave Jones <davej@redhat.com>
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/core/sock.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/core/sock.c b/net/core/sock.c
|
||||
index 3057920..a6000fb 100644
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -691,7 +691,8 @@ set_rcvbuf:
|
||||
|
||||
case SO_KEEPALIVE:
|
||||
#ifdef CONFIG_INET
|
||||
- if (sk->sk_protocol == IPPROTO_TCP)
|
||||
+ if (sk->sk_protocol == IPPROTO_TCP &&
|
||||
+ sk->sk_type == SOCK_STREAM)
|
||||
tcp_set_keepalive(sk, valbool);
|
||||
#endif
|
||||
sock_valbool_flag(sk, SOCK_KEEPOPEN, valbool);
|
||||
--
|
||||
cgit v1.1
|
||||
|
73
Patches/Linux_CVEs/CVE-2012-6689/0.patch
Normal file
73
Patches/Linux_CVEs/CVE-2012-6689/0.patch
Normal file
@ -0,0 +1,73 @@
|
||||
From 20e1db19db5d6b9e4e83021595eab0dc8f107bef Mon Sep 17 00:00:00 2001
|
||||
From: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Date: Thu, 23 Aug 2012 02:09:11 +0000
|
||||
Subject: netlink: fix possible spoofing from non-root processes
|
||||
|
||||
Non-root user-space processes can send Netlink messages to other
|
||||
processes that are well-known for being subscribed to Netlink
|
||||
asynchronous notifications. This allows ilegitimate non-root
|
||||
process to send forged messages to Netlink subscribers.
|
||||
|
||||
The userspace process usually verifies the legitimate origin in
|
||||
two ways:
|
||||
|
||||
a) Socket credentials. If UID != 0, then the message comes from
|
||||
some ilegitimate process and the message needs to be dropped.
|
||||
|
||||
b) Netlink portID. In general, portID == 0 means that the origin
|
||||
of the messages comes from the kernel. Thus, discarding any
|
||||
message not coming from the kernel.
|
||||
|
||||
However, ctnetlink sets the portID in event messages that has
|
||||
been triggered by some user-space process, eg. conntrack utility.
|
||||
So other processes subscribed to ctnetlink events, eg. conntrackd,
|
||||
know that the event was triggered by some user-space action.
|
||||
|
||||
Neither of the two ways to discard ilegitimate messages coming
|
||||
from non-root processes can help for ctnetlink.
|
||||
|
||||
This patch adds capability validation in case that dst_pid is set
|
||||
in netlink_sendmsg(). This approach is aggressive since existing
|
||||
applications using any Netlink bus to deliver messages between
|
||||
two user-space processes will break. Note that the exception is
|
||||
NETLINK_USERSOCK, since it is reserved for netlink-to-netlink
|
||||
userspace communication.
|
||||
|
||||
Still, if anyone wants that his Netlink bus allows netlink-to-netlink
|
||||
userspace, then they can set NL_NONROOT_SEND. However, by default,
|
||||
I don't think it makes sense to allow to use NETLINK_ROUTE to
|
||||
communicate two processes that are sending no matter what information
|
||||
that is not related to link/neighbouring/routing. They should be using
|
||||
NETLINK_USERSOCK instead for that.
|
||||
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/netlink/af_netlink.c | 4 +++-
|
||||
1 file changed, 3 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
|
||||
index 1445d73..5270238 100644
|
||||
--- a/net/netlink/af_netlink.c
|
||||
+++ b/net/netlink/af_netlink.c
|
||||
@@ -1373,7 +1373,8 @@ static int netlink_sendmsg(struct kiocb *kiocb, struct socket *sock,
|
||||
dst_pid = addr->nl_pid;
|
||||
dst_group = ffs(addr->nl_groups);
|
||||
err = -EPERM;
|
||||
- if (dst_group && !netlink_capable(sock, NL_NONROOT_SEND))
|
||||
+ if ((dst_group || dst_pid) &&
|
||||
+ !netlink_capable(sock, NL_NONROOT_SEND))
|
||||
goto out;
|
||||
} else {
|
||||
dst_pid = nlk->dst_pid;
|
||||
@@ -2147,6 +2148,7 @@ static void __init netlink_add_usersock_entry(void)
|
||||
rcu_assign_pointer(nl_table[NETLINK_USERSOCK].listeners, listeners);
|
||||
nl_table[NETLINK_USERSOCK].module = THIS_MODULE;
|
||||
nl_table[NETLINK_USERSOCK].registered = 1;
|
||||
+ nl_table[NETLINK_USERSOCK].nl_nonroot = NL_NONROOT_SEND;
|
||||
|
||||
netlink_table_ungrab();
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
106
Patches/Linux_CVEs/CVE-2012-6701/0.patch
Normal file
106
Patches/Linux_CVEs/CVE-2012-6701/0.patch
Normal file
@ -0,0 +1,106 @@
|
||||
From a70b52ec1aaeaf60f4739edb1b422827cb6f3893 Mon Sep 17 00:00:00 2001
|
||||
From: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Date: Mon, 21 May 2012 16:06:20 -0700
|
||||
Subject: vfs: make AIO use the proper rw_verify_area() area helpers
|
||||
|
||||
We had for some reason overlooked the AIO interface, and it didn't use
|
||||
the proper rw_verify_area() helper function that checks (for example)
|
||||
mandatory locking on the file, and that the size of the access doesn't
|
||||
cause us to overflow the provided offset limits etc.
|
||||
|
||||
Instead, AIO did just the security_file_permission() thing (that
|
||||
rw_verify_area() also does) directly.
|
||||
|
||||
This fixes it to do all the proper helper functions, which not only
|
||||
means that now mandatory file locking works with AIO too, we can
|
||||
actually remove lines of code.
|
||||
|
||||
Reported-by: Manish Honap <manish_honap_vit@yahoo.co.in>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/aio.c | 30 ++++++++++++++----------------
|
||||
1 file changed, 14 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/fs/aio.c b/fs/aio.c
|
||||
index 67a6db3..e7f2fad 100644
|
||||
--- a/fs/aio.c
|
||||
+++ b/fs/aio.c
|
||||
@@ -1456,6 +1456,10 @@ static ssize_t aio_setup_vectored_rw(int type, struct kiocb *kiocb, bool compat)
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
+ ret = rw_verify_area(type, kiocb->ki_filp, &kiocb->ki_pos, ret);
|
||||
+ if (ret < 0)
|
||||
+ goto out;
|
||||
+
|
||||
kiocb->ki_nr_segs = kiocb->ki_nbytes;
|
||||
kiocb->ki_cur_seg = 0;
|
||||
/* ki_nbytes/left now reflect bytes instead of segs */
|
||||
@@ -1467,11 +1471,17 @@ out:
|
||||
return ret;
|
||||
}
|
||||
|
||||
-static ssize_t aio_setup_single_vector(struct kiocb *kiocb)
|
||||
+static ssize_t aio_setup_single_vector(int type, struct file * file, struct kiocb *kiocb)
|
||||
{
|
||||
+ int bytes;
|
||||
+
|
||||
+ bytes = rw_verify_area(type, file, &kiocb->ki_pos, kiocb->ki_left);
|
||||
+ if (bytes < 0)
|
||||
+ return bytes;
|
||||
+
|
||||
kiocb->ki_iovec = &kiocb->ki_inline_vec;
|
||||
kiocb->ki_iovec->iov_base = kiocb->ki_buf;
|
||||
- kiocb->ki_iovec->iov_len = kiocb->ki_left;
|
||||
+ kiocb->ki_iovec->iov_len = bytes;
|
||||
kiocb->ki_nr_segs = 1;
|
||||
kiocb->ki_cur_seg = 0;
|
||||
return 0;
|
||||
@@ -1496,10 +1506,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
||||
if (unlikely(!access_ok(VERIFY_WRITE, kiocb->ki_buf,
|
||||
kiocb->ki_left)))
|
||||
break;
|
||||
- ret = security_file_permission(file, MAY_READ);
|
||||
- if (unlikely(ret))
|
||||
- break;
|
||||
- ret = aio_setup_single_vector(kiocb);
|
||||
+ ret = aio_setup_single_vector(READ, file, kiocb);
|
||||
if (ret)
|
||||
break;
|
||||
ret = -EINVAL;
|
||||
@@ -1514,10 +1521,7 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
||||
if (unlikely(!access_ok(VERIFY_READ, kiocb->ki_buf,
|
||||
kiocb->ki_left)))
|
||||
break;
|
||||
- ret = security_file_permission(file, MAY_WRITE);
|
||||
- if (unlikely(ret))
|
||||
- break;
|
||||
- ret = aio_setup_single_vector(kiocb);
|
||||
+ ret = aio_setup_single_vector(WRITE, file, kiocb);
|
||||
if (ret)
|
||||
break;
|
||||
ret = -EINVAL;
|
||||
@@ -1528,9 +1532,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
||||
ret = -EBADF;
|
||||
if (unlikely(!(file->f_mode & FMODE_READ)))
|
||||
break;
|
||||
- ret = security_file_permission(file, MAY_READ);
|
||||
- if (unlikely(ret))
|
||||
- break;
|
||||
ret = aio_setup_vectored_rw(READ, kiocb, compat);
|
||||
if (ret)
|
||||
break;
|
||||
@@ -1542,9 +1543,6 @@ static ssize_t aio_setup_iocb(struct kiocb *kiocb, bool compat)
|
||||
ret = -EBADF;
|
||||
if (unlikely(!(file->f_mode & FMODE_WRITE)))
|
||||
break;
|
||||
- ret = security_file_permission(file, MAY_WRITE);
|
||||
- if (unlikely(ret))
|
||||
- break;
|
||||
ret = aio_setup_vectored_rw(WRITE, kiocb, compat);
|
||||
if (ret)
|
||||
break;
|
||||
--
|
||||
cgit v1.1
|
||||
|
31
Patches/Linux_CVEs/CVE-2012-6703/0.patch
Normal file
31
Patches/Linux_CVEs/CVE-2012-6703/0.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From b35cc8225845112a616e3a2266d2fde5ab13d3ab Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Wed, 5 Sep 2012 15:32:18 +0300
|
||||
Subject: [PATCH] ALSA: compress_core: integer overflow in
|
||||
snd_compr_allocate_buffer()
|
||||
|
||||
These are 32 bit values that come from the user, we need to check for
|
||||
integer overflows or we could end up allocating a smaller buffer than
|
||||
expected.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/compress_offload.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
|
||||
index eb60cb8dbb8a6..68fe02c7400a2 100644
|
||||
--- a/sound/core/compress_offload.c
|
||||
+++ b/sound/core/compress_offload.c
|
||||
@@ -407,6 +407,10 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
|
||||
unsigned int buffer_size;
|
||||
void *buffer;
|
||||
|
||||
+ if (params->buffer.fragment_size == 0 ||
|
||||
+ params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
buffer_size = params->buffer.fragment_size * params->buffer.fragments;
|
||||
if (stream->ops->copy) {
|
||||
buffer = NULL;
|
31
Patches/Linux_CVEs/CVE-2012-6703/1.patch
Normal file
31
Patches/Linux_CVEs/CVE-2012-6703/1.patch
Normal file
@ -0,0 +1,31 @@
|
||||
From 81ce573830e9d5531531b3ec778c58e6b9167bcd Mon Sep 17 00:00:00 2001
|
||||
From: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Date: Wed, 5 Sep 2012 15:32:18 +0300
|
||||
Subject: [PATCH] ALSA: compress_core: integer overflow in
|
||||
snd_compr_allocate_buffer()
|
||||
|
||||
These are 32 bit values that come from the user, we need to check for
|
||||
integer overflows or we could end up allocating a smaller buffer than
|
||||
expected.
|
||||
|
||||
Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/compress_offload.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
|
||||
index eb60cb8dbb8a6..68fe02c7400a2 100644
|
||||
--- a/sound/core/compress_offload.c
|
||||
+++ b/sound/core/compress_offload.c
|
||||
@@ -407,6 +407,10 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
|
||||
unsigned int buffer_size;
|
||||
void *buffer;
|
||||
|
||||
+ if (params->buffer.fragment_size == 0 ||
|
||||
+ params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
buffer_size = params->buffer.fragment_size * params->buffer.fragments;
|
||||
if (stream->ops->copy) {
|
||||
buffer = NULL;
|
66
Patches/Linux_CVEs/CVE-2012-6703/2.patch
Normal file
66
Patches/Linux_CVEs/CVE-2012-6703/2.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From 4dc040a0b34890d2adc0d63da6e9bfb4eb791b19 Mon Sep 17 00:00:00 2001
|
||||
From: Vinod Koul <vinod.koul@linux.intel.com>
|
||||
Date: Mon, 17 Sep 2012 11:51:25 +0530
|
||||
Subject: [PATCH] ALSA: compress - move the buffer check
|
||||
|
||||
Commit ALSA: compress_core: integer overflow in snd_compr_allocate_buffer()
|
||||
added a new error check for input params.
|
||||
this add new routine for input checks and moves buffer overflow check to this
|
||||
new routine. This allows the error value to be propogated to user space
|
||||
|
||||
Signed-off-by: Vinod Koul <vinod.koul@linux.intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/compress_offload.c | 20 ++++++++++++++++----
|
||||
1 file changed, 16 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/sound/core/compress_offload.c b/sound/core/compress_offload.c
|
||||
index 68fe02c7400a2..bd7f28e892540 100644
|
||||
--- a/sound/core/compress_offload.c
|
||||
+++ b/sound/core/compress_offload.c
|
||||
@@ -407,10 +407,6 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
|
||||
unsigned int buffer_size;
|
||||
void *buffer;
|
||||
|
||||
- if (params->buffer.fragment_size == 0 ||
|
||||
- params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
|
||||
- return -EINVAL;
|
||||
-
|
||||
buffer_size = params->buffer.fragment_size * params->buffer.fragments;
|
||||
if (stream->ops->copy) {
|
||||
buffer = NULL;
|
||||
@@ -429,6 +425,16 @@ static int snd_compr_allocate_buffer(struct snd_compr_stream *stream,
|
||||
return 0;
|
||||
}
|
||||
|
||||
+static int snd_compress_check_input(struct snd_compr_params *params)
|
||||
+{
|
||||
+ /* first let's check the buffer parameter's */
|
||||
+ if (params->buffer.fragment_size == 0 ||
|
||||
+ params->buffer.fragments > SIZE_MAX / params->buffer.fragment_size)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int
|
||||
snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
|
||||
{
|
||||
@@ -447,11 +453,17 @@ snd_compr_set_params(struct snd_compr_stream *stream, unsigned long arg)
|
||||
retval = -EFAULT;
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
+ retval = snd_compress_check_input(params);
|
||||
+ if (retval)
|
||||
+ goto out;
|
||||
+
|
||||
retval = snd_compr_allocate_buffer(stream, params);
|
||||
if (retval) {
|
||||
retval = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
+
|
||||
retval = stream->ops->set_params(stream, params);
|
||||
if (retval)
|
||||
goto out;
|
97
Patches/Linux_CVEs/CVE-2012-6704/0.patch
Normal file
97
Patches/Linux_CVEs/CVE-2012-6704/0.patch
Normal file
@ -0,0 +1,97 @@
|
||||
From 82981930125abfd39d7c8378a9cfdf5e1be2002b Mon Sep 17 00:00:00 2001
|
||||
From: Eric Dumazet <edumazet@google.com>
|
||||
Date: Thu, 26 Apr 2012 20:07:59 +0000
|
||||
Subject: [PATCH] net: cleanups in sock_setsockopt()
|
||||
|
||||
Use min_t()/max_t() macros, reformat two comments, use !!test_bit() to
|
||||
match !!sock_flag()
|
||||
|
||||
Signed-off-by: Eric Dumazet <edumazet@google.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/core/sock.c | 42 +++++++++++++++---------------------------
|
||||
1 file changed, 15 insertions(+), 27 deletions(-)
|
||||
|
||||
diff --git a/net/core/sock.c b/net/core/sock.c
|
||||
index 0431aaf7473a2..10605d2ec8606 100644
|
||||
--- a/net/core/sock.c
|
||||
+++ b/net/core/sock.c
|
||||
@@ -577,23 +577,15 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
case SO_SNDBUF:
|
||||
/* Don't error on this BSD doesn't and if you think
|
||||
- about it this is right. Otherwise apps have to
|
||||
- play 'guess the biggest size' games. RCVBUF/SNDBUF
|
||||
- are treated in BSD as hints */
|
||||
-
|
||||
- if (val > sysctl_wmem_max)
|
||||
- val = sysctl_wmem_max;
|
||||
+ * about it this is right. Otherwise apps have to
|
||||
+ * play 'guess the biggest size' games. RCVBUF/SNDBUF
|
||||
+ * are treated in BSD as hints
|
||||
+ */
|
||||
+ val = min_t(u32, val, sysctl_wmem_max);
|
||||
set_sndbuf:
|
||||
sk->sk_userlocks |= SOCK_SNDBUF_LOCK;
|
||||
- if ((val * 2) < SOCK_MIN_SNDBUF)
|
||||
- sk->sk_sndbuf = SOCK_MIN_SNDBUF;
|
||||
- else
|
||||
- sk->sk_sndbuf = val * 2;
|
||||
-
|
||||
- /*
|
||||
- * Wake up sending tasks if we
|
||||
- * upped the value.
|
||||
- */
|
||||
+ sk->sk_sndbuf = max_t(u32, val * 2, SOCK_MIN_SNDBUF);
|
||||
+ /* Wake up sending tasks if we upped the value. */
|
||||
sk->sk_write_space(sk);
|
||||
break;
|
||||
|
||||
@@ -606,12 +598,11 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
|
||||
case SO_RCVBUF:
|
||||
/* Don't error on this BSD doesn't and if you think
|
||||
- about it this is right. Otherwise apps have to
|
||||
- play 'guess the biggest size' games. RCVBUF/SNDBUF
|
||||
- are treated in BSD as hints */
|
||||
-
|
||||
- if (val > sysctl_rmem_max)
|
||||
- val = sysctl_rmem_max;
|
||||
+ * about it this is right. Otherwise apps have to
|
||||
+ * play 'guess the biggest size' games. RCVBUF/SNDBUF
|
||||
+ * are treated in BSD as hints
|
||||
+ */
|
||||
+ val = min_t(u32, val, sysctl_rmem_max);
|
||||
set_rcvbuf:
|
||||
sk->sk_userlocks |= SOCK_RCVBUF_LOCK;
|
||||
/*
|
||||
@@ -629,10 +620,7 @@ int sock_setsockopt(struct socket *sock, int level, int optname,
|
||||
* returning the value we actually used in getsockopt
|
||||
* is the most desirable behavior.
|
||||
*/
|
||||
- if ((val * 2) < SOCK_MIN_RCVBUF)
|
||||
- sk->sk_rcvbuf = SOCK_MIN_RCVBUF;
|
||||
- else
|
||||
- sk->sk_rcvbuf = val * 2;
|
||||
+ sk->sk_rcvbuf = max_t(u32, val * 2, SOCK_MIN_RCVBUF);
|
||||
break;
|
||||
|
||||
case SO_RCVBUFFORCE:
|
||||
@@ -975,7 +963,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
|
||||
case SO_PASSCRED:
|
||||
- v.val = test_bit(SOCK_PASSCRED, &sock->flags) ? 1 : 0;
|
||||
+ v.val = !!test_bit(SOCK_PASSCRED, &sock->flags);
|
||||
break;
|
||||
|
||||
case SO_PEERCRED:
|
||||
@@ -1010,7 +998,7 @@ int sock_getsockopt(struct socket *sock, int level, int optname,
|
||||
break;
|
||||
|
||||
case SO_PASSSEC:
|
||||
- v.val = test_bit(SOCK_PASSSEC, &sock->flags) ? 1 : 0;
|
||||
+ v.val = !!test_bit(SOCK_PASSSEC, &sock->flags);
|
||||
break;
|
||||
|
||||
case SO_PEERSEC:
|
48
Patches/Linux_CVEs/CVE-2013-2015/0.patch
Normal file
48
Patches/Linux_CVEs/CVE-2013-2015/0.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 016a3592cc34fa349235b5a8b48af5cece2cbfeb Mon Sep 17 00:00:00 2001
|
||||
From: Theodore Ts'o <tytso@mit.edu>
|
||||
Date: Thu, 27 Dec 2012 01:42:50 -0500
|
||||
Subject: [PATCH] ext4: avoid hang when mounting non-journal filesystems with
|
||||
orphan list
|
||||
|
||||
commit 0e9a9a1ad619e7e987815d20262d36a2f95717ca upstream.
|
||||
|
||||
When trying to mount a file system which does not contain a journal,
|
||||
but which does have a orphan list containing an inode which needs to
|
||||
be truncated, the mount call with hang forever in
|
||||
ext4_orphan_cleanup() because ext4_orphan_del() will return
|
||||
immediately without removing the inode from the orphan list, leading
|
||||
to an uninterruptible loop in kernel code which will busy out one of
|
||||
the CPU's on the system.
|
||||
|
||||
This can be trivially reproduced by trying to mount the file system
|
||||
found in tests/f_orphan_extents_inode/image.gz from the e2fsprogs
|
||||
source tree. If a malicious user were to put this on a USB stick, and
|
||||
mount it on a Linux desktop which has automatic mounts enabled, this
|
||||
could be considered a potential denial of service attack. (Not a big
|
||||
deal in practice, but professional paranoids worry about such things,
|
||||
and have even been known to allocate CVE numbers for such problems.)
|
||||
|
||||
-js: This is a fix for CVE-2013-2015.
|
||||
|
||||
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
|
||||
Reviewed-by: Zheng Liu <wenqing.lz@taobao.com>
|
||||
Acked-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/ext4/namei.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/fs/ext4/namei.c b/fs/ext4/namei.c
|
||||
index 9fb3fae4898a..54ad9a54cd89 100644
|
||||
--- a/fs/ext4/namei.c
|
||||
+++ b/fs/ext4/namei.c
|
||||
@@ -2054,7 +2054,8 @@ int ext4_orphan_del(handle_t *handle, struct inode *inode)
|
||||
int err = 0;
|
||||
|
||||
/* ext4_handle_valid() assumes a valid handle_t pointer */
|
||||
- if (handle && !ext4_handle_valid(handle))
|
||||
+ if (handle && !ext4_handle_valid(handle) &&
|
||||
+ !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS))
|
||||
return 0;
|
||||
|
||||
mutex_lock(&EXT4_SB(inode->i_sb)->s_orphan_lock);
|
141
Patches/Linux_CVEs/CVE-2013-4312/0.patch
Normal file
141
Patches/Linux_CVEs/CVE-2013-4312/0.patch
Normal file
@ -0,0 +1,141 @@
|
||||
From a5a6cf8c405e826ff7ed1308dde72560c0ed4854 Mon Sep 17 00:00:00 2001
|
||||
From: willy tarreau <w@1wt.eu>
|
||||
Date: Sun, 10 Jan 2016 07:54:56 +0100
|
||||
Subject: unix: properly account for FDs passed over unix sockets
|
||||
|
||||
commit 712f4aad406bb1ed67f3f98d04c044191f0ff593 upstream.
|
||||
|
||||
It is possible for a process to allocate and accumulate far more FDs than
|
||||
the process' limit by sending them over a unix socket then closing them
|
||||
to keep the process' fd count low.
|
||||
|
||||
This change addresses this problem by keeping track of the number of FDs
|
||||
in flight per user and preventing non-privileged processes from having
|
||||
more FDs in flight than their configured FD limit.
|
||||
|
||||
Reported-by: socketpair@gmail.com
|
||||
Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
|
||||
Mitigates: CVE-2013-4312 (Linux 2.0+)
|
||||
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
[carnil: Backported to 3.16: adjust context]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
include/linux/sched.h | 1 +
|
||||
net/unix/af_unix.c | 24 ++++++++++++++++++++----
|
||||
net/unix/garbage.c | 14 ++++++++++----
|
||||
3 files changed, 31 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index 9b9ac29..2bffa8a 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -709,6 +709,7 @@ struct user_struct {
|
||||
unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
|
||||
#endif
|
||||
unsigned long locked_shm; /* How many pages of mlocked shm ? */
|
||||
+ unsigned long unix_inflight; /* How many files in flight in unix sockets */
|
||||
|
||||
#ifdef CONFIG_KEYS
|
||||
struct key *uid_keyring; /* UID specific keyring */
|
||||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
||||
index 6cb363d..6798b3c 100644
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -1472,6 +1472,21 @@ static void unix_destruct_scm(struct sk_buff *skb)
|
||||
sock_wfree(skb);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The "user->unix_inflight" variable is protected by the garbage
|
||||
+ * collection lock, and we just read it locklessly here. If you go
|
||||
+ * over the limit, there might be a tiny race in actually noticing
|
||||
+ * it across threads. Tough.
|
||||
+ */
|
||||
+static inline bool too_many_unix_fds(struct task_struct *p)
|
||||
+{
|
||||
+ struct user_struct *user = current_user();
|
||||
+
|
||||
+ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
|
||||
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
#define MAX_RECURSION_LEVEL 4
|
||||
|
||||
static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
@@ -1480,6 +1495,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
unsigned char max_level = 0;
|
||||
int unix_sock_count = 0;
|
||||
|
||||
+ if (too_many_unix_fds(current))
|
||||
+ return -ETOOMANYREFS;
|
||||
+
|
||||
for (i = scm->fp->count - 1; i >= 0; i--) {
|
||||
struct sock *sk = unix_get_socket(scm->fp->fp[i]);
|
||||
|
||||
@@ -1501,10 +1519,8 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
if (!UNIXCB(skb).fp)
|
||||
return -ENOMEM;
|
||||
|
||||
- if (unix_sock_count) {
|
||||
- for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
- unix_inflight(scm->fp->fp[i]);
|
||||
- }
|
||||
+ for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
+ unix_inflight(scm->fp->fp[i]);
|
||||
return max_level;
|
||||
}
|
||||
|
||||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
|
||||
index 00d3e56..fd1a840 100644
|
||||
--- a/net/unix/garbage.c
|
||||
+++ b/net/unix/garbage.c
|
||||
@@ -125,9 +125,11 @@ struct sock *unix_get_socket(struct file *filp)
|
||||
void unix_inflight(struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
+
|
||||
+ spin_lock(&unix_gc_lock);
|
||||
+
|
||||
if (s) {
|
||||
struct unix_sock *u = unix_sk(s);
|
||||
- spin_lock(&unix_gc_lock);
|
||||
if (atomic_long_inc_return(&u->inflight) == 1) {
|
||||
BUG_ON(!list_empty(&u->link));
|
||||
list_add_tail(&u->link, &gc_inflight_list);
|
||||
@@ -135,22 +137,26 @@ void unix_inflight(struct file *fp)
|
||||
BUG_ON(list_empty(&u->link));
|
||||
}
|
||||
unix_tot_inflight++;
|
||||
- spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
+ fp->f_cred->user->unix_inflight++;
|
||||
+ spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
void unix_notinflight(struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
+
|
||||
+ spin_lock(&unix_gc_lock);
|
||||
+
|
||||
if (s) {
|
||||
struct unix_sock *u = unix_sk(s);
|
||||
- spin_lock(&unix_gc_lock);
|
||||
BUG_ON(list_empty(&u->link));
|
||||
if (atomic_long_dec_and_test(&u->inflight))
|
||||
list_del_init(&u->link);
|
||||
unix_tot_inflight--;
|
||||
- spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
+ fp->f_cred->user->unix_inflight--;
|
||||
+ spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
|
||||
--
|
||||
cgit v1.1
|
||||
|
162
Patches/Linux_CVEs/CVE-2013-4312/1.patch
Normal file
162
Patches/Linux_CVEs/CVE-2013-4312/1.patch
Normal file
@ -0,0 +1,162 @@
|
||||
From 5ea820046ee399214221c0bb817eb35d304c9604 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Date: Wed, 3 Feb 2016 02:11:03 +0100
|
||||
Subject: unix: correctly track in-flight fds in sending process user_struct
|
||||
|
||||
commit 415e3d3e90ce9e18727e8843ae343eda5a58fad6 upstream.
|
||||
|
||||
The commit referenced in the Fixes tag incorrectly accounted the number
|
||||
of in-flight fds over a unix domain socket to the original opener
|
||||
of the file-descriptor. This allows another process to arbitrary
|
||||
deplete the original file-openers resource limit for the maximum of
|
||||
open files. Instead the sending processes and its struct cred should
|
||||
be credited.
|
||||
|
||||
To do so, we add a reference counted struct user_struct pointer to the
|
||||
scm_fp_list and use it to account for the number of inflight unix fds.
|
||||
|
||||
Fixes: 712f4aad406bb1 ("unix: properly account for FDs passed over unix sockets")
|
||||
Reported-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Cc: David Herrmann <dh.herrmann@gmail.com>
|
||||
Cc: Willy Tarreau <w@1wt.eu>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
[bwh: Backported to 3.2: adjust context]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
include/net/af_unix.h | 4 ++--
|
||||
include/net/scm.h | 1 +
|
||||
net/core/scm.c | 7 +++++++
|
||||
net/unix/af_unix.c | 4 ++--
|
||||
net/unix/garbage.c | 8 ++++----
|
||||
5 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
|
||||
index f4842f7..a69bfee 100644
|
||||
--- a/include/net/af_unix.h
|
||||
+++ b/include/net/af_unix.h
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
-extern void unix_inflight(struct file *fp);
|
||||
-extern void unix_notinflight(struct file *fp);
|
||||
+extern void unix_inflight(struct user_struct *user, struct file *fp);
|
||||
+extern void unix_notinflight(struct user_struct *user, struct file *fp);
|
||||
extern void unix_gc(void);
|
||||
extern void wait_for_unix_gc(void);
|
||||
extern struct sock *unix_get_socket(struct file *filp);
|
||||
diff --git a/include/net/scm.h b/include/net/scm.h
|
||||
index 5da0a7b..9822a68 100644
|
||||
--- a/include/net/scm.h
|
||||
+++ b/include/net/scm.h
|
||||
@@ -16,6 +16,7 @@ struct scm_fp_list {
|
||||
struct list_head list;
|
||||
short count;
|
||||
short max;
|
||||
+ struct user_struct *user;
|
||||
struct file *fp[SCM_MAX_FD];
|
||||
};
|
||||
|
||||
diff --git a/net/core/scm.c b/net/core/scm.c
|
||||
index 51b4d52..9adabed 100644
|
||||
--- a/net/core/scm.c
|
||||
+++ b/net/core/scm.c
|
||||
@@ -80,6 +80,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
|
||||
*fplp = fpl;
|
||||
fpl->count = 0;
|
||||
fpl->max = SCM_MAX_FD;
|
||||
+ fpl->user = NULL;
|
||||
}
|
||||
fpp = &fpl->fp[fpl->count];
|
||||
|
||||
@@ -100,6 +101,10 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
|
||||
*fpp++ = file;
|
||||
fpl->count++;
|
||||
}
|
||||
+
|
||||
+ if (!fpl->user)
|
||||
+ fpl->user = get_uid(current_user());
|
||||
+
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -124,6 +129,7 @@ void __scm_destroy(struct scm_cookie *scm)
|
||||
list_del(&fpl->list);
|
||||
for (i=fpl->count-1; i>=0; i--)
|
||||
fput(fpl->fp[i]);
|
||||
+ free_uid(fpl->user);
|
||||
kfree(fpl);
|
||||
}
|
||||
|
||||
@@ -342,6 +348,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
|
||||
for (i = 0; i < fpl->count; i++)
|
||||
get_file(fpl->fp[i]);
|
||||
new_fpl->max = new_fpl->count;
|
||||
+ new_fpl->user = get_uid(fpl->user);
|
||||
}
|
||||
return new_fpl;
|
||||
}
|
||||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
||||
index 6798b3c..390e079 100644
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -1454,7 +1454,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
UNIXCB(skb).fp = NULL;
|
||||
|
||||
for (i = scm->fp->count-1; i >= 0; i--)
|
||||
- unix_notinflight(scm->fp->fp[i]);
|
||||
+ unix_notinflight(scm->fp->user, scm->fp->fp[i]);
|
||||
}
|
||||
|
||||
static void unix_destruct_scm(struct sk_buff *skb)
|
||||
@@ -1520,7 +1520,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
- unix_inflight(scm->fp->fp[i]);
|
||||
+ unix_inflight(scm->fp->user, scm->fp->fp[i]);
|
||||
return max_level;
|
||||
}
|
||||
|
||||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
|
||||
index fd1a840..33a21260 100644
|
||||
--- a/net/unix/garbage.c
|
||||
+++ b/net/unix/garbage.c
|
||||
@@ -122,7 +122,7 @@ struct sock *unix_get_socket(struct file *filp)
|
||||
* descriptor if it is for an AF_UNIX socket.
|
||||
*/
|
||||
|
||||
-void unix_inflight(struct file *fp)
|
||||
+void unix_inflight(struct user_struct *user, struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
|
||||
@@ -138,11 +138,11 @@ void unix_inflight(struct file *fp)
|
||||
}
|
||||
unix_tot_inflight++;
|
||||
}
|
||||
- fp->f_cred->user->unix_inflight++;
|
||||
+ user->unix_inflight++;
|
||||
spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
-void unix_notinflight(struct file *fp)
|
||||
+void unix_notinflight(struct user_struct *user, struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
|
||||
@@ -155,7 +155,7 @@ void unix_notinflight(struct file *fp)
|
||||
list_del_init(&u->link);
|
||||
unix_tot_inflight--;
|
||||
}
|
||||
- fp->f_cred->user->unix_inflight--;
|
||||
+ user->unix_inflight--;
|
||||
spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
140
Patches/Linux_CVEs/CVE-2013-4312/2.patch
Normal file
140
Patches/Linux_CVEs/CVE-2013-4312/2.patch
Normal file
@ -0,0 +1,140 @@
|
||||
From 712f4aad406bb1ed67f3f98d04c044191f0ff593 Mon Sep 17 00:00:00 2001
|
||||
From: willy tarreau <w@1wt.eu>
|
||||
Date: Sun, 10 Jan 2016 07:54:56 +0100
|
||||
Subject: unix: properly account for FDs passed over unix sockets
|
||||
|
||||
It is possible for a process to allocate and accumulate far more FDs than
|
||||
the process' limit by sending them over a unix socket then closing them
|
||||
to keep the process' fd count low.
|
||||
|
||||
This change addresses this problem by keeping track of the number of FDs
|
||||
in flight per user and preventing non-privileged processes from having
|
||||
more FDs in flight than their configured FD limit.
|
||||
|
||||
Reported-by: socketpair@gmail.com
|
||||
Reported-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
|
||||
Mitigates: CVE-2013-4312 (Linux 2.0+)
|
||||
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Acked-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Signed-off-by: Willy Tarreau <w@1wt.eu>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/linux/sched.h | 1 +
|
||||
net/unix/af_unix.c | 24 ++++++++++++++++++++----
|
||||
net/unix/garbage.c | 13 ++++++++-----
|
||||
3 files changed, 29 insertions(+), 9 deletions(-)
|
||||
|
||||
diff --git a/include/linux/sched.h b/include/linux/sched.h
|
||||
index edad7a4..fbf25f1 100644
|
||||
--- a/include/linux/sched.h
|
||||
+++ b/include/linux/sched.h
|
||||
@@ -830,6 +830,7 @@ struct user_struct {
|
||||
unsigned long mq_bytes; /* How many bytes can be allocated to mqueue? */
|
||||
#endif
|
||||
unsigned long locked_shm; /* How many pages of mlocked shm ? */
|
||||
+ unsigned long unix_inflight; /* How many files in flight in unix sockets */
|
||||
|
||||
#ifdef CONFIG_KEYS
|
||||
struct key *uid_keyring; /* UID specific keyring */
|
||||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
||||
index ef05cd9..e3f85bc 100644
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -1513,6 +1513,21 @@ static void unix_destruct_scm(struct sk_buff *skb)
|
||||
sock_wfree(skb);
|
||||
}
|
||||
|
||||
+/*
|
||||
+ * The "user->unix_inflight" variable is protected by the garbage
|
||||
+ * collection lock, and we just read it locklessly here. If you go
|
||||
+ * over the limit, there might be a tiny race in actually noticing
|
||||
+ * it across threads. Tough.
|
||||
+ */
|
||||
+static inline bool too_many_unix_fds(struct task_struct *p)
|
||||
+{
|
||||
+ struct user_struct *user = current_user();
|
||||
+
|
||||
+ if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
|
||||
+ return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
|
||||
+ return false;
|
||||
+}
|
||||
+
|
||||
#define MAX_RECURSION_LEVEL 4
|
||||
|
||||
static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
@@ -1521,6 +1536,9 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
unsigned char max_level = 0;
|
||||
int unix_sock_count = 0;
|
||||
|
||||
+ if (too_many_unix_fds(current))
|
||||
+ return -ETOOMANYREFS;
|
||||
+
|
||||
for (i = scm->fp->count - 1; i >= 0; i--) {
|
||||
struct sock *sk = unix_get_socket(scm->fp->fp[i]);
|
||||
|
||||
@@ -1542,10 +1560,8 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
if (!UNIXCB(skb).fp)
|
||||
return -ENOMEM;
|
||||
|
||||
- if (unix_sock_count) {
|
||||
- for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
- unix_inflight(scm->fp->fp[i]);
|
||||
- }
|
||||
+ for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
+ unix_inflight(scm->fp->fp[i]);
|
||||
return max_level;
|
||||
}
|
||||
|
||||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
|
||||
index a73a226..8fcdc22 100644
|
||||
--- a/net/unix/garbage.c
|
||||
+++ b/net/unix/garbage.c
|
||||
@@ -120,11 +120,11 @@ void unix_inflight(struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
|
||||
+ spin_lock(&unix_gc_lock);
|
||||
+
|
||||
if (s) {
|
||||
struct unix_sock *u = unix_sk(s);
|
||||
|
||||
- spin_lock(&unix_gc_lock);
|
||||
-
|
||||
if (atomic_long_inc_return(&u->inflight) == 1) {
|
||||
BUG_ON(!list_empty(&u->link));
|
||||
list_add_tail(&u->link, &gc_inflight_list);
|
||||
@@ -132,25 +132,28 @@ void unix_inflight(struct file *fp)
|
||||
BUG_ON(list_empty(&u->link));
|
||||
}
|
||||
unix_tot_inflight++;
|
||||
- spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
+ fp->f_cred->user->unix_inflight++;
|
||||
+ spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
void unix_notinflight(struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
|
||||
+ spin_lock(&unix_gc_lock);
|
||||
+
|
||||
if (s) {
|
||||
struct unix_sock *u = unix_sk(s);
|
||||
|
||||
- spin_lock(&unix_gc_lock);
|
||||
BUG_ON(list_empty(&u->link));
|
||||
|
||||
if (atomic_long_dec_and_test(&u->inflight))
|
||||
list_del_init(&u->link);
|
||||
unix_tot_inflight--;
|
||||
- spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
+ fp->f_cred->user->unix_inflight--;
|
||||
+ spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
static void scan_inflight(struct sock *x, void (*func)(struct unix_sock *),
|
||||
--
|
||||
cgit v1.1
|
||||
|
158
Patches/Linux_CVEs/CVE-2013-4312/3.patch
Normal file
158
Patches/Linux_CVEs/CVE-2013-4312/3.patch
Normal file
@ -0,0 +1,158 @@
|
||||
From 415e3d3e90ce9e18727e8843ae343eda5a58fad6 Mon Sep 17 00:00:00 2001
|
||||
From: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Date: Wed, 3 Feb 2016 02:11:03 +0100
|
||||
Subject: unix: correctly track in-flight fds in sending process user_struct
|
||||
|
||||
The commit referenced in the Fixes tag incorrectly accounted the number
|
||||
of in-flight fds over a unix domain socket to the original opener
|
||||
of the file-descriptor. This allows another process to arbitrary
|
||||
deplete the original file-openers resource limit for the maximum of
|
||||
open files. Instead the sending processes and its struct cred should
|
||||
be credited.
|
||||
|
||||
To do so, we add a reference counted struct user_struct pointer to the
|
||||
scm_fp_list and use it to account for the number of inflight unix fds.
|
||||
|
||||
Fixes: 712f4aad406bb1 ("unix: properly account for FDs passed over unix sockets")
|
||||
Reported-by: David Herrmann <dh.herrmann@gmail.com>
|
||||
Cc: David Herrmann <dh.herrmann@gmail.com>
|
||||
Cc: Willy Tarreau <w@1wt.eu>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Suggested-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
include/net/af_unix.h | 4 ++--
|
||||
include/net/scm.h | 1 +
|
||||
net/core/scm.c | 7 +++++++
|
||||
net/unix/af_unix.c | 4 ++--
|
||||
net/unix/garbage.c | 8 ++++----
|
||||
5 files changed, 16 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/include/net/af_unix.h b/include/net/af_unix.h
|
||||
index 2a91a05..9b4c418 100644
|
||||
--- a/include/net/af_unix.h
|
||||
+++ b/include/net/af_unix.h
|
||||
@@ -6,8 +6,8 @@
|
||||
#include <linux/mutex.h>
|
||||
#include <net/sock.h>
|
||||
|
||||
-void unix_inflight(struct file *fp);
|
||||
-void unix_notinflight(struct file *fp);
|
||||
+void unix_inflight(struct user_struct *user, struct file *fp);
|
||||
+void unix_notinflight(struct user_struct *user, struct file *fp);
|
||||
void unix_gc(void);
|
||||
void wait_for_unix_gc(void);
|
||||
struct sock *unix_get_socket(struct file *filp);
|
||||
diff --git a/include/net/scm.h b/include/net/scm.h
|
||||
index 262532d..59fa93c 100644
|
||||
--- a/include/net/scm.h
|
||||
+++ b/include/net/scm.h
|
||||
@@ -21,6 +21,7 @@ struct scm_creds {
|
||||
struct scm_fp_list {
|
||||
short count;
|
||||
short max;
|
||||
+ struct user_struct *user;
|
||||
struct file *fp[SCM_MAX_FD];
|
||||
};
|
||||
|
||||
diff --git a/net/core/scm.c b/net/core/scm.c
|
||||
index 14596fb..2696aef 100644
|
||||
--- a/net/core/scm.c
|
||||
+++ b/net/core/scm.c
|
||||
@@ -87,6 +87,7 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
|
||||
*fplp = fpl;
|
||||
fpl->count = 0;
|
||||
fpl->max = SCM_MAX_FD;
|
||||
+ fpl->user = NULL;
|
||||
}
|
||||
fpp = &fpl->fp[fpl->count];
|
||||
|
||||
@@ -107,6 +108,10 @@ static int scm_fp_copy(struct cmsghdr *cmsg, struct scm_fp_list **fplp)
|
||||
*fpp++ = file;
|
||||
fpl->count++;
|
||||
}
|
||||
+
|
||||
+ if (!fpl->user)
|
||||
+ fpl->user = get_uid(current_user());
|
||||
+
|
||||
return num;
|
||||
}
|
||||
|
||||
@@ -119,6 +124,7 @@ void __scm_destroy(struct scm_cookie *scm)
|
||||
scm->fp = NULL;
|
||||
for (i=fpl->count-1; i>=0; i--)
|
||||
fput(fpl->fp[i]);
|
||||
+ free_uid(fpl->user);
|
||||
kfree(fpl);
|
||||
}
|
||||
}
|
||||
@@ -336,6 +342,7 @@ struct scm_fp_list *scm_fp_dup(struct scm_fp_list *fpl)
|
||||
for (i = 0; i < fpl->count; i++)
|
||||
get_file(fpl->fp[i]);
|
||||
new_fpl->max = new_fpl->count;
|
||||
+ new_fpl->user = get_uid(fpl->user);
|
||||
}
|
||||
return new_fpl;
|
||||
}
|
||||
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
|
||||
index 49d5093..29be035 100644
|
||||
--- a/net/unix/af_unix.c
|
||||
+++ b/net/unix/af_unix.c
|
||||
@@ -1496,7 +1496,7 @@ static void unix_detach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
UNIXCB(skb).fp = NULL;
|
||||
|
||||
for (i = scm->fp->count-1; i >= 0; i--)
|
||||
- unix_notinflight(scm->fp->fp[i]);
|
||||
+ unix_notinflight(scm->fp->user, scm->fp->fp[i]);
|
||||
}
|
||||
|
||||
static void unix_destruct_scm(struct sk_buff *skb)
|
||||
@@ -1561,7 +1561,7 @@ static int unix_attach_fds(struct scm_cookie *scm, struct sk_buff *skb)
|
||||
return -ENOMEM;
|
||||
|
||||
for (i = scm->fp->count - 1; i >= 0; i--)
|
||||
- unix_inflight(scm->fp->fp[i]);
|
||||
+ unix_inflight(scm->fp->user, scm->fp->fp[i]);
|
||||
return max_level;
|
||||
}
|
||||
|
||||
diff --git a/net/unix/garbage.c b/net/unix/garbage.c
|
||||
index 8fcdc22..6a0d485 100644
|
||||
--- a/net/unix/garbage.c
|
||||
+++ b/net/unix/garbage.c
|
||||
@@ -116,7 +116,7 @@ struct sock *unix_get_socket(struct file *filp)
|
||||
* descriptor if it is for an AF_UNIX socket.
|
||||
*/
|
||||
|
||||
-void unix_inflight(struct file *fp)
|
||||
+void unix_inflight(struct user_struct *user, struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
|
||||
@@ -133,11 +133,11 @@ void unix_inflight(struct file *fp)
|
||||
}
|
||||
unix_tot_inflight++;
|
||||
}
|
||||
- fp->f_cred->user->unix_inflight++;
|
||||
+ user->unix_inflight++;
|
||||
spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
-void unix_notinflight(struct file *fp)
|
||||
+void unix_notinflight(struct user_struct *user, struct file *fp)
|
||||
{
|
||||
struct sock *s = unix_get_socket(fp);
|
||||
|
||||
@@ -152,7 +152,7 @@ void unix_notinflight(struct file *fp)
|
||||
list_del_init(&u->link);
|
||||
unix_tot_inflight--;
|
||||
}
|
||||
- fp->f_cred->user->unix_inflight--;
|
||||
+ user->unix_inflight--;
|
||||
spin_unlock(&unix_gc_lock);
|
||||
}
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
80
Patches/Linux_CVEs/CVE-2014-0196/0.patch
Normal file
80
Patches/Linux_CVEs/CVE-2014-0196/0.patch
Normal file
@ -0,0 +1,80 @@
|
||||
From 4291086b1f081b869c6d79e5b7441633dc3ace00 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hurley <peter@hurleysoftware.com>
|
||||
Date: Sat, 3 May 2014 14:04:59 +0200
|
||||
Subject: [PATCH] n_tty: Fix n_tty_write crash when echoing in raw mode
|
||||
|
||||
The tty atomic_write_lock does not provide an exclusion guarantee for
|
||||
the tty driver if the termios settings are LECHO & !OPOST. And since
|
||||
it is unexpected and not allowed to call TTY buffer helpers like
|
||||
tty_insert_flip_string concurrently, this may lead to crashes when
|
||||
concurrect writers call pty_write. In that case the following two
|
||||
writers:
|
||||
* the ECHOing from a workqueue and
|
||||
* pty_write from the process
|
||||
race and can overflow the corresponding TTY buffer like follows.
|
||||
|
||||
If we look into tty_insert_flip_string_fixed_flag, there is:
|
||||
int space = __tty_buffer_request_room(port, goal, flags);
|
||||
struct tty_buffer *tb = port->buf.tail;
|
||||
...
|
||||
memcpy(char_buf_ptr(tb, tb->used), chars, space);
|
||||
...
|
||||
tb->used += space;
|
||||
|
||||
so the race of the two can result in something like this:
|
||||
A B
|
||||
__tty_buffer_request_room
|
||||
__tty_buffer_request_room
|
||||
memcpy(buf(tb->used), ...)
|
||||
tb->used += space;
|
||||
memcpy(buf(tb->used), ...) ->BOOM
|
||||
|
||||
B's memcpy is past the tty_buffer due to the previous A's tb->used
|
||||
increment.
|
||||
|
||||
Since the N_TTY line discipline input processing can output
|
||||
concurrently with a tty write, obtain the N_TTY ldisc output_lock to
|
||||
serialize echo output with normal tty writes. This ensures the tty
|
||||
buffer helper tty_insert_flip_string is not called concurrently and
|
||||
everything is fine.
|
||||
|
||||
Note that this is nicely reproducible by an ordinary user using
|
||||
forkpty and some setup around that (raw termios + ECHO). And it is
|
||||
present in kernels at least after commit
|
||||
d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty layer to
|
||||
use the normal buffering logic) in 2.6.31-rc3.
|
||||
|
||||
js: add more info to the commit log
|
||||
js: switch to bool
|
||||
js: lock unconditionally
|
||||
js: lock only the tty->ops->write call
|
||||
|
||||
References: CVE-2014-0196
|
||||
Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
|
||||
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
drivers/tty/n_tty.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
|
||||
index 41fe8a047d373..fe9d129c87351 100644
|
||||
--- a/drivers/tty/n_tty.c
|
||||
+++ b/drivers/tty/n_tty.c
|
||||
@@ -2353,8 +2353,12 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
|
||||
if (tty->ops->flush_chars)
|
||||
tty->ops->flush_chars(tty);
|
||||
} else {
|
||||
+ struct n_tty_data *ldata = tty->disc_data;
|
||||
+
|
||||
while (nr > 0) {
|
||||
+ mutex_lock(&ldata->output_lock);
|
||||
c = tty->ops->write(tty, b, nr);
|
||||
+ mutex_unlock(&ldata->output_lock);
|
||||
if (c < 0) {
|
||||
retval = c;
|
||||
goto break_out;
|
84
Patches/Linux_CVEs/CVE-2014-0196/1.patch
Normal file
84
Patches/Linux_CVEs/CVE-2014-0196/1.patch
Normal file
@ -0,0 +1,84 @@
|
||||
From 1e5099713cefc67aa562f6d8fe43444f41baf52d Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hurley <peter@hurleysoftware.com>
|
||||
Date: Sat, 3 May 2014 14:04:59 +0200
|
||||
Subject: n_tty: Fix n_tty_write crash when echoing in raw mode
|
||||
|
||||
commit 4291086b1f081b869c6d79e5b7441633dc3ace00 upstream.
|
||||
|
||||
The tty atomic_write_lock does not provide an exclusion guarantee for
|
||||
the tty driver if the termios settings are LECHO & !OPOST. And since
|
||||
it is unexpected and not allowed to call TTY buffer helpers like
|
||||
tty_insert_flip_string concurrently, this may lead to crashes when
|
||||
concurrect writers call pty_write. In that case the following two
|
||||
writers:
|
||||
* the ECHOing from a workqueue and
|
||||
* pty_write from the process
|
||||
race and can overflow the corresponding TTY buffer like follows.
|
||||
|
||||
If we look into tty_insert_flip_string_fixed_flag, there is:
|
||||
int space = __tty_buffer_request_room(port, goal, flags);
|
||||
struct tty_buffer *tb = port->buf.tail;
|
||||
...
|
||||
memcpy(char_buf_ptr(tb, tb->used), chars, space);
|
||||
...
|
||||
tb->used += space;
|
||||
|
||||
so the race of the two can result in something like this:
|
||||
A B
|
||||
__tty_buffer_request_room
|
||||
__tty_buffer_request_room
|
||||
memcpy(buf(tb->used), ...)
|
||||
tb->used += space;
|
||||
memcpy(buf(tb->used), ...) ->BOOM
|
||||
|
||||
B's memcpy is past the tty_buffer due to the previous A's tb->used
|
||||
increment.
|
||||
|
||||
Since the N_TTY line discipline input processing can output
|
||||
concurrently with a tty write, obtain the N_TTY ldisc output_lock to
|
||||
serialize echo output with normal tty writes. This ensures the tty
|
||||
buffer helper tty_insert_flip_string is not called concurrently and
|
||||
everything is fine.
|
||||
|
||||
Note that this is nicely reproducible by an ordinary user using
|
||||
forkpty and some setup around that (raw termios + ECHO). And it is
|
||||
present in kernels at least after commit
|
||||
d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty layer to
|
||||
use the normal buffering logic) in 2.6.31-rc3.
|
||||
|
||||
js: add more info to the commit log
|
||||
js: switch to bool
|
||||
js: lock unconditionally
|
||||
js: lock only the tty->ops->write call
|
||||
|
||||
References: CVE-2014-0196
|
||||
Reported-and-tested-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
|
||||
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
[bwh: Backported to 3.2: output_lock is a member of struct tty_struct]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
drivers/tty/n_tty.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
|
||||
index 0f8a785..bac83d8 100644
|
||||
--- a/drivers/tty/n_tty.c
|
||||
+++ b/drivers/tty/n_tty.c
|
||||
@@ -1997,7 +1997,9 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
|
||||
tty->ops->flush_chars(tty);
|
||||
} else {
|
||||
while (nr > 0) {
|
||||
+ mutex_lock(&tty->output_lock);
|
||||
c = tty->ops->write(tty, b, nr);
|
||||
+ mutex_unlock(&tty->output_lock);
|
||||
if (c < 0) {
|
||||
retval = c;
|
||||
goto break_out;
|
||||
--
|
||||
cgit v1.1
|
||||
|
83
Patches/Linux_CVEs/CVE-2014-0196/2.patch
Normal file
83
Patches/Linux_CVEs/CVE-2014-0196/2.patch
Normal file
@ -0,0 +1,83 @@
|
||||
From 9aabfc9e7775abbbcf534cdecccc4f12ee423b27 Mon Sep 17 00:00:00 2001
|
||||
From: Peter Hurley <peter@hurleysoftware.com>
|
||||
Date: Tue, 13 May 2014 14:36:46 -0700
|
||||
Subject: n_tty: Fix n_tty_write crash when echoing in raw mode
|
||||
|
||||
The tty atomic_write_lock does not provide an exclusion guarantee for
|
||||
the tty driver if the termios settings are LECHO & !OPOST. And since
|
||||
it is unexpected and not allowed to call TTY buffer helpers like
|
||||
tty_insert_flip_string concurrently, this may lead to crashes when
|
||||
concurrect writers call pty_write. In that case the following two
|
||||
writers:
|
||||
* the ECHOing from a workqueue and
|
||||
* pty_write from the process
|
||||
race and can overflow the corresponding TTY buffer like follows.
|
||||
|
||||
If we look into tty_insert_flip_string_fixed_flag, there is:
|
||||
int space = __tty_buffer_request_room(port, goal, flags);
|
||||
struct tty_buffer *tb = port->buf.tail;
|
||||
...
|
||||
memcpy(char_buf_ptr(tb, tb->used), chars, space);
|
||||
...
|
||||
tb->used += space;
|
||||
|
||||
so the race of the two can result in something like this:
|
||||
A B
|
||||
__tty_buffer_request_room
|
||||
__tty_buffer_request_room
|
||||
memcpy(buf(tb->used), ...)
|
||||
tb->used += space;
|
||||
memcpy(buf(tb->used), ...) ->BOOM
|
||||
|
||||
B's memcpy is past the tty_buffer due to the previous A's tb->used
|
||||
increment.
|
||||
|
||||
Since the N_TTY line discipline input processing can output
|
||||
concurrently with a tty write, obtain the N_TTY ldisc output_lock to
|
||||
serialize echo output with normal tty writes. This ensures the tty
|
||||
buffer helper tty_insert_flip_string is not called concurrently and
|
||||
everything is fine.
|
||||
|
||||
Note that this is nicely reproducible by an ordinary user using
|
||||
forkpty and some setup around that (raw termios + ECHO). And it is
|
||||
present in kernels at least after commit
|
||||
d945cb9cce20ac7143c2de8d88b187f62db99bdc (pty: Rework the pty layer to
|
||||
use the normal buffering logic) in 2.6.31-rc3.
|
||||
|
||||
js: add more info to the commit log
|
||||
js: switch to bool
|
||||
js: lock unconditionally
|
||||
js: lock only the tty->ops->write call
|
||||
|
||||
Signed-off-by: Peter Hurley <peter@hurleysoftware.com>
|
||||
Signed-off-by: Jiri Slaby <jslaby@suse.cz>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
Change-Id: I9e235db6ec2bb950f26bd8a23f6145dab5dc0a15
|
||||
Git-commit: 4291086b1f081b869c6d79e5b7441633dc3ace00
|
||||
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
Signed-off-by: Avijit Kanti Das <avijitnsec@codeaurora.org>
|
||||
[rsiddoji@codeaurora.org: resolve trivial merge conflicts]
|
||||
Signed-off-by: Ravi Kumar S <rsiddoji@codeaurora.org>
|
||||
---
|
||||
drivers/tty/n_tty.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
|
||||
index 8eb5573..54c46c8 100644
|
||||
--- a/drivers/tty/n_tty.c
|
||||
+++ b/drivers/tty/n_tty.c
|
||||
@@ -1998,8 +1998,11 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
|
||||
if (tty->ops->flush_chars)
|
||||
tty->ops->flush_chars(tty);
|
||||
} else {
|
||||
+
|
||||
while (nr > 0) {
|
||||
+ mutex_lock(&tty->output_lock);
|
||||
c = tty->ops->write(tty, b, nr);
|
||||
+ mutex_unlock(&tty->output_lock);
|
||||
if (c < 0) {
|
||||
retval = c;
|
||||
goto break_out;
|
||||
--
|
||||
cgit v1.1
|
||||
|
45
Patches/Linux_CVEs/CVE-2014-0206/0.patch
Normal file
45
Patches/Linux_CVEs/CVE-2014-0206/0.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From d36db46c2cba973557eb6138d22210c4e0cf17d6 Mon Sep 17 00:00:00 2001
|
||||
From: Benjamin LaHaise <bcrl@kvack.org>
|
||||
Date: Tue, 24 Jun 2014 13:32:51 -0400
|
||||
Subject: aio: fix kernel memory disclosure in io_getevents() introduced in
|
||||
v3.10
|
||||
|
||||
commit edfbbf388f293d70bf4b7c0bc38774d05e6f711a upstream.
|
||||
|
||||
A kernel memory disclosure was introduced in aio_read_events_ring() in v3.10
|
||||
by commit a31ad380bed817aa25f8830ad23e1a0480fef797. The changes made to
|
||||
aio_read_events_ring() failed to correctly limit the index into
|
||||
ctx->ring_pages[], allowing an attacked to cause the subsequent kmap() of
|
||||
an arbitrary page with a copy_to_user() to copy the contents into userspace.
|
||||
This vulnerability has been assigned CVE-2014-0206. Thanks to Mateusz and
|
||||
Petr for disclosing this issue.
|
||||
|
||||
This patch applies to v3.12+. A separate backport is needed for 3.10/3.11.
|
||||
|
||||
[jmoyer@redhat.com: backported to 3.10]
|
||||
Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
|
||||
Signed-off-by: Jeff Moyer <jmoyer@redhat.com>
|
||||
Cc: Mateusz Guzik <mguzik@redhat.com>
|
||||
Cc: Petr Matousek <pmatouse@redhat.com>
|
||||
Cc: Kent Overstreet <kmo@daterainc.com>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
fs/aio.c | 2 ++
|
||||
1 file changed, 2 insertions(+)
|
||||
|
||||
diff --git a/fs/aio.c b/fs/aio.c
|
||||
index 8d2c997..ded94c4 100644
|
||||
--- a/fs/aio.c
|
||||
+++ b/fs/aio.c
|
||||
@@ -717,6 +717,8 @@ static long aio_read_events_ring(struct kioctx *ctx,
|
||||
if (head == ctx->tail)
|
||||
goto out;
|
||||
|
||||
+ head %= ctx->nr_events;
|
||||
+
|
||||
while (ret < nr) {
|
||||
long avail;
|
||||
struct io_event *ev;
|
||||
--
|
||||
cgit v1.1
|
||||
|
33
Patches/Linux_CVEs/CVE-2014-1739/0.patch
Normal file
33
Patches/Linux_CVEs/CVE-2014-1739/0.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From e6a623460e5fc960ac3ee9f946d3106233fd28d8 Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Salva=20Peir=C3=B3?= <speiro@ai2.upv.es>
|
||||
Date: Wed, 30 Apr 2014 19:48:02 +0200
|
||||
Subject: [media] media-device: fix infoleak in ioctl media_enum_entities()
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
This fixes CVE-2014-1739.
|
||||
|
||||
Signed-off-by: Salva Peiró <speiro@ai2.upv.es>
|
||||
Acked-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Mauro Carvalho Chehab <m.chehab@samsung.com>
|
||||
---
|
||||
drivers/media/media-device.c | 1 +
|
||||
1 file changed, 1 insertion(+)
|
||||
|
||||
diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c
|
||||
index d5a7a13..703560f 100644
|
||||
--- a/drivers/media/media-device.c
|
||||
+++ b/drivers/media/media-device.c
|
||||
@@ -93,6 +93,7 @@ static long media_device_enum_entities(struct media_device *mdev,
|
||||
struct media_entity *ent;
|
||||
struct media_entity_desc u_ent;
|
||||
|
||||
+ memset(&u_ent, 0, sizeof(u_ent));
|
||||
if (copy_from_user(&u_ent.id, &uent->id, sizeof(u_ent.id)))
|
||||
return -EFAULT;
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
59
Patches/Linux_CVEs/CVE-2014-2523/0.patch
Normal file
59
Patches/Linux_CVEs/CVE-2014-2523/0.patch
Normal file
@ -0,0 +1,59 @@
|
||||
From b22f5126a24b3b2f15448c3f2a254fc10cbc2b92 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Borkmann <dborkman@redhat.com>
|
||||
Date: Mon, 6 Jan 2014 00:57:54 +0100
|
||||
Subject: [PATCH] netfilter: nf_conntrack_dccp: fix skb_header_pointer API
|
||||
usages
|
||||
|
||||
Some occurences in the netfilter tree use skb_header_pointer() in
|
||||
the following way ...
|
||||
|
||||
struct dccp_hdr _dh, *dh;
|
||||
...
|
||||
skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
|
||||
... where dh itself is a pointer that is being passed as the copy
|
||||
buffer. Instead, we need to use &_dh as the forth argument so that
|
||||
we're copying the data into an actual buffer that sits on the stack.
|
||||
|
||||
Currently, we probably could overwrite memory on the stack (e.g.
|
||||
with a possibly mal-formed DCCP packet), but unintentionally, as
|
||||
we only want the buffer to be placed into _dh variable.
|
||||
|
||||
Fixes: 2bc780499aa3 ("[NETFILTER]: nf_conntrack: add DCCP protocol support")
|
||||
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
net/netfilter/nf_conntrack_proto_dccp.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
index 38412684a8824..cb372f96f10dc 100644
|
||||
--- a/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
@@ -428,7 +428,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
const char *msg;
|
||||
u_int8_t state;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
BUG_ON(dh == NULL);
|
||||
|
||||
state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
|
||||
@@ -486,7 +486,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
u_int8_t type, old_state, new_state;
|
||||
enum ct_dccp_roles role;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
BUG_ON(dh == NULL);
|
||||
type = dh->dccph_type;
|
||||
|
||||
@@ -577,7 +577,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl,
|
||||
unsigned int cscov;
|
||||
const char *msg;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
if (dh == NULL) {
|
||||
msg = "nf_ct_dccp: short packet ";
|
||||
goto out_invalid;
|
64
Patches/Linux_CVEs/CVE-2014-2523/1.patch
Normal file
64
Patches/Linux_CVEs/CVE-2014-2523/1.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 5b866eaa34e4ddc312c927030fde5f6a6184ddc5 Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Borkmann <dborkman@redhat.com>
|
||||
Date: Mon, 6 Jan 2014 00:57:54 +0100
|
||||
Subject: netfilter: nf_conntrack_dccp: fix skb_header_pointer API usages
|
||||
|
||||
commit b22f5126a24b3b2f15448c3f2a254fc10cbc2b92 upstream.
|
||||
|
||||
Some occurences in the netfilter tree use skb_header_pointer() in
|
||||
the following way ...
|
||||
|
||||
struct dccp_hdr _dh, *dh;
|
||||
...
|
||||
skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
|
||||
... where dh itself is a pointer that is being passed as the copy
|
||||
buffer. Instead, we need to use &_dh as the forth argument so that
|
||||
we're copying the data into an actual buffer that sits on the stack.
|
||||
|
||||
Currently, we probably could overwrite memory on the stack (e.g.
|
||||
with a possibly mal-formed DCCP packet), but unintentionally, as
|
||||
we only want the buffer to be placed into _dh variable.
|
||||
|
||||
Fixes: 2bc780499aa3 ("[NETFILTER]: nf_conntrack: add DCCP protocol support")
|
||||
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/netfilter/nf_conntrack_proto_dccp.c | 6 +++---
|
||||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/net/netfilter/nf_conntrack_proto_dccp.c b/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
index 2e664a6..8aa94ee 100644
|
||||
--- a/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_dccp.c
|
||||
@@ -431,7 +431,7 @@ static bool dccp_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
const char *msg;
|
||||
u_int8_t state;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
BUG_ON(dh == NULL);
|
||||
|
||||
state = dccp_state_table[CT_DCCP_ROLE_CLIENT][dh->dccph_type][CT_DCCP_NONE];
|
||||
@@ -483,7 +483,7 @@ static int dccp_packet(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
u_int8_t type, old_state, new_state;
|
||||
enum ct_dccp_roles role;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
BUG_ON(dh == NULL);
|
||||
type = dh->dccph_type;
|
||||
|
||||
@@ -575,7 +575,7 @@ static int dccp_error(struct net *net, struct nf_conn *tmpl,
|
||||
unsigned int cscov;
|
||||
const char *msg;
|
||||
|
||||
- dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &dh);
|
||||
+ dh = skb_header_pointer(skb, dataoff, sizeof(_dh), &_dh);
|
||||
if (dh == NULL) {
|
||||
msg = "nf_ct_dccp: short packet ";
|
||||
goto out_invalid;
|
||||
--
|
||||
cgit v1.1
|
||||
|
160
Patches/Linux_CVEs/CVE-2014-2706/0.patch
Normal file
160
Patches/Linux_CVEs/CVE-2014-2706/0.patch
Normal file
@ -0,0 +1,160 @@
|
||||
From 1d147bfa64293b2723c4fec50922168658e613ba Mon Sep 17 00:00:00 2001
|
||||
From: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||||
Date: Thu, 20 Feb 2014 09:22:11 +0200
|
||||
Subject: mac80211: fix AP powersave TX vs. wakeup race
|
||||
|
||||
There is a race between the TX path and the STA wakeup: while
|
||||
a station is sleeping, mac80211 buffers frames until it wakes
|
||||
up, then the frames are transmitted. However, the RX and TX
|
||||
path are concurrent, so the packet indicating wakeup can be
|
||||
processed while a packet is being transmitted.
|
||||
|
||||
This can lead to a situation where the buffered frames list
|
||||
is emptied on the one side, while a frame is being added on
|
||||
the other side, as the station is still seen as sleeping in
|
||||
the TX path.
|
||||
|
||||
As a result, the newly added frame will not be send anytime
|
||||
soon. It might be sent much later (and out of order) when the
|
||||
station goes to sleep and wakes up the next time.
|
||||
|
||||
Additionally, it can lead to the crash below.
|
||||
|
||||
Fix all this by synchronising both paths with a new lock.
|
||||
Both path are not fastpath since they handle PS situations.
|
||||
|
||||
In a later patch we'll remove the extra skb queue locks to
|
||||
reduce locking overhead.
|
||||
|
||||
BUG: unable to handle kernel
|
||||
NULL pointer dereference at 000000b0
|
||||
IP: [<ff6f1791>] ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
|
||||
*pde = 00000000
|
||||
Oops: 0000 [#1] SMP DEBUG_PAGEALLOC
|
||||
EIP: 0060:[<ff6f1791>] EFLAGS: 00210282 CPU: 1
|
||||
EIP is at ieee80211_report_used_skb+0x11/0x3e0 [mac80211]
|
||||
EAX: e5900da0 EBX: 00000000 ECX: 00000001 EDX: 00000000
|
||||
ESI: e41d00c0 EDI: e5900da0 EBP: ebe458e4 ESP: ebe458b0
|
||||
DS: 007b ES: 007b FS: 00d8 GS: 00e0 SS: 0068
|
||||
CR0: 8005003b CR2: 000000b0 CR3: 25a78000 CR4: 000407d0
|
||||
DR0: 00000000 DR1: 00000000 DR2: 00000000 DR3: 00000000
|
||||
DR6: ffff0ff0 DR7: 00000400
|
||||
Process iperf (pid: 3934, ti=ebe44000 task=e757c0b0 task.ti=ebe44000)
|
||||
iwlwifi 0000:02:00.0: I iwl_pcie_enqueue_hcmd Sending command LQ_CMD (#4e), seq: 0x0903, 92 bytes at 3[3]:9
|
||||
Stack:
|
||||
e403b32c ebe458c4 00200002 00200286 e403b338 ebe458cc c10960bb e5900da0
|
||||
ff76a6ec ebe458d8 00000000 e41d00c0 e5900da0 ebe458f0 ff6f1b75 e403b210
|
||||
ebe4598c ff723dc1 00000000 ff76a6ec e597c978 e403b758 00000002 00000002
|
||||
Call Trace:
|
||||
[<ff6f1b75>] ieee80211_free_txskb+0x15/0x20 [mac80211]
|
||||
[<ff723dc1>] invoke_tx_handlers+0x1661/0x1780 [mac80211]
|
||||
[<ff7248a5>] ieee80211_tx+0x75/0x100 [mac80211]
|
||||
[<ff7249bf>] ieee80211_xmit+0x8f/0xc0 [mac80211]
|
||||
[<ff72550e>] ieee80211_subif_start_xmit+0x4fe/0xe20 [mac80211]
|
||||
[<c149ef70>] dev_hard_start_xmit+0x450/0x950
|
||||
[<c14b9aa9>] sch_direct_xmit+0xa9/0x250
|
||||
[<c14b9c9b>] __qdisc_run+0x4b/0x150
|
||||
[<c149f732>] dev_queue_xmit+0x2c2/0xca0
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Yaara Rozenblum <yaara.rozenblum@intel.com>
|
||||
Signed-off-by: Emmanuel Grumbach <emmanuel.grumbach@intel.com>
|
||||
Reviewed-by: Stanislaw Gruszka <sgruszka@redhat.com>
|
||||
[reword commit log, use a separate lock]
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
net/mac80211/sta_info.c | 4 ++++
|
||||
net/mac80211/sta_info.h | 7 +++----
|
||||
net/mac80211/tx.c | 15 +++++++++++++++
|
||||
3 files changed, 22 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
|
||||
index decd30c..62a5f08 100644
|
||||
--- a/net/mac80211/sta_info.c
|
||||
+++ b/net/mac80211/sta_info.c
|
||||
@@ -330,6 +330,7 @@ struct sta_info *sta_info_alloc(struct ieee80211_sub_if_data *sdata,
|
||||
rcu_read_unlock();
|
||||
|
||||
spin_lock_init(&sta->lock);
|
||||
+ spin_lock_init(&sta->ps_lock);
|
||||
INIT_WORK(&sta->drv_unblock_wk, sta_unblock);
|
||||
INIT_WORK(&sta->ampdu_mlme.work, ieee80211_ba_session_work);
|
||||
mutex_init(&sta->ampdu_mlme.mtx);
|
||||
@@ -1109,6 +1110,8 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
||||
|
||||
skb_queue_head_init(&pending);
|
||||
|
||||
+ /* sync with ieee80211_tx_h_unicast_ps_buf */
|
||||
+ spin_lock(&sta->ps_lock);
|
||||
/* Send all buffered frames to the station */
|
||||
for (ac = 0; ac < IEEE80211_NUM_ACS; ac++) {
|
||||
int count = skb_queue_len(&pending), tmp;
|
||||
@@ -1128,6 +1131,7 @@ void ieee80211_sta_ps_deliver_wakeup(struct sta_info *sta)
|
||||
}
|
||||
|
||||
ieee80211_add_pending_skbs_fn(local, &pending, clear_sta_ps_flags, sta);
|
||||
+ spin_unlock(&sta->ps_lock);
|
||||
|
||||
/* This station just woke up and isn't aware of our SMPS state */
|
||||
if (!ieee80211_smps_is_restrictive(sta->known_smps_mode,
|
||||
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
|
||||
index d77ff70..d3a6d82 100644
|
||||
--- a/net/mac80211/sta_info.h
|
||||
+++ b/net/mac80211/sta_info.h
|
||||
@@ -267,6 +267,7 @@ struct ieee80211_tx_latency_stat {
|
||||
* @drv_unblock_wk: used for driver PS unblocking
|
||||
* @listen_interval: listen interval of this station, when we're acting as AP
|
||||
* @_flags: STA flags, see &enum ieee80211_sta_info_flags, do not use directly
|
||||
+ * @ps_lock: used for powersave (when mac80211 is the AP) related locking
|
||||
* @ps_tx_buf: buffers (per AC) of frames to transmit to this station
|
||||
* when it leaves power saving state or polls
|
||||
* @tx_filtered: buffers (per AC) of frames we already tried to
|
||||
@@ -356,10 +357,8 @@ struct sta_info {
|
||||
/* use the accessors defined below */
|
||||
unsigned long _flags;
|
||||
|
||||
- /*
|
||||
- * STA powersave frame queues, no more than the internal
|
||||
- * locking required.
|
||||
- */
|
||||
+ /* STA powersave lock and frame queues */
|
||||
+ spinlock_t ps_lock;
|
||||
struct sk_buff_head ps_tx_buf[IEEE80211_NUM_ACS];
|
||||
struct sk_buff_head tx_filtered[IEEE80211_NUM_ACS];
|
||||
unsigned long driver_buffered_tids;
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index 97a02d3..4080c61 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -478,6 +478,20 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
|
||||
sta->sta.addr, sta->sta.aid, ac);
|
||||
if (tx->local->total_ps_buffered >= TOTAL_MAX_TX_BUFFER)
|
||||
purge_old_ps_buffers(tx->local);
|
||||
+
|
||||
+ /* sync with ieee80211_sta_ps_deliver_wakeup */
|
||||
+ spin_lock(&sta->ps_lock);
|
||||
+ /*
|
||||
+ * STA woke up the meantime and all the frames on ps_tx_buf have
|
||||
+ * been queued to pending queue. No reordering can happen, go
|
||||
+ * ahead and Tx the packet.
|
||||
+ */
|
||||
+ if (!test_sta_flag(sta, WLAN_STA_PS_STA) &&
|
||||
+ !test_sta_flag(sta, WLAN_STA_PS_DRIVER)) {
|
||||
+ spin_unlock(&sta->ps_lock);
|
||||
+ return TX_CONTINUE;
|
||||
+ }
|
||||
+
|
||||
if (skb_queue_len(&sta->ps_tx_buf[ac]) >= STA_MAX_TX_BUFFER) {
|
||||
struct sk_buff *old = skb_dequeue(&sta->ps_tx_buf[ac]);
|
||||
ps_dbg(tx->sdata,
|
||||
@@ -492,6 +506,7 @@ ieee80211_tx_h_unicast_ps_buf(struct ieee80211_tx_data *tx)
|
||||
info->flags |= IEEE80211_TX_INTFL_NEED_TXPROCESSING;
|
||||
info->flags &= ~IEEE80211_TX_TEMPORARY_FLAGS;
|
||||
skb_queue_tail(&sta->ps_tx_buf[ac], tx->skb);
|
||||
+ spin_unlock(&sta->ps_lock);
|
||||
|
||||
if (!timer_pending(&local->sta_cleanup))
|
||||
mod_timer(&local->sta_cleanup,
|
||||
--
|
||||
cgit v1.1
|
||||
|
64
Patches/Linux_CVEs/CVE-2014-2851/0.patch
Normal file
64
Patches/Linux_CVEs/CVE-2014-2851/0.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From b04c46190219a4f845e46a459e3102137b7f6cac Mon Sep 17 00:00:00 2001
|
||||
From: "Wang, Xiaoming" <xiaoming.wang@intel.com>
|
||||
Date: Mon, 14 Apr 2014 12:30:45 -0400
|
||||
Subject: net: ipv4: current group_info should be put after using.
|
||||
|
||||
Plug a group_info refcount leak in ping_init.
|
||||
group_info is only needed during initialization and
|
||||
the code failed to release the reference on exit.
|
||||
While here move grabbing the reference to a place
|
||||
where it is actually needed.
|
||||
|
||||
Signed-off-by: Chuansheng Liu <chuansheng.liu@intel.com>
|
||||
Signed-off-by: Zhang Dongxing <dongxing.zhang@intel.com>
|
||||
Signed-off-by: xiaoming wang <xiaoming.wang@intel.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/ipv4/ping.c | 15 +++++++++++----
|
||||
1 file changed, 11 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/net/ipv4/ping.c b/net/ipv4/ping.c
|
||||
index f4b19e5..8210964 100644
|
||||
--- a/net/ipv4/ping.c
|
||||
+++ b/net/ipv4/ping.c
|
||||
@@ -252,26 +252,33 @@ int ping_init_sock(struct sock *sk)
|
||||
{
|
||||
struct net *net = sock_net(sk);
|
||||
kgid_t group = current_egid();
|
||||
- struct group_info *group_info = get_current_groups();
|
||||
- int i, j, count = group_info->ngroups;
|
||||
+ struct group_info *group_info;
|
||||
+ int i, j, count;
|
||||
kgid_t low, high;
|
||||
+ int ret = 0;
|
||||
|
||||
inet_get_ping_group_range_net(net, &low, &high);
|
||||
if (gid_lte(low, group) && gid_lte(group, high))
|
||||
return 0;
|
||||
|
||||
+ group_info = get_current_groups();
|
||||
+ count = group_info->ngroups;
|
||||
for (i = 0; i < group_info->nblocks; i++) {
|
||||
int cp_count = min_t(int, NGROUPS_PER_BLOCK, count);
|
||||
for (j = 0; j < cp_count; j++) {
|
||||
kgid_t gid = group_info->blocks[i][j];
|
||||
if (gid_lte(low, gid) && gid_lte(gid, high))
|
||||
- return 0;
|
||||
+ goto out_release_group;
|
||||
}
|
||||
|
||||
count -= cp_count;
|
||||
}
|
||||
|
||||
- return -EACCES;
|
||||
+ ret = -EACCES;
|
||||
+
|
||||
+out_release_group:
|
||||
+ put_group_info(group_info);
|
||||
+ return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(ping_init_sock);
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
90
Patches/Linux_CVEs/CVE-2014-3145/0.patch
Normal file
90
Patches/Linux_CVEs/CVE-2014-3145/0.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From 05ab8f2647e4221cbdb3856dd7d32bd5407316b3 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Krause <minipli@googlemail.com>
|
||||
Date: Sun, 13 Apr 2014 18:23:33 +0200
|
||||
Subject: filter: prevent nla extensions to peek beyond the end of the message
|
||||
|
||||
The BPF_S_ANC_NLATTR and BPF_S_ANC_NLATTR_NEST extensions fail to check
|
||||
for a minimal message length before testing the supplied offset to be
|
||||
within the bounds of the message. This allows the subtraction of the nla
|
||||
header to underflow and therefore -- as the data type is unsigned --
|
||||
allowing far to big offset and length values for the search of the
|
||||
netlink attribute.
|
||||
|
||||
The remainder calculation for the BPF_S_ANC_NLATTR_NEST extension is
|
||||
also wrong. It has the minuend and subtrahend mixed up, therefore
|
||||
calculates a huge length value, allowing to overrun the end of the
|
||||
message while looking for the netlink attribute.
|
||||
|
||||
The following three BPF snippets will trigger the bugs when attached to
|
||||
a UNIX datagram socket and parsing a message with length 1, 2 or 3.
|
||||
|
||||
,-[ PoC for missing size check in BPF_S_ANC_NLATTR ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nla
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for the same bug in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for wrong remainder calculation in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ; (needs a fake netlink header at offset 0)
|
||||
| ld #0
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
Fix the first issue by ensuring the message length fulfills the minimal
|
||||
size constrains of a nla header. Fix the second bug by getting the math
|
||||
for the remainder calculation right.
|
||||
|
||||
Fixes: 4738c1db15 ("[SKFILTER]: Add SKF_ADF_NLATTR instruction")
|
||||
Fixes: d214c7537b ("filter: add SKF_AD_NLATTR_NEST to look for nested..")
|
||||
Cc: Patrick McHardy <kaber@trash.net>
|
||||
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Mathias Krause <minipli@googlemail.com>
|
||||
Acked-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
---
|
||||
net/core/filter.c | 8 +++++++-
|
||||
1 file changed, 7 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/core/filter.c b/net/core/filter.c
|
||||
index e08b382..0e0856f 100644
|
||||
--- a/net/core/filter.c
|
||||
+++ b/net/core/filter.c
|
||||
@@ -600,6 +600,9 @@ static u64 __skb_get_nlattr(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
+
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
@@ -618,11 +621,14 @@ static u64 __skb_get_nlattr_nest(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
+
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
nla = (struct nlattr *) &skb->data[A];
|
||||
- if (nla->nla_len > A - skb->len)
|
||||
+ if (nla->nla_len > skb->len - A)
|
||||
return 0;
|
||||
|
||||
nla = nla_find_nested(nla, X);
|
||||
--
|
||||
cgit v1.1
|
||||
|
91
Patches/Linux_CVEs/CVE-2014-3145/1.patch
Normal file
91
Patches/Linux_CVEs/CVE-2014-3145/1.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 314760e66c35c8ffa51b4c4ca6948d207e783079 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Krause <minipli@googlemail.com>
|
||||
Date: Sun, 13 Apr 2014 18:23:33 +0200
|
||||
Subject: filter: prevent nla extensions to peek beyond the end of the message
|
||||
|
||||
[ Upstream commit 05ab8f2647e4221cbdb3856dd7d32bd5407316b3 ]
|
||||
|
||||
The BPF_S_ANC_NLATTR and BPF_S_ANC_NLATTR_NEST extensions fail to check
|
||||
for a minimal message length before testing the supplied offset to be
|
||||
within the bounds of the message. This allows the subtraction of the nla
|
||||
header to underflow and therefore -- as the data type is unsigned --
|
||||
allowing far to big offset and length values for the search of the
|
||||
netlink attribute.
|
||||
|
||||
The remainder calculation for the BPF_S_ANC_NLATTR_NEST extension is
|
||||
also wrong. It has the minuend and subtrahend mixed up, therefore
|
||||
calculates a huge length value, allowing to overrun the end of the
|
||||
message while looking for the netlink attribute.
|
||||
|
||||
The following three BPF snippets will trigger the bugs when attached to
|
||||
a UNIX datagram socket and parsing a message with length 1, 2 or 3.
|
||||
|
||||
,-[ PoC for missing size check in BPF_S_ANC_NLATTR ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nla
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for the same bug in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for wrong remainder calculation in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ; (needs a fake netlink header at offset 0)
|
||||
| ld #0
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
Fix the first issue by ensuring the message length fulfills the minimal
|
||||
size constrains of a nla header. Fix the second bug by getting the math
|
||||
for the remainder calculation right.
|
||||
|
||||
Fixes: 4738c1db15 ("[SKFILTER]: Add SKF_ADF_NLATTR instruction")
|
||||
Fixes: d214c7537b ("filter: add SKF_AD_NLATTR_NEST to look for nested..")
|
||||
Cc: Patrick McHardy <kaber@trash.net>
|
||||
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Mathias Krause <minipli@googlemail.com>
|
||||
Acked-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
|
||||
---
|
||||
net/core/filter.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/core/filter.c b/net/core/filter.c
|
||||
index 52f01229..c6c18d8 100644
|
||||
--- a/net/core/filter.c
|
||||
+++ b/net/core/filter.c
|
||||
@@ -355,6 +355,8 @@ load_b:
|
||||
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
@@ -371,11 +373,13 @@ load_b:
|
||||
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
nla = (struct nlattr *)&skb->data[A];
|
||||
- if (nla->nla_len > A - skb->len)
|
||||
+ if (nla->nla_len > skb->len - A)
|
||||
return 0;
|
||||
|
||||
nla = nla_find_nested(nla, X);
|
||||
--
|
||||
cgit v1.1
|
||||
|
92
Patches/Linux_CVEs/CVE-2014-3145/2.patch
Normal file
92
Patches/Linux_CVEs/CVE-2014-3145/2.patch
Normal file
@ -0,0 +1,92 @@
|
||||
From d41eb74e53d94aba656ffda647d106808e636cd6 Mon Sep 17 00:00:00 2001
|
||||
From: Mathias Krause <minipli@googlemail.com>
|
||||
Date: Sun, 13 Apr 2014 18:23:33 +0200
|
||||
Subject: filter: prevent nla extensions to peek beyond the end of the message
|
||||
|
||||
[ Upstream commit 05ab8f2647e4221cbdb3856dd7d32bd5407316b3 ]
|
||||
|
||||
The BPF_S_ANC_NLATTR and BPF_S_ANC_NLATTR_NEST extensions fail to check
|
||||
for a minimal message length before testing the supplied offset to be
|
||||
within the bounds of the message. This allows the subtraction of the nla
|
||||
header to underflow and therefore -- as the data type is unsigned --
|
||||
allowing far to big offset and length values for the search of the
|
||||
netlink attribute.
|
||||
|
||||
The remainder calculation for the BPF_S_ANC_NLATTR_NEST extension is
|
||||
also wrong. It has the minuend and subtrahend mixed up, therefore
|
||||
calculates a huge length value, allowing to overrun the end of the
|
||||
message while looking for the netlink attribute.
|
||||
|
||||
The following three BPF snippets will trigger the bugs when attached to
|
||||
a UNIX datagram socket and parsing a message with length 1, 2 or 3.
|
||||
|
||||
,-[ PoC for missing size check in BPF_S_ANC_NLATTR ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nla
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for the same bug in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ld #0x87654321
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
,-[ PoC for wrong remainder calculation in BPF_S_ANC_NLATTR_NEST ]--
|
||||
| ; (needs a fake netlink header at offset 0)
|
||||
| ld #0
|
||||
| ldx #42
|
||||
| ld #nlan
|
||||
| ret a
|
||||
`---
|
||||
|
||||
Fix the first issue by ensuring the message length fulfills the minimal
|
||||
size constrains of a nla header. Fix the second bug by getting the math
|
||||
for the remainder calculation right.
|
||||
|
||||
Fixes: 4738c1db15 ("[SKFILTER]: Add SKF_ADF_NLATTR instruction")
|
||||
Fixes: d214c7537b ("filter: add SKF_AD_NLATTR_NEST to look for nested..")
|
||||
Cc: Patrick McHardy <kaber@trash.net>
|
||||
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Mathias Krause <minipli@googlemail.com>
|
||||
Acked-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Signed-off-by: David S. Miller <davem@davemloft.net>
|
||||
[bwh: Fix misplacement of the first check due to a bug in the patch program]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/core/filter.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/core/filter.c b/net/core/filter.c
|
||||
index 5dea452..9c88080 100644
|
||||
--- a/net/core/filter.c
|
||||
+++ b/net/core/filter.c
|
||||
@@ -320,6 +320,8 @@ load_b:
|
||||
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
@@ -336,11 +338,13 @@ load_b:
|
||||
|
||||
if (skb_is_nonlinear(skb))
|
||||
return 0;
|
||||
+ if (skb->len < sizeof(struct nlattr))
|
||||
+ return 0;
|
||||
if (A > skb->len - sizeof(struct nlattr))
|
||||
return 0;
|
||||
|
||||
nla = (struct nlattr *)&skb->data[A];
|
||||
- if (nla->nla_len > A - skb->len)
|
||||
+ if (nla->nla_len > skb->len - A)
|
||||
return 0;
|
||||
|
||||
nla = nla_find_nested(nla, X);
|
||||
--
|
||||
cgit v1.1
|
||||
|
206
Patches/Linux_CVEs/CVE-2014-4014/0.patch
Normal file
206
Patches/Linux_CVEs/CVE-2014-4014/0.patch
Normal file
@ -0,0 +1,206 @@
|
||||
From 23adbe12ef7d3d4195e80800ab36b37bee28cd03 Mon Sep 17 00:00:00 2001
|
||||
From: Andy Lutomirski <luto@amacapital.net>
|
||||
Date: Tue, 10 Jun 2014 12:45:42 -0700
|
||||
Subject: fs,userns: Change inode_capable to capable_wrt_inode_uidgid
|
||||
|
||||
The kernel has no concept of capabilities with respect to inodes; inodes
|
||||
exist independently of namespaces. For example, inode_capable(inode,
|
||||
CAP_LINUX_IMMUTABLE) would be nonsense.
|
||||
|
||||
This patch changes inode_capable to check for uid and gid mappings and
|
||||
renames it to capable_wrt_inode_uidgid, which should make it more
|
||||
obvious what it does.
|
||||
|
||||
Fixes CVE-2014-4014.
|
||||
|
||||
Cc: Theodore Ts'o <tytso@mit.edu>
|
||||
Cc: Serge Hallyn <serge.hallyn@ubuntu.com>
|
||||
Cc: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Cc: Dave Chinner <david@fromorbit.com>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
fs/attr.c | 8 ++++----
|
||||
fs/inode.c | 10 +++++++---
|
||||
fs/namei.c | 11 ++++++-----
|
||||
fs/xfs/xfs_ioctl.c | 2 +-
|
||||
include/linux/capability.h | 2 +-
|
||||
kernel/capability.c | 20 ++++++++------------
|
||||
6 files changed, 27 insertions(+), 26 deletions(-)
|
||||
|
||||
diff --git a/fs/attr.c b/fs/attr.c
|
||||
index 5d4e59d..6530ced 100644
|
||||
--- a/fs/attr.c
|
||||
+++ b/fs/attr.c
|
||||
@@ -50,14 +50,14 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
|
||||
if ((ia_valid & ATTR_UID) &&
|
||||
(!uid_eq(current_fsuid(), inode->i_uid) ||
|
||||
!uid_eq(attr->ia_uid, inode->i_uid)) &&
|
||||
- !inode_capable(inode, CAP_CHOWN))
|
||||
+ !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
|
||||
return -EPERM;
|
||||
|
||||
/* Make sure caller can chgrp. */
|
||||
if ((ia_valid & ATTR_GID) &&
|
||||
(!uid_eq(current_fsuid(), inode->i_uid) ||
|
||||
(!in_group_p(attr->ia_gid) && !gid_eq(attr->ia_gid, inode->i_gid))) &&
|
||||
- !inode_capable(inode, CAP_CHOWN))
|
||||
+ !capable_wrt_inode_uidgid(inode, CAP_CHOWN))
|
||||
return -EPERM;
|
||||
|
||||
/* Make sure a caller can chmod. */
|
||||
@@ -67,7 +67,7 @@ int inode_change_ok(const struct inode *inode, struct iattr *attr)
|
||||
/* Also check the setgid bit! */
|
||||
if (!in_group_p((ia_valid & ATTR_GID) ? attr->ia_gid :
|
||||
inode->i_gid) &&
|
||||
- !inode_capable(inode, CAP_FSETID))
|
||||
+ !capable_wrt_inode_uidgid(inode, CAP_FSETID))
|
||||
attr->ia_mode &= ~S_ISGID;
|
||||
}
|
||||
|
||||
@@ -160,7 +160,7 @@ void setattr_copy(struct inode *inode, const struct iattr *attr)
|
||||
umode_t mode = attr->ia_mode;
|
||||
|
||||
if (!in_group_p(inode->i_gid) &&
|
||||
- !inode_capable(inode, CAP_FSETID))
|
||||
+ !capable_wrt_inode_uidgid(inode, CAP_FSETID))
|
||||
mode &= ~S_ISGID;
|
||||
inode->i_mode = mode;
|
||||
}
|
||||
diff --git a/fs/inode.c b/fs/inode.c
|
||||
index 2feb9b6..6eecb7f 100644
|
||||
--- a/fs/inode.c
|
||||
+++ b/fs/inode.c
|
||||
@@ -1839,14 +1839,18 @@ EXPORT_SYMBOL(inode_init_owner);
|
||||
* inode_owner_or_capable - check current task permissions to inode
|
||||
* @inode: inode being checked
|
||||
*
|
||||
- * Return true if current either has CAP_FOWNER to the inode, or
|
||||
- * owns the file.
|
||||
+ * Return true if current either has CAP_FOWNER in a namespace with the
|
||||
+ * inode owner uid mapped, or owns the file.
|
||||
*/
|
||||
bool inode_owner_or_capable(const struct inode *inode)
|
||||
{
|
||||
+ struct user_namespace *ns;
|
||||
+
|
||||
if (uid_eq(current_fsuid(), inode->i_uid))
|
||||
return true;
|
||||
- if (inode_capable(inode, CAP_FOWNER))
|
||||
+
|
||||
+ ns = current_user_ns();
|
||||
+ if (ns_capable(ns, CAP_FOWNER) && kuid_has_mapping(ns, inode->i_uid))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
diff --git a/fs/namei.c b/fs/namei.c
|
||||
index 8016827..985c6f3 100644
|
||||
--- a/fs/namei.c
|
||||
+++ b/fs/namei.c
|
||||
@@ -332,10 +332,11 @@ int generic_permission(struct inode *inode, int mask)
|
||||
|
||||
if (S_ISDIR(inode->i_mode)) {
|
||||
/* DACs are overridable for directories */
|
||||
- if (inode_capable(inode, CAP_DAC_OVERRIDE))
|
||||
+ if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
|
||||
return 0;
|
||||
if (!(mask & MAY_WRITE))
|
||||
- if (inode_capable(inode, CAP_DAC_READ_SEARCH))
|
||||
+ if (capable_wrt_inode_uidgid(inode,
|
||||
+ CAP_DAC_READ_SEARCH))
|
||||
return 0;
|
||||
return -EACCES;
|
||||
}
|
||||
@@ -345,7 +346,7 @@ int generic_permission(struct inode *inode, int mask)
|
||||
* at least one exec bit set.
|
||||
*/
|
||||
if (!(mask & MAY_EXEC) || (inode->i_mode & S_IXUGO))
|
||||
- if (inode_capable(inode, CAP_DAC_OVERRIDE))
|
||||
+ if (capable_wrt_inode_uidgid(inode, CAP_DAC_OVERRIDE))
|
||||
return 0;
|
||||
|
||||
/*
|
||||
@@ -353,7 +354,7 @@ int generic_permission(struct inode *inode, int mask)
|
||||
*/
|
||||
mask &= MAY_READ | MAY_WRITE | MAY_EXEC;
|
||||
if (mask == MAY_READ)
|
||||
- if (inode_capable(inode, CAP_DAC_READ_SEARCH))
|
||||
+ if (capable_wrt_inode_uidgid(inode, CAP_DAC_READ_SEARCH))
|
||||
return 0;
|
||||
|
||||
return -EACCES;
|
||||
@@ -2379,7 +2380,7 @@ static inline int check_sticky(struct inode *dir, struct inode *inode)
|
||||
return 0;
|
||||
if (uid_eq(dir->i_uid, fsuid))
|
||||
return 0;
|
||||
- return !inode_capable(inode, CAP_FOWNER);
|
||||
+ return !capable_wrt_inode_uidgid(inode, CAP_FOWNER);
|
||||
}
|
||||
|
||||
/*
|
||||
diff --git a/fs/xfs/xfs_ioctl.c b/fs/xfs/xfs_ioctl.c
|
||||
index 0b18776..6152cbe 100644
|
||||
--- a/fs/xfs/xfs_ioctl.c
|
||||
+++ b/fs/xfs/xfs_ioctl.c
|
||||
@@ -1215,7 +1215,7 @@ xfs_ioctl_setattr(
|
||||
* cleared upon successful return from chown()
|
||||
*/
|
||||
if ((ip->i_d.di_mode & (S_ISUID|S_ISGID)) &&
|
||||
- !inode_capable(VFS_I(ip), CAP_FSETID))
|
||||
+ !capable_wrt_inode_uidgid(VFS_I(ip), CAP_FSETID))
|
||||
ip->i_d.di_mode &= ~(S_ISUID|S_ISGID);
|
||||
|
||||
/*
|
||||
diff --git a/include/linux/capability.h b/include/linux/capability.h
|
||||
index a6ee1f9..84b13ad 100644
|
||||
--- a/include/linux/capability.h
|
||||
+++ b/include/linux/capability.h
|
||||
@@ -210,7 +210,7 @@ extern bool has_ns_capability_noaudit(struct task_struct *t,
|
||||
struct user_namespace *ns, int cap);
|
||||
extern bool capable(int cap);
|
||||
extern bool ns_capable(struct user_namespace *ns, int cap);
|
||||
-extern bool inode_capable(const struct inode *inode, int cap);
|
||||
+extern bool capable_wrt_inode_uidgid(const struct inode *inode, int cap);
|
||||
extern bool file_ns_capable(const struct file *file, struct user_namespace *ns, int cap);
|
||||
|
||||
/* audit system wants to get cap info from files as well */
|
||||
diff --git a/kernel/capability.c b/kernel/capability.c
|
||||
index 84b2bbf..a5cf13c 100644
|
||||
--- a/kernel/capability.c
|
||||
+++ b/kernel/capability.c
|
||||
@@ -424,23 +424,19 @@ bool capable(int cap)
|
||||
EXPORT_SYMBOL(capable);
|
||||
|
||||
/**
|
||||
- * inode_capable - Check superior capability over inode
|
||||
+ * capable_wrt_inode_uidgid - Check nsown_capable and uid and gid mapped
|
||||
* @inode: The inode in question
|
||||
* @cap: The capability in question
|
||||
*
|
||||
- * Return true if the current task has the given superior capability
|
||||
- * targeted at it's own user namespace and that the given inode is owned
|
||||
- * by the current user namespace or a child namespace.
|
||||
- *
|
||||
- * Currently we check to see if an inode is owned by the current
|
||||
- * user namespace by seeing if the inode's owner maps into the
|
||||
- * current user namespace.
|
||||
- *
|
||||
+ * Return true if the current task has the given capability targeted at
|
||||
+ * its own user namespace and that the given inode's uid and gid are
|
||||
+ * mapped into the current user namespace.
|
||||
*/
|
||||
-bool inode_capable(const struct inode *inode, int cap)
|
||||
+bool capable_wrt_inode_uidgid(const struct inode *inode, int cap)
|
||||
{
|
||||
struct user_namespace *ns = current_user_ns();
|
||||
|
||||
- return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid);
|
||||
+ return ns_capable(ns, cap) && kuid_has_mapping(ns, inode->i_uid) &&
|
||||
+ kgid_has_mapping(ns, inode->i_gid);
|
||||
}
|
||||
-EXPORT_SYMBOL(inode_capable);
|
||||
+EXPORT_SYMBOL(capable_wrt_inode_uidgid);
|
||||
--
|
||||
cgit v1.1
|
||||
|
33
Patches/Linux_CVEs/CVE-2014-4323/0.patch
Normal file
33
Patches/Linux_CVEs/CVE-2014-4323/0.patch
Normal file
@ -0,0 +1,33 @@
|
||||
From 014fa8def84c62893fa016e873c12de1da498603 Mon Sep 17 00:00:00 2001
|
||||
From: raghavendra ambadas <rambad@codeaurora.org>
|
||||
Date: Mon, 6 Oct 2014 14:59:57 +0530
|
||||
Subject: msm: mdp: Validate input arguments from user space
|
||||
|
||||
Fully verify the input arguments from user client are safe
|
||||
to use.
|
||||
|
||||
Change-Id: Ie14332443b187951009c63ebfb78456dcd9ba60f
|
||||
Signed-off-by: Raghavendra Ambadas <rambad@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/mdp.c | 5 +++++
|
||||
1 file changed, 5 insertions(+)
|
||||
|
||||
diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
|
||||
index 4ede0b52..c00bd78 100644
|
||||
--- a/drivers/video/msm/mdp.c
|
||||
+++ b/drivers/video/msm/mdp.c
|
||||
@@ -485,6 +485,11 @@ static int mdp_lut_hw_update(struct fb_cmap *cmap)
|
||||
c[1] = cmap->blue;
|
||||
c[2] = cmap->red;
|
||||
|
||||
+ if (cmap->start > MDP_HIST_LUT_SIZE || cmap->len > MDP_HIST_LUT_SIZE ||
|
||||
+ (cmap->start + cmap->len > MDP_HIST_LUT_SIZE)) {
|
||||
+ pr_err("mdp_lut_hw_update invalid arguments\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
for (i = 0; i < cmap->len; i++) {
|
||||
if (copy_from_user(&r, cmap->red++, sizeof(r)) ||
|
||||
copy_from_user(&g, cmap->green++, sizeof(g)) ||
|
||||
--
|
||||
cgit v1.1
|
||||
|
85
Patches/Linux_CVEs/CVE-2014-4655/0.patch
Normal file
85
Patches/Linux_CVEs/CVE-2014-4655/0.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 82262a46627bebb0febcc26664746c25cef08563 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:32 +0200
|
||||
Subject: [PATCH] ALSA: control: Fix replacing user controls
|
||||
|
||||
There are two issues with the current implementation for replacing user
|
||||
controls. The first is that the code does not check if the control is actually a
|
||||
user control and neither does it check if the control is owned by the process
|
||||
that tries to remove it. That allows userspace applications to remove arbitrary
|
||||
controls, which can cause a user after free if a for example a driver does not
|
||||
expect a control to be removed from under its feed.
|
||||
|
||||
The second issue is that on one hand when a control is replaced the
|
||||
user_ctl_count limit is not checked and on the other hand the user_ctl_count is
|
||||
increased (even though the number of user controls does not change). This allows
|
||||
userspace, once the user_ctl_count limit as been reached, to repeatedly replace
|
||||
a control until user_ctl_count overflows. Once that happens new controls can be
|
||||
added effectively bypassing the user_ctl_count limit.
|
||||
|
||||
Both issues can be fixed by instead of open-coding the removal of the control
|
||||
that is to be replaced to use snd_ctl_remove_user_ctl(). This function does
|
||||
proper permission checks as well as decrements user_ctl_count after the control
|
||||
has been removed.
|
||||
|
||||
Note that by using snd_ctl_remove_user_ctl() the check which returns -EBUSY at
|
||||
beginning of the function if the control already exists is removed. This is not
|
||||
a problem though since the check is quite useless, because the lock that is
|
||||
protecting the control list is released between the check and before adding the
|
||||
new control to the list, which means that it is possible that a different
|
||||
control with the same settings is added to the list after the check. Luckily
|
||||
there is another check that is done while holding the lock in snd_ctl_add(), so
|
||||
we'll rely on that to make sure that the same control is not added twice.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Acked-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/control.c | 25 +++++++++----------------
|
||||
1 file changed, 9 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 00ab034f5fcbe..1f413c2865113 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -1154,8 +1154,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
- if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
- return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
||||
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
||||
@@ -1164,21 +1162,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
|
||||
info->id.numid = 0;
|
||||
memset(&kctl, 0, sizeof(kctl));
|
||||
- down_write(&card->controls_rwsem);
|
||||
- _kctl = snd_ctl_find_id(card, &info->id);
|
||||
- err = 0;
|
||||
- if (_kctl) {
|
||||
- if (replace)
|
||||
- err = snd_ctl_remove(card, _kctl);
|
||||
- else
|
||||
- err = -EBUSY;
|
||||
- } else {
|
||||
- if (replace)
|
||||
- err = -ENOENT;
|
||||
+
|
||||
+ if (replace) {
|
||||
+ err = snd_ctl_remove_user_ctl(file, &info->id);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
}
|
||||
- up_write(&card->controls_rwsem);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+
|
||||
+ if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
memcpy(&kctl.id, &info->id, sizeof(info->id));
|
||||
kctl.count = info->owner ? info->owner : 1;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
90
Patches/Linux_CVEs/CVE-2014-4655/1.patch
Normal file
90
Patches/Linux_CVEs/CVE-2014-4655/1.patch
Normal file
@ -0,0 +1,90 @@
|
||||
From 0e2e43eca302b31f64ebfe4734fd2cc7358c4555 Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:32 +0200
|
||||
Subject: ALSA: control: Fix replacing user controls
|
||||
|
||||
commit 82262a46627bebb0febcc26664746c25cef08563 upstream.
|
||||
|
||||
There are two issues with the current implementation for replacing user
|
||||
controls. The first is that the code does not check if the control is actually a
|
||||
user control and neither does it check if the control is owned by the process
|
||||
that tries to remove it. That allows userspace applications to remove arbitrary
|
||||
controls, which can cause a user after free if a for example a driver does not
|
||||
expect a control to be removed from under its feed.
|
||||
|
||||
The second issue is that on one hand when a control is replaced the
|
||||
user_ctl_count limit is not checked and on the other hand the user_ctl_count is
|
||||
increased (even though the number of user controls does not change). This allows
|
||||
userspace, once the user_ctl_count limit as been reached, to repeatedly replace
|
||||
a control until user_ctl_count overflows. Once that happens new controls can be
|
||||
added effectively bypassing the user_ctl_count limit.
|
||||
|
||||
Both issues can be fixed by instead of open-coding the removal of the control
|
||||
that is to be replaced to use snd_ctl_remove_user_ctl(). This function does
|
||||
proper permission checks as well as decrements user_ctl_count after the control
|
||||
has been removed.
|
||||
|
||||
Note that by using snd_ctl_remove_user_ctl() the check which returns -EBUSY at
|
||||
beginning of the function if the control already exists is removed. This is not
|
||||
a problem though since the check is quite useless, because the lock that is
|
||||
protecting the control list is released between the check and before adding the
|
||||
new control to the list, which means that it is possible that a different
|
||||
control with the same settings is added to the list after the check. Luckily
|
||||
there is another check that is done while holding the lock in snd_ctl_add(), so
|
||||
we'll rely on that to make sure that the same control is not added twice.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Acked-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
sound/core/control.c | 25 +++++++++----------------
|
||||
1 file changed, 9 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 920ea56..caa949e 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -1151,8 +1151,6 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
- if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
- return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
||||
access = info->access == 0 ? SNDRV_CTL_ELEM_ACCESS_READWRITE :
|
||||
@@ -1161,21 +1159,16 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
SNDRV_CTL_ELEM_ACCESS_TLV_READWRITE));
|
||||
info->id.numid = 0;
|
||||
memset(&kctl, 0, sizeof(kctl));
|
||||
- down_write(&card->controls_rwsem);
|
||||
- _kctl = snd_ctl_find_id(card, &info->id);
|
||||
- err = 0;
|
||||
- if (_kctl) {
|
||||
- if (replace)
|
||||
- err = snd_ctl_remove(card, _kctl);
|
||||
- else
|
||||
- err = -EBUSY;
|
||||
- } else {
|
||||
- if (replace)
|
||||
- err = -ENOENT;
|
||||
+
|
||||
+ if (replace) {
|
||||
+ err = snd_ctl_remove_user_ctl(file, &info->id);
|
||||
+ if (err)
|
||||
+ return err;
|
||||
}
|
||||
- up_write(&card->controls_rwsem);
|
||||
- if (err < 0)
|
||||
- return err;
|
||||
+
|
||||
+ if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
+ return -ENOMEM;
|
||||
+
|
||||
memcpy(&kctl.id, &info->id, sizeof(info->id));
|
||||
kctl.count = info->owner ? info->owner : 1;
|
||||
access |= SNDRV_CTL_ELEM_ACCESS_USER;
|
||||
--
|
||||
cgit v1.1
|
||||
|
27
Patches/Linux_CVEs/CVE-2014-4655/2.patch
Normal file
27
Patches/Linux_CVEs/CVE-2014-4655/2.patch
Normal file
@ -0,0 +1,27 @@
|
||||
From 08ede038a738f22c1b3425051175e1d627d8dd43 Mon Sep 17 00:00:00 2001
|
||||
From: Lu Guanqun <guanqun.lu@intel.com>
|
||||
Date: Wed, 24 Aug 2011 14:45:10 +0800
|
||||
Subject: [PATCH] ALSA: core: release the constraint check for replace ops
|
||||
|
||||
Suppose the ALSA card already has a number of MAX_USER_CONTROLS controls, and
|
||||
the user wants to replace one, it should not fail at this condition check.
|
||||
|
||||
Signed-off-by: Lu Guanqun <guanqun.lu@intel.com>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/control.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 7f2b3a7eabb2b..dc2a44048c850 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -1073,7 +1073,7 @@ static int snd_ctl_elem_add(struct snd_ctl_file *file,
|
||||
struct user_element *ue;
|
||||
int idx, err;
|
||||
|
||||
- if (card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
+ if (!replace && card->user_ctl_count >= MAX_USER_CONTROLS)
|
||||
return -ENOMEM;
|
||||
if (info->count < 1)
|
||||
return -EINVAL;
|
37
Patches/Linux_CVEs/CVE-2014-4656/0.patch
Normal file
37
Patches/Linux_CVEs/CVE-2014-4656/0.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 883a1d49f0d77d30012f114b2e19fc141beb3e8e Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:35 +0200
|
||||
Subject: ALSA: control: Make sure that id->index does not overflow
|
||||
|
||||
The ALSA control code expects that the range of assigned indices to a control is
|
||||
continuous and does not overflow. Currently there are no checks to enforce this.
|
||||
If a control with a overflowing index range is created that control becomes
|
||||
effectively inaccessible and unremovable since snd_ctl_find_id() will not be
|
||||
able to find it. This patch adds a check that makes sure that controls with a
|
||||
overflowing index range can not be created.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Acked-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Cc: <stable@vger.kernel.org>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
---
|
||||
sound/core/control.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index 8d6e4ba..f0b0e14 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -342,6 +342,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
if (snd_BUG_ON(!card || !kcontrol->info))
|
||||
goto error;
|
||||
id = kcontrol->id;
|
||||
+ if (id.index > UINT_MAX - kcontrol->count)
|
||||
+ goto error;
|
||||
+
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
up_write(&card->controls_rwsem);
|
||||
--
|
||||
cgit v1.1
|
||||
|
39
Patches/Linux_CVEs/CVE-2014-4656/1.patch
Normal file
39
Patches/Linux_CVEs/CVE-2014-4656/1.patch
Normal file
@ -0,0 +1,39 @@
|
||||
From f7500568b7633324e7c4282bb8baa3ff3f17fd7a Mon Sep 17 00:00:00 2001
|
||||
From: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Date: Wed, 18 Jun 2014 13:32:35 +0200
|
||||
Subject: ALSA: control: Make sure that id->index does not overflow
|
||||
|
||||
commit 883a1d49f0d77d30012f114b2e19fc141beb3e8e upstream.
|
||||
|
||||
The ALSA control code expects that the range of assigned indices to a control is
|
||||
continuous and does not overflow. Currently there are no checks to enforce this.
|
||||
If a control with a overflowing index range is created that control becomes
|
||||
effectively inaccessible and unremovable since snd_ctl_find_id() will not be
|
||||
able to find it. This patch adds a check that makes sure that controls with a
|
||||
overflowing index range can not be created.
|
||||
|
||||
Signed-off-by: Lars-Peter Clausen <lars@metafoo.de>
|
||||
Acked-by: Jaroslav Kysela <perex@perex.cz>
|
||||
Signed-off-by: Takashi Iwai <tiwai@suse.de>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
sound/core/control.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/sound/core/control.c b/sound/core/control.c
|
||||
index d3f17de..9210594 100644
|
||||
--- a/sound/core/control.c
|
||||
+++ b/sound/core/control.c
|
||||
@@ -341,6 +341,9 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
|
||||
if (snd_BUG_ON(!card || !kcontrol->info))
|
||||
goto error;
|
||||
id = kcontrol->id;
|
||||
+ if (id.index > UINT_MAX - kcontrol->count)
|
||||
+ goto error;
|
||||
+
|
||||
down_write(&card->controls_rwsem);
|
||||
if (snd_ctl_find_id(card, &id)) {
|
||||
up_write(&card->controls_rwsem);
|
||||
--
|
||||
cgit v1.1
|
||||
|
51
Patches/Linux_CVEs/CVE-2014-4943/0.patch
Normal file
51
Patches/Linux_CVEs/CVE-2014-4943/0.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From 3cf521f7dc87c031617fd47e4b7aa2593c2f3daf Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <sasha.levin@oracle.com>
|
||||
Date: Mon, 14 Jul 2014 17:02:31 -0700
|
||||
Subject: [PATCH] net/l2tp: don't fall back on UDP [get|set]sockopt
|
||||
|
||||
The l2tp [get|set]sockopt() code has fallen back to the UDP functions
|
||||
for socket option levels != SOL_PPPOL2TP since day one, but that has
|
||||
never actually worked, since the l2tp socket isn't an inet socket.
|
||||
|
||||
As David Miller points out:
|
||||
|
||||
"If we wanted this to work, it'd have to look up the tunnel and then
|
||||
use tunnel->sk, but I wonder how useful that would be"
|
||||
|
||||
Since this can never have worked so nobody could possibly have depended
|
||||
on that functionality, just remove the broken code and return -EINVAL.
|
||||
|
||||
Reported-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Acked-by: James Chapman <jchapman@katalix.com>
|
||||
Acked-by: David Miller <davem@davemloft.net>
|
||||
Cc: Phil Turnbull <phil.turnbull@oracle.com>
|
||||
Cc: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Cc: Willy Tarreau <w@1wt.eu>
|
||||
Cc: stable@vger.kernel.org
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
net/l2tp/l2tp_ppp.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
|
||||
index 950909f04ee6a..13752d96275e8 100644
|
||||
--- a/net/l2tp/l2tp_ppp.c
|
||||
+++ b/net/l2tp/l2tp_ppp.c
|
||||
@@ -1365,7 +1365,7 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
||||
int err;
|
||||
|
||||
if (level != SOL_PPPOL2TP)
|
||||
- return udp_prot.setsockopt(sk, level, optname, optval, optlen);
|
||||
+ return -EINVAL;
|
||||
|
||||
if (optlen < sizeof(int))
|
||||
return -EINVAL;
|
||||
@@ -1491,7 +1491,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level, int optname,
|
||||
struct pppol2tp_session *ps;
|
||||
|
||||
if (level != SOL_PPPOL2TP)
|
||||
- return udp_prot.getsockopt(sk, level, optname, optval, optlen);
|
||||
+ return -EINVAL;
|
||||
|
||||
if (get_user(len, optlen))
|
||||
return -EFAULT;
|
56
Patches/Linux_CVEs/CVE-2014-4943/1.patch
Normal file
56
Patches/Linux_CVEs/CVE-2014-4943/1.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 1179c8f1caca90caf4ce0eec54b499de4f1551c4 Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <sasha.levin@oracle.com>
|
||||
Date: Mon, 14 Jul 2014 17:02:31 -0700
|
||||
Subject: net/l2tp: don't fall back on UDP [get|set]sockopt
|
||||
|
||||
commit 3cf521f7dc87c031617fd47e4b7aa2593c2f3daf upstream.
|
||||
|
||||
The l2tp [get|set]sockopt() code has fallen back to the UDP functions
|
||||
for socket option levels != SOL_PPPOL2TP since day one, but that has
|
||||
never actually worked, since the l2tp socket isn't an inet socket.
|
||||
|
||||
As David Miller points out:
|
||||
|
||||
"If we wanted this to work, it'd have to look up the tunnel and then
|
||||
use tunnel->sk, but I wonder how useful that would be"
|
||||
|
||||
Since this can never have worked so nobody could possibly have depended
|
||||
on that functionality, just remove the broken code and return -EINVAL.
|
||||
|
||||
Reported-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Acked-by: James Chapman <jchapman@katalix.com>
|
||||
Acked-by: David Miller <davem@davemloft.net>
|
||||
Cc: Phil Turnbull <phil.turnbull@oracle.com>
|
||||
Cc: Vegard Nossum <vegard.nossum@oracle.com>
|
||||
Cc: Willy Tarreau <w@1wt.eu>
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/l2tp/l2tp_ppp.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
|
||||
index e0f0934..437fb59 100644
|
||||
--- a/net/l2tp/l2tp_ppp.c
|
||||
+++ b/net/l2tp/l2tp_ppp.c
|
||||
@@ -1351,7 +1351,7 @@ static int pppol2tp_setsockopt(struct socket *sock, int level, int optname,
|
||||
int err;
|
||||
|
||||
if (level != SOL_PPPOL2TP)
|
||||
- return udp_prot.setsockopt(sk, level, optname, optval, optlen);
|
||||
+ return -EINVAL;
|
||||
|
||||
if (optlen < sizeof(int))
|
||||
return -EINVAL;
|
||||
@@ -1477,7 +1477,7 @@ static int pppol2tp_getsockopt(struct socket *sock, int level,
|
||||
struct pppol2tp_session *ps;
|
||||
|
||||
if (level != SOL_PPPOL2TP)
|
||||
- return udp_prot.getsockopt(sk, level, optname, optval, optlen);
|
||||
+ return -EINVAL;
|
||||
|
||||
if (get_user(len, (int __user *) optlen))
|
||||
return -EFAULT;
|
||||
--
|
||||
cgit v1.1
|
||||
|
52
Patches/Linux_CVEs/CVE-2014-5206/0.patch
Normal file
52
Patches/Linux_CVEs/CVE-2014-5206/0.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From a6138db815df5ee542d848318e5dae681590fccd Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Mon, 28 Jul 2014 16:26:53 -0700
|
||||
Subject: [PATCH] mnt: Only change user settable mount flags in remount
|
||||
|
||||
Kenton Varda <kenton@sandstorm.io> discovered that by remounting a
|
||||
read-only bind mount read-only in a user namespace the
|
||||
MNT_LOCK_READONLY bit would be cleared, allowing an unprivileged user
|
||||
to the remount a read-only mount read-write.
|
||||
|
||||
Correct this by replacing the mask of mount flags to preserve
|
||||
with a mask of mount flags that may be changed, and preserve
|
||||
all others. This ensures that any future bugs with this mask and
|
||||
remount will fail in an easy to detect way where new mount flags
|
||||
simply won't change.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Acked-by: Serge E. Hallyn <serge.hallyn@ubuntu.com>
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
---
|
||||
fs/namespace.c | 2 +-
|
||||
include/linux/mount.h | 4 +++-
|
||||
2 files changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index 7187d01329c35..cb40449ea0dfe 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -1937,7 +1937,7 @@ static int do_remount(struct path *path, int flags, int mnt_flags,
|
||||
err = do_remount_sb(sb, flags, data, 0);
|
||||
if (!err) {
|
||||
lock_mount_hash();
|
||||
- mnt_flags |= mnt->mnt.mnt_flags & MNT_PROPAGATION_MASK;
|
||||
+ mnt_flags |= mnt->mnt.mnt_flags & ~MNT_USER_SETTABLE_MASK;
|
||||
mnt->mnt.mnt_flags = mnt_flags;
|
||||
touch_mnt_namespace(mnt->mnt_ns);
|
||||
unlock_mount_hash();
|
||||
diff --git a/include/linux/mount.h b/include/linux/mount.h
|
||||
index 839bac2709048..b637a89e1faeb 100644
|
||||
--- a/include/linux/mount.h
|
||||
+++ b/include/linux/mount.h
|
||||
@@ -42,7 +42,9 @@ struct mnt_namespace;
|
||||
* flag, consider how it interacts with shared mounts.
|
||||
*/
|
||||
#define MNT_SHARED_MASK (MNT_UNBINDABLE)
|
||||
-#define MNT_PROPAGATION_MASK (MNT_SHARED | MNT_UNBINDABLE)
|
||||
+#define MNT_USER_SETTABLE_MASK (MNT_NOSUID | MNT_NODEV | MNT_NOEXEC \
|
||||
+ | MNT_NOATIME | MNT_NODIRATIME | MNT_RELATIME \
|
||||
+ | MNT_READONLY)
|
||||
|
||||
#define MNT_INTERNAL_FLAGS (MNT_SHARED | MNT_WRITE_HOLD | MNT_INTERNAL | \
|
||||
MNT_DOOMED | MNT_SYNC_UMOUNT | MNT_MARKED)
|
72
Patches/Linux_CVEs/CVE-2014-7822/0.patch
Normal file
72
Patches/Linux_CVEs/CVE-2014-7822/0.patch
Normal file
@ -0,0 +1,72 @@
|
||||
From 894c6350eaad7e613ae267504014a456e00a3e2a Mon Sep 17 00:00:00 2001
|
||||
From: Ben Hutchings <ben@decadent.org.uk>
|
||||
Date: Thu, 29 Jan 2015 02:50:33 +0000
|
||||
Subject: splice: Apply generic position and size checks to each write
|
||||
|
||||
We need to check the position and size of file writes against various
|
||||
limits, using generic_write_check(). This was not being done for
|
||||
the splice write path. It was fixed upstream by commit 8d0207652cbe
|
||||
("->splice_write() via ->write_iter()") but we can't apply that.
|
||||
|
||||
CVE-2014-7822
|
||||
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
fs/ocfs2/file.c | 8 ++++++--
|
||||
fs/splice.c | 8 ++++++--
|
||||
2 files changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
|
||||
index d20d64c..0de24a2 100644
|
||||
--- a/fs/ocfs2/file.c
|
||||
+++ b/fs/ocfs2/file.c
|
||||
@@ -2468,9 +2468,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
|
||||
struct address_space *mapping = out->f_mapping;
|
||||
struct inode *inode = mapping->host;
|
||||
struct splice_desc sd = {
|
||||
- .total_len = len,
|
||||
.flags = flags,
|
||||
- .pos = *ppos,
|
||||
.u.file = out,
|
||||
};
|
||||
|
||||
@@ -2480,6 +2478,12 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
|
||||
out->f_path.dentry->d_name.len,
|
||||
out->f_path.dentry->d_name.name, len);
|
||||
|
||||
+ ret = generic_write_checks(out, ppos, &len, 0);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ sd.total_len = len;
|
||||
+ sd.pos = *ppos;
|
||||
+
|
||||
if (pipe->inode)
|
||||
mutex_lock_nested(&pipe->inode->i_mutex, I_MUTEX_PARENT);
|
||||
|
||||
diff --git a/fs/splice.c b/fs/splice.c
|
||||
index 714471d..34c2b2b 100644
|
||||
--- a/fs/splice.c
|
||||
+++ b/fs/splice.c
|
||||
@@ -1013,13 +1013,17 @@ generic_file_splice_write(struct pipe_inode_info *pipe, struct file *out,
|
||||
struct address_space *mapping = out->f_mapping;
|
||||
struct inode *inode = mapping->host;
|
||||
struct splice_desc sd = {
|
||||
- .total_len = len,
|
||||
.flags = flags,
|
||||
- .pos = *ppos,
|
||||
.u.file = out,
|
||||
};
|
||||
ssize_t ret;
|
||||
|
||||
+ ret = generic_write_checks(out, ppos, &len, S_ISBLK(inode->i_mode));
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
+ sd.total_len = len;
|
||||
+ sd.pos = *ppos;
|
||||
+
|
||||
pipe_lock(pipe);
|
||||
|
||||
splice_from_pipe_begin(&sd);
|
||||
--
|
||||
cgit v1.1
|
||||
|
50
Patches/Linux_CVEs/CVE-2014-7825/0.patch
Normal file
50
Patches/Linux_CVEs/CVE-2014-7825/0.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 6f25b4e75a87fea8087b543f3d1298d301d24ad7 Mon Sep 17 00:00:00 2001
|
||||
From: Will Deacon <will.deacon@arm.com>
|
||||
Date: Thu, 16 Aug 2012 18:14:14 +0100
|
||||
Subject: tracing/syscalls: Fix perf syscall tracing when syscall_nr == -1
|
||||
|
||||
commit 60916a9382e88fbf5e54fd36a3e658efd7ab7bed upstream.
|
||||
|
||||
syscall_get_nr can return -1 in the case that the task is not executing
|
||||
a system call.
|
||||
|
||||
This patch fixes perf_syscall_{enter,exit} to check that the syscall
|
||||
number is valid before using it as an index into a bitmap.
|
||||
|
||||
Link: http://lkml.kernel.org/r/1345137254-7377-1-git-send-email-will.deacon@arm.com
|
||||
|
||||
Cc: Jason Baron <jbaron@redhat.com>
|
||||
Cc: Wade Farnsworth <wade_farnsworth@mentor.com>
|
||||
Cc: Frederic Weisbecker <fweisbec@gmail.com>
|
||||
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
||||
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
kernel/trace/trace_syscalls.c | 4 ++++
|
||||
1 file changed, 4 insertions(+)
|
||||
|
||||
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
|
||||
index 7c75bbb..22a7c9b 100644
|
||||
--- a/kernel/trace/trace_syscalls.c
|
||||
+++ b/kernel/trace/trace_syscalls.c
|
||||
@@ -519,6 +519,8 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
|
||||
int size;
|
||||
|
||||
syscall_nr = syscall_get_nr(current, regs);
|
||||
+ if (syscall_nr < 0)
|
||||
+ return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
|
||||
return;
|
||||
|
||||
@@ -593,6 +595,8 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
|
||||
int size;
|
||||
|
||||
syscall_nr = syscall_get_nr(current, regs);
|
||||
+ if (syscall_nr < 0)
|
||||
+ return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
|
||||
return;
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
91
Patches/Linux_CVEs/CVE-2014-7825/1.patch
Normal file
91
Patches/Linux_CVEs/CVE-2014-7825/1.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From 8043761416d5ae6d8fe5e95331d26465d52e8c6e Mon Sep 17 00:00:00 2001
|
||||
From: Rabin Vincent <rabin@rab.in>
|
||||
Date: Wed, 29 Oct 2014 23:06:58 +0100
|
||||
Subject: tracing/syscalls: Ignore numbers outside NR_syscalls' range
|
||||
|
||||
commit 086ba77a6db00ed858ff07451bedee197df868c9 upstream.
|
||||
|
||||
ARM has some private syscalls (for example, set_tls(2)) which lie
|
||||
outside the range of NR_syscalls. If any of these are called while
|
||||
syscall tracing is being performed, out-of-bounds array access will
|
||||
occur in the ftrace and perf sys_{enter,exit} handlers.
|
||||
|
||||
# trace-cmd record -e raw_syscalls:* true && trace-cmd report
|
||||
...
|
||||
true-653 [000] 384.675777: sys_enter: NR 192 (0, 1000, 3, 4000022, ffffffff, 0)
|
||||
true-653 [000] 384.675812: sys_exit: NR 192 = 1995915264
|
||||
true-653 [000] 384.675971: sys_enter: NR 983045 (76f74480, 76f74000, 76f74b28, 76f74480, 76f76f74, 1)
|
||||
true-653 [000] 384.675988: sys_exit: NR 983045 = 0
|
||||
...
|
||||
|
||||
# trace-cmd record -e syscalls:* true
|
||||
[ 17.289329] Unable to handle kernel paging request at virtual address aaaaaace
|
||||
[ 17.289590] pgd = 9e71c000
|
||||
[ 17.289696] [aaaaaace] *pgd=00000000
|
||||
[ 17.289985] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
|
||||
[ 17.290169] Modules linked in:
|
||||
[ 17.290391] CPU: 0 PID: 704 Comm: true Not tainted 3.18.0-rc2+ #21
|
||||
[ 17.290585] task: 9f4dab00 ti: 9e710000 task.ti: 9e710000
|
||||
[ 17.290747] PC is at ftrace_syscall_enter+0x48/0x1f8
|
||||
[ 17.290866] LR is at syscall_trace_enter+0x124/0x184
|
||||
|
||||
Fix this by ignoring out-of-NR_syscalls-bounds syscall numbers.
|
||||
|
||||
Commit cd0980fc8add "tracing: Check invalid syscall nr while tracing syscalls"
|
||||
added the check for less than zero, but it should have also checked
|
||||
for greater than NR_syscalls.
|
||||
|
||||
Link: http://lkml.kernel.org/p/1414620418-29472-1-git-send-email-rabin@rab.in
|
||||
|
||||
Fixes: cd0980fc8add "tracing: Check invalid syscall nr while tracing syscalls"
|
||||
Signed-off-by: Rabin Vincent <rabin@rab.in>
|
||||
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
|
||||
[bwh: Backported to 3.2: adjust context]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
kernel/trace/trace_syscalls.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
|
||||
index 22a7c9b..1129062 100644
|
||||
--- a/kernel/trace/trace_syscalls.c
|
||||
+++ b/kernel/trace/trace_syscalls.c
|
||||
@@ -309,7 +309,7 @@ void ftrace_syscall_enter(void *ignore, struct pt_regs *regs, long id)
|
||||
int syscall_nr;
|
||||
|
||||
syscall_nr = syscall_get_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_enter_syscalls))
|
||||
return;
|
||||
@@ -349,7 +349,7 @@ void ftrace_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
|
||||
int syscall_nr;
|
||||
|
||||
syscall_nr = syscall_get_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_exit_syscalls))
|
||||
return;
|
||||
@@ -519,7 +519,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
|
||||
int size;
|
||||
|
||||
syscall_nr = syscall_get_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
|
||||
return;
|
||||
@@ -595,7 +595,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
|
||||
int size;
|
||||
|
||||
syscall_nr = syscall_get_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
|
||||
return;
|
||||
--
|
||||
cgit v1.1
|
||||
|
85
Patches/Linux_CVEs/CVE-2014-7825/2.patch
Normal file
85
Patches/Linux_CVEs/CVE-2014-7825/2.patch
Normal file
@ -0,0 +1,85 @@
|
||||
From 086ba77a6db00ed858ff07451bedee197df868c9 Mon Sep 17 00:00:00 2001
|
||||
From: Rabin Vincent <rabin@rab.in>
|
||||
Date: Wed, 29 Oct 2014 23:06:58 +0100
|
||||
Subject: [PATCH] tracing/syscalls: Ignore numbers outside NR_syscalls' range
|
||||
|
||||
ARM has some private syscalls (for example, set_tls(2)) which lie
|
||||
outside the range of NR_syscalls. If any of these are called while
|
||||
syscall tracing is being performed, out-of-bounds array access will
|
||||
occur in the ftrace and perf sys_{enter,exit} handlers.
|
||||
|
||||
# trace-cmd record -e raw_syscalls:* true && trace-cmd report
|
||||
...
|
||||
true-653 [000] 384.675777: sys_enter: NR 192 (0, 1000, 3, 4000022, ffffffff, 0)
|
||||
true-653 [000] 384.675812: sys_exit: NR 192 = 1995915264
|
||||
true-653 [000] 384.675971: sys_enter: NR 983045 (76f74480, 76f74000, 76f74b28, 76f74480, 76f76f74, 1)
|
||||
true-653 [000] 384.675988: sys_exit: NR 983045 = 0
|
||||
...
|
||||
|
||||
# trace-cmd record -e syscalls:* true
|
||||
[ 17.289329] Unable to handle kernel paging request at virtual address aaaaaace
|
||||
[ 17.289590] pgd = 9e71c000
|
||||
[ 17.289696] [aaaaaace] *pgd=00000000
|
||||
[ 17.289985] Internal error: Oops: 5 [#1] PREEMPT SMP ARM
|
||||
[ 17.290169] Modules linked in:
|
||||
[ 17.290391] CPU: 0 PID: 704 Comm: true Not tainted 3.18.0-rc2+ #21
|
||||
[ 17.290585] task: 9f4dab00 ti: 9e710000 task.ti: 9e710000
|
||||
[ 17.290747] PC is at ftrace_syscall_enter+0x48/0x1f8
|
||||
[ 17.290866] LR is at syscall_trace_enter+0x124/0x184
|
||||
|
||||
Fix this by ignoring out-of-NR_syscalls-bounds syscall numbers.
|
||||
|
||||
Commit cd0980fc8add "tracing: Check invalid syscall nr while tracing syscalls"
|
||||
added the check for less than zero, but it should have also checked
|
||||
for greater than NR_syscalls.
|
||||
|
||||
Link: http://lkml.kernel.org/p/1414620418-29472-1-git-send-email-rabin@rab.in
|
||||
|
||||
Fixes: cd0980fc8add "tracing: Check invalid syscall nr while tracing syscalls"
|
||||
Cc: stable@vger.kernel.org # 2.6.33+
|
||||
Signed-off-by: Rabin Vincent <rabin@rab.in>
|
||||
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
|
||||
---
|
||||
kernel/trace/trace_syscalls.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/kernel/trace/trace_syscalls.c b/kernel/trace/trace_syscalls.c
|
||||
index 4dc8b79c5f75d..29228c4d56969 100644
|
||||
--- a/kernel/trace/trace_syscalls.c
|
||||
+++ b/kernel/trace/trace_syscalls.c
|
||||
@@ -313,7 +313,7 @@ static void ftrace_syscall_enter(void *data, struct pt_regs *regs, long id)
|
||||
int size;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
|
||||
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE) */
|
||||
@@ -360,7 +360,7 @@ static void ftrace_syscall_exit(void *data, struct pt_regs *regs, long ret)
|
||||
int syscall_nr;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
|
||||
/* Here we're inside tp handler's rcu_read_lock_sched (__DO_TRACE()) */
|
||||
@@ -567,7 +567,7 @@ static void perf_syscall_enter(void *ignore, struct pt_regs *regs, long id)
|
||||
int size;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_enter_syscalls))
|
||||
return;
|
||||
@@ -641,7 +641,7 @@ static void perf_syscall_exit(void *ignore, struct pt_regs *regs, long ret)
|
||||
int size;
|
||||
|
||||
syscall_nr = trace_get_syscall_nr(current, regs);
|
||||
- if (syscall_nr < 0)
|
||||
+ if (syscall_nr < 0 || syscall_nr >= NR_syscalls)
|
||||
return;
|
||||
if (!test_bit(syscall_nr, enabled_perf_exit_syscalls))
|
||||
return;
|
47
Patches/Linux_CVEs/CVE-2014-7970/0.patch
Normal file
47
Patches/Linux_CVEs/CVE-2014-7970/0.patch
Normal file
@ -0,0 +1,47 @@
|
||||
From 0d0826019e529f21c84687521d03f60cd241ca7d Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Wed, 8 Oct 2014 10:42:27 -0700
|
||||
Subject: mnt: Prevent pivot_root from creating a loop in the mount tree
|
||||
|
||||
Andy Lutomirski recently demonstrated that when chroot is used to set
|
||||
the root path below the path for the new ``root'' passed to pivot_root
|
||||
the pivot_root system call succeeds and leaks mounts.
|
||||
|
||||
In examining the code I see that starting with a new root that is
|
||||
below the current root in the mount tree will result in a loop in the
|
||||
mount tree after the mounts are detached and then reattached to one
|
||||
another. Resulting in all kinds of ugliness including a leak of that
|
||||
mounts involved in the leak of the mount loop.
|
||||
|
||||
Prevent this problem by ensuring that the new mount is reachable from
|
||||
the current root of the mount tree.
|
||||
|
||||
[Added stable cc. Fixes CVE-2014-7970. --Andy]
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Link: http://lkml.kernel.org/r/87bnpmihks.fsf@x220.int.ebiederm.org
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
||||
---
|
||||
fs/namespace.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index ef42d9b..74647c2 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -2820,6 +2820,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||
/* make sure we can reach put_old from new_root */
|
||||
if (!is_path_reachable(old_mnt, old.dentry, &new))
|
||||
goto out4;
|
||||
+ /* make certain new is below the root */
|
||||
+ if (!is_path_reachable(new_mnt, new.dentry, &root))
|
||||
+ goto out4;
|
||||
root_mp->m_count++; /* pin it so it won't go away */
|
||||
lock_mount_hash();
|
||||
detach_mnt(new_mnt, &parent_path);
|
||||
--
|
||||
cgit v1.1
|
||||
|
54
Patches/Linux_CVEs/CVE-2014-7970/1.patch
Normal file
54
Patches/Linux_CVEs/CVE-2014-7970/1.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From c88f7bbd8026761a615c9969d186ffa2a1a3da3c Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Thu, 15 Jan 2015 17:49:27 +0000
|
||||
Subject: [PATCH] mnt: Prevent pivot_root from creating a loop in the mount
|
||||
tree
|
||||
|
||||
Andy Lutomirski recently demonstrated that when chroot is used to set
|
||||
the root path below the path for the new ``root'' passed to pivot_root
|
||||
the pivot_root system call succeeds and leaks mounts.
|
||||
|
||||
In examining the code I see that starting with a new root that is
|
||||
below the current root in the mount tree will result in a loop in the
|
||||
mount tree after the mounts are detached and then reattached to one
|
||||
another. Resulting in all kinds of ugliness including a leak of that
|
||||
mounts involved in the leak of the mount loop.
|
||||
|
||||
Prevent this problem by ensuring that the new mount is reachable from
|
||||
the current root of the mount tree.
|
||||
|
||||
[Added stable cc. Fixes CVE-2014-7970. --Andy]
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Reported-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Link: http://lkml.kernel.org/r/87bnpmihks.fsf@x220.int.ebiederm.org
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
||||
(backported from commit 0d0826019e529f21c84687521d03f60cd241ca7d)
|
||||
CVE-2014-7970
|
||||
BugLink: http://bugs.launchpad.net/bugs/1383356
|
||||
Signed-off-by: Luis Henriques <luis.henriques@canonical.com>
|
||||
Acked-by: Stefan Bader <stefan.bader@canonical.com>
|
||||
Acked-by: Andy Whitcroft <apw@canonical.com>
|
||||
Signed-off-by: Andy Whitcroft <apw@canonical.com>
|
||||
|
||||
Change-Id: I0fe1d090eeb4765cc49401784e44a430f9585498
|
||||
---
|
||||
fs/namespace.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index 912d273d970..4f47629a4e0 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -2618,6 +2618,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||
goto out4;
|
||||
} else if (!is_subdir(old.dentry, new.dentry))
|
||||
goto out4;
|
||||
+ /* make certain new is below the root */
|
||||
+ if (!is_path_reachable(new.mnt, new.dentry, &root))
|
||||
+ goto out4;
|
||||
br_write_lock(vfsmount_lock);
|
||||
detach_mnt(new.mnt, &parent_path);
|
||||
detach_mnt(root.mnt, &root_parent);
|
50
Patches/Linux_CVEs/CVE-2014-7970/2.patch
Normal file
50
Patches/Linux_CVEs/CVE-2014-7970/2.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 9f7d53c09a1f87ebe228b55a83c1b8f952d76260 Mon Sep 17 00:00:00 2001
|
||||
From: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Date: Wed, 8 Oct 2014 10:42:27 -0700
|
||||
Subject: mnt: Prevent pivot_root from creating a loop in the mount tree
|
||||
|
||||
commit 0d0826019e529f21c84687521d03f60cd241ca7d upstream.
|
||||
|
||||
Andy Lutomirski recently demonstrated that when chroot is used to set
|
||||
the root path below the path for the new ``root'' passed to pivot_root
|
||||
the pivot_root system call succeeds and leaks mounts.
|
||||
|
||||
In examining the code I see that starting with a new root that is
|
||||
below the current root in the mount tree will result in a loop in the
|
||||
mount tree after the mounts are detached and then reattached to one
|
||||
another. Resulting in all kinds of ugliness including a leak of that
|
||||
mounts involved in the leak of the mount loop.
|
||||
|
||||
Prevent this problem by ensuring that the new mount is reachable from
|
||||
the current root of the mount tree.
|
||||
|
||||
[Added stable cc. Fixes CVE-2014-7970. --Andy]
|
||||
|
||||
Reported-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Reviewed-by: Andy Lutomirski <luto@amacapital.net>
|
||||
Link: http://lkml.kernel.org/r/87bnpmihks.fsf@x220.int.ebiederm.org
|
||||
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
|
||||
Signed-off-by: Andy Lutomirski <luto@amacapital.net>
|
||||
[lizf: Backported to 3.4: adjust context]
|
||||
Signed-off-by: Zefan Li <lizefan@huawei.com>
|
||||
---
|
||||
fs/namespace.c | 3 +++
|
||||
1 file changed, 3 insertions(+)
|
||||
|
||||
diff --git a/fs/namespace.c b/fs/namespace.c
|
||||
index f0f2e06..f7be8d9 100644
|
||||
--- a/fs/namespace.c
|
||||
+++ b/fs/namespace.c
|
||||
@@ -2508,6 +2508,9 @@ SYSCALL_DEFINE2(pivot_root, const char __user *, new_root,
|
||||
/* make sure we can reach put_old from new_root */
|
||||
if (!is_path_reachable(real_mount(old.mnt), old.dentry, &new))
|
||||
goto out4;
|
||||
+ /* make certain new is below the root */
|
||||
+ if (!is_path_reachable(new_mnt, new.dentry, &root))
|
||||
+ goto out4;
|
||||
br_write_lock(vfsmount_lock);
|
||||
detach_mnt(new_mnt, &parent_path);
|
||||
detach_mnt(root_mnt, &root_parent);
|
||||
--
|
||||
cgit v1.1
|
||||
|
88
Patches/Linux_CVEs/CVE-2014-8160/0.patch
Normal file
88
Patches/Linux_CVEs/CVE-2014-8160/0.patch
Normal file
@ -0,0 +1,88 @@
|
||||
From db29a9508a9246e77087c5531e45b2c88ec6988b Mon Sep 17 00:00:00 2001
|
||||
From: Florian Westphal <fw@strlen.de>
|
||||
Date: Fri, 26 Sep 2014 11:35:42 +0200
|
||||
Subject: [PATCH] netfilter: conntrack: disable generic tracking for known
|
||||
protocols
|
||||
|
||||
Given following iptables ruleset:
|
||||
|
||||
-P FORWARD DROP
|
||||
-A FORWARD -m sctp --dport 9 -j ACCEPT
|
||||
-A FORWARD -p tcp --dport 80 -j ACCEPT
|
||||
-A FORWARD -p tcp -m conntrack -m state ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
One would assume that this allows SCTP on port 9 and TCP on port 80.
|
||||
Unfortunately, if the SCTP conntrack module is not loaded, this allows
|
||||
*all* SCTP communication, to pass though, i.e. -p sctp -j ACCEPT,
|
||||
which we think is a security issue.
|
||||
|
||||
This is because on the first SCTP packet on port 9, we create a dummy
|
||||
"generic l4" conntrack entry without any port information (since
|
||||
conntrack doesn't know how to extract this information).
|
||||
|
||||
All subsequent packets that are unknown will then be in established
|
||||
state since they will fallback to proto_generic and will match the
|
||||
'generic' entry.
|
||||
|
||||
Our originally proposed version [1] completely disabled generic protocol
|
||||
tracking, but Jozsef suggests to not track protocols for which a more
|
||||
suitable helper is available, hence we now mitigate the issue for in
|
||||
tree known ct protocol helpers only, so that at least NAT and direction
|
||||
information will still be preserved for others.
|
||||
|
||||
[1] http://www.spinics.net/lists/netfilter-devel/msg33430.html
|
||||
|
||||
Joint work with Daniel Borkmann.
|
||||
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
net/netfilter/nf_conntrack_proto_generic.c | 26 +++++++++++++++++++++++++-
|
||||
1 file changed, 25 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
|
||||
index d25f293776482..957c1db666525 100644
|
||||
--- a/net/netfilter/nf_conntrack_proto_generic.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_generic.c
|
||||
@@ -14,6 +14,30 @@
|
||||
|
||||
static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
|
||||
|
||||
+static bool nf_generic_should_process(u8 proto)
|
||||
+{
|
||||
+ switch (proto) {
|
||||
+#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE
|
||||
+ case IPPROTO_SCTP:
|
||||
+ return false;
|
||||
+#endif
|
||||
+#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE
|
||||
+ case IPPROTO_DCCP:
|
||||
+ return false;
|
||||
+#endif
|
||||
+#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE
|
||||
+ case IPPROTO_GRE:
|
||||
+ return false;
|
||||
+#endif
|
||||
+#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE
|
||||
+ case IPPROTO_UDPLITE:
|
||||
+ return false;
|
||||
+#endif
|
||||
+ default:
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static inline struct nf_generic_net *generic_pernet(struct net *net)
|
||||
{
|
||||
return &net->ct.nf_ct_proto.generic;
|
||||
@@ -67,7 +91,7 @@ static int generic_packet(struct nf_conn *ct,
|
||||
static bool generic_new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
unsigned int dataoff, unsigned int *timeouts)
|
||||
{
|
||||
- return true;
|
||||
+ return nf_generic_should_process(nf_ct_protonum(ct));
|
||||
}
|
||||
|
||||
#if IS_ENABLED(CONFIG_NF_CT_NETLINK_TIMEOUT)
|
94
Patches/Linux_CVEs/CVE-2014-8160/1.patch
Normal file
94
Patches/Linux_CVEs/CVE-2014-8160/1.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From d7cde286daad20dd171247ea47fc5ff4868591f0 Mon Sep 17 00:00:00 2001
|
||||
From: Florian Westphal <fw@strlen.de>
|
||||
Date: Fri, 26 Sep 2014 11:35:42 +0200
|
||||
Subject: netfilter: conntrack: disable generic tracking for known protocols
|
||||
|
||||
commit db29a9508a9246e77087c5531e45b2c88ec6988b upstream.
|
||||
|
||||
Given following iptables ruleset:
|
||||
|
||||
-P FORWARD DROP
|
||||
-A FORWARD -m sctp --dport 9 -j ACCEPT
|
||||
-A FORWARD -p tcp --dport 80 -j ACCEPT
|
||||
-A FORWARD -p tcp -m conntrack -m state ESTABLISHED,RELATED -j ACCEPT
|
||||
|
||||
One would assume that this allows SCTP on port 9 and TCP on port 80.
|
||||
Unfortunately, if the SCTP conntrack module is not loaded, this allows
|
||||
*all* SCTP communication, to pass though, i.e. -p sctp -j ACCEPT,
|
||||
which we think is a security issue.
|
||||
|
||||
This is because on the first SCTP packet on port 9, we create a dummy
|
||||
"generic l4" conntrack entry without any port information (since
|
||||
conntrack doesn't know how to extract this information).
|
||||
|
||||
All subsequent packets that are unknown will then be in established
|
||||
state since they will fallback to proto_generic and will match the
|
||||
'generic' entry.
|
||||
|
||||
Our originally proposed version [1] completely disabled generic protocol
|
||||
tracking, but Jozsef suggests to not track protocols for which a more
|
||||
suitable helper is available, hence we now mitigate the issue for in
|
||||
tree known ct protocol helpers only, so that at least NAT and direction
|
||||
information will still be preserved for others.
|
||||
|
||||
[1] http://www.spinics.net/lists/netfilter-devel/msg33430.html
|
||||
|
||||
Joint work with Daniel Borkmann.
|
||||
|
||||
Signed-off-by: Florian Westphal <fw@strlen.de>
|
||||
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
|
||||
Acked-by: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
[bwh: Backported to 3.2: adjust context]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/netfilter/nf_conntrack_proto_generic.c | 26 +++++++++++++++++++++++++-
|
||||
1 file changed, 25 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/netfilter/nf_conntrack_proto_generic.c b/net/netfilter/nf_conntrack_proto_generic.c
|
||||
index e2091d0..53bf12a 100644
|
||||
--- a/net/netfilter/nf_conntrack_proto_generic.c
|
||||
+++ b/net/netfilter/nf_conntrack_proto_generic.c
|
||||
@@ -14,6 +14,30 @@
|
||||
|
||||
static unsigned int nf_ct_generic_timeout __read_mostly = 600*HZ;
|
||||
|
||||
+static bool nf_generic_should_process(u8 proto)
|
||||
+{
|
||||
+ switch (proto) {
|
||||
+#ifdef CONFIG_NF_CT_PROTO_SCTP_MODULE
|
||||
+ case IPPROTO_SCTP:
|
||||
+ return false;
|
||||
+#endif
|
||||
+#ifdef CONFIG_NF_CT_PROTO_DCCP_MODULE
|
||||
+ case IPPROTO_DCCP:
|
||||
+ return false;
|
||||
+#endif
|
||||
+#ifdef CONFIG_NF_CT_PROTO_GRE_MODULE
|
||||
+ case IPPROTO_GRE:
|
||||
+ return false;
|
||||
+#endif
|
||||
+#ifdef CONFIG_NF_CT_PROTO_UDPLITE_MODULE
|
||||
+ case IPPROTO_UDPLITE:
|
||||
+ return false;
|
||||
+#endif
|
||||
+ default:
|
||||
+ return true;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static bool generic_pkt_to_tuple(const struct sk_buff *skb,
|
||||
unsigned int dataoff,
|
||||
struct nf_conntrack_tuple *tuple)
|
||||
@@ -56,7 +80,7 @@ static int packet(struct nf_conn *ct,
|
||||
static bool new(struct nf_conn *ct, const struct sk_buff *skb,
|
||||
unsigned int dataoff)
|
||||
{
|
||||
- return true;
|
||||
+ return nf_generic_should_process(nf_ct_protonum(ct));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_SYSCTL
|
||||
--
|
||||
cgit v1.1
|
||||
|
51
Patches/Linux_CVEs/CVE-2014-8173/0.patch
Normal file
51
Patches/Linux_CVEs/CVE-2014-8173/0.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From ee53664bda169f519ce3c6a22d378f0b946c8178 Mon Sep 17 00:00:00 2001
|
||||
From: "Kirill A. Shutemov" <kirill.shutemov@linux.intel.com>
|
||||
Date: Fri, 20 Dec 2013 15:10:03 +0200
|
||||
Subject: [PATCH] mm: Fix NULL pointer dereference in madvise(MADV_WILLNEED)
|
||||
support
|
||||
|
||||
Sasha Levin found a NULL pointer dereference that is due to a missing
|
||||
page table lock, which in turn is due to the pmd entry in question being
|
||||
a transparent huge-table entry.
|
||||
|
||||
The code - introduced in commit 1998cc048901 ("mm: make
|
||||
madvise(MADV_WILLNEED) support swap file prefetch") - correctly checks
|
||||
for this situation using pmd_none_or_trans_huge_or_clear_bad(), but it
|
||||
turns out that that function doesn't work correctly.
|
||||
|
||||
pmd_none_or_trans_huge_or_clear_bad() expected that pmd_bad() would
|
||||
trigger if the transparent hugepage bit was set, but it doesn't do that
|
||||
if pmd_numa() is also set. Note that the NUMA bit only gets set on real
|
||||
NUMA machines, so people trying to reproduce this on most normal
|
||||
development systems would never actually trigger this.
|
||||
|
||||
Fix it by removing the very subtle (and subtly incorrect) expectation,
|
||||
and instead just checking pmd_trans_huge() explicitly.
|
||||
|
||||
Reported-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Acked-by: Andrea Arcangeli <aarcange@redhat.com>
|
||||
[ Additionally remove the now stale test for pmd_trans_huge() inside the
|
||||
pmd_bad() case - Linus ]
|
||||
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
---
|
||||
include/asm-generic/pgtable.h | 5 ++---
|
||||
1 file changed, 2 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
|
||||
index b12079afbd5f2..db09234589409 100644
|
||||
--- a/include/asm-generic/pgtable.h
|
||||
+++ b/include/asm-generic/pgtable.h
|
||||
@@ -599,11 +599,10 @@ static inline int pmd_none_or_trans_huge_or_clear_bad(pmd_t *pmd)
|
||||
#ifdef CONFIG_TRANSPARENT_HUGEPAGE
|
||||
barrier();
|
||||
#endif
|
||||
- if (pmd_none(pmdval))
|
||||
+ if (pmd_none(pmdval) || pmd_trans_huge(pmdval))
|
||||
return 1;
|
||||
if (unlikely(pmd_bad(pmdval))) {
|
||||
- if (!pmd_trans_huge(pmdval))
|
||||
- pmd_clear_bad(pmd);
|
||||
+ pmd_clear_bad(pmd);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
53
Patches/Linux_CVEs/CVE-2014-8709/0.patch
Normal file
53
Patches/Linux_CVEs/CVE-2014-8709/0.patch
Normal file
@ -0,0 +1,53 @@
|
||||
From 338f977f4eb441e69bb9a46eaa0ac715c931a67f Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sat, 1 Feb 2014 00:16:23 +0100
|
||||
Subject: mac80211: fix fragmentation code, particularly for encryption
|
||||
|
||||
The "new" fragmentation code (since my rewrite almost 5 years ago)
|
||||
erroneously sets skb->len rather than using skb_trim() to adjust
|
||||
the length of the first fragment after copying out all the others.
|
||||
This leaves the skb tail pointer pointing to after where the data
|
||||
originally ended, and thus causes the encryption MIC to be written
|
||||
at that point, rather than where it belongs: immediately after the
|
||||
data.
|
||||
|
||||
The impact of this is that if software encryption is done, then
|
||||
a) encryption doesn't work for the first fragment, the connection
|
||||
becomes unusable as the first fragment will never be properly
|
||||
verified at the receiver, the MIC is practically guaranteed to
|
||||
be wrong
|
||||
b) we leak up to 8 bytes of plaintext (!) of the packet out into
|
||||
the air
|
||||
|
||||
This is only mitigated by the fact that many devices are capable
|
||||
of doing encryption in hardware, in which case this can't happen
|
||||
as the tail pointer is irrelevant in that case. Additionally,
|
||||
fragmentation is not used very frequently and would normally have
|
||||
to be configured manually.
|
||||
|
||||
Fix this by using skb_trim() properly.
|
||||
|
||||
Cc: stable@vger.kernel.org
|
||||
Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
|
||||
Reported-by: Jouni Malinen <j@w1.fi>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
---
|
||||
net/mac80211/tx.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index 27c990b..97a02d3 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -878,7 +878,7 @@ static int ieee80211_fragment(struct ieee80211_tx_data *tx,
|
||||
}
|
||||
|
||||
/* adjust first fragment's length */
|
||||
- skb->len = hdrlen + per_fragm;
|
||||
+ skb_trim(skb, hdrlen + per_fragm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
56
Patches/Linux_CVEs/CVE-2014-8709/1.patch
Normal file
56
Patches/Linux_CVEs/CVE-2014-8709/1.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From c7b18cdf1887e8ce91e04342cfd2d8fe1630be92 Mon Sep 17 00:00:00 2001
|
||||
From: Johannes Berg <johannes.berg@intel.com>
|
||||
Date: Sat, 1 Feb 2014 00:16:23 +0100
|
||||
Subject: mac80211: fix fragmentation code, particularly for encryption
|
||||
|
||||
commit 338f977f4eb441e69bb9a46eaa0ac715c931a67f upstream.
|
||||
|
||||
The "new" fragmentation code (since my rewrite almost 5 years ago)
|
||||
erroneously sets skb->len rather than using skb_trim() to adjust
|
||||
the length of the first fragment after copying out all the others.
|
||||
This leaves the skb tail pointer pointing to after where the data
|
||||
originally ended, and thus causes the encryption MIC to be written
|
||||
at that point, rather than where it belongs: immediately after the
|
||||
data.
|
||||
|
||||
The impact of this is that if software encryption is done, then
|
||||
a) encryption doesn't work for the first fragment, the connection
|
||||
becomes unusable as the first fragment will never be properly
|
||||
verified at the receiver, the MIC is practically guaranteed to
|
||||
be wrong
|
||||
b) we leak up to 8 bytes of plaintext (!) of the packet out into
|
||||
the air
|
||||
|
||||
This is only mitigated by the fact that many devices are capable
|
||||
of doing encryption in hardware, in which case this can't happen
|
||||
as the tail pointer is irrelevant in that case. Additionally,
|
||||
fragmentation is not used very frequently and would normally have
|
||||
to be configured manually.
|
||||
|
||||
Fix this by using skb_trim() properly.
|
||||
|
||||
Fixes: 2de8e0d999b8 ("mac80211: rewrite fragmentation")
|
||||
Reported-by: Jouni Malinen <j@w1.fi>
|
||||
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
|
||||
[bwh: Backported to 3.2: adjust context]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
net/mac80211/tx.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/net/mac80211/tx.c b/net/mac80211/tx.c
|
||||
index 4ff35bf..5186f8b 100644
|
||||
--- a/net/mac80211/tx.c
|
||||
+++ b/net/mac80211/tx.c
|
||||
@@ -884,7 +884,7 @@ static int ieee80211_fragment(struct ieee80211_local *local,
|
||||
pos += fraglen;
|
||||
}
|
||||
|
||||
- skb->len = hdrlen + per_fragm;
|
||||
+ skb_trim(skb, hdrlen + per_fragm);
|
||||
return 0;
|
||||
}
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
52
Patches/Linux_CVEs/CVE-2014-9420/0.patch
Normal file
52
Patches/Linux_CVEs/CVE-2014-9420/0.patch
Normal file
@ -0,0 +1,52 @@
|
||||
From f54e18f1b831c92f6512d2eedb224cd63d607d3d Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Mon, 15 Dec 2014 14:22:46 +0100
|
||||
Subject: [PATCH] isofs: Fix infinite looping over CE entries
|
||||
|
||||
Rock Ridge extensions define so called Continuation Entries (CE) which
|
||||
define where is further space with Rock Ridge data. Corrupted isofs
|
||||
image can contain arbitrarily long chain of these, including a one
|
||||
containing loop and thus causing kernel to end in an infinite loop when
|
||||
traversing these entries.
|
||||
|
||||
Limit the traversal to 32 entries which should be more than enough space
|
||||
to store all the Rock Ridge data.
|
||||
|
||||
Reported-by: P J P <ppandit@redhat.com>
|
||||
CC: stable@vger.kernel.org
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
---
|
||||
fs/isofs/rock.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
||||
index f488bbae541ac..bb63254ed8486 100644
|
||||
--- a/fs/isofs/rock.c
|
||||
+++ b/fs/isofs/rock.c
|
||||
@@ -30,6 +30,7 @@ struct rock_state {
|
||||
int cont_size;
|
||||
int cont_extent;
|
||||
int cont_offset;
|
||||
+ int cont_loops;
|
||||
struct inode *inode;
|
||||
};
|
||||
|
||||
@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
|
||||
rs->inode = inode;
|
||||
}
|
||||
|
||||
+/* Maximum number of Rock Ridge continuation entries */
|
||||
+#define RR_MAX_CE_ENTRIES 32
|
||||
+
|
||||
/*
|
||||
* Returns 0 if the caller should continue scanning, 1 if the scan must end
|
||||
* and -ve on error.
|
||||
@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs)
|
||||
goto out;
|
||||
}
|
||||
ret = -EIO;
|
||||
+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
|
||||
+ goto out;
|
||||
bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
|
||||
if (bh) {
|
||||
memcpy(rs->buffer, bh->b_data + rs->cont_offset,
|
57
Patches/Linux_CVEs/CVE-2014-9420/1.patch
Normal file
57
Patches/Linux_CVEs/CVE-2014-9420/1.patch
Normal file
@ -0,0 +1,57 @@
|
||||
From 212c4d33ca83e2144064fe9c2911607fbed5386f Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Mon, 15 Dec 2014 14:22:46 +0100
|
||||
Subject: isofs: Fix infinite looping over CE entries
|
||||
|
||||
commit f54e18f1b831c92f6512d2eedb224cd63d607d3d upstream.
|
||||
|
||||
Rock Ridge extensions define so called Continuation Entries (CE) which
|
||||
define where is further space with Rock Ridge data. Corrupted isofs
|
||||
image can contain arbitrarily long chain of these, including a one
|
||||
containing loop and thus causing kernel to end in an infinite loop when
|
||||
traversing these entries.
|
||||
|
||||
Limit the traversal to 32 entries which should be more than enough space
|
||||
to store all the Rock Ridge data.
|
||||
|
||||
Reported-by: P J P <ppandit@redhat.com>
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
fs/isofs/rock.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/fs/isofs/rock.c b/fs/isofs/rock.c
|
||||
index ee62cc0..26859de 100644
|
||||
--- a/fs/isofs/rock.c
|
||||
+++ b/fs/isofs/rock.c
|
||||
@@ -30,6 +30,7 @@ struct rock_state {
|
||||
int cont_size;
|
||||
int cont_extent;
|
||||
int cont_offset;
|
||||
+ int cont_loops;
|
||||
struct inode *inode;
|
||||
};
|
||||
|
||||
@@ -73,6 +74,9 @@ static void init_rock_state(struct rock_state *rs, struct inode *inode)
|
||||
rs->inode = inode;
|
||||
}
|
||||
|
||||
+/* Maximum number of Rock Ridge continuation entries */
|
||||
+#define RR_MAX_CE_ENTRIES 32
|
||||
+
|
||||
/*
|
||||
* Returns 0 if the caller should continue scanning, 1 if the scan must end
|
||||
* and -ve on error.
|
||||
@@ -105,6 +109,8 @@ static int rock_continue(struct rock_state *rs)
|
||||
goto out;
|
||||
}
|
||||
ret = -EIO;
|
||||
+ if (++rs->cont_loops >= RR_MAX_CE_ENTRIES)
|
||||
+ goto out;
|
||||
bh = sb_bread(rs->inode->i_sb, rs->cont_extent);
|
||||
if (bh) {
|
||||
memcpy(rs->buffer, bh->b_data + rs->cont_offset,
|
||||
--
|
||||
cgit v1.1
|
||||
|
44
Patches/Linux_CVEs/CVE-2014-9529/0.patch
Normal file
44
Patches/Linux_CVEs/CVE-2014-9529/0.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From a3a8784454692dd72e5d5d34dcdab17b4420e74c Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <sasha.levin@oracle.com>
|
||||
Date: Mon, 29 Dec 2014 09:39:01 -0500
|
||||
Subject: [PATCH] KEYS: close race between key lookup and freeing
|
||||
|
||||
When a key is being garbage collected, it's key->user would get put before
|
||||
the ->destroy() callback is called, where the key is removed from it's
|
||||
respective tracking structures.
|
||||
|
||||
This leaves a key hanging in a semi-invalid state which leaves a window open
|
||||
for a different task to try an access key->user. An example is
|
||||
find_keyring_by_name() which would dereference key->user for a key that is
|
||||
in the process of being garbage collected (where key->user was freed but
|
||||
->destroy() wasn't called yet - so it's still present in the linked list).
|
||||
|
||||
This would cause either a panic, or corrupt memory.
|
||||
|
||||
Fixes CVE-2014-9529.
|
||||
|
||||
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
---
|
||||
security/keys/gc.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/keys/gc.c b/security/keys/gc.c
|
||||
index 9609a7f0faea2..c7952375ac532 100644
|
||||
--- a/security/keys/gc.c
|
||||
+++ b/security/keys/gc.c
|
||||
@@ -148,12 +148,12 @@ static noinline void key_gc_unused_keys(struct list_head *keys)
|
||||
if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
|
||||
atomic_dec(&key->user->nikeys);
|
||||
|
||||
- key_user_put(key->user);
|
||||
-
|
||||
/* now throw away the key memory */
|
||||
if (key->type->destroy)
|
||||
key->type->destroy(key);
|
||||
|
||||
+ key_user_put(key->user);
|
||||
+
|
||||
kfree(key->description);
|
||||
|
||||
#ifdef KEY_DEBUGGING
|
51
Patches/Linux_CVEs/CVE-2014-9529/1.patch
Normal file
51
Patches/Linux_CVEs/CVE-2014-9529/1.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From dc4a2f40de419c01b538c87f6bdfc15d574d9f7e Mon Sep 17 00:00:00 2001
|
||||
From: Sasha Levin <sasha.levin@oracle.com>
|
||||
Date: Mon, 29 Dec 2014 09:39:01 -0500
|
||||
Subject: KEYS: close race between key lookup and freeing
|
||||
|
||||
commit a3a8784454692dd72e5d5d34dcdab17b4420e74c upstream.
|
||||
|
||||
When a key is being garbage collected, it's key->user would get put before
|
||||
the ->destroy() callback is called, where the key is removed from it's
|
||||
respective tracking structures.
|
||||
|
||||
This leaves a key hanging in a semi-invalid state which leaves a window open
|
||||
for a different task to try an access key->user. An example is
|
||||
find_keyring_by_name() which would dereference key->user for a key that is
|
||||
in the process of being garbage collected (where key->user was freed but
|
||||
->destroy() wasn't called yet - so it's still present in the linked list).
|
||||
|
||||
This would cause either a panic, or corrupt memory.
|
||||
|
||||
Fixes CVE-2014-9529.
|
||||
|
||||
Signed-off-by: Sasha Levin <sasha.levin@oracle.com>
|
||||
Signed-off-by: David Howells <dhowells@redhat.com>
|
||||
[bwh: Backported to 3.2: adjust indentation]
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
security/keys/gc.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/security/keys/gc.c b/security/keys/gc.c
|
||||
index bf4d8da..2e2395d 100644
|
||||
--- a/security/keys/gc.c
|
||||
+++ b/security/keys/gc.c
|
||||
@@ -186,12 +186,12 @@ static noinline void key_gc_unused_key(struct key *key)
|
||||
if (test_bit(KEY_FLAG_INSTANTIATED, &key->flags))
|
||||
atomic_dec(&key->user->nikeys);
|
||||
|
||||
- key_user_put(key->user);
|
||||
-
|
||||
/* now throw away the key memory */
|
||||
if (key->type->destroy)
|
||||
key->type->destroy(key);
|
||||
|
||||
+ key_user_put(key->user);
|
||||
+
|
||||
kfree(key->description);
|
||||
|
||||
#ifdef KEY_DEBUGGING
|
||||
--
|
||||
cgit v1.1
|
||||
|
32
Patches/Linux_CVEs/CVE-2014-9683/0.patch
Normal file
32
Patches/Linux_CVEs/CVE-2014-9683/0.patch
Normal file
@ -0,0 +1,32 @@
|
||||
From 942080643bce061c3dd9d5718d3b745dcb39a8bc Mon Sep 17 00:00:00 2001
|
||||
From: Michael Halcrow <mhalcrow@google.com>
|
||||
Date: Wed, 26 Nov 2014 09:09:16 -0800
|
||||
Subject: [PATCH] eCryptfs: Remove buggy and unnecessary write in file name
|
||||
decode routine
|
||||
|
||||
Dmitry Chernenkov used KASAN to discover that eCryptfs writes past the
|
||||
end of the allocated buffer during encrypted filename decoding. This
|
||||
fix corrects the issue by getting rid of the unnecessary 0 write when
|
||||
the current bit offset is 2.
|
||||
|
||||
Signed-off-by: Michael Halcrow <mhalcrow@google.com>
|
||||
Reported-by: Dmitry Chernenkov <dmitryc@google.com>
|
||||
Suggested-by: Kees Cook <keescook@chromium.org>
|
||||
Cc: stable@vger.kernel.org # v2.6.29+: 51ca58d eCryptfs: Filename Encryption: Encoding and encryption functions
|
||||
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
---
|
||||
fs/ecryptfs/crypto.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
|
||||
index 2f6735dbf1a9d..31b148f3e7729 100644
|
||||
--- a/fs/ecryptfs/crypto.c
|
||||
+++ b/fs/ecryptfs/crypto.c
|
||||
@@ -1917,7 +1917,6 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size,
|
||||
break;
|
||||
case 2:
|
||||
dst[dst_byte_offset++] |= (src_byte);
|
||||
- dst[dst_byte_offset] = 0;
|
||||
current_bit_offset = 0;
|
||||
break;
|
||||
}
|
37
Patches/Linux_CVEs/CVE-2014-9683/1.patch
Normal file
37
Patches/Linux_CVEs/CVE-2014-9683/1.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From f2d130454e46c3989af1b4f882b6a666d24fa2e0 Mon Sep 17 00:00:00 2001
|
||||
From: Michael Halcrow <mhalcrow@google.com>
|
||||
Date: Wed, 26 Nov 2014 09:09:16 -0800
|
||||
Subject: eCryptfs: Remove buggy and unnecessary write in file name decode
|
||||
routine
|
||||
|
||||
commit 942080643bce061c3dd9d5718d3b745dcb39a8bc upstream.
|
||||
|
||||
Dmitry Chernenkov used KASAN to discover that eCryptfs writes past the
|
||||
end of the allocated buffer during encrypted filename decoding. This
|
||||
fix corrects the issue by getting rid of the unnecessary 0 write when
|
||||
the current bit offset is 2.
|
||||
|
||||
Signed-off-by: Michael Halcrow <mhalcrow@google.com>
|
||||
Reported-by: Dmitry Chernenkov <dmitryc@google.com>
|
||||
Suggested-by: Kees Cook <keescook@chromium.org>
|
||||
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
fs/ecryptfs/crypto.c | 1 -
|
||||
1 file changed, 1 deletion(-)
|
||||
|
||||
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
|
||||
index 68b19ab..dceedec 100644
|
||||
--- a/fs/ecryptfs/crypto.c
|
||||
+++ b/fs/ecryptfs/crypto.c
|
||||
@@ -2038,7 +2038,6 @@ ecryptfs_decode_from_filename(unsigned char *dst, size_t *dst_size,
|
||||
break;
|
||||
case 2:
|
||||
dst[dst_byte_offset++] |= (src_byte);
|
||||
- dst[dst_byte_offset] = 0;
|
||||
current_bit_offset = 0;
|
||||
break;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
50
Patches/Linux_CVEs/CVE-2014-9715/0.patch
Normal file
50
Patches/Linux_CVEs/CVE-2014-9715/0.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From 223b02d923ecd7c84cf9780bb3686f455d279279 Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Vagin <avagin@openvz.org>
|
||||
Date: Fri, 28 Mar 2014 13:54:32 +0400
|
||||
Subject: [PATCH] netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len
|
||||
|
||||
"len" contains sizeof(nf_ct_ext) and size of extensions. In a worst
|
||||
case it can contain all extensions. Bellow you can find sizes for all
|
||||
types of extensions. Their sum is definitely bigger than 256.
|
||||
|
||||
nf_ct_ext_types[0]->len = 24
|
||||
nf_ct_ext_types[1]->len = 32
|
||||
nf_ct_ext_types[2]->len = 24
|
||||
nf_ct_ext_types[3]->len = 32
|
||||
nf_ct_ext_types[4]->len = 152
|
||||
nf_ct_ext_types[5]->len = 2
|
||||
nf_ct_ext_types[6]->len = 16
|
||||
nf_ct_ext_types[7]->len = 8
|
||||
|
||||
I have seen "len" up to 280 and my host has crashes w/o this patch.
|
||||
|
||||
The right way to fix this problem is reducing the size of the ecache
|
||||
extension (4) and Florian is going to do this, but these changes will
|
||||
be quite large to be appropriate for a stable tree.
|
||||
|
||||
Fixes: 5b423f6a40a0 (netfilter: nf_conntrack: fix racy timer handling with reliable)
|
||||
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Cc: Patrick McHardy <kaber@trash.net>
|
||||
Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
Cc: "David S. Miller" <davem@davemloft.net>
|
||||
Signed-off-by: Andrey Vagin <avagin@openvz.org>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
---
|
||||
include/net/netfilter/nf_conntrack_extend.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
|
||||
index 956b175523ffa..55d15049ab2fd 100644
|
||||
--- a/include/net/netfilter/nf_conntrack_extend.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_extend.h
|
||||
@@ -47,8 +47,8 @@ enum nf_ct_ext_id {
|
||||
/* Extensions: optional stuff which isn't permanently in struct. */
|
||||
struct nf_ct_ext {
|
||||
struct rcu_head rcu;
|
||||
- u8 offset[NF_CT_EXT_NUM];
|
||||
- u8 len;
|
||||
+ u16 offset[NF_CT_EXT_NUM];
|
||||
+ u16 len;
|
||||
char data[0];
|
||||
};
|
||||
|
56
Patches/Linux_CVEs/CVE-2014-9715/1.patch
Normal file
56
Patches/Linux_CVEs/CVE-2014-9715/1.patch
Normal file
@ -0,0 +1,56 @@
|
||||
From 33eedfe8ecbaabcdc38be63901cb2b79e3190fda Mon Sep 17 00:00:00 2001
|
||||
From: Andrey Vagin <avagin@openvz.org>
|
||||
Date: Fri, 28 Mar 2014 13:54:32 +0400
|
||||
Subject: netfilter: nf_conntrack: reserve two bytes for nf_ct_ext->len
|
||||
|
||||
commit 223b02d923ecd7c84cf9780bb3686f455d279279 upstream.
|
||||
|
||||
"len" contains sizeof(nf_ct_ext) and size of extensions. In a worst
|
||||
case it can contain all extensions. Bellow you can find sizes for all
|
||||
types of extensions. Their sum is definitely bigger than 256.
|
||||
|
||||
nf_ct_ext_types[0]->len = 24
|
||||
nf_ct_ext_types[1]->len = 32
|
||||
nf_ct_ext_types[2]->len = 24
|
||||
nf_ct_ext_types[3]->len = 32
|
||||
nf_ct_ext_types[4]->len = 152
|
||||
nf_ct_ext_types[5]->len = 2
|
||||
nf_ct_ext_types[6]->len = 16
|
||||
nf_ct_ext_types[7]->len = 8
|
||||
|
||||
I have seen "len" up to 280 and my host has crashes w/o this patch.
|
||||
|
||||
The right way to fix this problem is reducing the size of the ecache
|
||||
extension (4) and Florian is going to do this, but these changes will
|
||||
be quite large to be appropriate for a stable tree.
|
||||
|
||||
Fixes: 5b423f6a40a0 (netfilter: nf_conntrack: fix racy timer handling with reliable)
|
||||
Cc: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Cc: Patrick McHardy <kaber@trash.net>
|
||||
Cc: Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
|
||||
Cc: "David S. Miller" <davem@davemloft.net>
|
||||
Signed-off-by: Andrey Vagin <avagin@openvz.org>
|
||||
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
|
||||
Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
|
||||
---
|
||||
include/net/netfilter/nf_conntrack_extend.h | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/include/net/netfilter/nf_conntrack_extend.h b/include/net/netfilter/nf_conntrack_extend.h
|
||||
index 2dcf317..d918074 100644
|
||||
--- a/include/net/netfilter/nf_conntrack_extend.h
|
||||
+++ b/include/net/netfilter/nf_conntrack_extend.h
|
||||
@@ -33,8 +33,8 @@ enum nf_ct_ext_id {
|
||||
/* Extensions: optional stuff which isn't permanently in struct. */
|
||||
struct nf_ct_ext {
|
||||
struct rcu_head rcu;
|
||||
- u8 offset[NF_CT_EXT_NUM];
|
||||
- u8 len;
|
||||
+ u16 offset[NF_CT_EXT_NUM];
|
||||
+ u16 len;
|
||||
char data[0];
|
||||
};
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
236
Patches/Linux_CVEs/CVE-2014-9731/0.patch
Normal file
236
Patches/Linux_CVEs/CVE-2014-9731/0.patch
Normal file
@ -0,0 +1,236 @@
|
||||
From 0e5cc9a40ada6046e6bc3bdfcd0c0d7e4b706b14 Mon Sep 17 00:00:00 2001
|
||||
From: Jan Kara <jack@suse.cz>
|
||||
Date: Thu, 18 Dec 2014 22:37:50 +0100
|
||||
Subject: udf: Check path length when reading symlink
|
||||
|
||||
Symlink reading code does not check whether the resulting path fits into
|
||||
the page provided by the generic code. This isn't as easy as just
|
||||
checking the symlink size because of various encoding conversions we
|
||||
perform on path. So we have to check whether there is still enough space
|
||||
in the buffer on the fly.
|
||||
|
||||
CC: stable@vger.kernel.org
|
||||
Reported-by: Carl Henrik Lunde <chlunde@ping.uio.no>
|
||||
Signed-off-by: Jan Kara <jack@suse.cz>
|
||||
---
|
||||
fs/udf/dir.c | 3 ++-
|
||||
fs/udf/namei.c | 3 ++-
|
||||
fs/udf/symlink.c | 31 ++++++++++++++++++++++++++-----
|
||||
fs/udf/udfdecl.h | 3 ++-
|
||||
fs/udf/unicode.c | 28 ++++++++++++++++------------
|
||||
5 files changed, 48 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/fs/udf/dir.c b/fs/udf/dir.c
|
||||
index a012c51..a7690b4 100644
|
||||
--- a/fs/udf/dir.c
|
||||
+++ b/fs/udf/dir.c
|
||||
@@ -167,7 +167,8 @@ static int udf_readdir(struct file *file, struct dir_context *ctx)
|
||||
continue;
|
||||
}
|
||||
|
||||
- flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
|
||||
+ flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname,
|
||||
+ UDF_NAME_LEN);
|
||||
if (!flen)
|
||||
continue;
|
||||
|
||||
diff --git a/fs/udf/namei.c b/fs/udf/namei.c
|
||||
index c12e260..6ff19b5 100644
|
||||
--- a/fs/udf/namei.c
|
||||
+++ b/fs/udf/namei.c
|
||||
@@ -233,7 +233,8 @@ static struct fileIdentDesc *udf_find_entry(struct inode *dir,
|
||||
if (!lfi)
|
||||
continue;
|
||||
|
||||
- flen = udf_get_filename(dir->i_sb, nameptr, fname, lfi);
|
||||
+ flen = udf_get_filename(dir->i_sb, nameptr, lfi, fname,
|
||||
+ UDF_NAME_LEN);
|
||||
if (flen && udf_match(flen, fname, child->len, child->name))
|
||||
goto out_ok;
|
||||
}
|
||||
diff --git a/fs/udf/symlink.c b/fs/udf/symlink.c
|
||||
index c3aa6fa..0f1b3a2 100644
|
||||
--- a/fs/udf/symlink.c
|
||||
+++ b/fs/udf/symlink.c
|
||||
@@ -30,13 +30,16 @@
|
||||
#include <linux/buffer_head.h>
|
||||
#include "udf_i.h"
|
||||
|
||||
-static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
|
||||
- int fromlen, unsigned char *to)
|
||||
+static int udf_pc_to_char(struct super_block *sb, unsigned char *from,
|
||||
+ int fromlen, unsigned char *to, int tolen)
|
||||
{
|
||||
struct pathComponent *pc;
|
||||
int elen = 0;
|
||||
+ int comp_len;
|
||||
unsigned char *p = to;
|
||||
|
||||
+ /* Reserve one byte for terminating \0 */
|
||||
+ tolen--;
|
||||
while (elen < fromlen) {
|
||||
pc = (struct pathComponent *)(from + elen);
|
||||
switch (pc->componentType) {
|
||||
@@ -49,22 +52,37 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
|
||||
break;
|
||||
/* Fall through */
|
||||
case 2:
|
||||
+ if (tolen == 0)
|
||||
+ return -ENAMETOOLONG;
|
||||
p = to;
|
||||
*p++ = '/';
|
||||
+ tolen--;
|
||||
break;
|
||||
case 3:
|
||||
+ if (tolen < 3)
|
||||
+ return -ENAMETOOLONG;
|
||||
memcpy(p, "../", 3);
|
||||
p += 3;
|
||||
+ tolen -= 3;
|
||||
break;
|
||||
case 4:
|
||||
+ if (tolen < 2)
|
||||
+ return -ENAMETOOLONG;
|
||||
memcpy(p, "./", 2);
|
||||
p += 2;
|
||||
+ tolen -= 2;
|
||||
/* that would be . - just ignore */
|
||||
break;
|
||||
case 5:
|
||||
- p += udf_get_filename(sb, pc->componentIdent, p,
|
||||
- pc->lengthComponentIdent);
|
||||
+ comp_len = udf_get_filename(sb, pc->componentIdent,
|
||||
+ pc->lengthComponentIdent,
|
||||
+ p, tolen);
|
||||
+ p += comp_len;
|
||||
+ tolen -= comp_len;
|
||||
+ if (tolen == 0)
|
||||
+ return -ENAMETOOLONG;
|
||||
*p++ = '/';
|
||||
+ tolen--;
|
||||
break;
|
||||
}
|
||||
elen += sizeof(struct pathComponent) + pc->lengthComponentIdent;
|
||||
@@ -73,6 +91,7 @@ static void udf_pc_to_char(struct super_block *sb, unsigned char *from,
|
||||
p[-1] = '\0';
|
||||
else
|
||||
p[0] = '\0';
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
static int udf_symlink_filler(struct file *file, struct page *page)
|
||||
@@ -108,8 +127,10 @@ static int udf_symlink_filler(struct file *file, struct page *page)
|
||||
symlink = bh->b_data;
|
||||
}
|
||||
|
||||
- udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p);
|
||||
+ err = udf_pc_to_char(inode->i_sb, symlink, inode->i_size, p, PAGE_SIZE);
|
||||
brelse(bh);
|
||||
+ if (err)
|
||||
+ goto out_unlock_inode;
|
||||
|
||||
up_read(&iinfo->i_data_sem);
|
||||
SetPageUptodate(page);
|
||||
diff --git a/fs/udf/udfdecl.h b/fs/udf/udfdecl.h
|
||||
index 1cc3c99..47bb3f5 100644
|
||||
--- a/fs/udf/udfdecl.h
|
||||
+++ b/fs/udf/udfdecl.h
|
||||
@@ -211,7 +211,8 @@ udf_get_lb_pblock(struct super_block *sb, struct kernel_lb_addr *loc,
|
||||
}
|
||||
|
||||
/* unicode.c */
|
||||
-extern int udf_get_filename(struct super_block *, uint8_t *, uint8_t *, int);
|
||||
+extern int udf_get_filename(struct super_block *, uint8_t *, int, uint8_t *,
|
||||
+ int);
|
||||
extern int udf_put_filename(struct super_block *, const uint8_t *, uint8_t *,
|
||||
int);
|
||||
extern int udf_build_ustr(struct ustr *, dstring *, int);
|
||||
diff --git a/fs/udf/unicode.c b/fs/udf/unicode.c
|
||||
index afd470e..b84fee3 100644
|
||||
--- a/fs/udf/unicode.c
|
||||
+++ b/fs/udf/unicode.c
|
||||
@@ -28,7 +28,8 @@
|
||||
|
||||
#include "udf_sb.h"
|
||||
|
||||
-static int udf_translate_to_linux(uint8_t *, uint8_t *, int, uint8_t *, int);
|
||||
+static int udf_translate_to_linux(uint8_t *, int, uint8_t *, int, uint8_t *,
|
||||
+ int);
|
||||
|
||||
static int udf_char_to_ustr(struct ustr *dest, const uint8_t *src, int strlen)
|
||||
{
|
||||
@@ -333,8 +334,8 @@ try_again:
|
||||
return u_len + 1;
|
||||
}
|
||||
|
||||
-int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
|
||||
- int flen)
|
||||
+int udf_get_filename(struct super_block *sb, uint8_t *sname, int slen,
|
||||
+ uint8_t *dname, int dlen)
|
||||
{
|
||||
struct ustr *filename, *unifilename;
|
||||
int len = 0;
|
||||
@@ -347,7 +348,7 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
|
||||
if (!unifilename)
|
||||
goto out1;
|
||||
|
||||
- if (udf_build_ustr_exact(unifilename, sname, flen))
|
||||
+ if (udf_build_ustr_exact(unifilename, sname, slen))
|
||||
goto out2;
|
||||
|
||||
if (UDF_QUERY_FLAG(sb, UDF_FLAG_UTF8)) {
|
||||
@@ -366,7 +367,8 @@ int udf_get_filename(struct super_block *sb, uint8_t *sname, uint8_t *dname,
|
||||
} else
|
||||
goto out2;
|
||||
|
||||
- len = udf_translate_to_linux(dname, filename->u_name, filename->u_len,
|
||||
+ len = udf_translate_to_linux(dname, dlen,
|
||||
+ filename->u_name, filename->u_len,
|
||||
unifilename->u_name, unifilename->u_len);
|
||||
out2:
|
||||
kfree(unifilename);
|
||||
@@ -403,10 +405,12 @@ int udf_put_filename(struct super_block *sb, const uint8_t *sname,
|
||||
#define EXT_MARK '.'
|
||||
#define CRC_MARK '#'
|
||||
#define EXT_SIZE 5
|
||||
+/* Number of chars we need to store generated CRC to make filename unique */
|
||||
+#define CRC_LEN 5
|
||||
|
||||
-static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
|
||||
- int udfLen, uint8_t *fidName,
|
||||
- int fidNameLen)
|
||||
+static int udf_translate_to_linux(uint8_t *newName, int newLen,
|
||||
+ uint8_t *udfName, int udfLen,
|
||||
+ uint8_t *fidName, int fidNameLen)
|
||||
{
|
||||
int index, newIndex = 0, needsCRC = 0;
|
||||
int extIndex = 0, newExtIndex = 0, hasExt = 0;
|
||||
@@ -439,7 +443,7 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
|
||||
newExtIndex = newIndex;
|
||||
}
|
||||
}
|
||||
- if (newIndex < 256)
|
||||
+ if (newIndex < newLen)
|
||||
newName[newIndex++] = curr;
|
||||
else
|
||||
needsCRC = 1;
|
||||
@@ -467,13 +471,13 @@ static int udf_translate_to_linux(uint8_t *newName, uint8_t *udfName,
|
||||
}
|
||||
ext[localExtIndex++] = curr;
|
||||
}
|
||||
- maxFilenameLen = 250 - localExtIndex;
|
||||
+ maxFilenameLen = newLen - CRC_LEN - localExtIndex;
|
||||
if (newIndex > maxFilenameLen)
|
||||
newIndex = maxFilenameLen;
|
||||
else
|
||||
newIndex = newExtIndex;
|
||||
- } else if (newIndex > 250)
|
||||
- newIndex = 250;
|
||||
+ } else if (newIndex > newLen - CRC_LEN)
|
||||
+ newIndex = newLen - CRC_LEN;
|
||||
newName[newIndex++] = CRC_MARK;
|
||||
valueCRC = crc_itu_t(0, fidName, fidNameLen);
|
||||
newName[newIndex++] = hex_asc_upper_hi(valueCRC >> 8);
|
||||
--
|
||||
cgit v1.1
|
||||
|
48
Patches/Linux_CVEs/CVE-2014-9777/0.patch
Normal file
48
Patches/Linux_CVEs/CVE-2014-9777/0.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From af85054aa6a1bcd38be2354921f2f80aef1440e5 Mon Sep 17 00:00:00 2001
|
||||
From: "Pachika, Vikas Reddy" <vpachi@codeaurora.org>
|
||||
Date: Fri, 1 Nov 2013 21:06:37 +0530
|
||||
Subject: msm: vidc: Validate userspace buffer count
|
||||
|
||||
Makesure the number of buffers count is less than
|
||||
the maximum limit to avoid structure overflow errors.
|
||||
|
||||
Change-Id: Icf3850de36325637ae43ac95f1c8f0f63e201d31
|
||||
CRs-fixed: 563694
|
||||
Signed-off-by: Pachika, Vikas Reddy <vpachi@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/vidc/common/dec/vdec.c | 6 ++++++
|
||||
include/media/msm/vidc_init.h | 1 +
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
|
||||
index a843889..b45100f 100644
|
||||
--- a/drivers/video/msm/vidc/common/dec/vdec.c
|
||||
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
|
||||
@@ -1201,6 +1201,12 @@ static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx,
|
||||
vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd;
|
||||
vcd_h264_mv_buffer->offset = mv_data->offset;
|
||||
|
||||
+ if (mv_data->count > MAX_MV_BUFFERS) {
|
||||
+ ERR("MV buffers maximum count reached, count = %d",
|
||||
+ mv_data->count);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!vcd_get_ion_status()) {
|
||||
if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
|
||||
(unsigned long *) (&(vcd_h264_mv_buffer->
|
||||
diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h
|
||||
index c35f770..5df0c3e 100644
|
||||
--- a/include/media/msm/vidc_init.h
|
||||
+++ b/include/media/msm/vidc_init.h
|
||||
@@ -20,6 +20,7 @@
|
||||
#define VIDC_MAX_NUM_CLIENTS 4
|
||||
#define MAX_VIDEO_NUM_OF_BUFF 100
|
||||
#define MAX_META_BUFFERS 32
|
||||
+#define MAX_MV_BUFFERS 32
|
||||
|
||||
enum buffer_dir {
|
||||
BUFFER_TYPE_INPUT,
|
||||
--
|
||||
cgit v1.1
|
||||
|
48
Patches/Linux_CVEs/CVE-2014-9778/0.patch
Normal file
48
Patches/Linux_CVEs/CVE-2014-9778/0.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From af85054aa6a1bcd38be2354921f2f80aef1440e5 Mon Sep 17 00:00:00 2001
|
||||
From: "Pachika, Vikas Reddy" <vpachi@codeaurora.org>
|
||||
Date: Fri, 1 Nov 2013 21:06:37 +0530
|
||||
Subject: msm: vidc: Validate userspace buffer count
|
||||
|
||||
Makesure the number of buffers count is less than
|
||||
the maximum limit to avoid structure overflow errors.
|
||||
|
||||
Change-Id: Icf3850de36325637ae43ac95f1c8f0f63e201d31
|
||||
CRs-fixed: 563694
|
||||
Signed-off-by: Pachika, Vikas Reddy <vpachi@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/vidc/common/dec/vdec.c | 6 ++++++
|
||||
include/media/msm/vidc_init.h | 1 +
|
||||
2 files changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/video/msm/vidc/common/dec/vdec.c b/drivers/video/msm/vidc/common/dec/vdec.c
|
||||
index a843889..b45100f 100644
|
||||
--- a/drivers/video/msm/vidc/common/dec/vdec.c
|
||||
+++ b/drivers/video/msm/vidc/common/dec/vdec.c
|
||||
@@ -1201,6 +1201,12 @@ static u32 vid_dec_set_h264_mv_buffers(struct video_client_ctx *client_ctx,
|
||||
vcd_h264_mv_buffer->pmem_fd = mv_data->pmem_fd;
|
||||
vcd_h264_mv_buffer->offset = mv_data->offset;
|
||||
|
||||
+ if (mv_data->count > MAX_MV_BUFFERS) {
|
||||
+ ERR("MV buffers maximum count reached, count = %d",
|
||||
+ mv_data->count);
|
||||
+ return false;
|
||||
+ }
|
||||
+
|
||||
if (!vcd_get_ion_status()) {
|
||||
if (get_pmem_file(vcd_h264_mv_buffer->pmem_fd,
|
||||
(unsigned long *) (&(vcd_h264_mv_buffer->
|
||||
diff --git a/include/media/msm/vidc_init.h b/include/media/msm/vidc_init.h
|
||||
index c35f770..5df0c3e 100644
|
||||
--- a/include/media/msm/vidc_init.h
|
||||
+++ b/include/media/msm/vidc_init.h
|
||||
@@ -20,6 +20,7 @@
|
||||
#define VIDC_MAX_NUM_CLIENTS 4
|
||||
#define MAX_VIDEO_NUM_OF_BUFF 100
|
||||
#define MAX_META_BUFFERS 32
|
||||
+#define MAX_MV_BUFFERS 32
|
||||
|
||||
enum buffer_dir {
|
||||
BUFFER_TYPE_INPUT,
|
||||
--
|
||||
cgit v1.1
|
||||
|
30
Patches/Linux_CVEs/CVE-2014-9780/0.patch
Normal file
30
Patches/Linux_CVEs/CVE-2014-9780/0.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From b5bb13e1f738f90df11e0c17f843c73999a84a54 Mon Sep 17 00:00:00 2001
|
||||
From: Terence Hampson <thampson@codeaurora.org>
|
||||
Date: Thu, 19 Sep 2013 10:53:18 -0400
|
||||
Subject: mdss: mdp3: Validate input from userspace
|
||||
|
||||
Fully verify that the values from client are safe to use.
|
||||
|
||||
Change-Id: I73d6839f5bccd53b8bc2d812dc7673b13735299c
|
||||
Signed-off-by: Terence Hampson <thampson@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/mdss/mdp3_ctrl.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
|
||||
index ee51e92..1d6d437 100644
|
||||
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
|
||||
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
|
||||
@@ -1218,7 +1218,8 @@ static int mdp3_ctrl_lut_update(struct msm_fb_data_type *mfd,
|
||||
if (!mdp3_session->dma->config_lut)
|
||||
return -EINVAL;
|
||||
|
||||
- if (cmap->start + cmap->len > MDP_LUT_SIZE) {
|
||||
+ if (cmap->start > MDP_LUT_SIZE || cmap->len > MDP_LUT_SIZE ||
|
||||
+ (cmap->start + cmap->len > MDP_LUT_SIZE)) {
|
||||
pr_err("mdp3_ctrl_lut_update invalid arguments\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
37
Patches/Linux_CVEs/CVE-2014-9781/0.patch
Normal file
37
Patches/Linux_CVEs/CVE-2014-9781/0.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From a2b5237ad265ec634489c8b296d870827b2a1b13 Mon Sep 17 00:00:00 2001
|
||||
From: Shalabh Jain <shalabhj@codeaurora.org>
|
||||
Date: Tue, 12 Nov 2013 15:10:44 -0800
|
||||
Subject: fbcmap: prevent memory overflow
|
||||
|
||||
Add bounds check before copying data to prevent
|
||||
buffer overflow.
|
||||
|
||||
Change-Id: I47b9685b1ab13c4863fb6db62bbb9497a00b36da
|
||||
Signed-off-by: Shalabh Jain <shalabhj@codeaurora.org>
|
||||
---
|
||||
drivers/video/fbcmap.c | 6 ++++--
|
||||
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
|
||||
index 31e93a5..f26570d 100644
|
||||
--- a/drivers/video/fbcmap.c
|
||||
+++ b/drivers/video/fbcmap.c
|
||||
@@ -203,11 +203,13 @@ int fb_cmap_to_user(const struct fb_cmap *from, struct fb_cmap_user *to)
|
||||
fromoff = to->start - from->start;
|
||||
else
|
||||
tooff = from->start - to->start;
|
||||
+ if ((to->len <= tooff) || (from->len <= fromoff))
|
||||
+ return -EINVAL;
|
||||
+
|
||||
size = to->len - tooff;
|
||||
+
|
||||
if (size > (int) (from->len - fromoff))
|
||||
size = from->len - fromoff;
|
||||
- if (size <= 0)
|
||||
- return -EINVAL;
|
||||
size *= sizeof(u16);
|
||||
|
||||
if (from->red && to->red)
|
||||
--
|
||||
cgit v1.1
|
||||
|
135
Patches/Linux_CVEs/CVE-2014-9782/0.patch
Normal file
135
Patches/Linux_CVEs/CVE-2014-9782/0.patch
Normal file
@ -0,0 +1,135 @@
|
||||
From 2e57a46ab2ba7299d99d9cdc1382bd1e612963fb Mon Sep 17 00:00:00 2001
|
||||
From: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
Date: Wed, 24 Jul 2013 10:42:21 -0700
|
||||
Subject: msm: camera: Fix various small issues in Actuator driver
|
||||
|
||||
Bound check and validate userspace parameters direction,
|
||||
number of steps and direction sign. Also fix possible
|
||||
memory leak in certain error cases.
|
||||
|
||||
CRs-Fixed: 511349
|
||||
Change-Id: Icaa324468574494fb40f2de78e522090806744cb
|
||||
Signed-off-by: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
---
|
||||
.../msm/camera_v2/sensor/actuator/msm_actuator.c | 40 +++++++++++++++++++---
|
||||
include/media/msm_cam_sensor.h | 4 +++
|
||||
2 files changed, 40 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
index 87178b7..fe2c16f 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
@@ -245,6 +245,20 @@ static int32_t msm_actuator_move_focus(
|
||||
if (dest_step_pos == a_ctrl->curr_step_pos)
|
||||
return rc;
|
||||
|
||||
+ if ((sign_dir > MSM_ACTUATOR_MOVE_SIGNED_NEAR) ||
|
||||
+ (sign_dir < MSM_ACTUATOR_MOVE_SIGNED_FAR)) {
|
||||
+ pr_err("Invalid sign_dir = %d\n", sign_dir);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if ((dir > MOVE_FAR) || (dir < MOVE_NEAR)) {
|
||||
+ pr_err("Invalid direction = %d\n", dir);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if (dest_step_pos > a_ctrl->total_steps) {
|
||||
+ pr_err("Step pos greater than total steps = %d\n",
|
||||
+ dest_step_pos);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
curr_lens_pos = a_ctrl->step_position_table[a_ctrl->curr_step_pos];
|
||||
a_ctrl->i2c_tbl_index = 0;
|
||||
CDBG("curr_step_pos =%d dest_step_pos =%d curr_lens_pos=%d\n",
|
||||
@@ -318,6 +332,12 @@ static int32_t msm_actuator_init_step_table(struct msm_actuator_ctrl_t *a_ctrl,
|
||||
kfree(a_ctrl->step_position_table);
|
||||
a_ctrl->step_position_table = NULL;
|
||||
|
||||
+ if (set_info->af_tuning_params.total_steps
|
||||
+ > MAX_ACTUATOR_AF_TOTAL_STEPS) {
|
||||
+ pr_err("Max actuator totalsteps exceeded = %d\n",
|
||||
+ set_info->af_tuning_params.total_steps);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
/* Fill step position table */
|
||||
a_ctrl->step_position_table =
|
||||
kmalloc(sizeof(uint16_t) *
|
||||
@@ -409,12 +429,19 @@ static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
|
||||
pr_err("Actuator function table not found\n");
|
||||
return rc;
|
||||
}
|
||||
-
|
||||
- a_ctrl->region_size = set_info->af_tuning_params.region_size;
|
||||
- if (a_ctrl->region_size > MAX_ACTUATOR_REGION) {
|
||||
+ if (set_info->af_tuning_params.total_steps
|
||||
+ > MAX_ACTUATOR_AF_TOTAL_STEPS) {
|
||||
+ pr_err("Max actuator totalsteps exceeded = %d\n",
|
||||
+ set_info->af_tuning_params.total_steps);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+ if (set_info->af_tuning_params.region_size
|
||||
+ > MAX_ACTUATOR_REGION) {
|
||||
pr_err("MAX_ACTUATOR_REGION is exceeded.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
+
|
||||
+ a_ctrl->region_size = set_info->af_tuning_params.region_size;
|
||||
a_ctrl->pwd_step = set_info->af_tuning_params.pwd_step;
|
||||
a_ctrl->total_steps = set_info->af_tuning_params.total_steps;
|
||||
|
||||
@@ -461,7 +488,9 @@ static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
- if (set_info->actuator_params.init_setting_size) {
|
||||
+ if (set_info->actuator_params.init_setting_size &&
|
||||
+ set_info->actuator_params.init_setting_size
|
||||
+ <= MAX_ACTUATOR_REG_TBL_SIZE) {
|
||||
if (a_ctrl->func_tbl->actuator_init_focus) {
|
||||
init_settings = kmalloc(sizeof(struct reg_settings_t) *
|
||||
(set_info->actuator_params.init_setting_size),
|
||||
@@ -793,6 +822,7 @@ static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
|
||||
&pdev->id);
|
||||
CDBG("cell-index %d, rc %d\n", pdev->id, rc);
|
||||
if (rc < 0) {
|
||||
+ kfree(msm_actuator_t);
|
||||
pr_err("failed rc %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
@@ -801,6 +831,7 @@ static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
|
||||
&msm_actuator_t->cci_master);
|
||||
CDBG("qcom,cci-master %d, rc %d\n", msm_actuator_t->cci_master, rc);
|
||||
if (rc < 0) {
|
||||
+ kfree(msm_actuator_t);
|
||||
pr_err("failed rc %d\n", rc);
|
||||
return rc;
|
||||
}
|
||||
@@ -817,6 +848,7 @@ static int32_t msm_actuator_platform_probe(struct platform_device *pdev)
|
||||
msm_actuator_t->i2c_client.cci_client = kzalloc(sizeof(
|
||||
struct msm_camera_cci_client), GFP_KERNEL);
|
||||
if (!msm_actuator_t->i2c_client.cci_client) {
|
||||
+ kfree(msm_actuator_t);
|
||||
pr_err("failed no memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
|
||||
index 326e8bf..08a2025 100644
|
||||
--- a/include/media/msm_cam_sensor.h
|
||||
+++ b/include/media/msm_cam_sensor.h
|
||||
@@ -40,10 +40,14 @@
|
||||
#define MAX_ACTUATOR_REGION 5
|
||||
#define MAX_ACTUATOR_INIT_SET 12
|
||||
#define MAX_ACTUATOR_REG_TBL_SIZE 8
|
||||
+#define MAX_ACTUATOR_AF_TOTAL_STEPS 1024
|
||||
|
||||
#define MOVE_NEAR 0
|
||||
#define MOVE_FAR 1
|
||||
|
||||
+#define MSM_ACTUATOR_MOVE_SIGNED_FAR -1
|
||||
+#define MSM_ACTUATOR_MOVE_SIGNED_NEAR 1
|
||||
+
|
||||
#define MAX_EEPROM_NAME 32
|
||||
|
||||
#define MAX_AF_ITERATIONS 3
|
||||
--
|
||||
cgit v1.1
|
||||
|
218
Patches/Linux_CVEs/CVE-2014-9783/0.patch
Normal file
218
Patches/Linux_CVEs/CVE-2014-9783/0.patch
Normal file
@ -0,0 +1,218 @@
|
||||
From 2b1050b49a9a5f7bb57006648d145e001a3eaa8b Mon Sep 17 00:00:00 2001
|
||||
From: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
Date: Wed, 31 Jul 2013 14:30:36 -0700
|
||||
Subject: msm: camera: Fix various small issues in cci driver
|
||||
|
||||
Remove some unused ioctl exposed, Also add
|
||||
some bound checks for ioctl user params.
|
||||
|
||||
Change-Id: Ifdd441fdb25fd20b005c4e4e1ebe4e203f1216ac
|
||||
CRs-Fixed: 511382
|
||||
Signed-off-by: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
---
|
||||
.../platform/msm/camera_v2/sensor/cci/msm_cci.c | 101 +++++++++++++--------
|
||||
include/media/msm_cam_sensor.h | 2 +
|
||||
2 files changed, 63 insertions(+), 40 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
|
||||
index 7f4f231..6beb92e 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/cci/msm_cci.c
|
||||
@@ -41,6 +41,9 @@
|
||||
|
||||
/* Max bytes that can be read per CCI read transaction */
|
||||
#define CCI_READ_MAX 12
|
||||
+#define CCI_I2C_READ_MAX_RETRIES 3
|
||||
+#define CCI_I2C_MAX_READ 8192
|
||||
+#define CCI_I2C_MAX_WRITE 8192
|
||||
|
||||
static struct v4l2_subdev *g_cci_subdev;
|
||||
|
||||
@@ -87,36 +90,6 @@ static void msm_cci_set_clk_param(struct cci_device *cci_dev)
|
||||
return;
|
||||
}
|
||||
|
||||
-static int32_t msm_cci_i2c_config_sync_timer(struct v4l2_subdev *sd,
|
||||
- struct msm_camera_cci_ctrl *c_ctrl)
|
||||
-{
|
||||
- struct cci_device *cci_dev;
|
||||
- cci_dev = v4l2_get_subdevdata(sd);
|
||||
- msm_camera_io_w(c_ctrl->cci_info->cid, cci_dev->base +
|
||||
- CCI_SET_CID_SYNC_TIMER_0_ADDR + (c_ctrl->cci_info->cid * 0x4));
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
-static int32_t msm_cci_i2c_set_freq(struct v4l2_subdev *sd,
|
||||
- struct msm_camera_cci_ctrl *c_ctrl)
|
||||
-{
|
||||
- struct cci_device *cci_dev;
|
||||
- uint32_t val;
|
||||
- cci_dev = v4l2_get_subdevdata(sd);
|
||||
- val = c_ctrl->cci_info->freq;
|
||||
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SCL_CTL_ADDR +
|
||||
- c_ctrl->cci_info->cci_i2c_master*0x100);
|
||||
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_0_ADDR +
|
||||
- c_ctrl->cci_info->cci_i2c_master*0x100);
|
||||
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_1_ADDR +
|
||||
- c_ctrl->cci_info->cci_i2c_master*0x100);
|
||||
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_SDA_CTL_2_ADDR +
|
||||
- c_ctrl->cci_info->cci_i2c_master*0x100);
|
||||
- msm_camera_io_w(val, cci_dev->base + CCI_I2C_M0_MISC_CTL_ADDR +
|
||||
- c_ctrl->cci_info->cci_i2c_master*0x100);
|
||||
- return 0;
|
||||
-}
|
||||
-
|
||||
static void msm_cci_flush_queue(struct cci_device *cci_dev,
|
||||
enum cci_i2c_master_t master)
|
||||
{
|
||||
@@ -213,8 +186,29 @@ static int32_t msm_cci_data_queue(struct cci_device *cci_dev,
|
||||
uint16_t cmd_size = i2c_msg->size;
|
||||
struct msm_camera_i2c_reg_conf *i2c_cmd = i2c_msg->reg_conf_tbl;
|
||||
enum cci_i2c_master_t master = c_ctrl->cci_info->cci_i2c_master;
|
||||
+
|
||||
+ if (i2c_cmd == NULL) {
|
||||
+ pr_err("%s:%d Failed line\n", __func__,
|
||||
+ __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if ((!cmd_size) || (cmd_size > CCI_I2C_MAX_WRITE)) {
|
||||
+ pr_err("%s:%d Failed line\n", __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
CDBG("%s addr type %d data type %d\n", __func__,
|
||||
i2c_msg->addr_type, i2c_msg->data_type);
|
||||
+
|
||||
+ if (i2c_msg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
|
||||
+ pr_err("%s failed line %d\n", __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (i2c_msg->data_type >= MSM_CAMERA_I2C_DATA_TYPE_MAX) {
|
||||
+ pr_err("%s failed line %d\n", __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
/* assume total size within the max queue */
|
||||
while (cmd_size) {
|
||||
CDBG("%s cmd_size %d addr 0x%x data 0x%x", __func__,
|
||||
@@ -321,6 +315,18 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
+ if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
|
||||
+ pr_err("%s:%d More than max retries\n", __func__,
|
||||
+ __LINE__);
|
||||
+ goto ERROR;
|
||||
+ }
|
||||
+
|
||||
+ if (read_cfg->data == NULL) {
|
||||
+ pr_err("%s:%d Data ptr is NULL\n", __func__,
|
||||
+ __LINE__);
|
||||
+ goto ERROR;
|
||||
+ }
|
||||
+
|
||||
CDBG("%s master %d, queue %d\n", __func__, master, queue);
|
||||
CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
|
||||
c_ctrl->cci_info->sid, c_ctrl->cci_info->retries,
|
||||
@@ -341,6 +347,11 @@ static int32_t msm_cci_i2c_read(struct v4l2_subdev *sd,
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
+ if (read_cfg->addr_type >= MSM_CAMERA_I2C_ADDR_TYPE_MAX) {
|
||||
+ CDBG("%s failed line %d\n", __func__, __LINE__);
|
||||
+ goto ERROR;
|
||||
+ }
|
||||
+
|
||||
if (read_cfg->addr_type == MSM_CAMERA_I2C_BYTE_ADDR)
|
||||
val = CCI_I2C_WRITE_DISABLE_P_CMD | (read_cfg->addr_type << 4) |
|
||||
((read_cfg->addr & 0xFF) << 8);
|
||||
@@ -454,9 +465,14 @@ static int32_t msm_cci_i2c_read_bytes(struct v4l2_subdev *sd,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) {
|
||||
+ pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
master = c_ctrl->cci_info->cci_i2c_master;
|
||||
read_cfg = &c_ctrl->cfg.cci_i2c_read_cfg;
|
||||
- if (!read_cfg->num_byte) {
|
||||
+ if ((!read_cfg->num_byte) || (read_cfg->num_byte > CCI_I2C_MAX_READ)) {
|
||||
pr_err("%s:%d read num bytes 0\n", __func__, __LINE__);
|
||||
rc = -EINVAL;
|
||||
goto ERROR;
|
||||
@@ -494,6 +510,10 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
|
||||
enum cci_i2c_master_t master;
|
||||
enum cci_i2c_queue_t queue = QUEUE_0;
|
||||
cci_dev = v4l2_get_subdevdata(sd);
|
||||
+ if (c_ctrl->cci_info->cci_i2c_master > MASTER_MAX) {
|
||||
+ pr_err("%s:%d Invalid I2C master addr\n", __func__, __LINE__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
master = c_ctrl->cci_info->cci_i2c_master;
|
||||
CDBG("%s master %d, queue %d\n", __func__, master, queue);
|
||||
CDBG("%s set param sid 0x%x retries %d id_map %d\n", __func__,
|
||||
@@ -514,6 +534,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
|
||||
__LINE__, rc);
|
||||
goto ERROR;
|
||||
}
|
||||
+ if (c_ctrl->cci_info->retries > CCI_I2C_READ_MAX_RETRIES) {
|
||||
+ pr_err("%s:%d More than max retries\n", __func__,
|
||||
+ __LINE__);
|
||||
+ goto ERROR;
|
||||
+ }
|
||||
|
||||
val = CCI_I2C_SET_PARAM_CMD | c_ctrl->cci_info->sid << 4 |
|
||||
c_ctrl->cci_info->retries << 16 |
|
||||
@@ -533,7 +558,11 @@ static int32_t msm_cci_i2c_write(struct v4l2_subdev *sd,
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
- msm_cci_data_queue(cci_dev, c_ctrl, queue);
|
||||
+ rc = msm_cci_data_queue(cci_dev, c_ctrl, queue);
|
||||
+ if (rc < 0) {
|
||||
+ CDBG("%s failed line %d\n", __func__, __LINE__);
|
||||
+ goto ERROR;
|
||||
+ }
|
||||
val = CCI_I2C_UNLOCK_CMD;
|
||||
CDBG("%s:%d CCI_I2C_UNLOCK_CMD\n", __func__, __LINE__);
|
||||
rc = msm_cci_write_i2c_queue(cci_dev, val, master, queue);
|
||||
@@ -703,14 +732,6 @@ static int32_t msm_cci_config(struct v4l2_subdev *sd,
|
||||
case MSM_CCI_RELEASE:
|
||||
rc = msm_cci_release(sd);
|
||||
break;
|
||||
- case MSM_CCI_SET_SID:
|
||||
- break;
|
||||
- case MSM_CCI_SET_FREQ:
|
||||
- rc = msm_cci_i2c_set_freq(sd, cci_ctrl);
|
||||
- break;
|
||||
- case MSM_CCI_SET_SYNC_CID:
|
||||
- rc = msm_cci_i2c_config_sync_timer(sd, cci_ctrl);
|
||||
- break;
|
||||
case MSM_CCI_I2C_READ:
|
||||
rc = msm_cci_i2c_read_bytes(sd, cci_ctrl);
|
||||
break;
|
||||
diff --git a/include/media/msm_cam_sensor.h b/include/media/msm_cam_sensor.h
|
||||
index 2805401..da16bb8 100644
|
||||
--- a/include/media/msm_cam_sensor.h
|
||||
+++ b/include/media/msm_cam_sensor.h
|
||||
@@ -52,6 +52,7 @@ enum msm_camera_i2c_reg_addr_type {
|
||||
MSM_CAMERA_I2C_BYTE_ADDR = 1,
|
||||
MSM_CAMERA_I2C_WORD_ADDR,
|
||||
MSM_CAMERA_I2C_3B_ADDR,
|
||||
+ MSM_CAMERA_I2C_ADDR_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum msm_camera_i2c_data_type {
|
||||
@@ -62,6 +63,7 @@ enum msm_camera_i2c_data_type {
|
||||
MSM_CAMERA_I2C_SET_WORD_MASK,
|
||||
MSM_CAMERA_I2C_UNSET_WORD_MASK,
|
||||
MSM_CAMERA_I2C_SET_BYTE_WRITE_MASK_DATA,
|
||||
+ MSM_CAMERA_I2C_DATA_TYPE_MAX,
|
||||
};
|
||||
|
||||
enum msm_sensor_power_seq_type_t {
|
||||
--
|
||||
cgit v1.1
|
||||
|
203
Patches/Linux_CVEs/CVE-2014-9784/0.patch
Normal file
203
Patches/Linux_CVEs/CVE-2014-9784/0.patch
Normal file
@ -0,0 +1,203 @@
|
||||
From 36503d639cedcc73880974ed92132247576e72ba Mon Sep 17 00:00:00 2001
|
||||
From: Sreelakshmi Gownipalli <sgownipa@codeaurora.org>
|
||||
Date: Tue, 14 Jan 2014 16:54:46 -0800
|
||||
Subject: diag: Fix for diag debugfs buffer overflow
|
||||
|
||||
Diag debugfs buffer has potential buffer overflow scenario which can cause
|
||||
memory corruption. Added safeguard to prevent this.
|
||||
|
||||
Crs-fixed: 585147
|
||||
Change-Id: Ie1f099bb4bb626adff99ae225966aef70c1bc15e
|
||||
Signed-off-by: Sreelakshmi Gownipalli <sgownipa@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diag_debugfs.c | 44 +++++++++++++++++++++++++---------------
|
||||
1 file changed, 28 insertions(+), 16 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
|
||||
index d63d34b..96c0fa0 100644
|
||||
--- a/drivers/char/diag/diag_debugfs.c
|
||||
+++ b/drivers/char/diag/diag_debugfs.c
|
||||
@@ -1,4 +1,4 @@
|
||||
-/* Copyright (c) 2011-2013, The Linux Foundation. All rights reserved.
|
||||
+/* Copyright (c) 2011-2014, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
@@ -33,14 +33,14 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
|
||||
{
|
||||
char *buf;
|
||||
int ret;
|
||||
-
|
||||
+ unsigned int buf_size;
|
||||
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
pr_err("diag: %s, Error allocating memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
-
|
||||
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
|
||||
+ buf_size = ksize(buf);
|
||||
+ ret = scnprintf(buf, buf_size,
|
||||
"modem ch: 0x%p\n"
|
||||
"lpass ch: 0x%p\n"
|
||||
"riva ch: 0x%p\n"
|
||||
@@ -183,7 +183,7 @@ static ssize_t diag_dbgfs_read_status(struct file *file, char __user *ubuf,
|
||||
driver->real_time_mode);
|
||||
|
||||
#ifdef CONFIG_DIAG_OVER_USB
|
||||
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
|
||||
+ ret += scnprintf(buf+ret, buf_size-ret,
|
||||
"usb_connected: %d\n",
|
||||
driver->usb_connected);
|
||||
#endif
|
||||
@@ -200,7 +200,8 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
|
||||
unsigned int bytes_remaining, bytes_written = 0;
|
||||
unsigned int bytes_in_buf = 0, i = 0;
|
||||
struct diag_dci_data_info *temp_data = dci_data_smd;
|
||||
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
+ unsigned int buf_size;
|
||||
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
|
||||
if (diag_dbgfs_dci_finished) {
|
||||
diag_dbgfs_dci_finished = 0;
|
||||
@@ -213,6 +214,7 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ buf_size = ksize(buf);
|
||||
bytes_remaining = buf_size;
|
||||
|
||||
if (diag_dbgfs_dci_data_index == 0) {
|
||||
@@ -281,6 +283,7 @@ static ssize_t diag_dbgfs_read_workpending(struct file *file,
|
||||
{
|
||||
char *buf;
|
||||
int ret;
|
||||
+ unsigned int buf_size;
|
||||
|
||||
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
|
||||
if (!buf) {
|
||||
@@ -288,7 +291,8 @@ static ssize_t diag_dbgfs_read_workpending(struct file *file,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
|
||||
+ buf_size = ksize(buf);
|
||||
+ ret = scnprintf(buf, buf_size,
|
||||
"Pending status for work_stucts:\n"
|
||||
"diag_drain_work: %d\n"
|
||||
"Modem data diag_read_smd_work: %d\n"
|
||||
@@ -336,7 +340,7 @@ static ssize_t diag_dbgfs_read_workpending(struct file *file,
|
||||
diag_notify_update_smd_work)));
|
||||
|
||||
#ifdef CONFIG_DIAG_OVER_USB
|
||||
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE,
|
||||
+ ret += scnprintf(buf+ret, buf_size-ret,
|
||||
"diag_proc_hdlc_work: %d\n"
|
||||
"diag_read_work: %d\n",
|
||||
work_pending(&(driver->diag_proc_hdlc_work)),
|
||||
@@ -357,7 +361,8 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
|
||||
unsigned int bytes_remaining;
|
||||
unsigned int bytes_in_buffer = 0;
|
||||
unsigned int bytes_written;
|
||||
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
+ unsigned int buf_size;
|
||||
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
|
||||
if (diag_dbgfs_table_index >= diag_max_reg) {
|
||||
/* Done. Reset to prepare for future requests */
|
||||
@@ -370,7 +375,7 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
|
||||
pr_err("diag: %s, Error allocating memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
-
|
||||
+ buf_size = ksize(buf);
|
||||
bytes_remaining = buf_size;
|
||||
|
||||
if (diag_dbgfs_table_index == 0) {
|
||||
@@ -379,6 +384,7 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
|
||||
"WCNSS: %d, APPS: %d\n",
|
||||
MODEM_DATA, LPASS_DATA, WCNSS_DATA, APPS_DATA);
|
||||
bytes_in_buffer += bytes_written;
|
||||
+ bytes_remaining -= bytes_written;
|
||||
}
|
||||
|
||||
for (i = diag_dbgfs_table_index; i < diag_max_reg; i++) {
|
||||
@@ -422,14 +428,15 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
|
||||
{
|
||||
char *buf = NULL;
|
||||
int ret = 0, i = 0;
|
||||
-
|
||||
+ unsigned int buf_size;
|
||||
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
|
||||
if (ZERO_OR_NULL_PTR(buf)) {
|
||||
pr_err("diag: %s, Error allocating memory\n", __func__);
|
||||
return -ENOMEM;
|
||||
}
|
||||
+ buf_size = ksize(buf);
|
||||
|
||||
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
|
||||
+ ret = scnprintf(buf, buf_size,
|
||||
"POOL_TYPE_COPY: [0x%p : 0x%p] count = %d\n"
|
||||
"POOL_TYPE_HDLC: [0x%p : 0x%p] count = %d\n"
|
||||
"POOL_TYPE_USER: [0x%p : 0x%p] count = %d\n"
|
||||
@@ -454,7 +461,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
|
||||
for (i = 0; i < MAX_HSIC_CH; i++) {
|
||||
if (!diag_hsic[i].hsic_inited)
|
||||
continue;
|
||||
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
|
||||
+ ret += scnprintf(buf+ret, buf_size-ret,
|
||||
"POOL_TYPE_HSIC_%d: [0x%p : 0x%p] count = %d\n",
|
||||
i+1,
|
||||
diag_hsic[i].diag_hsic_pool,
|
||||
@@ -465,7 +472,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
|
||||
for (i = 0; i < MAX_HSIC_CH; i++) {
|
||||
if (!diag_hsic[i].hsic_inited)
|
||||
continue;
|
||||
- ret += scnprintf(buf+ret, DEBUG_BUF_SIZE-ret,
|
||||
+ ret += scnprintf(buf+ret, buf_size-ret,
|
||||
"POOL_TYPE_HSIC_%d_WRITE: [0x%p : 0x%p] count = %d\n",
|
||||
i+1,
|
||||
diag_hsic[i].diag_hsic_write_pool,
|
||||
@@ -484,6 +491,7 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
|
||||
{
|
||||
char *buf = NULL;
|
||||
int ret = 0;
|
||||
+ unsigned int buf_size;
|
||||
|
||||
buf = kzalloc(sizeof(char) * DEBUG_BUF_SIZE, GFP_KERNEL);
|
||||
if (ZERO_OR_NULL_PTR(buf)) {
|
||||
@@ -491,7 +499,8 @@ static ssize_t diag_dbgfs_read_mempool(struct file *file, char __user *ubuf,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
- ret = scnprintf(buf, DEBUG_BUF_SIZE,
|
||||
+ buf_size = ksize(buf);
|
||||
+ ret = scnprintf(buf, buf_size,
|
||||
"POOL_TYPE_COPY: [0x%p : 0x%p] count = %d\n"
|
||||
"POOL_TYPE_HDLC: [0x%p : 0x%p] count = %d\n"
|
||||
"POOL_TYPE_USER: [0x%p : 0x%p] count = %d\n"
|
||||
@@ -530,10 +539,12 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
|
||||
unsigned int bytes_remaining;
|
||||
unsigned int bytes_in_buffer = 0;
|
||||
unsigned int bytes_written;
|
||||
- int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
+ unsigned int buf_size;
|
||||
int bytes_hsic_inited = 45;
|
||||
int bytes_hsic_not_inited = 410;
|
||||
|
||||
+ buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
+
|
||||
if (diag_dbgfs_finished) {
|
||||
diag_dbgfs_finished = 0;
|
||||
return 0;
|
||||
@@ -545,6 +556,7 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
+ buf_size = ksize(buf);
|
||||
bytes_remaining = buf_size;
|
||||
|
||||
/* Only one smux for now */
|
||||
--
|
||||
cgit v1.1
|
||||
|
66
Patches/Linux_CVEs/CVE-2014-9785/0.patch
Normal file
66
Patches/Linux_CVEs/CVE-2014-9785/0.patch
Normal file
@ -0,0 +1,66 @@
|
||||
From b4338420db61f029ca6713a89c41b3a5852b20ce Mon Sep 17 00:00:00 2001
|
||||
From: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
|
||||
Date: Tue, 1 Oct 2013 18:25:21 -0700
|
||||
Subject: qseecom: Change __copy_from_user to copy_from_user
|
||||
|
||||
__copy_from_user does not do address check, so use
|
||||
copy_from_user instead.
|
||||
|
||||
Change-Id: I575c0f3c44b55a521c0d42828988c518c0640a29
|
||||
Signed-off-by: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 10 +++++-----
|
||||
1 file changed, 5 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 04fe140..8e9731f 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -431,7 +431,7 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data,
|
||||
uint32_t len;
|
||||
|
||||
/* Copy the relevant information needed for loading the image */
|
||||
- if (__copy_from_user(&req, (void __user *)argp, sizeof(req)))
|
||||
+ if (copy_from_user(&req, (void __user *)argp, sizeof(req)))
|
||||
return -EFAULT;
|
||||
|
||||
/* Get the handle of the shared fd */
|
||||
@@ -604,7 +604,7 @@ static int qseecom_load_app(struct qseecom_dev_handle *data, void __user *argp)
|
||||
struct qseecom_load_app_ireq load_req;
|
||||
|
||||
/* Copy the relevant information needed for loading the image */
|
||||
- if (__copy_from_user(&load_img_req,
|
||||
+ if (copy_from_user(&load_img_req,
|
||||
(void __user *)argp,
|
||||
sizeof(struct qseecom_load_img_req))) {
|
||||
pr_err("copy_from_user failed\n");
|
||||
@@ -875,7 +875,7 @@ static int qseecom_send_service_cmd(struct qseecom_dev_handle *data,
|
||||
struct qseecom_send_svc_cmd_req req;
|
||||
/*struct qseecom_command_scm_resp resp;*/
|
||||
|
||||
- if (__copy_from_user(&req,
|
||||
+ if (copy_from_user(&req,
|
||||
(void __user *)argp,
|
||||
sizeof(req))) {
|
||||
pr_err("copy_from_user failed\n");
|
||||
@@ -2086,7 +2086,7 @@ static int qseecom_load_external_elf(struct qseecom_dev_handle *data,
|
||||
struct qseecom_command_scm_resp resp;
|
||||
|
||||
/* Copy the relevant information needed for loading the image */
|
||||
- if (__copy_from_user(&load_img_req,
|
||||
+ if (copy_from_user(&load_img_req,
|
||||
(void __user *)argp,
|
||||
sizeof(struct qseecom_load_img_req))) {
|
||||
pr_err("copy_from_user failed\n");
|
||||
@@ -2248,7 +2248,7 @@ static int qseecom_query_app_loaded(struct qseecom_dev_handle *data,
|
||||
unsigned long flags = 0;
|
||||
|
||||
/* Copy the relevant information needed for loading the image */
|
||||
- if (__copy_from_user(&query_req,
|
||||
+ if (copy_from_user(&query_req,
|
||||
(void __user *)argp,
|
||||
sizeof(struct qseecom_qseos_app_load_query))) {
|
||||
pr_err("copy_from_user failed\n");
|
||||
--
|
||||
cgit v1.1
|
||||
|
48
Patches/Linux_CVEs/CVE-2014-9786/0.patch
Normal file
48
Patches/Linux_CVEs/CVE-2014-9786/0.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 2fb303d9c6ca080f253b10ed9384293ca69ad32b Mon Sep 17 00:00:00 2001
|
||||
From: Vasko Kalanoski <vaskok@codeaurora.org>
|
||||
Date: Tue, 8 Oct 2013 10:50:32 -0700
|
||||
Subject: msm: actuator: fix to prevent kernel heap buffer overflow
|
||||
|
||||
fix to prevent kernel heap buffer overflow allows user
|
||||
controlled data to be written to the heap via the
|
||||
msm_camera actuator IOCTLs
|
||||
|
||||
Change-Id: I4458831e28e0081fb2f5ae55506be866100e1b4f
|
||||
Signed-off-by: Vasko Kalanoski <vaskok@codeaurora.org>
|
||||
---
|
||||
.../platform/msm/camera_v2/sensor/actuator/msm_actuator.c | 12 ++++++++++--
|
||||
1 file changed, 10 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
index baa2db8..e605326 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
@@ -79,6 +79,11 @@ static void msm_actuator_parse_i2c_params(struct msm_actuator_ctrl_t *a_ctrl,
|
||||
struct msm_camera_i2c_reg_array *i2c_tbl = a_ctrl->i2c_reg_tbl;
|
||||
CDBG("Enter\n");
|
||||
for (i = 0; i < size; i++) {
|
||||
+ /* check that the index into i2c_tbl cannot grow larger that
|
||||
+ the allocated size of i2c_tbl */
|
||||
+ if ((a_ctrl->total_steps + 1) < (a_ctrl->i2c_tbl_index)) {
|
||||
+ break;
|
||||
+ }
|
||||
if (write_arr[i].reg_write_type == MSM_ACTUATOR_WRITE_DAC) {
|
||||
value = (next_lens_position <<
|
||||
write_arr[i].data_shift) |
|
||||
@@ -464,8 +469,11 @@ static int32_t msm_actuator_init(struct msm_actuator_ctrl_t *a_ctrl,
|
||||
|
||||
a_ctrl->i2c_data_type = set_info->actuator_params.i2c_data_type;
|
||||
a_ctrl->i2c_client.addr_type = set_info->actuator_params.i2c_addr_type;
|
||||
- a_ctrl->reg_tbl_size = set_info->actuator_params.reg_tbl_size;
|
||||
- if (a_ctrl->reg_tbl_size > MAX_ACTUATOR_REG_TBL_SIZE) {
|
||||
+ if (set_info->actuator_params.reg_tbl_size <=
|
||||
+ MAX_ACTUATOR_REG_TBL_SIZE) {
|
||||
+ a_ctrl->reg_tbl_size = set_info->actuator_params.reg_tbl_size;
|
||||
+ } else {
|
||||
+ a_ctrl->reg_tbl_size = 0;
|
||||
pr_err("MAX_ACTUATOR_REG_TBL_SIZE is exceeded.\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
43
Patches/Linux_CVEs/CVE-2014-9787/0.patch
Normal file
43
Patches/Linux_CVEs/CVE-2014-9787/0.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From 528400ae4cba715f6c9ff4a2657dafd913f30b8b Mon Sep 17 00:00:00 2001
|
||||
From: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
|
||||
Date: Thu, 3 Oct 2013 16:43:39 -0700
|
||||
Subject: qseecom: Validate the incoming length from user space
|
||||
|
||||
Check if there is no integer overflow before using req_len and
|
||||
resp_len (received from user space). If an overflow is detected
|
||||
then exit the operation.
|
||||
|
||||
Change-Id: I0459a6992bb3b280db42be63a275c55fa6105b1c
|
||||
Signed-off-by: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 7 ++++++-
|
||||
1 file changed, 6 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 58703cf..1452908 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -961,6 +961,11 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
+ if (req->cmd_req_len > UINT_MAX - req->resp_len) {
|
||||
+ pr_err("Integer overflow detected in req_len & rsp_len, exiting now\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
reqd_len_sb_in = req->cmd_req_len + req->resp_len;
|
||||
if (reqd_len_sb_in > data->client.sb_length) {
|
||||
pr_debug("Not enough memory to fit cmd_buf and "
|
||||
@@ -980,7 +985,7 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
|
||||
msm_ion_do_cache_op(qseecom.ion_clnt, data->client.ihandle,
|
||||
data->client.sb_virt,
|
||||
- (req->cmd_req_len + req->resp_len),
|
||||
+ reqd_len_sb_in,
|
||||
ION_IOC_CLEAN_INV_CACHES);
|
||||
|
||||
ret = scm_call(SCM_SVC_TZSCHEDULER, 1, (const void *) &send_data_req,
|
||||
--
|
||||
cgit v1.1
|
||||
|
194
Patches/Linux_CVEs/CVE-2014-9788/0.patch
Normal file
194
Patches/Linux_CVEs/CVE-2014-9788/0.patch
Normal file
@ -0,0 +1,194 @@
|
||||
From 73bfc22aa70cc0b7e6709381125a0a42aa72a4f2 Mon Sep 17 00:00:00 2001
|
||||
From: Shiv Maliyappanahalli <smaliyap@codeaurora.org>
|
||||
Date: Wed, 2 Oct 2013 17:00:30 -0700
|
||||
Subject: ASoC: msm: qdsp6v2: Fix buffer overflow in voice driver
|
||||
|
||||
Userspace registers calibration data with acdb driver
|
||||
through ioctls. Voice driver registers the calibration
|
||||
data with CVD by querying acdb data from acdb driver and
|
||||
copies the calibration data in apr message.
|
||||
|
||||
The size of the calibration data can be controlled by userspace
|
||||
and can result in buffer overflow if the calibration size is
|
||||
greater than the destination buffer size.
|
||||
|
||||
Reject acdb data if the size is greater than the size of
|
||||
destination buffer.
|
||||
|
||||
CRs-Fixed: 548872
|
||||
Change-Id: I4cd23a38c90b745226ddbc28656c82ff7c10432b
|
||||
Signed-off-by: Shiv Maliyappanahalli <smaliyap@codeaurora.org>
|
||||
---
|
||||
sound/soc/msm/qdsp6/q6voice.c | 9 ++++---
|
||||
sound/soc/msm/qdsp6v2/q6voice.c | 53 ++++++++++++++++++++++++++++++++++-------
|
||||
2 files changed, 50 insertions(+), 12 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/msm/qdsp6/q6voice.c b/sound/soc/msm/qdsp6/q6voice.c
|
||||
index 0e53c64..7294350 100644
|
||||
--- a/sound/soc/msm/qdsp6/q6voice.c
|
||||
+++ b/sound/soc/msm/qdsp6/q6voice.c
|
||||
@@ -1519,7 +1519,8 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
|
||||
|
||||
/* get the cvs cal data */
|
||||
get_all_vocstrm_cal(&cal_block);
|
||||
- if (cal_block.cal_size == 0)
|
||||
+ if (cal_block.cal_size == 0 ||
|
||||
+ cal_block.cal_size > CVS_CAL_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (v == NULL) {
|
||||
@@ -1928,7 +1929,8 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
|
||||
|
||||
/* get the cvp cal data */
|
||||
get_all_vocproc_cal(&cal_block);
|
||||
- if (cal_block.cal_size == 0)
|
||||
+ if (cal_block.cal_size == 0 ||
|
||||
+ cal_block.cal_size > CVP_CAL_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (v == NULL) {
|
||||
@@ -2063,7 +2065,8 @@ static int voice_send_cvp_register_vol_cal_table_cmd(struct voice_data *v)
|
||||
get_all_vocvol_cal(&vol_block);
|
||||
get_all_vocproc_cal(&voc_block);
|
||||
|
||||
- if (vol_block.cal_size == 0)
|
||||
+ if (vol_block.cal_size == 0 ||
|
||||
+ vol_block.cal_size > CVP_CAL_SIZE)
|
||||
goto fail;
|
||||
|
||||
if (v == NULL) {
|
||||
diff --git a/sound/soc/msm/qdsp6v2/q6voice.c b/sound/soc/msm/qdsp6v2/q6voice.c
|
||||
index 079cc4d..622fae1 100644
|
||||
--- a/sound/soc/msm/qdsp6v2/q6voice.c
|
||||
+++ b/sound/soc/msm/qdsp6v2/q6voice.c
|
||||
@@ -1955,20 +1955,22 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
|
||||
if (!common.apr_q6_cvs) {
|
||||
pr_err("%s: apr_cvs is NULL\n", __func__);
|
||||
|
||||
- ret = -EPERM;
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!common.cal_mem_handle) {
|
||||
pr_err("%s: Cal mem handle is NULL\n", __func__);
|
||||
- ret = -EPERM;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
get_vocstrm_cal(&cal_block);
|
||||
if (cal_block.cal_size == 0) {
|
||||
pr_err("%s: CVS cal size is 0\n", __func__);
|
||||
- ret = -EPERM;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1989,6 +1991,15 @@ static int voice_send_cvs_register_cal_cmd(struct voice_data *v)
|
||||
|
||||
/* Get the column info corresponding to CVS cal from ACDB. */
|
||||
get_voice_col_data(VOCSTRM_CAL, &cal_block);
|
||||
+ if (cal_block.cal_size == 0 ||
|
||||
+ cal_block.cal_size >
|
||||
+ sizeof(cvs_reg_cal_cmd.cvs_cal_data.column_info)) {
|
||||
+ pr_err("%s: Invalid VOCSTRM_CAL size %d\n",
|
||||
+ __func__, cal_block.cal_size);
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
memcpy(&cvs_reg_cal_cmd.cvs_cal_data.column_info[0],
|
||||
(void *) cal_block.cal_kvaddr,
|
||||
cal_block.cal_size);
|
||||
@@ -2227,20 +2238,22 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
|
||||
if (!common.apr_q6_cvp) {
|
||||
pr_err("%s: apr_cvp is NULL\n", __func__);
|
||||
|
||||
- ret = -EPERM;
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!common.cal_mem_handle) {
|
||||
pr_err("%s: Cal mem handle is NULL\n", __func__);
|
||||
- ret = -EPERM;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
get_vocproc_cal(&cal_block);
|
||||
if (cal_block.cal_size == 0) {
|
||||
pr_err("%s: CVP cal size is 0\n", __func__);
|
||||
- ret = -EPERM;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2261,6 +2274,16 @@ static int voice_send_cvp_register_cal_cmd(struct voice_data *v)
|
||||
|
||||
/* Get the column info corresponding to CVP cal from ACDB. */
|
||||
get_voice_col_data(VOCPROC_CAL, &cal_block);
|
||||
+ if (cal_block.cal_size == 0 ||
|
||||
+ cal_block.cal_size >
|
||||
+ sizeof(cvp_reg_cal_cmd.cvp_cal_data.column_info)) {
|
||||
+ pr_err("%s: Invalid VOCPROC_CAL size %d\n",
|
||||
+ __func__, cal_block.cal_size);
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
memcpy(&cvp_reg_cal_cmd.cvp_cal_data.column_info[0],
|
||||
(void *) cal_block.cal_kvaddr,
|
||||
cal_block.cal_size);
|
||||
@@ -2363,20 +2386,22 @@ static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
|
||||
if (!common.apr_q6_cvp) {
|
||||
pr_err("%s: apr_cvp is NULL\n", __func__);
|
||||
|
||||
- ret = -EPERM;
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
if (!common.cal_mem_handle) {
|
||||
pr_err("%s: Cal mem handle is NULL\n", __func__);
|
||||
- ret = -EPERM;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
get_vocvol_cal(&cal_block);
|
||||
if (cal_block.cal_size == 0) {
|
||||
pr_err("%s: CVP vol cal size is 0\n", __func__);
|
||||
- ret = -EPERM;
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -2399,6 +2424,16 @@ static int voice_send_cvp_register_vol_cal_cmd(struct voice_data *v)
|
||||
|
||||
/* Get the column info corresponding to CVP volume cal from ACDB. */
|
||||
get_voice_col_data(VOCVOL_CAL, &cal_block);
|
||||
+ if (cal_block.cal_size == 0 ||
|
||||
+ cal_block.cal_size >
|
||||
+ sizeof(cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info)) {
|
||||
+ pr_err("%s: Invalid VOCVOL_CAL size %d\n",
|
||||
+ __func__, cal_block.cal_size);
|
||||
+
|
||||
+ ret = -EINVAL;
|
||||
+ goto done;
|
||||
+ }
|
||||
+
|
||||
memcpy(&cvp_reg_vol_cal_cmd.cvp_vol_cal_data.column_info[0],
|
||||
(void *) cal_block.cal_kvaddr,
|
||||
cal_block.cal_size);
|
||||
--
|
||||
cgit v1.1
|
||||
|
105
Patches/Linux_CVEs/CVE-2014-9789/0.patch
Normal file
105
Patches/Linux_CVEs/CVE-2014-9789/0.patch
Normal file
@ -0,0 +1,105 @@
|
||||
From 5720ed5c3a786e3ba0a2428ac45da5d7ec996b4e Mon Sep 17 00:00:00 2001
|
||||
From: Gopikrishnaiah Anandan <agopik@codeaurora.org>
|
||||
Date: Fri, 16 Aug 2013 17:34:21 -0400
|
||||
Subject: Soc: msm: qdsp6v2: Fix invalid params handling
|
||||
|
||||
Alloc and free apis should sanity check all input params.
|
||||
If allocation fails set client and ion handle to NULL.
|
||||
|
||||
Change-Id: Ide3bd782eb90ee8b033e39de232929a1ca7174b7
|
||||
Signed-off-by: Gopikrishnaiah Anandan <agopik@codeaurora.org>
|
||||
---
|
||||
arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c | 30 +++++++++++++++++++++++++-----
|
||||
1 file changed, 25 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c b/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
|
||||
index 0c71659..f9e9d6d 100644
|
||||
--- a/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
|
||||
+++ b/arch/arm/mach-msm/qdsp6v2/msm_audio_ion.c
|
||||
@@ -53,7 +53,11 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client,
|
||||
pr_debug("%s:probe is not done, deferred\n", __func__);
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
-
|
||||
+ if (!name || !client || !handle || !paddr || !vaddr
|
||||
+ || !bufsz || !pa_len) {
|
||||
+ pr_err("%s: Invalid params\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
*client = msm_audio_ion_client_create(UINT_MAX, name);
|
||||
if (IS_ERR_OR_NULL((void *)(*client))) {
|
||||
pr_err("%s: ION create client for AUDIO failed\n", __func__);
|
||||
@@ -102,9 +106,9 @@ int msm_audio_ion_alloc(const char *name, struct ion_client **client,
|
||||
|
||||
err_ion_handle:
|
||||
ion_free(*client, *handle);
|
||||
- *handle = NULL;
|
||||
err_ion_client:
|
||||
msm_audio_ion_client_destroy(*client);
|
||||
+ *handle = NULL;
|
||||
*client = NULL;
|
||||
err:
|
||||
return -EINVAL;
|
||||
@@ -116,10 +120,17 @@ int msm_audio_ion_import(const char *name, struct ion_client **client,
|
||||
ion_phys_addr_t *paddr, size_t *pa_len, void **vaddr)
|
||||
{
|
||||
int rc = 0;
|
||||
+ if (!name || !client || !handle || !ionflag || !paddr || !vaddr
|
||||
+ || !bufsz || !pa_len) {
|
||||
+ pr_err("%s: Invalid params\n", __func__);
|
||||
+ rc = -EINVAL;
|
||||
+ goto err;
|
||||
+ }
|
||||
|
||||
*client = msm_audio_ion_client_create(UINT_MAX, name);
|
||||
if (IS_ERR_OR_NULL((void *)(*client))) {
|
||||
pr_err("%s: ION create client for AUDIO failed\n", __func__);
|
||||
+ rc = -EINVAL;
|
||||
goto err;
|
||||
}
|
||||
|
||||
@@ -132,8 +143,9 @@ int msm_audio_ion_import(const char *name, struct ion_client **client,
|
||||
if (IS_ERR_OR_NULL((void *) (*handle))) {
|
||||
pr_err("%s: ion import dma buffer failed\n",
|
||||
__func__);
|
||||
- goto err_ion_handle;
|
||||
- }
|
||||
+ rc = -EINVAL;
|
||||
+ goto err_destroy_client;
|
||||
+ }
|
||||
|
||||
if (ionflag != NULL) {
|
||||
rc = ion_handle_get_flags(*client, *handle, ionflag);
|
||||
@@ -154,6 +166,7 @@ int msm_audio_ion_import(const char *name, struct ion_client **client,
|
||||
*vaddr = ion_map_kernel(*client, *handle);
|
||||
if (IS_ERR_OR_NULL((void *)*vaddr)) {
|
||||
pr_err("%s: ION memory mapping for AUDIO failed\n", __func__);
|
||||
+ rc = -ENOMEM;
|
||||
goto err_ion_handle;
|
||||
}
|
||||
pr_debug("%s: mapped address = %p, size=%d\n", __func__, *vaddr, bufsz);
|
||||
@@ -162,13 +175,20 @@ int msm_audio_ion_import(const char *name, struct ion_client **client,
|
||||
|
||||
err_ion_handle:
|
||||
ion_free(*client, *handle);
|
||||
+err_destroy_client:
|
||||
msm_audio_ion_client_destroy(*client);
|
||||
+ *client = NULL;
|
||||
+ *handle = NULL;
|
||||
err:
|
||||
- return -EINVAL;
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
int msm_audio_ion_free(struct ion_client *client, struct ion_handle *handle)
|
||||
{
|
||||
+ if (!client || !handle) {
|
||||
+ pr_err("%s Invalid params\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
if (msm_audio_ion_data.smmu_enabled) {
|
||||
/* Need to populate book kept infomation */
|
||||
pr_debug("client=%p, domain=%p, domain_id=%d, group=%p",
|
||||
--
|
||||
cgit v1.1
|
||||
|
64
Patches/Linux_CVEs/CVE-2014-9790/0.patch
Normal file
64
Patches/Linux_CVEs/CVE-2014-9790/0.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 6ed921bda8cbb505e8654dfc1095185b0bccc38e Mon Sep 17 00:00:00 2001
|
||||
From: Raviv Shvili <rshvili@codeaurora.org>
|
||||
Date: Tue, 1 Oct 2013 17:18:29 +0300
|
||||
Subject: mmc: core : fix arbitrary read/write to user space
|
||||
|
||||
In the MMC card debug_fs the read and write handlers use the strlcat
|
||||
and sscanf, without checking the pointer given.
|
||||
Since the pointer is not checked it is possible to write
|
||||
everywhere (ring 0 or 3).
|
||||
In order to fix it, an access_ok function is being used to verify
|
||||
the buffer's pointer supplied by user is valid.
|
||||
|
||||
CRs-fixed: 545716
|
||||
Change-Id: Ia710b6af5a95974fc930ca902e8ff18afa4e17ba
|
||||
Signed-off-by: Raviv Shvili <rshvili@codeaurora.org>
|
||||
---
|
||||
drivers/mmc/core/debugfs.c | 10 ++++++++++
|
||||
1 file changed, 10 insertions(+)
|
||||
|
||||
diff --git a/drivers/mmc/core/debugfs.c b/drivers/mmc/core/debugfs.c
|
||||
index 903decf..9897f9f 100644
|
||||
--- a/drivers/mmc/core/debugfs.c
|
||||
+++ b/drivers/mmc/core/debugfs.c
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/stat.h>
|
||||
#include <linux/fault-inject.h>
|
||||
+#include <linux/uaccess.h>
|
||||
|
||||
#include <linux/mmc/card.h>
|
||||
#include <linux/mmc/host.h>
|
||||
@@ -392,6 +393,9 @@ static ssize_t mmc_wr_pack_stats_read(struct file *filp, char __user *ubuf,
|
||||
if (!card)
|
||||
return cnt;
|
||||
|
||||
+ if (!access_ok(VERIFY_WRITE, ubuf, cnt))
|
||||
+ return cnt;
|
||||
+
|
||||
if (!card->wr_pack_stats.print_in_read)
|
||||
return 0;
|
||||
|
||||
@@ -532,6 +536,9 @@ static ssize_t mmc_wr_pack_stats_write(struct file *filp,
|
||||
if (!card)
|
||||
return cnt;
|
||||
|
||||
+ if (!access_ok(VERIFY_READ, ubuf, cnt))
|
||||
+ return cnt;
|
||||
+
|
||||
sscanf(ubuf, "%d", &value);
|
||||
if (value) {
|
||||
mmc_blk_init_packed_statistics(card);
|
||||
@@ -571,6 +578,9 @@ static ssize_t mmc_bkops_stats_read(struct file *filp, char __user *ubuf,
|
||||
if (!card)
|
||||
return cnt;
|
||||
|
||||
+ if (!access_ok(VERIFY_WRITE, ubuf, cnt))
|
||||
+ return cnt;
|
||||
+
|
||||
bkops_stats = &card->bkops_info.bkops_stats;
|
||||
|
||||
if (!bkops_stats->print_stats)
|
||||
--
|
||||
cgit v1.1
|
||||
|
34
Patches/Linux_CVEs/CVE-2014-9792/0.patch
Normal file
34
Patches/Linux_CVEs/CVE-2014-9792/0.patch
Normal file
@ -0,0 +1,34 @@
|
||||
From a3e3dd9fc0a2699ae053ffd3efb52cdc73ad94cd Mon Sep 17 00:00:00 2001
|
||||
From: Zaheerulla Meer <zmeer@codeaurora.org>
|
||||
Date: Fri, 11 Oct 2013 18:18:35 +0530
|
||||
Subject: msm: ipc: Possible memory corruption due to Sign Conversion
|
||||
|
||||
msm_ipc_router_skb_to_buf() takes an unsigned argument and assigns the
|
||||
same to a signed local variable. This might cause issues when the value
|
||||
of the argument is too high.
|
||||
|
||||
Change the datatype of the local variable to unsigned.
|
||||
|
||||
CRs-Fixed: 550606
|
||||
Change-Id: I257a095681dd82fba05367fd6faf25820e95c719
|
||||
Signed-off-by: Zaheerulla Meer <zmeer@codeaurora.org>
|
||||
---
|
||||
arch/arm/mach-msm/ipc_router.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/arch/arm/mach-msm/ipc_router.c b/arch/arm/mach-msm/ipc_router.c
|
||||
index 9cdad6a1..cb9ad4c 100644
|
||||
--- a/arch/arm/mach-msm/ipc_router.c
|
||||
+++ b/arch/arm/mach-msm/ipc_router.c
|
||||
@@ -434,7 +434,7 @@ static void *msm_ipc_router_skb_to_buf(struct sk_buff_head *skb_head,
|
||||
unsigned int len)
|
||||
{
|
||||
struct sk_buff *temp;
|
||||
- int offset = 0, buf_len = 0, copy_len;
|
||||
+ unsigned int offset = 0, buf_len = 0, copy_len;
|
||||
void *buf;
|
||||
|
||||
if (!skb_head) {
|
||||
--
|
||||
cgit v1.1
|
||||
|
70
Patches/Linux_CVEs/CVE-2014-9803/0.patch
Normal file
70
Patches/Linux_CVEs/CVE-2014-9803/0.patch
Normal file
@ -0,0 +1,70 @@
|
||||
From 5a0fdfada3a2aa50d7b947a2e958bf00cbe0d830 Mon Sep 17 00:00:00 2001
|
||||
From: Catalin Marinas <catalin.marinas@arm.com>
|
||||
Date: Fri, 16 May 2014 16:44:32 +0100
|
||||
Subject: Revert "arm64: Introduce execute-only page access permissions"
|
||||
|
||||
This reverts commit bc07c2c6e9ed125d362af0214b6313dca180cb08.
|
||||
|
||||
While the aim is increased security for --x memory maps, it does not
|
||||
protect against kernel level reads. Until SECCOMP is implemented for
|
||||
arm64, revert this patch to avoid giving a false idea of execute-only
|
||||
mappings.
|
||||
|
||||
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
|
||||
---
|
||||
arch/arm64/include/asm/pgtable.h | 11 +++++------
|
||||
1 file changed, 5 insertions(+), 6 deletions(-)
|
||||
|
||||
(limited to 'arch/arm64/include/asm/pgtable.h')
|
||||
|
||||
diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgtable.h
|
||||
index e4c60d6..aa150ed 100644
|
||||
--- a/arch/arm64/include/asm/pgtable.h
|
||||
+++ b/arch/arm64/include/asm/pgtable.h
|
||||
@@ -86,13 +86,12 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
||||
#define PAGE_COPY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
|
||||
#define PAGE_READONLY __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN | PTE_UXN)
|
||||
#define PAGE_READONLY_EXEC __pgprot(_PAGE_DEFAULT | PTE_USER | PTE_NG | PTE_PXN)
|
||||
-#define PAGE_EXECONLY __pgprot(_PAGE_DEFAULT | PTE_NG | PTE_PXN)
|
||||
|
||||
#define __P000 PAGE_NONE
|
||||
#define __P001 PAGE_READONLY
|
||||
#define __P010 PAGE_COPY
|
||||
#define __P011 PAGE_COPY
|
||||
-#define __P100 PAGE_EXECONLY
|
||||
+#define __P100 PAGE_READONLY_EXEC
|
||||
#define __P101 PAGE_READONLY_EXEC
|
||||
#define __P110 PAGE_COPY_EXEC
|
||||
#define __P111 PAGE_COPY_EXEC
|
||||
@@ -101,7 +100,7 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
|
||||
#define __S001 PAGE_READONLY
|
||||
#define __S010 PAGE_SHARED
|
||||
#define __S011 PAGE_SHARED
|
||||
-#define __S100 PAGE_EXECONLY
|
||||
+#define __S100 PAGE_READONLY_EXEC
|
||||
#define __S101 PAGE_READONLY_EXEC
|
||||
#define __S110 PAGE_SHARED_EXEC
|
||||
#define __S111 PAGE_SHARED_EXEC
|
||||
@@ -137,8 +136,8 @@ extern struct page *empty_zero_page;
|
||||
#define pte_write(pte) (!!(pte_val(pte) & PTE_WRITE))
|
||||
#define pte_exec(pte) (!(pte_val(pte) & PTE_UXN))
|
||||
|
||||
-#define pte_valid_ng(pte) \
|
||||
- ((pte_val(pte) & (PTE_VALID | PTE_NG)) == (PTE_VALID | PTE_NG))
|
||||
+#define pte_valid_user(pte) \
|
||||
+ ((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER))
|
||||
|
||||
static inline pte_t pte_wrprotect(pte_t pte)
|
||||
{
|
||||
@@ -192,7 +191,7 @@ extern void __sync_icache_dcache(pte_t pteval, unsigned long addr);
|
||||
static inline void set_pte_at(struct mm_struct *mm, unsigned long addr,
|
||||
pte_t *ptep, pte_t pte)
|
||||
{
|
||||
- if (pte_valid_ng(pte)) {
|
||||
+ if (pte_valid_user(pte)) {
|
||||
if (!pte_special(pte) && pte_exec(pte))
|
||||
__sync_icache_dcache(pte, addr);
|
||||
if (pte_dirty(pte) && pte_write(pte))
|
||||
--
|
||||
cgit v1.1
|
||||
|
123
Patches/Linux_CVEs/CVE-2014-9863/0.patch
Normal file
123
Patches/Linux_CVEs/CVE-2014-9863/0.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From 75eac48a48562f819f50eeff8369b296d89102d7 Mon Sep 17 00:00:00 2001
|
||||
From: Katish Paran <kparan@codeaurora.org>
|
||||
Date: Tue, 24 Dec 2013 17:46:29 +0530
|
||||
Subject: diag: Safeguard for bound checks and integer underflow
|
||||
|
||||
At certain point in diag driver there can be integer underflow
|
||||
and thus can lead to memory leak. Bound checks are placed to
|
||||
ensure correct behavior of condition statements.
|
||||
|
||||
Change-Id: I47e02f764c2c7412db6f90fd42192fee32a761d3
|
||||
CRs-fixed: 549470
|
||||
Signed-off-by: Katish Paran <kparan@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diag_debugfs.c | 15 ++++++++-------
|
||||
drivers/char/diag/diagchar_core.c | 15 +++++++++++++--
|
||||
drivers/char/diag/diagchar_hdlc.c | 4 ++--
|
||||
3 files changed, 23 insertions(+), 11 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diag_debugfs.c b/drivers/char/diag/diag_debugfs.c
|
||||
index 4bbe948..d63d34b 100644
|
||||
--- a/drivers/char/diag/diag_debugfs.c
|
||||
+++ b/drivers/char/diag/diag_debugfs.c
|
||||
@@ -197,7 +197,8 @@ static ssize_t diag_dbgfs_read_dcistats(struct file *file,
|
||||
char __user *ubuf, size_t count, loff_t *ppos)
|
||||
{
|
||||
char *buf = NULL;
|
||||
- int bytes_remaining, bytes_written = 0, bytes_in_buf = 0, i = 0;
|
||||
+ unsigned int bytes_remaining, bytes_written = 0;
|
||||
+ unsigned int bytes_in_buf = 0, i = 0;
|
||||
struct diag_dci_data_info *temp_data = dci_data_smd;
|
||||
int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
|
||||
@@ -353,9 +354,9 @@ static ssize_t diag_dbgfs_read_table(struct file *file, char __user *ubuf,
|
||||
char *buf;
|
||||
int ret = 0;
|
||||
int i;
|
||||
- int bytes_remaining;
|
||||
- int bytes_in_buffer = 0;
|
||||
- int bytes_written;
|
||||
+ unsigned int bytes_remaining;
|
||||
+ unsigned int bytes_in_buffer = 0;
|
||||
+ unsigned int bytes_written;
|
||||
int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
|
||||
if (diag_dbgfs_table_index >= diag_max_reg) {
|
||||
@@ -526,9 +527,9 @@ static ssize_t diag_dbgfs_read_bridge(struct file *file, char __user *ubuf,
|
||||
char *buf;
|
||||
int ret;
|
||||
int i;
|
||||
- int bytes_remaining;
|
||||
- int bytes_in_buffer = 0;
|
||||
- int bytes_written;
|
||||
+ unsigned int bytes_remaining;
|
||||
+ unsigned int bytes_in_buffer = 0;
|
||||
+ unsigned int bytes_written;
|
||||
int buf_size = (DEBUG_BUF_SIZE < count) ? DEBUG_BUF_SIZE : count;
|
||||
int bytes_hsic_inited = 45;
|
||||
int bytes_hsic_not_inited = 410;
|
||||
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
|
||||
index 38ca47b..ab68902 100644
|
||||
--- a/drivers/char/diag/diagchar_core.c
|
||||
+++ b/drivers/char/diag/diagchar_core.c
|
||||
@@ -51,6 +51,7 @@ MODULE_DESCRIPTION("Diag Char Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_VERSION("1.0");
|
||||
|
||||
+#define MIN_SIZ_ALLOW 4
|
||||
#define INIT 1
|
||||
#define EXIT -1
|
||||
struct diagchar_dev *driver;
|
||||
@@ -1461,6 +1462,10 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
|
||||
index = 0;
|
||||
/* Get the packet type F3/log/event/Pkt response */
|
||||
err = copy_from_user((&pkt_type), buf, 4);
|
||||
+ if (err) {
|
||||
+ pr_alert("diag: copy failed for pkt_type\n");
|
||||
+ return -EAGAIN;
|
||||
+ }
|
||||
/* First 4 bytes indicate the type of payload - ignore these */
|
||||
if (count < 4) {
|
||||
pr_err("diag: Client sending short data\n");
|
||||
@@ -1504,8 +1509,9 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
|
||||
return err;
|
||||
}
|
||||
if (pkt_type == CALLBACK_DATA_TYPE) {
|
||||
- if (payload_size > driver->itemsize) {
|
||||
- pr_err("diag: Dropping packet, packet payload size crosses 4KB limit. Current payload size %d\n",
|
||||
+ if (payload_size > driver->itemsize ||
|
||||
+ payload_size <= MIN_SIZ_ALLOW) {
|
||||
+ pr_err("diag: Dropping packet, invalid packet size. Current payload size %d\n",
|
||||
payload_size);
|
||||
driver->dropped_count++;
|
||||
return -EBADMSG;
|
||||
@@ -1639,6 +1645,11 @@ static ssize_t diagchar_write(struct file *file, const char __user *buf,
|
||||
diag_get_remote(*(int *)driver->user_space_data_buf);
|
||||
|
||||
if (remote_proc) {
|
||||
+ if (payload_size <= MIN_SIZ_ALLOW) {
|
||||
+ pr_err("diag: Integer underflow in %s, payload size: %d",
|
||||
+ __func__, payload_size);
|
||||
+ return -EBADMSG;
|
||||
+ }
|
||||
token_offset = 4;
|
||||
payload_size -= 4;
|
||||
buf += 4;
|
||||
diff --git a/drivers/char/diag/diagchar_hdlc.c b/drivers/char/diag/diagchar_hdlc.c
|
||||
index d5ba452..39f1f44 100644
|
||||
--- a/drivers/char/diag/diagchar_hdlc.c
|
||||
+++ b/drivers/char/diag/diagchar_hdlc.c
|
||||
@@ -177,8 +177,8 @@ int diag_hdlc_decode(struct diag_hdlc_decode_type *hdlc)
|
||||
int msg_start;
|
||||
|
||||
if (hdlc && hdlc->src_ptr && hdlc->dest_ptr &&
|
||||
- (hdlc->src_size - hdlc->src_idx > 0) &&
|
||||
- (hdlc->dest_size - hdlc->dest_idx > 0)) {
|
||||
+ (hdlc->src_size > hdlc->src_idx) &&
|
||||
+ (hdlc->dest_size > hdlc->dest_idx)) {
|
||||
|
||||
msg_start = (hdlc->src_idx == 0) ? 1 : 0;
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
343
Patches/Linux_CVEs/CVE-2014-9864/0.patch
Normal file
343
Patches/Linux_CVEs/CVE-2014-9864/0.patch
Normal file
@ -0,0 +1,343 @@
|
||||
From a1124defc680055e2f2a8c8e3da4a94ca2ec842e Mon Sep 17 00:00:00 2001
|
||||
From: Mona Hossain <mhossain@codeaurora.org>
|
||||
Date: Tue, 1 Oct 2013 13:41:09 -0700
|
||||
Subject: qseecom: Add checks for API called in IOCTL
|
||||
|
||||
Validate the caller is the right type for the IOCTL being
|
||||
issued and inputs are valid.
|
||||
|
||||
Change-Id: Iad71f0f5ed4d53c5d011bd55cdf74ec053d09af5
|
||||
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
|
||||
Signed-off-by: Hariprasad Dhalinarasimha <hnamgund@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 165 +++++++++++++++++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 159 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 7cc1c9f..51f0228 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -434,6 +434,12 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data,
|
||||
if (copy_from_user(&req, (void __user *)argp, sizeof(req)))
|
||||
return -EFAULT;
|
||||
|
||||
+ if ((req.ifd_data_fd <= 0) || (req.virt_sb_base == 0) ||
|
||||
+ (req.sb_len == 0)) {
|
||||
+ pr_err("Inavlid input(s)ion_fd(%d), sb_len(%d), vaddr(0x%x)\n",
|
||||
+ req.ifd_data_fd, req.sb_len, req.virt_sb_base);
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
/* Get the handle of the shared fd */
|
||||
data->client.ihandle = ion_import_dma_buf(qseecom.ion_clnt,
|
||||
req.ifd_data_fd);
|
||||
@@ -2680,6 +2686,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
|
||||
switch (cmd) {
|
||||
case QSEECOM_IOCTL_REGISTER_LISTENER_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("reg lstnr req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
pr_debug("ioctl register_listener_req()\n");
|
||||
atomic_inc(&data->ioctl_count);
|
||||
data->type = QSEECOM_LISTENER_SERVICE;
|
||||
@@ -2691,6 +2703,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_UNREGISTER_LISTENER_REQ: {
|
||||
+ if ((data->listener.id == 0) ||
|
||||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
|
||||
+ pr_err("unreg lstnr req: invalid handle (%d) lid(%d)\n",
|
||||
+ data->type, data->listener.id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
pr_debug("ioctl unregister_listener_req()\n");
|
||||
atomic_inc(&data->ioctl_count);
|
||||
ret = qseecom_unregister_listener(data);
|
||||
@@ -2701,6 +2720,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SEND_CMD_REQ: {
|
||||
+ if ((data->client.app_id == 0) ||
|
||||
+ (data->type != QSEECOM_CLIENT_APP)) {
|
||||
+ pr_err("send cmd req: invalid handle (%d) app_id(%d)\n",
|
||||
+ data->type, data->client.app_id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
/* Only one client allowed here at a time */
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
@@ -2713,6 +2739,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SEND_MODFD_CMD_REQ: {
|
||||
+ if ((data->client.app_id == 0) ||
|
||||
+ (data->type != QSEECOM_CLIENT_APP)) {
|
||||
+ pr_err("send mdfd cmd: invalid handle (%d) appid(%d)\n",
|
||||
+ data->type, data->client.app_id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
/* Only one client allowed here at a time */
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
@@ -2725,6 +2758,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_RECEIVE_REQ: {
|
||||
+ if ((data->listener.id == 0) ||
|
||||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
|
||||
+ pr_err("receive req: invalid handle (%d), lid(%d)\n",
|
||||
+ data->type, data->listener.id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
atomic_inc(&data->ioctl_count);
|
||||
ret = qseecom_receive_req(data);
|
||||
atomic_dec(&data->ioctl_count);
|
||||
@@ -2734,6 +2774,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SEND_RESP_REQ: {
|
||||
+ if ((data->listener.id == 0) ||
|
||||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
|
||||
+ pr_err("send resp req: invalid handle (%d), lid(%d)\n",
|
||||
+ data->type, data->listener.id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
atomic_inc(&data->ioctl_count);
|
||||
ret = qseecom_send_resp();
|
||||
atomic_dec(&data->ioctl_count);
|
||||
@@ -2743,7 +2790,14 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SET_MEM_PARAM_REQ: {
|
||||
- data->type = QSEECOM_CLIENT_APP;
|
||||
+ if ((data->type != QSEECOM_CLIENT_APP) &&
|
||||
+ (data->type != QSEECOM_GENERIC) &&
|
||||
+ (data->type != QSEECOM_SECURE_SERVICE)) {
|
||||
+ pr_err("set mem param req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
pr_debug("SET_MEM_PARAM: qseecom addr = 0x%x\n", (u32)data);
|
||||
ret = qseecom_set_client_mem_param(data, argp);
|
||||
if (ret)
|
||||
@@ -2752,6 +2806,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_LOAD_APP_REQ: {
|
||||
+ if ((data->type != QSEECOM_GENERIC) &&
|
||||
+ (data->type != QSEECOM_CLIENT_APP)) {
|
||||
+ pr_err("load app req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
data->type = QSEECOM_CLIENT_APP;
|
||||
pr_debug("LOAD_APP_REQ: qseecom_addr = 0x%x\n", (u32)data);
|
||||
mutex_lock(&app_access_lock);
|
||||
@@ -2772,6 +2833,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_UNLOAD_APP_REQ: {
|
||||
+ if ((data->client.app_id == 0) ||
|
||||
+ (data->type != QSEECOM_CLIENT_APP)) {
|
||||
+ pr_err("unload app req:invalid handle(%d) app_id(%d)\n",
|
||||
+ data->type, data->client.app_id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
pr_debug("UNLOAD_APP: qseecom_addr = 0x%x\n", (u32)data);
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
@@ -2791,6 +2859,20 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_PERF_ENABLE_REQ:{
|
||||
+ if ((data->type != QSEECOM_GENERIC) &&
|
||||
+ (data->type != QSEECOM_CLIENT_APP)) {
|
||||
+ pr_err("perf enable req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if ((data->type == QSEECOM_CLIENT_APP) &&
|
||||
+ (data->client.app_id == 0)) {
|
||||
+ pr_err("perf enable req:invalid handle(%d) appid(%d)\n",
|
||||
+ data->type, data->client.app_id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
atomic_inc(&data->ioctl_count);
|
||||
ret = qsee_vote_for_clock(data, CLK_DFAB);
|
||||
if (ret)
|
||||
@@ -2802,13 +2884,33 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_PERF_DISABLE_REQ:{
|
||||
+ if ((data->type != QSEECOM_SECURE_SERVICE) &&
|
||||
+ (data->type != QSEECOM_CLIENT_APP)) {
|
||||
+ pr_err("perf disable req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
+ if ((data->type == QSEECOM_CLIENT_APP) &&
|
||||
+ (data->client.app_id == 0)) {
|
||||
+ pr_err("perf disable: invalid handle (%d)app_id(%d)\n",
|
||||
+ data->type, data->client.app_id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
atomic_inc(&data->ioctl_count);
|
||||
- qsee_disable_clock_vote(data, CLK_DFAB);
|
||||
- qsee_disable_clock_vote(data, CLK_SFPB);
|
||||
+ qsee_disable_clock_vote(data, CLK_DFAB);
|
||||
+ qsee_disable_clock_vote(data, CLK_SFPB);
|
||||
atomic_dec(&data->ioctl_count);
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_LOAD_EXTERNAL_ELF_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("load ext elf req: invalid client handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
data->type = QSEECOM_UNAVAILABLE_CLIENT_APP;
|
||||
data->released = true;
|
||||
mutex_lock(&app_access_lock);
|
||||
@@ -2821,6 +2923,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_UNLOAD_EXTERNAL_ELF_REQ: {
|
||||
+ if (data->type != QSEECOM_UNAVAILABLE_CLIENT_APP) {
|
||||
+ pr_err("unload ext elf req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
data->released = true;
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
@@ -2842,9 +2950,15 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SEND_CMD_SERVICE_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("send cmd svc req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
data->type = QSEECOM_SECURE_SERVICE;
|
||||
if (qseecom.qsee_version < QSEE_VERSION_03) {
|
||||
- pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee version %u\n",
|
||||
+ pr_err("SEND_CMD_SERVICE_REQ: Invalid qsee ver %u\n",
|
||||
qseecom.qsee_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2856,8 +2970,14 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_CREATE_KEY_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("create key req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
if (qseecom.qsee_version < QSEE_VERSION_05) {
|
||||
- pr_err("Create Key feature not supported in qsee version %u\n",
|
||||
+ pr_err("Create Key feature unsupported: qsee ver %u\n",
|
||||
qseecom.qsee_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2873,8 +2993,14 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_WIPE_KEY_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("wipe key req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
if (qseecom.qsee_version < QSEE_VERSION_05) {
|
||||
- pr_err("Wipe Key feature not supported in qsee version %u\n",
|
||||
+ pr_err("Wipe Key feature unsupported in qsee ver %u\n",
|
||||
qseecom.qsee_version);
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -2889,6 +3015,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SAVE_PARTITION_HASH_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("save part hash req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
data->released = true;
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
@@ -2898,6 +3030,12 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_IS_ES_ACTIVATED_REQ: {
|
||||
+ if (data->type != QSEECOM_GENERIC) {
|
||||
+ pr_err("ES activated req: invalid handle (%d)\n",
|
||||
+ data->type);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
data->released = true;
|
||||
mutex_lock(&app_access_lock);
|
||||
atomic_inc(&data->ioctl_count);
|
||||
@@ -2907,6 +3045,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_SEND_MODFD_RESP: {
|
||||
+ if ((data->listener.id == 0) ||
|
||||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
|
||||
+ pr_err("receive req: invalid handle (%d), lid(%d)\n",
|
||||
+ data->type, data->listener.id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
/* Only one client allowed here at a time */
|
||||
atomic_inc(&data->ioctl_count);
|
||||
ret = qseecom_send_modfd_resp(data, argp);
|
||||
@@ -2917,6 +3062,13 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
case QSEECOM_IOCTL_UNPROTECT_BUF: {
|
||||
+ if ((data->listener.id == 0) ||
|
||||
+ (data->type != QSEECOM_LISTENER_SERVICE)) {
|
||||
+ pr_err("receive req: invalid handle (%d), lid(%d)\n",
|
||||
+ data->type, data->listener.id);
|
||||
+ ret = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
/* Only one client allowed here at a time */
|
||||
atomic_inc(&data->ioctl_count);
|
||||
ret = qseecom_unprotect_buffer(argp);
|
||||
@@ -2927,6 +3079,7 @@ static long qseecom_ioctl(struct file *file, unsigned cmd,
|
||||
break;
|
||||
}
|
||||
default:
|
||||
+ pr_err("Invalid IOCTL: %d\n", cmd);
|
||||
return -EINVAL;
|
||||
}
|
||||
return ret;
|
||||
--
|
||||
cgit v1.1
|
||||
|
91
Patches/Linux_CVEs/CVE-2014-9865/0.patch
Normal file
91
Patches/Linux_CVEs/CVE-2014-9865/0.patch
Normal file
@ -0,0 +1,91 @@
|
||||
From e65a876a155de945e306f2726f3a557415e6044e Mon Sep 17 00:00:00 2001
|
||||
From: Mona Hossain <mhossain@codeaurora.org>
|
||||
Date: Tue, 1 Oct 2013 14:08:20 -0700
|
||||
Subject: qseecom: Validate inputs from user space
|
||||
|
||||
Validate send_cmd, send_modfd_cmd and send_mdfd_resp
|
||||
input parameters: cmd and response pointers and buffer
|
||||
lengths and offsets issued to modify data.
|
||||
|
||||
Change-Id: I381836d08aaa48357486fbdc6a122eb5b42bfa0b
|
||||
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 35 +++++++++++++++++++++++++++++++++--
|
||||
1 file changed, 33 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 4c1943b..97f3362 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -1134,9 +1134,22 @@ static int __qseecom_send_cmd(struct qseecom_dev_handle *data,
|
||||
pr_err("cmd buffer or response buffer is null\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
+ if (((uint32_t)req->cmd_req_buf < data->client.user_virt_sb_base) ||
|
||||
+ ((uint32_t)req->cmd_req_buf >= (data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length))) {
|
||||
+ pr_err("cmd buffer address not within shared bufffer\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
+ if (((uint32_t)req->resp_buf < data->client.user_virt_sb_base) ||
|
||||
+ ((uint32_t)req->resp_buf >= (data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length))){
|
||||
+ pr_err("response buffer address not within shared bufffer\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
|
||||
- if (req->cmd_req_len <= 0 ||
|
||||
- req->resp_len <= 0 ||
|
||||
+ if ((req->cmd_req_len == 0) || (req->resp_len == 0) ||
|
||||
req->cmd_req_len > data->client.sb_length ||
|
||||
req->resp_len > data->client.sb_length) {
|
||||
pr_err("cmd buffer length or "
|
||||
@@ -1371,6 +1384,7 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
|
||||
void __user *argp)
|
||||
{
|
||||
int ret = 0;
|
||||
+ int i;
|
||||
struct qseecom_send_modfd_cmd_req req;
|
||||
struct qseecom_send_cmd_req send_cmd_req;
|
||||
|
||||
@@ -1384,6 +1398,14 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
|
||||
send_cmd_req.resp_buf = req.resp_buf;
|
||||
send_cmd_req.resp_len = req.resp_len;
|
||||
|
||||
+ /* validate offsets */
|
||||
+ for (i = 0; i < MAX_ION_FD; i++) {
|
||||
+ if (req.ifd_data[i].cmd_buf_offset >= req.cmd_req_len) {
|
||||
+ pr_err("Invalid offset %d = 0x%x\n",
|
||||
+ i, req.ifd_data[i].cmd_buf_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
ret = __qseecom_update_cmd_buf(&req, false, data, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -2001,11 +2023,20 @@ static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data,
|
||||
void __user *argp)
|
||||
{
|
||||
struct qseecom_send_modfd_listener_resp resp;
|
||||
+ int i;
|
||||
|
||||
if (copy_from_user(&resp, argp, sizeof(resp))) {
|
||||
pr_err("copy_from_user failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
+ /* validate offsets */
|
||||
+ for (i = 0; i < MAX_ION_FD; i++) {
|
||||
+ if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) {
|
||||
+ pr_err("Invalid offset %d = 0x%x\n",
|
||||
+ i, resp.ifd_data[i].cmd_buf_offset);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ }
|
||||
__qseecom_update_cmd_buf(&resp, false, data, true);
|
||||
qseecom.send_resp_flag = 1;
|
||||
wake_up_interruptible(&qseecom.send_resp_wq);
|
||||
--
|
||||
cgit v1.1
|
||||
|
45
Patches/Linux_CVEs/CVE-2014-9866/0.patch
Normal file
45
Patches/Linux_CVEs/CVE-2014-9866/0.patch
Normal file
@ -0,0 +1,45 @@
|
||||
From 8e6daae70422ad35146a87700e6634a747d1ff5d Mon Sep 17 00:00:00 2001
|
||||
From: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
Date: Tue, 16 Jul 2013 11:23:47 -0700
|
||||
Subject: msm: camera: Bound check num_cid from userspace in csid driver
|
||||
|
||||
Upper and lower bound checks are enforced for num_cid
|
||||
which is passed from userspace with lower as 1 and
|
||||
max of 16.
|
||||
|
||||
Change-Id: Ic5456289cb2f2b4ea17610a7672eb2c5225b7954
|
||||
Signed-off-by: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c | 9 ++++++++-
|
||||
1 file changed, 8 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
|
||||
index 9aca234..229fdb2 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/csid/msm_csid.c
|
||||
@@ -440,7 +440,7 @@ static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
|
||||
case CSID_CFG: {
|
||||
struct msm_camera_csid_params csid_params;
|
||||
struct msm_camera_csid_vc_cfg *vc_cfg = NULL;
|
||||
- int32_t i = 0;
|
||||
+ int8_t i = 0;
|
||||
if (copy_from_user(&csid_params,
|
||||
(void *)cdata->cfg.csid_params,
|
||||
sizeof(struct msm_camera_csid_params))) {
|
||||
@@ -448,6 +448,13 @@ static long msm_csid_cmd(struct csid_device *csid_dev, void *arg)
|
||||
rc = -EFAULT;
|
||||
break;
|
||||
}
|
||||
+ if (csid_params.lut_params.num_cid < 1 ||
|
||||
+ csid_params.lut_params.num_cid > 16) {
|
||||
+ pr_err("%s: %d num_cid outside range\n",
|
||||
+ __func__, __LINE__);
|
||||
+ rc = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
for (i = 0; i < csid_params.lut_params.num_cid; i++) {
|
||||
vc_cfg = kzalloc(csid_params.lut_params.num_cid *
|
||||
sizeof(struct msm_camera_csid_vc_cfg),
|
||||
--
|
||||
cgit v1.1
|
||||
|
108
Patches/Linux_CVEs/CVE-2014-9867/0.patch
Normal file
108
Patches/Linux_CVEs/CVE-2014-9867/0.patch
Normal file
@ -0,0 +1,108 @@
|
||||
From 322c518689a7f820165ca4c5d6b750b02ac34665 Mon Sep 17 00:00:00 2001
|
||||
From: Jim Rasche <jrasche@codeaurora.org>
|
||||
Date: Mon, 22 Jul 2013 15:03:50 -0700
|
||||
Subject: msm:camera: Fix multiple bounds check
|
||||
|
||||
Added bounds check to user input num_streams at several location,
|
||||
without checking a position outside array could be dereferenced
|
||||
|
||||
Change-Id: I6e82d8b51e4ec6772316c7daef243240c029db96
|
||||
Signed-off-by: Jim Rasche <jrasche@codeaurora.org>
|
||||
---
|
||||
.../platform/msm/camera_v2/isp/msm_isp_axi_util.c | 46 ++++++++++++++++++++++
|
||||
1 file changed, 46 insertions(+)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
|
||||
index 5b7658d..746425b 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_axi_util.c
|
||||
@@ -300,7 +300,16 @@ int msm_isp_axi_check_stream_state(
|
||||
struct msm_vfe_axi_stream *stream_info;
|
||||
enum msm_vfe_axi_state valid_state =
|
||||
(stream_cfg_cmd->cmd == START_STREAM) ? INACTIVE : ACTIVE;
|
||||
+
|
||||
+ if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
+ if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
|
||||
+ > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
stream_info = &axi_data->stream_info[
|
||||
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
|
||||
spin_lock_irqsave(&stream_info->lock, flags);
|
||||
@@ -840,7 +849,16 @@ static void msm_isp_update_camif_output_count(
|
||||
int i;
|
||||
struct msm_vfe_axi_stream *stream_info;
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
+
|
||||
+ if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
+ if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
|
||||
+ > MAX_NUM_STREAM) {
|
||||
+ return;
|
||||
+ }
|
||||
stream_info =
|
||||
&axi_data->stream_info[
|
||||
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
|
||||
@@ -1020,7 +1038,16 @@ static int msm_isp_start_axi_stream(struct vfe_device *vfe_dev,
|
||||
uint32_t wm_reload_mask = 0x0;
|
||||
struct msm_vfe_axi_stream *stream_info;
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
+
|
||||
+ if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
+ if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
|
||||
+ > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
stream_info = &axi_data->stream_info[
|
||||
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
|
||||
src_state = axi_data->src_info[
|
||||
@@ -1073,7 +1100,16 @@ static int msm_isp_stop_axi_stream(struct vfe_device *vfe_dev,
|
||||
uint8_t wait_for_complete = 0;
|
||||
struct msm_vfe_axi_stream *stream_info;
|
||||
struct msm_vfe_axi_shared_data *axi_data = &vfe_dev->axi_data;
|
||||
+
|
||||
+ if (stream_cfg_cmd->num_streams > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
+ if (HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])
|
||||
+ > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
stream_info = &axi_data->stream_info[
|
||||
HANDLE_TO_IDX(stream_cfg_cmd->stream_handle[i])];
|
||||
|
||||
@@ -1158,8 +1194,18 @@ int msm_isp_update_axi_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
return -EBUSY;
|
||||
}
|
||||
|
||||
+ /*num_stream is uint32 and update_info[] bound by MAX_NUM_STREAM*/
|
||||
+ if (update_cmd->num_streams > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
for (i = 0; i < update_cmd->num_streams; i++) {
|
||||
update_info = &update_cmd->update_info[i];
|
||||
+ /*check array reference bounds*/
|
||||
+ if (HANDLE_TO_IDX(update_info->stream_handle)
|
||||
+ > MAX_NUM_STREAM) {
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
stream_info = &axi_data->stream_info[
|
||||
HANDLE_TO_IDX(update_info->stream_handle)];
|
||||
if (stream_info->state != ACTIVE &&
|
||||
--
|
||||
cgit v1.1
|
||||
|
60
Patches/Linux_CVEs/CVE-2014-9868/0.patch
Normal file
60
Patches/Linux_CVEs/CVE-2014-9868/0.patch
Normal file
@ -0,0 +1,60 @@
|
||||
From 1f274b74c00187ba1c379971503f51944148b22f Mon Sep 17 00:00:00 2001
|
||||
From: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
|
||||
Date: Thu, 25 Jul 2013 15:55:03 -0700
|
||||
Subject: msm: camera: Fix possible out of bound writes in csi driver
|
||||
|
||||
The value csi_lane_mask which is uint16_t is controllable from userspace.
|
||||
The while loop can loop for 2^16 - 1, Hence extract the required
|
||||
bit combination from the userspace argument, used it for further
|
||||
processing.
|
||||
|
||||
CRs-Fixed: 511976
|
||||
Change-Id: I80b0fe7ac273352503d9705510f05debe6cbb10a
|
||||
Signed-off-by: Lakshmi Narayana Kalavala <lkalaval@codeaurora.org>
|
||||
---
|
||||
drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c | 8 ++++----
|
||||
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
|
||||
index 21b9cdc..32cf0d3 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/csiphy/msm_csiphy.c
|
||||
@@ -423,7 +423,7 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
|
||||
__LINE__, csi_lane_params);
|
||||
return -EINVAL;
|
||||
}
|
||||
- csi_lane_mask = csi_lane_params->csi_lane_mask;
|
||||
+ csi_lane_mask = (csi_lane_params->csi_lane_mask & 0x1F);
|
||||
|
||||
CDBG("%s csiphy_params, lane assign %x mask = %x\n",
|
||||
__func__,
|
||||
@@ -436,7 +436,7 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
|
||||
csiphy_dev->lane_mask[csiphy_dev->pdev->id] &=
|
||||
~(csi_lane_mask);
|
||||
i = 0;
|
||||
- while (csi_lane_mask & 0x1F) {
|
||||
+ while (csi_lane_mask) {
|
||||
if (csi_lane_mask & 0x1) {
|
||||
msm_camera_io_w(0x0, csiphy_dev->base +
|
||||
MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
|
||||
@@ -507,7 +507,7 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
|
||||
__LINE__, csi_lane_params);
|
||||
return -EINVAL;
|
||||
}
|
||||
- csi_lane_mask = csi_lane_params->csi_lane_mask;
|
||||
+ csi_lane_mask = (csi_lane_params->csi_lane_mask & 0x1F);
|
||||
|
||||
CDBG("%s csiphy_params, lane assign %x mask = %x\n",
|
||||
__func__,
|
||||
@@ -520,7 +520,7 @@ static int msm_csiphy_release(struct csiphy_device *csiphy_dev, void *arg)
|
||||
csiphy_dev->lane_mask[csiphy_dev->pdev->id] &=
|
||||
~(csi_lane_mask);
|
||||
i = 0;
|
||||
- while (csi_lane_mask & 0x1F) {
|
||||
+ while (csi_lane_mask) {
|
||||
if (csi_lane_mask & 0x1) {
|
||||
msm_camera_io_w(0x0, csiphy_dev->base +
|
||||
MIPI_CSIPHY_LNn_CFG2_ADDR + 0x40*i);
|
||||
--
|
||||
cgit v1.1
|
||||
|
74
Patches/Linux_CVEs/CVE-2014-9869/0.patch
Normal file
74
Patches/Linux_CVEs/CVE-2014-9869/0.patch
Normal file
@ -0,0 +1,74 @@
|
||||
From 8d1f7531ff379befc129a6447642061e87562bca Mon Sep 17 00:00:00 2001
|
||||
From: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
Date: Tue, 23 Jul 2013 15:39:09 -0700
|
||||
Subject: msm: camera: Check stats index MAX in ISP driver
|
||||
|
||||
Add a check for the stats index MAX using
|
||||
MSM_ISP_STATS_MAX before accessing stream info
|
||||
using that index to avoid any invalid memory access.
|
||||
|
||||
Change-Id: Iaade2af5d0e3e073e9519961a0f84a93038284bf
|
||||
CRs-Fixed: 514711
|
||||
Signed-off-by: Hariram Purushothaman <hpurus@codeaurora.org>
|
||||
---
|
||||
.../msm/camera_v2/isp/msm_isp_stats_util.c | 22 +++++++++++++++++++---
|
||||
1 file changed, 19 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
|
||||
index d857a14..33f63b3 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
|
||||
@@ -150,6 +150,12 @@ int msm_isp_stats_create_stream(struct vfe_device *vfe_dev,
|
||||
stats_idx = vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
get_stats_idx(stream_req_cmd->stats_type);
|
||||
|
||||
+ if ((stats_idx > MSM_ISP_STATS_MAX) ||
|
||||
+ (stats_idx == -EINVAL)) {
|
||||
+ pr_err("%s: Stats idx Error\n", __func__);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
if (stream_info->state != STATS_AVALIABLE) {
|
||||
pr_err("%s: Stats already requested\n", __func__);
|
||||
@@ -188,7 +194,7 @@ int msm_isp_stats_create_stream(struct vfe_device *vfe_dev,
|
||||
|
||||
int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
{
|
||||
- int rc = 0;
|
||||
+ int rc = -1;
|
||||
struct msm_vfe_stats_stream_request_cmd *stream_req_cmd = arg;
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
@@ -202,6 +208,11 @@ int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
}
|
||||
|
||||
stats_idx = STATS_IDX(stream_req_cmd->stream_handle);
|
||||
+ if (stats_idx > MSM_ISP_STATS_MAX) {
|
||||
+ pr_err("%s: Stats idx Error\n", __func__);
|
||||
+ return rc;
|
||||
+ }
|
||||
+
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
|
||||
framedrop_period = msm_isp_get_framedrop_period(
|
||||
@@ -228,9 +239,14 @@ int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
struct msm_vfe_stats_stream_release_cmd *stream_release_cmd = arg;
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
int stats_idx = STATS_IDX(stream_release_cmd->stream_handle);
|
||||
- struct msm_vfe_stats_stream *stream_info =
|
||||
- &stats_data->stream_info[stats_idx];
|
||||
+ struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
+
|
||||
+ if (stats_idx > MSM_ISP_STATS_MAX) {
|
||||
+ pr_err("%s: Stats idx Error\n", __func__);
|
||||
+ return rc;
|
||||
+ }
|
||||
|
||||
+ stream_info = &stats_data->stream_info[stats_idx];
|
||||
if (stream_info->state == STATS_AVALIABLE) {
|
||||
pr_err("%s: stream already release\n", __func__);
|
||||
return rc;
|
||||
--
|
||||
cgit v1.1
|
||||
|
145
Patches/Linux_CVEs/CVE-2014-9869/1.patch
Normal file
145
Patches/Linux_CVEs/CVE-2014-9869/1.patch
Normal file
@ -0,0 +1,145 @@
|
||||
From 7a26934e4196b4aa61944081989189d59b108768 Mon Sep 17 00:00:00 2001
|
||||
From: Petar Sivenov <psiven@codeaurora.org>
|
||||
Date: Tue, 13 Aug 2013 10:12:39 -0700
|
||||
Subject: msm: camera: isp: Bound check for number stats registers
|
||||
|
||||
The index of used stats register is derived from a stream handle least
|
||||
significant byte and thus can be up to 255. However the stats registers
|
||||
are up to 8 depending of the target. Thus a bound check is done before
|
||||
use of the received stats register index value.
|
||||
|
||||
Change-Id: Ic008918f4263f57a5b8aabd34266ac1ba3612a9c
|
||||
Signed-off-by: Petar Sivenov <psiven@codeaurora.org>
|
||||
---
|
||||
.../msm/camera_v2/isp/msm_isp_stats_util.c | 50 ++++++++++++++++------
|
||||
.../platform/msm/camera_v2/isp/msm_isp_util.c | 4 +-
|
||||
2 files changed, 41 insertions(+), 13 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
|
||||
index 0840e30..b479857 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_stats_util.c
|
||||
@@ -23,8 +23,16 @@ static int msm_isp_stats_cfg_ping_pong_address(struct vfe_device *vfe_dev,
|
||||
struct msm_isp_buffer *buf;
|
||||
uint32_t pingpong_bit = 0;
|
||||
uint32_t bufq_handle = stream_info->bufq_handle;
|
||||
- uint32_t stats_pingpong_offset =
|
||||
- STATS_IDX(stream_info->stream_handle) +
|
||||
+ uint32_t stats_pingpong_offset;
|
||||
+
|
||||
+ if (STATS_IDX(stream_info->stream_handle) >=
|
||||
+ vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__,
|
||||
+ STATS_IDX(stream_info->stream_handle));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ stats_pingpong_offset = STATS_IDX(stream_info->stream_handle) +
|
||||
vfe_dev->hw_info->stats_hw_info->stats_ping_pong_offset;
|
||||
|
||||
pingpong_bit = (~(pingpong_status >> stats_pingpong_offset) & 0x1);
|
||||
@@ -151,10 +159,9 @@ int msm_isp_stats_create_stream(struct vfe_device *vfe_dev,
|
||||
stats_idx = vfe_dev->hw_info->vfe_ops.stats_ops.
|
||||
get_stats_idx(stream_req_cmd->stats_type);
|
||||
|
||||
- if ((stats_idx > MSM_ISP_STATS_MAX) ||
|
||||
- (stats_idx == -EINVAL)) {
|
||||
- pr_err("%s: Stats idx Error\n", __func__);
|
||||
- return rc;
|
||||
+ if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
@@ -209,9 +216,10 @@ int msm_isp_request_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
}
|
||||
|
||||
stats_idx = STATS_IDX(stream_req_cmd->stream_handle);
|
||||
- if (stats_idx > MSM_ISP_STATS_MAX) {
|
||||
- pr_err("%s: Stats idx Error\n", __func__);
|
||||
- return rc;
|
||||
+
|
||||
+ if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
@@ -242,9 +250,9 @@ int msm_isp_release_stats_stream(struct vfe_device *vfe_dev, void *arg)
|
||||
int stats_idx = STATS_IDX(stream_release_cmd->stream_handle);
|
||||
struct msm_vfe_stats_stream *stream_info = NULL;
|
||||
|
||||
- if (stats_idx > MSM_ISP_STATS_MAX) {
|
||||
- pr_err("%s: Stats idx Error\n", __func__);
|
||||
- return rc;
|
||||
+ if (stats_idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__, stats_idx);
|
||||
+ return -EINVAL;
|
||||
}
|
||||
|
||||
stream_info = &stats_data->stream_info[stats_idx];
|
||||
@@ -379,6 +387,12 @@ static int msm_isp_start_stats_stream(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
+
|
||||
+ if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
stream_info = &stats_data->stream_info[idx];
|
||||
if (stream_info->stream_handle !=
|
||||
stream_cfg_cmd->stream_handle[i]) {
|
||||
@@ -423,6 +437,12 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev,
|
||||
struct msm_vfe_stats_shared_data *stats_data = &vfe_dev->stats_data;
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
+
|
||||
+ if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
stream_info = &stats_data->stream_info[idx];
|
||||
if (stream_info->stream_handle !=
|
||||
stream_cfg_cmd->stream_handle[i]) {
|
||||
@@ -453,6 +473,12 @@ static int msm_isp_stop_stats_stream(struct vfe_device *vfe_dev,
|
||||
|
||||
for (i = 0; i < stream_cfg_cmd->num_streams; i++) {
|
||||
idx = STATS_IDX(stream_cfg_cmd->stream_handle[i]);
|
||||
+
|
||||
+ if (idx >= vfe_dev->hw_info->stats_hw_info->num_stats_type) {
|
||||
+ pr_err("%s Invalid stats index %d", __func__, idx);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
stream_info = &stats_data->stream_info[idx];
|
||||
msm_isp_deinit_stats_ping_pong_reg(vfe_dev, stream_info);
|
||||
}
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
index fcdf34e..6dba4153 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
@@ -768,6 +768,8 @@ void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev)
|
||||
void msm_isp_process_error_info(struct vfe_device *vfe_dev)
|
||||
{
|
||||
int i;
|
||||
+ uint8_t num_stats_type =
|
||||
+ vfe_dev->hw_info->stats_hw_info->num_stats_type;
|
||||
struct msm_vfe_error_info *error_info = &vfe_dev->error_info;
|
||||
static DEFINE_RATELIMIT_STATE(rs,
|
||||
DEFAULT_RATELIMIT_INTERVAL, DEFAULT_RATELIMIT_BURST);
|
||||
@@ -791,7 +793,7 @@ void msm_isp_process_error_info(struct vfe_device *vfe_dev)
|
||||
error_info->stream_framedrop_count[i] = 0;
|
||||
}
|
||||
}
|
||||
- for (i = 0; i < MSM_ISP_STATS_MAX; i++) {
|
||||
+ for (i = 0; i < num_stats_type; i++) {
|
||||
if (error_info->stats_framedrop_count[i] != 0 &&
|
||||
__ratelimit(&rs_stats)) {
|
||||
pr_err("%s: Stats stream[%d]: dropped %d frames\n",
|
||||
--
|
||||
cgit v1.1
|
||||
|
216
Patches/Linux_CVEs/CVE-2014-9870/0.patch
Normal file
216
Patches/Linux_CVEs/CVE-2014-9870/0.patch
Normal file
@ -0,0 +1,216 @@
|
||||
From 4f57652fcd2dce7741f1ac6dc0417e2f265cd1de Mon Sep 17 00:00:00 2001
|
||||
From: =?UTF-8?q?Andr=C3=A9=20Hentschel?= <nerv@dawncrow.de>
|
||||
Date: Tue, 18 Jun 2013 23:23:26 +0100
|
||||
Subject: ARM: 7735/2: Preserve the user r/w register TPIDRURW on context
|
||||
switch and fork
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
Since commit 6a1c53124aa1 the user writeable TLS register was zeroed to
|
||||
prevent it from being used as a covert channel between two tasks.
|
||||
|
||||
There are more and more applications coming to Windows RT,
|
||||
Wine could support them, but mostly they expect to have
|
||||
the thread environment block (TEB) in TPIDRURW.
|
||||
|
||||
This patch preserves that register per thread instead of clearing it.
|
||||
Unlike the TPIDRURO, which is already switched, the TPIDRURW
|
||||
can be updated from userspace so needs careful treatment in the case that we
|
||||
modify TPIDRURW and call fork(). To avoid this we must always read
|
||||
TPIDRURW in copy_thread.
|
||||
|
||||
Change-Id: Ib1e25be7b9faa846ba5335aad2574e21a1246066
|
||||
Signed-off-by: André Hentschel <nerv@dawncrow.de>
|
||||
Signed-off-by: Will Deacon <will.deacon@arm.com>
|
||||
Signed-off-by: Jonathan Austin <jonathan.austin@arm.com>
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Git-commit: a4780adeefd042482f624f5e0d577bf9cdcbb760
|
||||
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
|
||||
[joonwoop@codeaurora.org: fixed merge conflict]
|
||||
CRs-fixed: 561044
|
||||
Signed-off-by: Joonwoo Park <joonwoop@codeaurora.org>
|
||||
---
|
||||
arch/arm/include/asm/thread_info.h | 2 +-
|
||||
arch/arm/include/asm/tls.h | 40 +++++++++++++++++++++++++-------------
|
||||
arch/arm/kernel/entry-armv.S | 5 +++--
|
||||
arch/arm/kernel/process.c | 4 +++-
|
||||
arch/arm/kernel/ptrace.c | 2 +-
|
||||
arch/arm/kernel/traps.c | 4 ++--
|
||||
6 files changed, 37 insertions(+), 20 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/include/asm/thread_info.h b/arch/arm/include/asm/thread_info.h
|
||||
index 67d6443..2eb0c2c 100644
|
||||
--- a/arch/arm/include/asm/thread_info.h
|
||||
+++ b/arch/arm/include/asm/thread_info.h
|
||||
@@ -58,7 +58,7 @@ struct thread_info {
|
||||
struct cpu_context_save cpu_context; /* cpu context */
|
||||
__u32 syscall; /* syscall number */
|
||||
__u8 used_cp[16]; /* thread used copro */
|
||||
- unsigned long tp_value;
|
||||
+ unsigned long tp_value[2]; /* TLS registers */
|
||||
struct crunch_state crunchstate;
|
||||
union fp_state fpstate __attribute__((aligned(8)));
|
||||
union vfp_state vfpstate;
|
||||
diff --git a/arch/arm/include/asm/tls.h b/arch/arm/include/asm/tls.h
|
||||
index 73409e6..83259b8 100644
|
||||
--- a/arch/arm/include/asm/tls.h
|
||||
+++ b/arch/arm/include/asm/tls.h
|
||||
@@ -2,27 +2,30 @@
|
||||
#define __ASMARM_TLS_H
|
||||
|
||||
#ifdef __ASSEMBLY__
|
||||
- .macro set_tls_none, tp, tmp1, tmp2
|
||||
+#include <asm/asm-offsets.h>
|
||||
+ .macro switch_tls_none, base, tp, tpuser, tmp1, tmp2
|
||||
.endm
|
||||
|
||||
- .macro set_tls_v6k, tp, tmp1, tmp2
|
||||
+ .macro switch_tls_v6k, base, tp, tpuser, tmp1, tmp2
|
||||
+ mrc p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
|
||||
mcr p15, 0, \tp, c13, c0, 3 @ set TLS register
|
||||
- mov \tmp1, #0
|
||||
- mcr p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
|
||||
+ mcr p15, 0, \tpuser, c13, c0, 2 @ and the user r/w register
|
||||
+ str \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
|
||||
.endm
|
||||
|
||||
- .macro set_tls_v6, tp, tmp1, tmp2
|
||||
+ .macro switch_tls_v6, base, tp, tpuser, tmp1, tmp2
|
||||
ldr \tmp1, =elf_hwcap
|
||||
ldr \tmp1, [\tmp1, #0]
|
||||
mov \tmp2, #0xffff0fff
|
||||
tst \tmp1, #HWCAP_TLS @ hardware TLS available?
|
||||
- mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
|
||||
- movne \tmp1, #0
|
||||
- mcrne p15, 0, \tmp1, c13, c0, 2 @ clear user r/w TLS register
|
||||
streq \tp, [\tmp2, #-15] @ set TLS value at 0xffff0ff0
|
||||
+ mrcne p15, 0, \tmp2, c13, c0, 2 @ get the user r/w register
|
||||
+ mcrne p15, 0, \tp, c13, c0, 3 @ yes, set TLS register
|
||||
+ mcrne p15, 0, \tpuser, c13, c0, 2 @ set user r/w register
|
||||
+ strne \tmp2, [\base, #TI_TP_VALUE + 4] @ save it
|
||||
.endm
|
||||
|
||||
- .macro set_tls_software, tp, tmp1, tmp2
|
||||
+ .macro switch_tls_software, base, tp, tpuser, tmp1, tmp2
|
||||
mov \tmp1, #0xffff0fff
|
||||
str \tp, [\tmp1, #-15] @ set TLS value at 0xffff0ff0
|
||||
.endm
|
||||
@@ -31,19 +34,30 @@
|
||||
#ifdef CONFIG_TLS_REG_EMUL
|
||||
#define tls_emu 1
|
||||
#define has_tls_reg 1
|
||||
-#define set_tls set_tls_none
|
||||
+#define switch_tls switch_tls_none
|
||||
#elif defined(CONFIG_CPU_V6)
|
||||
#define tls_emu 0
|
||||
#define has_tls_reg (elf_hwcap & HWCAP_TLS)
|
||||
-#define set_tls set_tls_v6
|
||||
+#define switch_tls switch_tls_v6
|
||||
#elif defined(CONFIG_CPU_32v6K)
|
||||
#define tls_emu 0
|
||||
#define has_tls_reg 1
|
||||
-#define set_tls set_tls_v6k
|
||||
+#define switch_tls switch_tls_v6k
|
||||
#else
|
||||
#define tls_emu 0
|
||||
#define has_tls_reg 0
|
||||
-#define set_tls set_tls_software
|
||||
+#define switch_tls switch_tls_software
|
||||
#endif
|
||||
|
||||
+#ifndef __ASSEMBLY__
|
||||
+static inline unsigned long get_tpuser(void)
|
||||
+{
|
||||
+ unsigned long reg = 0;
|
||||
+
|
||||
+ if (has_tls_reg && !tls_emu)
|
||||
+ __asm__("mrc p15, 0, %0, c13, c0, 2" : "=r" (reg));
|
||||
+
|
||||
+ return reg;
|
||||
+}
|
||||
+#endif
|
||||
#endif /* __ASMARM_TLS_H */
|
||||
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
|
||||
index 7a8c2d6..0bdba55 100644
|
||||
--- a/arch/arm/kernel/entry-armv.S
|
||||
+++ b/arch/arm/kernel/entry-armv.S
|
||||
@@ -698,15 +698,16 @@ ENTRY(__switch_to)
|
||||
UNWIND(.fnstart )
|
||||
UNWIND(.cantunwind )
|
||||
add ip, r1, #TI_CPU_SAVE
|
||||
- ldr r3, [r2, #TI_TP_VALUE]
|
||||
ARM( stmia ip!, {r4 - sl, fp, sp, lr} ) @ Store most regs on stack
|
||||
THUMB( stmia ip!, {r4 - sl, fp} ) @ Store most regs on stack
|
||||
THUMB( str sp, [ip], #4 )
|
||||
THUMB( str lr, [ip], #4 )
|
||||
+ ldr r4, [r2, #TI_TP_VALUE]
|
||||
+ ldr r5, [r2, #TI_TP_VALUE + 4]
|
||||
#ifdef CONFIG_CPU_USE_DOMAINS
|
||||
ldr r6, [r2, #TI_CPU_DOMAIN]
|
||||
#endif
|
||||
- set_tls r3, r4, r5
|
||||
+ switch_tls r1, r4, r5, r3, r7
|
||||
#if defined(CONFIG_CC_STACKPROTECTOR) && !defined(CONFIG_SMP)
|
||||
ldr r7, [r2, #TI_TASK]
|
||||
ldr r8, =__stack_chk_guard
|
||||
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
|
||||
index 0ff45bd..18e92f6 100644
|
||||
--- a/arch/arm/kernel/process.c
|
||||
+++ b/arch/arm/kernel/process.c
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <asm/thread_notify.h>
|
||||
#include <asm/stacktrace.h>
|
||||
#include <asm/mach/time.h>
|
||||
+#include <asm/tls.h>
|
||||
|
||||
#ifdef CONFIG_CC_STACKPROTECTOR
|
||||
#include <linux/stackprotector.h>
|
||||
@@ -558,7 +559,8 @@ copy_thread(unsigned long clone_flags, unsigned long stack_start,
|
||||
clear_ptrace_hw_breakpoint(p);
|
||||
|
||||
if (clone_flags & CLONE_SETTLS)
|
||||
- thread->tp_value = regs->ARM_r3;
|
||||
+ thread->tp_value[0] = childregs->ARM_r3;
|
||||
+ thread->tp_value[1] = get_tpuser();
|
||||
|
||||
thread_notify(THREAD_NOTIFY_COPY, thread);
|
||||
|
||||
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
|
||||
index 9650c14..c6c6be7 100644
|
||||
--- a/arch/arm/kernel/ptrace.c
|
||||
+++ b/arch/arm/kernel/ptrace.c
|
||||
@@ -844,7 +844,7 @@ long arch_ptrace(struct task_struct *child, long request,
|
||||
#endif
|
||||
|
||||
case PTRACE_GET_THREAD_AREA:
|
||||
- ret = put_user(task_thread_info(child)->tp_value,
|
||||
+ ret = put_user(task_thread_info(child)->tp_value[0],
|
||||
datap);
|
||||
break;
|
||||
|
||||
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
|
||||
index 12e6fcb..e0a066b 100644
|
||||
--- a/arch/arm/kernel/traps.c
|
||||
+++ b/arch/arm/kernel/traps.c
|
||||
@@ -593,7 +593,7 @@ asmlinkage int arm_syscall(int no, struct pt_regs *regs)
|
||||
return regs->ARM_r0;
|
||||
|
||||
case NR(set_tls):
|
||||
- thread->tp_value = regs->ARM_r0;
|
||||
+ thread->tp_value[0] = regs->ARM_r0;
|
||||
if (tls_emu)
|
||||
return 0;
|
||||
if (has_tls_reg) {
|
||||
@@ -711,7 +711,7 @@ static int get_tp_trap(struct pt_regs *regs, unsigned int instr)
|
||||
int reg = (instr >> 12) & 15;
|
||||
if (reg == 15)
|
||||
return 1;
|
||||
- regs->uregs[reg] = current_thread_info()->tp_value;
|
||||
+ regs->uregs[reg] = current_thread_info()->tp_value[0];
|
||||
regs->ARM_pc += 4;
|
||||
return 0;
|
||||
}
|
||||
--
|
||||
cgit v1.1
|
||||
|
146
Patches/Linux_CVEs/CVE-2014-9871/0.patch
Normal file
146
Patches/Linux_CVEs/CVE-2014-9871/0.patch
Normal file
@ -0,0 +1,146 @@
|
||||
From f615e40c706708f74cd826d5b19c63025f54c041 Mon Sep 17 00:00:00 2001
|
||||
From: Seemanta Dutta <seemanta@codeaurora.org>
|
||||
Date: Tue, 23 Jul 2013 15:52:22 -0700
|
||||
Subject: msm: camera: Fix potential memory overflow errors
|
||||
|
||||
Fix potential memory overflow errors in msm_isp_util.c which happen
|
||||
under certain rare conditions.
|
||||
|
||||
CRs-fixed: 514717
|
||||
Change-Id: I8c70e089df9bf1e7a364c5c8264b782c9c23bf0b
|
||||
Signed-off-by: Seemanta Dutta <seemanta@codeaurora.org>
|
||||
---
|
||||
.../platform/msm/camera_v2/isp/msm_isp_util.c | 47 +++++++++++++++++++---
|
||||
.../platform/msm/camera_v2/isp/msm_isp_util.h | 2 +-
|
||||
2 files changed, 43 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
index 3806213..9b9c5a3 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.c
|
||||
@@ -366,7 +366,7 @@ long msm_isp_ioctl(struct v4l2_subdev *sd,
|
||||
break;
|
||||
case VIDIOC_MSM_ISP_SET_SRC_STATE:
|
||||
mutex_lock(&vfe_dev->core_mutex);
|
||||
- msm_isp_set_src_state(vfe_dev, arg);
|
||||
+ rc = msm_isp_set_src_state(vfe_dev, arg);
|
||||
mutex_unlock(&vfe_dev->core_mutex);
|
||||
break;
|
||||
case VIDIOC_MSM_ISP_REQUEST_STATS_STREAM:
|
||||
@@ -410,7 +410,7 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
if (resource_size(vfe_dev->vfe_mem) <
|
||||
(reg_cfg_cmd->u.rw_info.reg_offset +
|
||||
reg_cfg_cmd->u.rw_info.len)) {
|
||||
- pr_err("%s: Invalid length\n", __func__);
|
||||
+ pr_err("%s: VFE_WRITE: Invalid length\n", __func__);
|
||||
return -EINVAL;
|
||||
}
|
||||
msm_camera_io_memcpy(vfe_dev->vfe_base +
|
||||
@@ -422,16 +422,37 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
case VFE_WRITE_MB: {
|
||||
uint32_t *data_ptr = cfg_data +
|
||||
reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
|
||||
+
|
||||
+ if ((UINT_MAX - sizeof(*data_ptr) <
|
||||
+ reg_cfg_cmd->u.rw_info.reg_offset) ||
|
||||
+ (resource_size(vfe_dev->vfe_mem) <
|
||||
+ reg_cfg_cmd->u.rw_info.reg_offset +
|
||||
+ sizeof(*data_ptr))) {
|
||||
+ pr_err("%s: VFE_WRITE_MB: Invalid length\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
msm_camera_io_w_mb(*data_ptr, vfe_dev->vfe_base +
|
||||
reg_cfg_cmd->u.rw_info.reg_offset);
|
||||
break;
|
||||
}
|
||||
case VFE_CFG_MASK: {
|
||||
uint32_t temp;
|
||||
+ if (resource_size(vfe_dev->vfe_mem) <
|
||||
+ reg_cfg_cmd->u.mask_info.reg_offset)
|
||||
+ return -EINVAL;
|
||||
temp = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
reg_cfg_cmd->u.mask_info.reg_offset);
|
||||
+
|
||||
temp &= ~reg_cfg_cmd->u.mask_info.mask;
|
||||
temp |= reg_cfg_cmd->u.mask_info.val;
|
||||
+ if ((UINT_MAX - sizeof(temp) <
|
||||
+ reg_cfg_cmd->u.mask_info.reg_offset) ||
|
||||
+ (resource_size(vfe_dev->vfe_mem) <
|
||||
+ reg_cfg_cmd->u.mask_info.reg_offset +
|
||||
+ sizeof(temp))) {
|
||||
+ pr_err("%s: VFE_CFG_MASK: Invalid length\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
msm_camera_io_w(temp, vfe_dev->vfe_base +
|
||||
reg_cfg_cmd->u.mask_info.reg_offset);
|
||||
break;
|
||||
@@ -443,8 +464,10 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
uint32_t *hi_tbl_ptr = NULL, *lo_tbl_ptr = NULL;
|
||||
uint32_t hi_val, lo_val, lo_val1;
|
||||
if (reg_cfg_cmd->cmd_type == VFE_WRITE_DMI_64BIT) {
|
||||
- if (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||||
- reg_cfg_cmd->u.dmi_info.len > cmd_len) {
|
||||
+ if ((UINT_MAX - reg_cfg_cmd->u.dmi_info.hi_tbl_offset <
|
||||
+ reg_cfg_cmd->u.dmi_info.len) ||
|
||||
+ (reg_cfg_cmd->u.dmi_info.hi_tbl_offset +
|
||||
+ reg_cfg_cmd->u.dmi_info.len > cmd_len)) {
|
||||
pr_err("Invalid Hi Table out of bounds\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
@@ -528,6 +551,12 @@ static int msm_isp_send_hw_cmd(struct vfe_device *vfe_dev,
|
||||
uint32_t *data_ptr = cfg_data +
|
||||
reg_cfg_cmd->u.rw_info.cmd_data_offset/4;
|
||||
for (i = 0; i < reg_cfg_cmd->u.rw_info.len/4; i++) {
|
||||
+ if ((data_ptr < cfg_data) ||
|
||||
+ (UINT_MAX / sizeof(*data_ptr) <
|
||||
+ (data_ptr - cfg_data)) ||
|
||||
+ (sizeof(*data_ptr) * (data_ptr - cfg_data) >
|
||||
+ cmd_len))
|
||||
+ return -EINVAL;
|
||||
*data_ptr++ = msm_camera_io_r(vfe_dev->vfe_base +
|
||||
reg_cfg_cmd->u.rw_info.reg_offset);
|
||||
reg_cfg_cmd->u.rw_info.reg_offset += 4;
|
||||
@@ -545,6 +574,11 @@ int msm_isp_proc_cmd(struct vfe_device *vfe_dev, void *arg)
|
||||
struct msm_vfe_reg_cfg_cmd *reg_cfg_cmd;
|
||||
uint32_t *cfg_data;
|
||||
|
||||
+ if (!proc_cmd->num_cfg) {
|
||||
+ pr_err("%s: Passed num_cfg as 0\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
reg_cfg_cmd = kzalloc(sizeof(struct msm_vfe_reg_cfg_cmd)*
|
||||
proc_cmd->num_cfg, GFP_KERNEL);
|
||||
if (!reg_cfg_cmd) {
|
||||
@@ -856,11 +890,14 @@ void msm_isp_do_tasklet(unsigned long data)
|
||||
}
|
||||
}
|
||||
|
||||
-void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
|
||||
+int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg)
|
||||
{
|
||||
struct msm_vfe_axi_src_state *src_state = arg;
|
||||
+ if (src_state->input_src >= VFE_SRC_MAX)
|
||||
+ return -EINVAL;
|
||||
vfe_dev->axi_data.src_info[src_state->input_src].active =
|
||||
src_state->src_active;
|
||||
+ return 0;
|
||||
}
|
||||
|
||||
int msm_isp_open_node(struct v4l2_subdev *sd, struct v4l2_subdev_fh *fh)
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
|
||||
index 34b9859..9d9558a 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
|
||||
+++ b/drivers/media/platform/msm/camera_v2/isp/msm_isp_util.h
|
||||
@@ -64,7 +64,7 @@ int msm_isp_cal_word_per_line(uint32_t output_format,
|
||||
uint32_t pixel_per_line);
|
||||
int msm_isp_get_bit_per_pixel(uint32_t output_format);
|
||||
irqreturn_t msm_isp_process_irq(int irq_num, void *data);
|
||||
-void msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg);
|
||||
+int msm_isp_set_src_state(struct vfe_device *vfe_dev, void *arg);
|
||||
void msm_isp_do_tasklet(unsigned long data);
|
||||
void msm_isp_update_error_frame_count(struct vfe_device *vfe_dev);
|
||||
void msm_isp_process_error_info(struct vfe_device *vfe_dev);
|
||||
--
|
||||
cgit v1.1
|
||||
|
99
Patches/Linux_CVEs/CVE-2014-9872/0.patch
Normal file
99
Patches/Linux_CVEs/CVE-2014-9872/0.patch
Normal file
@ -0,0 +1,99 @@
|
||||
From fc787ebd71fa231cc7dd2a0d5f2208da0527096a Mon Sep 17 00:00:00 2001
|
||||
From: Katish Paran <kparan@codeaurora.org>
|
||||
Date: Fri, 31 Jan 2014 12:00:37 +0530
|
||||
Subject: diag: dci: Index DCI client table by client id
|
||||
|
||||
Diag driver maintains a table of all DCI clients. This table
|
||||
is currently indexed by the PID of the clients. Make changes
|
||||
to index the table base on an unique client id.
|
||||
|
||||
Change-Id: I57bfab9eae1381882b8eb6270d7ac212e0aaf271
|
||||
CRs-fixed: 590721
|
||||
Signed-off-by: Katish Paran <kparan@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diag_dci.c | 16 ++++++++++++++++
|
||||
drivers/char/diag/diag_dci.h | 4 ++++
|
||||
drivers/char/diag/diagchar_core.c | 4 +++-
|
||||
3 files changed, 23 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
|
||||
index 37c236d..0edfdad 100644
|
||||
--- a/drivers/char/diag/diag_dci.c
|
||||
+++ b/drivers/char/diag/diag_dci.c
|
||||
@@ -847,6 +847,22 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int diag_dci_find_client_index_health(int client_id)
|
||||
+{
|
||||
+ int i, ret = DCI_CLIENT_INDEX_INVALID;
|
||||
+
|
||||
+ for (i = 0; i < MAX_DCI_CLIENTS; i++) {
|
||||
+ if (driver->dci_client_tbl[i].client != NULL) {
|
||||
+ if (driver->dci_client_tbl[i].client_id ==
|
||||
+ client_id) {
|
||||
+ ret = i;
|
||||
+ break;
|
||||
+ }
|
||||
+ }
|
||||
+ }
|
||||
+ return ret;
|
||||
+}
|
||||
+
|
||||
int diag_dci_find_client_index(int client_id)
|
||||
{
|
||||
int i, ret = DCI_CLIENT_INDEX_INVALID;
|
||||
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
|
||||
index 2ab8a36..870b0f3 100644
|
||||
--- a/drivers/char/diag/diag_dci.h
|
||||
+++ b/drivers/char/diag/diag_dci.h
|
||||
@@ -56,6 +56,7 @@ struct dci_pkt_req_entry_t {
|
||||
} __packed;
|
||||
|
||||
struct diag_dci_client_tbl {
|
||||
+ uint32_t client_id;
|
||||
struct task_struct *client;
|
||||
uint16_t list; /* bit mask */
|
||||
int signal_type;
|
||||
@@ -74,6 +75,7 @@ struct diag_dci_client_tbl {
|
||||
|
||||
/* This is used for DCI health stats */
|
||||
struct diag_dci_health_stats {
|
||||
+ int client_id;
|
||||
int dropped_logs;
|
||||
int dropped_events;
|
||||
int received_logs;
|
||||
@@ -119,6 +121,8 @@ int diag_process_smd_dci_read_data(struct diag_smd_info *smd_info, void *buf,
|
||||
int recd_bytes);
|
||||
int diag_process_dci_transaction(unsigned char *buf, int len);
|
||||
void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf);
|
||||
+
|
||||
+int diag_dci_find_client_index_health(int client_id);
|
||||
int diag_dci_find_client_index(int client_id);
|
||||
/* DCI Log streaming functions */
|
||||
void create_dci_log_mask_tbl(unsigned char *tbl_buf);
|
||||
diff --git a/drivers/char/diag/diagchar_core.c b/drivers/char/diag/diagchar_core.c
|
||||
index 9a4e108..0e475c9 100644
|
||||
--- a/drivers/char/diag/diagchar_core.c
|
||||
+++ b/drivers/char/diag/diagchar_core.c
|
||||
@@ -943,6 +943,8 @@ long diagchar_ioctl(struct file *filp,
|
||||
for (i = 0; i < MAX_DCI_CLIENTS; i++) {
|
||||
if (driver->dci_client_tbl[i].client == NULL) {
|
||||
driver->dci_client_tbl[i].client = current;
|
||||
+ driver->dci_client_tbl[i].client_id =
|
||||
+ driver->dci_client_id;
|
||||
driver->dci_client_tbl[i].list =
|
||||
dci_params->list;
|
||||
driver->dci_client_tbl[i].signal_type =
|
||||
@@ -1043,7 +1045,7 @@ long diagchar_ioctl(struct file *filp,
|
||||
sizeof(struct diag_dci_health_stats)))
|
||||
return -EFAULT;
|
||||
mutex_lock(&dci_health_mutex);
|
||||
- i = diag_dci_find_client_index(current->tgid);
|
||||
+ i = diag_dci_find_client_index_health(stats.client_id);
|
||||
if (i != DCI_CLIENT_INDEX_INVALID) {
|
||||
dci_params = &(driver->dci_client_tbl[i]);
|
||||
stats.dropped_logs = dci_params->dropped_logs;
|
||||
--
|
||||
cgit v1.1
|
||||
|
35
Patches/Linux_CVEs/CVE-2014-9873/0.patch
Normal file
35
Patches/Linux_CVEs/CVE-2014-9873/0.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From ef29ae1d40536fef7fb95e4d5bb5b6b57bdf9420 Mon Sep 17 00:00:00 2001
|
||||
From: Katish Paran <kparan@codeaurora.org>
|
||||
Date: Tue, 17 Dec 2013 13:36:15 +0530
|
||||
Subject: diag: dci: Safeguard to prevent Integer Underflow and Memory Leak
|
||||
|
||||
At certain point in diag driver there can be integer underflow
|
||||
thus can lead to memory leak. Added a safeguard for that.
|
||||
|
||||
Change-Id: I2a0304f5b9888fe12ca9ef5fbaa9a68ee4ab9c15
|
||||
Crs-fixed: 556860
|
||||
Signed-off-by: Katish Paran <kparan@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diag_dci.c | 6 +++++-
|
||||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
|
||||
index 7772ebe..414207f 100644
|
||||
--- a/drivers/char/diag/diag_dci.c
|
||||
+++ b/drivers/char/diag/diag_dci.c
|
||||
@@ -216,7 +216,11 @@ void extract_dci_pkt_rsp(struct diag_smd_info *smd_info, unsigned char *buf)
|
||||
if (recv_pkt_cmd_code != DCI_PKT_RSP_CODE)
|
||||
cmd_code_len = 4; /* delayed response */
|
||||
write_len = (int)(*(uint16_t *)(buf+2)) - cmd_code_len;
|
||||
-
|
||||
+ if (write_len <= 0) {
|
||||
+ pr_err("diag: Invalid length in %s, write_len: %d",
|
||||
+ __func__, write_len);
|
||||
+ return;
|
||||
+ }
|
||||
pr_debug("diag: len = %d\n", write_len);
|
||||
tag = (int *)(buf + (4 + cmd_code_len)); /* Retrieve the Tag field */
|
||||
req_entry = diag_dci_get_request_entry(*tag);
|
||||
--
|
||||
cgit v1.1
|
||||
|
64
Patches/Linux_CVEs/CVE-2014-9874/0.patch
Normal file
64
Patches/Linux_CVEs/CVE-2014-9874/0.patch
Normal file
@ -0,0 +1,64 @@
|
||||
From 56ff68b1f93eaf22e5e0284648fd862dc08c9236 Mon Sep 17 00:00:00 2001
|
||||
From: Mohammad Johny Shaik <mjshai@codeaurora.org>
|
||||
Date: Thu, 12 Dec 2013 14:26:42 +0530
|
||||
Subject: Asoc:msm:Added Buffer overflow check
|
||||
|
||||
The overflow check is required to ensure that user space data
|
||||
in kernel may not go beyond buffer boundary.
|
||||
|
||||
Change-Id: I79b7e5f875fadcaeceb05f9163ae3666d4b6b7e1
|
||||
CRs-Fixed: 563086
|
||||
Signed-off-by: Mohammad Johny Shaik <mjshai@codeaurora.org>
|
||||
---
|
||||
arch/arm/mach-msm/qdsp6v2/audio_utils.c | 6 ++++++
|
||||
sound/soc/msm/qdsp6v2/q6asm.c | 3 +++
|
||||
2 files changed, 9 insertions(+)
|
||||
|
||||
diff --git a/arch/arm/mach-msm/qdsp6v2/audio_utils.c b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
|
||||
index 2a245f8..b8e55f9 100644
|
||||
--- a/arch/arm/mach-msm/qdsp6v2/audio_utils.c
|
||||
+++ b/arch/arm/mach-msm/qdsp6v2/audio_utils.c
|
||||
@@ -23,6 +23,7 @@
|
||||
#include <asm/ioctls.h>
|
||||
#include "audio_utils.h"
|
||||
|
||||
+#define FRAME_SIZE (1 + ((1536+sizeof(struct meta_out_dsp)) * 5))
|
||||
static int audio_in_pause(struct q6audio_in *audio)
|
||||
{
|
||||
int rc;
|
||||
@@ -258,6 +259,11 @@ long audio_in_ioctl(struct file *file,
|
||||
rc = -EINVAL;
|
||||
break;
|
||||
}
|
||||
+ if ((cfg.buffer_size > FRAME_SIZE) ||
|
||||
+ (cfg.buffer_count != FRAME_NUM)) {
|
||||
+ rc = -EINVAL;
|
||||
+ break;
|
||||
+ }
|
||||
audio->str_cfg.buffer_size = cfg.buffer_size;
|
||||
audio->str_cfg.buffer_count = cfg.buffer_count;
|
||||
rc = q6asm_audio_client_buf_alloc(OUT, audio->ac,
|
||||
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
|
||||
index 82b92aa9..09c40d6 100644
|
||||
--- a/sound/soc/msm/qdsp6v2/q6asm.c
|
||||
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
|
||||
@@ -55,6 +55,7 @@
|
||||
#define READDONE_IDX_FLAGS 8
|
||||
#define READDONE_IDX_NUMFRAMES 9
|
||||
#define READDONE_IDX_SEQ_ID 10
|
||||
+#define FRAME_NUM (8)
|
||||
|
||||
/* TODO, combine them together */
|
||||
static DEFINE_MUTEX(session_lock);
|
||||
@@ -608,6 +609,8 @@ int q6asm_audio_client_buf_alloc(unsigned int dir,
|
||||
pr_debug("%s: buffer already allocated\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
+ if (bufcnt != FRAME_NUM)
|
||||
+ goto fail;
|
||||
mutex_lock(&ac->cmd_lock);
|
||||
buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
|
||||
GFP_KERNEL);
|
||||
--
|
||||
cgit v1.1
|
||||
|
44
Patches/Linux_CVEs/CVE-2014-9874/1.patch
Normal file
44
Patches/Linux_CVEs/CVE-2014-9874/1.patch
Normal file
@ -0,0 +1,44 @@
|
||||
From 6b7b66961934660a91fb035e6e4223689a2500da Mon Sep 17 00:00:00 2001
|
||||
From: Masaki Sato <ams087@motorola.com>
|
||||
Date: Fri, 18 Apr 2014 13:23:17 -0500
|
||||
Subject: [PATCH] Revert "(CR): Asoc:msm:Added Buffer overflow check"
|
||||
|
||||
This change was only meant for A-family and causes EVRC encoder
|
||||
buffer allocation failure on B-family.
|
||||
|
||||
This reverts commit fdd50cb69df64e8eef0933c9ee9bccb1eeae69ca.
|
||||
|
||||
Change-Id: I2ce76602ef396a2939de05626c43ad4e87737418
|
||||
Signed-off-by: Masaki Sato <ams087@motorola.com>
|
||||
Reviewed-on: http://gerrit.mot.com/629216
|
||||
Submit-Approved: Jira Key <jirakey@motorola.com>
|
||||
Tested-by: Jira Key <jirakey@motorola.com>
|
||||
SLTApproved: Slta Waiver <sltawvr@motorola.com>
|
||||
Reviewed-by: Jeffrey Carlyle <jeff.carlyle@motorola.com>
|
||||
Reviewed-by: Sriram Divakar <sriramhd@motorola.com>
|
||||
Reviewed-by: Yin-Jun Chen <a7301c@motorola.com>
|
||||
---
|
||||
sound/soc/msm/qdsp6v2/q6asm.c | 3 ---
|
||||
1 file changed, 3 deletions(-)
|
||||
|
||||
diff --git a/sound/soc/msm/qdsp6v2/q6asm.c b/sound/soc/msm/qdsp6v2/q6asm.c
|
||||
index e09af8b48ba..77736150a60 100644
|
||||
--- a/sound/soc/msm/qdsp6v2/q6asm.c
|
||||
+++ b/sound/soc/msm/qdsp6v2/q6asm.c
|
||||
@@ -46,7 +46,6 @@
|
||||
|
||||
#define TRUE 0x01
|
||||
#define FALSE 0x00
|
||||
-#define FRAME_NUM (8)
|
||||
|
||||
/* TODO, combine them together */
|
||||
static DEFINE_MUTEX(session_lock);
|
||||
@@ -924,8 +923,6 @@ int q6asm_audio_client_buf_alloc(unsigned int dir,
|
||||
pr_debug("%s: buffer already allocated\n", __func__);
|
||||
return 0;
|
||||
}
|
||||
- if (bufcnt != FRAME_NUM)
|
||||
- goto fail;
|
||||
mutex_lock(&ac->cmd_lock);
|
||||
buf = kzalloc(((sizeof(struct audio_buffer))*bufcnt),
|
||||
GFP_KERNEL);
|
246
Patches/Linux_CVEs/CVE-2014-9875/0.patch
Normal file
246
Patches/Linux_CVEs/CVE-2014-9875/0.patch
Normal file
@ -0,0 +1,246 @@
|
||||
From b77c694b88a994d077316c157168c710696f8805 Mon Sep 17 00:00:00 2001
|
||||
From: Ravi Aravamudhan <aravamud@codeaurora.org>
|
||||
Date: Tue, 4 Jun 2013 10:10:11 -0700
|
||||
Subject: diag: dci: Check for request pkt length being lesser than minimum
|
||||
length
|
||||
|
||||
Added checks for DCI request packets to be greater than the minimum
|
||||
packet length. We would drop the request and print an error otherwise.
|
||||
|
||||
CRs-Fixed: 483310
|
||||
Change-Id: I0d89ded58ee97a08ebe6b06b411ac17d2fcb11df
|
||||
Signed-off-by: Ravi Aravamudhan <aravamud@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diag_dci.c | 114 ++++++++++++++++++++++++++++++++++---------
|
||||
drivers/char/diag/diag_dci.h | 3 ++
|
||||
2 files changed, 93 insertions(+), 24 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
|
||||
index 9b404c6..fa0e9d7 100644
|
||||
--- a/drivers/char/diag/diag_dci.c
|
||||
+++ b/drivers/char/diag/diag_dci.c
|
||||
@@ -375,16 +375,23 @@ void diag_dci_notify_client(int peripheral_mask, int data)
|
||||
int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
|
||||
int len, int index)
|
||||
{
|
||||
- int i;
|
||||
- int status = 0;
|
||||
+ int i, status = 0;
|
||||
+ unsigned int read_len = 0;
|
||||
|
||||
- /* remove UID from user space pkt before sending to peripheral */
|
||||
- buf = buf + 4;
|
||||
+ /* The first 4 bytes is the uid tag and the next four bytes is
|
||||
+ the minmum packet length of a request packet */
|
||||
+ if (len < DCI_PKT_REQ_MIN_LEN) {
|
||||
+ pr_err("diag: dci: Invalid pkt len %d in %s\n", len, __func__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
if (len > APPS_BUF_SIZE - 10) {
|
||||
- pr_err("diag: dci: buffer overwrite possible since payload bigger than buf size\n");
|
||||
+ pr_err("diag: dci: Invalid payload length in %s\n", __func__);
|
||||
return -EIO;
|
||||
}
|
||||
- len = len - 4;
|
||||
+ /* remove UID from user space pkt before sending to peripheral*/
|
||||
+ buf = buf + sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
+ len = len - sizeof(int);
|
||||
mutex_lock(&driver->dci_mutex);
|
||||
/* prepare DCI packet */
|
||||
driver->apps_dci_buf[0] = CONTROL_CHAR; /* start */
|
||||
@@ -395,7 +402,13 @@ int diag_send_dci_pkt(struct diag_master_table entry, unsigned char *buf,
|
||||
driver->req_tracking_tbl[index].tag;
|
||||
for (i = 0; i < len; i++)
|
||||
driver->apps_dci_buf[i+9] = *(buf+i);
|
||||
+ read_len += len;
|
||||
driver->apps_dci_buf[9+len] = CONTROL_CHAR; /* end */
|
||||
+ if ((read_len + 9) >= USER_SPACE_DATA) {
|
||||
+ pr_err("diag: dci: Invalid length while forming dci pkt in %s",
|
||||
+ __func__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
|
||||
for (i = 0; i < NUM_SMD_DCI_CHANNELS; i++) {
|
||||
struct diag_smd_info *smd_info = driver->separate_cmdrsp[i] ?
|
||||
@@ -449,10 +462,10 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
{
|
||||
unsigned char *temp = buf;
|
||||
uint16_t subsys_cmd_code, log_code, item_num;
|
||||
- int subsys_id, cmd_code, ret = -1, index = -1, found = 0, read_len = 0;
|
||||
+ int subsys_id, cmd_code, ret = -1, index = -1, found = 0;
|
||||
struct diag_master_table entry;
|
||||
int count, set_mask, num_codes, bit_index, event_id, offset = 0, i;
|
||||
- unsigned int byte_index;
|
||||
+ unsigned int byte_index, read_len = 0;
|
||||
uint8_t equip_id, *log_mask_ptr, *head_log_mask_ptr, byte_mask;
|
||||
uint8_t *event_mask_ptr;
|
||||
|
||||
@@ -462,15 +475,24 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
return DIAG_DCI_SEND_DATA_FAIL;
|
||||
}
|
||||
|
||||
+ if (!temp) {
|
||||
+ pr_err("diag: Invalid buffer in %s\n", __func__);
|
||||
+ }
|
||||
+
|
||||
/* This is Pkt request/response transaction */
|
||||
if (*(int *)temp > 0) {
|
||||
+ if (len < DCI_PKT_REQ_MIN_LEN || len > USER_SPACE_DATA) {
|
||||
+ pr_err("diag: dci: Invalid length %d len in %s", len,
|
||||
+ __func__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
/* enter this UID into kernel table and return index */
|
||||
index = diag_register_dci_transaction(*(int *)temp);
|
||||
if (index < 0) {
|
||||
pr_alert("diag: registering new DCI transaction failed\n");
|
||||
return DIAG_DCI_NO_REG;
|
||||
}
|
||||
- temp += 4;
|
||||
+ temp += sizeof(int);
|
||||
/*
|
||||
* Check for registered peripheral and fwd pkt to
|
||||
* appropriate proc
|
||||
@@ -480,7 +502,12 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
subsys_id = (int)(*(char *)temp);
|
||||
temp++;
|
||||
subsys_cmd_code = *(uint16_t *)temp;
|
||||
- temp += 2;
|
||||
+ temp += sizeof(uint16_t);
|
||||
+ read_len += sizeof(int) + 2 + sizeof(uint16_t);
|
||||
+ if (read_len >= USER_SPACE_DATA) {
|
||||
+ pr_err("diag: dci: Invalid length in %s\n", __func__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
pr_debug("diag: %d %d %d", cmd_code, subsys_id,
|
||||
subsys_cmd_code);
|
||||
for (i = 0; i < diag_max_reg; i++) {
|
||||
@@ -514,6 +541,12 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
}
|
||||
}
|
||||
} else if (*(int *)temp == DCI_LOG_TYPE) {
|
||||
+ /* Minimum length of a log mask config is 12 + 2 bytes for
|
||||
+ atleast one log code to be set or reset */
|
||||
+ if (len < DCI_LOG_CON_MIN_LEN || len > USER_SPACE_DATA) {
|
||||
+ pr_err("diag: dci: Invalid length in %s\n", __func__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
/* find client id and table */
|
||||
i = diag_dci_find_client_index(current->tgid);
|
||||
if (i == DCI_CLIENT_INDEX_INVALID) {
|
||||
@@ -521,21 +554,33 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
return ret;
|
||||
}
|
||||
/* Extract each log code and put in client table */
|
||||
- temp += 4;
|
||||
- read_len += 4;
|
||||
+ temp += sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
set_mask = *(int *)temp;
|
||||
- temp += 4;
|
||||
- read_len += 4;
|
||||
+ temp += sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
num_codes = *(int *)temp;
|
||||
- temp += 4;
|
||||
- read_len += 4;
|
||||
+ temp += sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
+
|
||||
+ if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
|
||||
+ pr_err("diag: dci: Invalid number of log codes %d\n",
|
||||
+ num_codes);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
|
||||
head_log_mask_ptr = driver->dci_client_tbl[i].dci_log_mask;
|
||||
+ if (!head_log_mask_ptr) {
|
||||
+ pr_err("diag: dci: Invalid Log mask pointer in %s\n",
|
||||
+ __func__);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
pr_debug("diag: head of dci log mask %p\n", head_log_mask_ptr);
|
||||
count = 0; /* iterator for extracting log codes */
|
||||
while (count < num_codes) {
|
||||
if (read_len >= USER_SPACE_DATA) {
|
||||
- pr_err("diag: dci: Log type, possible buffer overflow\n");
|
||||
+ pr_err("diag: dci: Invalid length for log type in %s",
|
||||
+ __func__);
|
||||
return -EIO;
|
||||
}
|
||||
log_code = *(uint16_t *)temp;
|
||||
@@ -589,6 +634,12 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
/* send updated mask to peripherals */
|
||||
ret = diag_send_dci_log_mask(driver->smd_cntl[MODEM_DATA].ch);
|
||||
} else if (*(int *)temp == DCI_EVENT_TYPE) {
|
||||
+ /* Minimum length of a event mask config is 12 + 4 bytes for
|
||||
+ atleast one event id to be set or reset. */
|
||||
+ if (len < DCI_EVENT_CON_MIN_LEN || len > USER_SPACE_DATA) {
|
||||
+ pr_err("diag: dci: Invalid length in %s\n", __func__);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
/* find client id and table */
|
||||
i = diag_dci_find_client_index(current->tgid);
|
||||
if (i == DCI_CLIENT_INDEX_INVALID) {
|
||||
@@ -596,21 +647,36 @@ int diag_process_dci_transaction(unsigned char *buf, int len)
|
||||
return ret;
|
||||
}
|
||||
/* Extract each log code and put in client table */
|
||||
- temp += 4;
|
||||
- read_len += 4;
|
||||
+ temp += sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
set_mask = *(int *)temp;
|
||||
- temp += 4;
|
||||
- read_len += 4;
|
||||
+ temp += sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
num_codes = *(int *)temp;
|
||||
- temp += 4;
|
||||
- read_len += 4;
|
||||
+ temp += sizeof(int);
|
||||
+ read_len += sizeof(int);
|
||||
+
|
||||
+ /* Check for positive number of event ids. Also, the number of
|
||||
+ event ids should fit in the buffer along with set_mask and
|
||||
+ num_codes which are 4 bytes each */
|
||||
+ if (num_codes == 0 || (num_codes >= (USER_SPACE_DATA - 8)/2)) {
|
||||
+ pr_err("diag: dci: Invalid number of event ids %d\n",
|
||||
+ num_codes);
|
||||
+ return -EIO;
|
||||
+ }
|
||||
|
||||
event_mask_ptr = driver->dci_client_tbl[i].dci_event_mask;
|
||||
+ if (!event_mask_ptr) {
|
||||
+ pr_err("diag: dci: Invalid event mask pointer in %s\n",
|
||||
+ __func__);
|
||||
+ return -ENOMEM;
|
||||
+ }
|
||||
pr_debug("diag: head of dci event mask %p\n", event_mask_ptr);
|
||||
count = 0; /* iterator for extracting log codes */
|
||||
while (count < num_codes) {
|
||||
if (read_len >= USER_SPACE_DATA) {
|
||||
- pr_err("diag: dci: Event type, possible buffer overflow\n");
|
||||
+ pr_err("diag: dci: Invalid length for event type in %s",
|
||||
+ __func__);
|
||||
return -EIO;
|
||||
}
|
||||
event_id = *(int *)temp;
|
||||
diff --git a/drivers/char/diag/diag_dci.h b/drivers/char/diag/diag_dci.h
|
||||
index 4dc1bfc..d530de9 100644
|
||||
--- a/drivers/char/diag/diag_dci.h
|
||||
+++ b/drivers/char/diag/diag_dci.h
|
||||
@@ -24,6 +24,9 @@
|
||||
#define DISABLE_LOG_MASK 0
|
||||
#define MAX_EVENT_SIZE 512
|
||||
#define DCI_CLIENT_INDEX_INVALID -1
|
||||
+#define DCI_PKT_REQ_MIN_LEN 8
|
||||
+#define DCI_LOG_CON_MIN_LEN 14
|
||||
+#define DCI_EVENT_CON_MIN_LEN 16
|
||||
|
||||
|
||||
/* 16 log code categories, each has:
|
||||
--
|
||||
cgit v1.1
|
||||
|
51
Patches/Linux_CVEs/CVE-2014-9876/0.patch
Normal file
51
Patches/Linux_CVEs/CVE-2014-9876/0.patch
Normal file
@ -0,0 +1,51 @@
|
||||
From 7efd393ca08ac74b2e3d2639b0ad77da139e9139 Mon Sep 17 00:00:00 2001
|
||||
From: Mohit Aggarwal <maggarwa@codeaurora.org>
|
||||
Date: Thu, 30 May 2013 11:12:39 +0530
|
||||
Subject: diag: Fix possible underflow/overflow issues
|
||||
|
||||
Add check in order to fix possible integer underflow
|
||||
during HDLC encoding which may lead to buffer
|
||||
overflow. Also added check for packet length to
|
||||
avoid buffer overflow.
|
||||
|
||||
Change-Id: I72858e7625764652571aee3154e3c2eb61655168
|
||||
CRs-Fixed: 483400
|
||||
CRs-Fixed: 483408
|
||||
Signed-off-by: Mohit Aggarwal <maggarwa@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diagfwd.c | 11 +++++++++--
|
||||
1 file changed, 9 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diagfwd.c b/drivers/char/diag/diagfwd.c
|
||||
index 05b2872..baa0a83 100644
|
||||
--- a/drivers/char/diag/diagfwd.c
|
||||
+++ b/drivers/char/diag/diagfwd.c
|
||||
@@ -95,7 +95,7 @@ do { \
|
||||
} while (0)
|
||||
|
||||
#define CHK_OVERFLOW(bufStart, start, end, length) \
|
||||
-((bufStart <= start) && (end - start >= length)) ? 1 : 0
|
||||
+((bufStart <= start) && (end - start >= length) && (length > 0)) ? 1 : 0
|
||||
|
||||
/* Determine if this device uses a device tree */
|
||||
#ifdef CONFIG_OF
|
||||
@@ -1604,8 +1604,15 @@ void diag_process_hdlc(void *data, unsigned len)
|
||||
|
||||
ret = diag_hdlc_decode(&hdlc);
|
||||
|
||||
+ /*
|
||||
+ * If the message is 3 bytes or less in length then the message is
|
||||
+ * too short. A message will need 4 bytes minimum, since there are
|
||||
+ * 2 bytes for the CRC and 1 byte for the ending 0x7e for the hdlc
|
||||
+ * encoding
|
||||
+ */
|
||||
if (hdlc.dest_idx < 4) {
|
||||
- pr_err("diag: Integer underflow in hdlc processing\n");
|
||||
+ pr_err_ratelimited("diag: In %s, message is too short, len: %d,"
|
||||
+ " dest len: %d\n", __func__, len, hdlc.dest_idx);
|
||||
return;
|
||||
}
|
||||
if (ret) {
|
||||
--
|
||||
cgit v1.1
|
||||
|
30
Patches/Linux_CVEs/CVE-2014-9876/1.patch
Normal file
30
Patches/Linux_CVEs/CVE-2014-9876/1.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From 794cd44fe8e32a4afe31a2f9f6a4499aaa874a48 Mon Sep 17 00:00:00 2001
|
||||
From: Mohit Aggarwal <maggarwa@codeaurora.org>
|
||||
Date: Thu, 2 Jun 2016 18:02:29 -0700
|
||||
Subject: [PATCH] diag: Fix possible underflow/overflow issues
|
||||
|
||||
Add check in order to fix possible integer underflow
|
||||
during HDLC encoding which may lead to buffer
|
||||
overflow. Also added check for packet length to
|
||||
avoid buffer overflow.
|
||||
|
||||
Bug: 28767796
|
||||
Change-Id: Ifbac719a7db73aab121cb00c2090edf1bf1094bb
|
||||
Signed-off-by: Yuan Lin <yualin@google.com>
|
||||
---
|
||||
drivers/char/diag/diagfwd.h | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diagfwd.h b/drivers/char/diag/diagfwd.h
|
||||
index c6e1273dc585c..9c514e629fb4c 100644
|
||||
--- a/drivers/char/diag/diagfwd.h
|
||||
+++ b/drivers/char/diag/diagfwd.h
|
||||
@@ -20,7 +20,7 @@
|
||||
#define RESET_AND_QUEUE 1
|
||||
|
||||
#define CHK_OVERFLOW(bufStart, start, end, length) \
|
||||
- ((((bufStart) <= (start)) && ((end) - (start) >= (length))) ? 1 : 0)
|
||||
+ ((((bufStart) <= (start)) && ((end) - (start) >= (length)) && ((length) > 0)) ? 1 : 0)
|
||||
|
||||
void diagfwd_init(void);
|
||||
void diagfwd_exit(void);
|
94
Patches/Linux_CVEs/CVE-2014-9877/0.patch
Normal file
94
Patches/Linux_CVEs/CVE-2014-9877/0.patch
Normal file
@ -0,0 +1,94 @@
|
||||
From f0c0112a6189747a3f24f20210157f9974477e03 Mon Sep 17 00:00:00 2001
|
||||
From: Vasko Kalanoski <vaskok@codeaurora.org>
|
||||
Date: Fri, 4 Oct 2013 15:28:34 +0300
|
||||
Subject: msm: actuator: fix to prevent untrusted pointer to lead DoS
|
||||
|
||||
fix to prevent untrusted userspace pointer in actuator kernel
|
||||
driver to lead DoS
|
||||
|
||||
Change-Id: I1b64270deb494530d268539e7b420be5ec79b658
|
||||
Signed-off-by: Vasko Kalanoski <vaskok@codeaurora.org>
|
||||
---
|
||||
.../msm/camera_v2/sensor/actuator/msm_actuator.c | 26 +++++++++++++++++-----
|
||||
1 file changed, 20 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
index baa2db8..201a011 100644
|
||||
--- a/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
+++ b/drivers/media/platform/msm/camera_v2/sensor/actuator/msm_actuator.c
|
||||
@@ -196,11 +196,19 @@ static int32_t msm_actuator_piezo_move_focus(
|
||||
struct msm_actuator_move_params_t *move_params)
|
||||
{
|
||||
int32_t dest_step_position = move_params->dest_step_pos;
|
||||
+ struct damping_params_t ringing_params_kernel;
|
||||
int32_t rc = 0;
|
||||
int32_t num_steps = move_params->num_steps;
|
||||
struct msm_camera_i2c_reg_setting reg_setting;
|
||||
CDBG("Enter\n");
|
||||
|
||||
+ if (copy_from_user(&ringing_params_kernel,
|
||||
+ &(move_params->ringing_params[0]),
|
||||
+ sizeof(struct damping_params_t))) {
|
||||
+ pr_err("copy_from_user failed\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
if (num_steps == 0)
|
||||
return rc;
|
||||
|
||||
@@ -208,7 +216,7 @@ static int32_t msm_actuator_piezo_move_focus(
|
||||
a_ctrl->func_tbl->actuator_parse_i2c_params(a_ctrl,
|
||||
(num_steps *
|
||||
a_ctrl->region_params[0].code_per_step),
|
||||
- move_params->ringing_params[0].hw_params, 0);
|
||||
+ ringing_params_kernel.hw_params, 0);
|
||||
|
||||
reg_setting.reg_setting = a_ctrl->i2c_reg_tbl;
|
||||
reg_setting.data_type = a_ctrl->i2c_data_type;
|
||||
@@ -230,6 +238,7 @@ static int32_t msm_actuator_move_focus(
|
||||
struct msm_actuator_move_params_t *move_params)
|
||||
{
|
||||
int32_t rc = 0;
|
||||
+ struct damping_params_t ringing_params_kernel;
|
||||
int8_t sign_dir = move_params->sign_dir;
|
||||
uint16_t step_boundary = 0;
|
||||
uint16_t target_step_pos = 0;
|
||||
@@ -240,6 +249,14 @@ static int32_t msm_actuator_move_focus(
|
||||
int32_t num_steps = move_params->num_steps;
|
||||
struct msm_camera_i2c_reg_setting reg_setting;
|
||||
|
||||
+ if (copy_from_user(&ringing_params_kernel,
|
||||
+ &(move_params->ringing_params[a_ctrl->curr_region_index]),
|
||||
+ sizeof(struct damping_params_t))) {
|
||||
+ pr_err("copy_from_user failed\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
+
|
||||
+
|
||||
CDBG("called, dir %d, num_steps %d\n", dir, num_steps);
|
||||
|
||||
if (dest_step_pos == a_ctrl->curr_step_pos)
|
||||
@@ -276,9 +293,7 @@ static int32_t msm_actuator_move_focus(
|
||||
a_ctrl->step_position_table[target_step_pos];
|
||||
a_ctrl->func_tbl->actuator_write_focus(a_ctrl,
|
||||
curr_lens_pos,
|
||||
- &(move_params->
|
||||
- ringing_params[a_ctrl->
|
||||
- curr_region_index]),
|
||||
+ &ringing_params_kernel,
|
||||
sign_dir,
|
||||
target_lens_pos);
|
||||
curr_lens_pos = target_lens_pos;
|
||||
@@ -289,8 +304,7 @@ static int32_t msm_actuator_move_focus(
|
||||
a_ctrl->step_position_table[target_step_pos];
|
||||
a_ctrl->func_tbl->actuator_write_focus(a_ctrl,
|
||||
curr_lens_pos,
|
||||
- &(move_params->ringing_params[a_ctrl->
|
||||
- curr_region_index]),
|
||||
+ &ringing_params_kernel,
|
||||
sign_dir,
|
||||
target_lens_pos);
|
||||
curr_lens_pos = target_lens_pos;
|
||||
--
|
||||
cgit v1.1
|
||||
|
103
Patches/Linux_CVEs/CVE-2014-9878/0.patch
Normal file
103
Patches/Linux_CVEs/CVE-2014-9878/0.patch
Normal file
@ -0,0 +1,103 @@
|
||||
From 96a62c1de93a44e6ca69514411baf4b3d67f6dee Mon Sep 17 00:00:00 2001
|
||||
From: Lee Susman <lsusman@codeaurora.org>
|
||||
Date: Mon, 11 Nov 2013 08:53:40 +0200
|
||||
Subject: mmc: card: fix arbitrary write via read handler in mmc_block_test
|
||||
|
||||
In mmc_block_test, the debug_fs based read function handlers write to an
|
||||
arbitrary buffer which is given by any user. We add an access_ok check
|
||||
to verify that the address pointed by *buffer is not in kernel space.
|
||||
Only if the buffer is valid, do we continue the read handler.
|
||||
|
||||
Change-Id: I35fe9bb70df8de92cb4d3b15c851aa9131a0e8d9
|
||||
Signed-off-by: Lee Susman <lsusman@codeaurora.org>
|
||||
---
|
||||
drivers/mmc/card/mmc_block_test.c | 24 ++++++++++++++++++++++++
|
||||
1 file changed, 24 insertions(+)
|
||||
|
||||
diff --git a/drivers/mmc/card/mmc_block_test.c b/drivers/mmc/card/mmc_block_test.c
|
||||
index ea73352..b24c367 100644
|
||||
--- a/drivers/mmc/card/mmc_block_test.c
|
||||
+++ b/drivers/mmc/card/mmc_block_test.c
|
||||
@@ -2219,6 +2219,9 @@ static ssize_t send_write_packing_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2317,6 +2320,9 @@ static ssize_t err_check_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2425,6 +2431,9 @@ static ssize_t send_invalid_packed_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2539,6 +2548,9 @@ static ssize_t write_packing_control_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2621,6 +2633,9 @@ static ssize_t bkops_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2709,6 +2724,9 @@ static ssize_t long_sequential_read_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2869,6 +2887,9 @@ static ssize_t long_sequential_write_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
@@ -2942,6 +2963,9 @@ static ssize_t new_req_notification_test_read(struct file *file,
|
||||
size_t count,
|
||||
loff_t *offset)
|
||||
{
|
||||
+ if (!access_ok(VERIFY_WRITE, buffer, count))
|
||||
+ return count;
|
||||
+
|
||||
memset((void *)buffer, 0, count);
|
||||
|
||||
snprintf(buffer, count,
|
||||
--
|
||||
cgit v1.1
|
||||
|
155
Patches/Linux_CVEs/CVE-2014-9879/0.patch
Normal file
155
Patches/Linux_CVEs/CVE-2014-9879/0.patch
Normal file
@ -0,0 +1,155 @@
|
||||
From ecc8116e1befb3a764109f47ba0389434ddabbe4 Mon Sep 17 00:00:00 2001
|
||||
From: Terence Hampson <thampson@codeaurora.org>
|
||||
Date: Wed, 7 Aug 2013 16:54:51 -0400
|
||||
Subject: mdss: mdp3: validate histogram data passed in
|
||||
|
||||
Data passed in from userspace should be validated to be within
|
||||
the appropriate ranges.
|
||||
|
||||
Change-Id: I50ff818a2b03c1fff55f44403f0f1b67c26d9f0e
|
||||
Signed-off-by: Terence Hampson <thampson@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/mdss/mdp3_ctrl.c | 77 +++++++++++++++++++++++++++++++++++---
|
||||
drivers/video/msm/mdss/mdp3_dma.c | 2 +-
|
||||
drivers/video/msm/mdss/mdp3_dma.h | 6 +++
|
||||
3 files changed, 79 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/drivers/video/msm/mdss/mdp3_ctrl.c b/drivers/video/msm/mdss/mdp3_ctrl.c
|
||||
index 74e6983c..31aae26 100644
|
||||
--- a/drivers/video/msm/mdss/mdp3_ctrl.c
|
||||
+++ b/drivers/video/msm/mdss/mdp3_ctrl.c
|
||||
@@ -775,6 +775,64 @@ static int mdp3_get_metadata(struct msm_fb_data_type *mfd,
|
||||
return ret;
|
||||
}
|
||||
|
||||
+int mdp3_validate_start_req(struct mdp_histogram_start_req *req)
|
||||
+{
|
||||
+ if (req->frame_cnt >= MDP_HISTOGRAM_FRAME_COUNT_MAX) {
|
||||
+ pr_err("%s invalid req frame_cnt\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (req->bit_mask >= MDP_HISTOGRAM_BIT_MASK_MAX) {
|
||||
+ pr_err("%s invalid req bit mask\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (req->block != MDP_BLOCK_DMA_P ||
|
||||
+ req->num_bins != MDP_HISTOGRAM_BIN_NUM) {
|
||||
+ pr_err("mdp3_histogram_start invalid request\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mdp3_validate_scale_config(struct mdp_bl_scale_data *data)
|
||||
+{
|
||||
+ if (data->scale > MDP_HISTOGRAM_BL_SCALE_MAX) {
|
||||
+ pr_err("%s invalid bl_scale\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (data->min_lvl > MDP_HISTOGRAM_BL_LEVEL_MAX) {
|
||||
+ pr_err("%s invalid bl_min_lvl\n", __func__);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+int mdp3_validate_csc_data(struct mdp_csc_cfg_data *data)
|
||||
+{
|
||||
+ int i;
|
||||
+ for (i = 0; i < 9; i++) {
|
||||
+ if (data->csc_data.csc_mv[i] >=
|
||||
+ MDP_HISTOGRAM_CSC_MATRIX_MAX)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ for (i = 0; i < 3; i++) {
|
||||
+ if (data->csc_data.csc_pre_bv[i] >=
|
||||
+ MDP_HISTOGRAM_CSC_VECTOR_MAX)
|
||||
+ return -EINVAL;
|
||||
+ if (data->csc_data.csc_post_bv[i] >=
|
||||
+ MDP_HISTOGRAM_CSC_VECTOR_MAX)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ for (i = 0; i < 6; i++) {
|
||||
+ if (data->csc_data.csc_pre_lv[i] >=
|
||||
+ MDP_HISTOGRAM_CSC_VECTOR_MAX)
|
||||
+ return -EINVAL;
|
||||
+ if (data->csc_data.csc_post_lv[i] >=
|
||||
+ MDP_HISTOGRAM_CSC_VECTOR_MAX)
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
static int mdp3_histogram_start(struct mdp3_session_data *session,
|
||||
struct mdp_histogram_start_req *req)
|
||||
{
|
||||
@@ -782,11 +840,10 @@ static int mdp3_histogram_start(struct mdp3_session_data *session,
|
||||
struct mdp3_dma_histogram_config histo_config;
|
||||
|
||||
pr_debug("mdp3_histogram_start\n");
|
||||
- if (req->block != MDP_BLOCK_DMA_P ||
|
||||
- req->num_bins != MDP_HISTOGRAM_BIN_NUM) {
|
||||
- pr_err("mdp3_histogram_start invalid request\n");
|
||||
- return -EINVAL;
|
||||
- }
|
||||
+
|
||||
+ ret = mdp3_validate_start_req(req);
|
||||
+ if (ret)
|
||||
+ return ret;
|
||||
|
||||
if (!session->dma->histo_op ||
|
||||
!session->dma->config_histo) {
|
||||
@@ -986,10 +1043,20 @@ static int mdp3_pp_ioctl(struct msm_fb_data_type *mfd,
|
||||
|
||||
switch (mdp_pp.op) {
|
||||
case mdp_bl_scale_cfg:
|
||||
+ ret = mdp3_validate_scale_config(&mdp_pp.data.bl_scale_data);
|
||||
+ if (ret) {
|
||||
+ pr_err("%s: invalid scale config\n", __func__);
|
||||
+ break;
|
||||
+ }
|
||||
ret = mdp3_bl_scale_config(mfd, (struct mdp_bl_scale_data *)
|
||||
&mdp_pp.data.bl_scale_data);
|
||||
break;
|
||||
case mdp_op_csc_cfg:
|
||||
+ ret = mdp3_validate_csc_data(&(mdp_pp.data.csc_cfg_data));
|
||||
+ if (ret) {
|
||||
+ pr_err("%s: invalid csc data\n", __func__);
|
||||
+ break;
|
||||
+ }
|
||||
ret = mdp3_csc_config(mdp3_session,
|
||||
&(mdp_pp.data.csc_cfg_data));
|
||||
break;
|
||||
diff --git a/drivers/video/msm/mdss/mdp3_dma.c b/drivers/video/msm/mdss/mdp3_dma.c
|
||||
index 3e1bf5d..d3f1538 100644
|
||||
--- a/drivers/video/msm/mdss/mdp3_dma.c
|
||||
+++ b/drivers/video/msm/mdss/mdp3_dma.c
|
||||
@@ -497,7 +497,7 @@ static int mdp3_dmap_histo_config(struct mdp3_dma *dma,
|
||||
struct mdp3_dma_histogram_config *histo_config)
|
||||
{
|
||||
unsigned long flag;
|
||||
- u32 histo_bit_mask, histo_control;
|
||||
+ u32 histo_bit_mask = 0, histo_control = 0;
|
||||
u32 histo_isr_mask = MDP3_DMA_P_HIST_INTR_HIST_DONE_BIT |
|
||||
MDP3_DMA_P_HIST_INTR_RESET_DONE_BIT;
|
||||
|
||||
diff --git a/drivers/video/msm/mdss/mdp3_dma.h b/drivers/video/msm/mdss/mdp3_dma.h
|
||||
index e4a28dc..7dd6ba7 100644
|
||||
--- a/drivers/video/msm/mdss/mdp3_dma.h
|
||||
+++ b/drivers/video/msm/mdss/mdp3_dma.h
|
||||
@@ -16,6 +16,12 @@
|
||||
|
||||
#include <linux/sched.h>
|
||||
|
||||
+#define MDP_HISTOGRAM_BL_SCALE_MAX 1024
|
||||
+#define MDP_HISTOGRAM_BL_LEVEL_MAX 255
|
||||
+#define MDP_HISTOGRAM_FRAME_COUNT_MAX 0x20
|
||||
+#define MDP_HISTOGRAM_BIT_MASK_MAX 0x4
|
||||
+#define MDP_HISTOGRAM_CSC_MATRIX_MAX 0x2000
|
||||
+#define MDP_HISTOGRAM_CSC_VECTOR_MAX 0x200
|
||||
#define MDP_HISTOGRAM_BIN_NUM 32
|
||||
#define MDP_LUT_SIZE 256
|
||||
|
||||
--
|
||||
cgit v1.1
|
||||
|
35
Patches/Linux_CVEs/CVE-2014-9880/0.patch
Normal file
35
Patches/Linux_CVEs/CVE-2014-9880/0.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From f2a3f5e63e15e97a66e8f5a300457378bcb89d9c Mon Sep 17 00:00:00 2001
|
||||
From: Deepak Verma <dverma@codeaurora.org>
|
||||
Date: Mon, 21 Oct 2013 17:37:11 +0530
|
||||
Subject: msm: vidc: Check validity of userspace address
|
||||
|
||||
Before writing to a userspace address, verification
|
||||
of the validity of user space address is required.
|
||||
|
||||
Change-Id: I9141e44a6c11aaf3f4d57c08bb0dd26a7b214f34
|
||||
CRs-fixed: 556356
|
||||
Signed-off-by: Deepak Verma <dverma@codeaurora.org>
|
||||
---
|
||||
drivers/video/msm/vidc/common/enc/venc.c | 6 ++++++
|
||||
1 file changed, 6 insertions(+)
|
||||
|
||||
diff --git a/drivers/video/msm/vidc/common/enc/venc.c b/drivers/video/msm/vidc/common/enc/venc.c
|
||||
index 1801461..707d948 100644
|
||||
--- a/drivers/video/msm/vidc/common/enc/venc.c
|
||||
+++ b/drivers/video/msm/vidc/common/enc/venc.c
|
||||
@@ -1414,6 +1414,12 @@ static long vid_enc_ioctl(struct file *file,
|
||||
return -EFAULT;
|
||||
|
||||
DBG("VEN_IOCTL_GET_SEQUENCE_HDR\n");
|
||||
+ if (!access_ok(VERIFY_WRITE, seq_header.hdrbufptr,
|
||||
+ seq_header.bufsize)) {
|
||||
+ ERR("VEN_IOCTL_GET_SEQUENCE_HDR:"\
|
||||
+ " Userspace address verification failed.\n");
|
||||
+ return -EFAULT;
|
||||
+ }
|
||||
result = vid_enc_get_sequence_header(client_ctx,
|
||||
&seq_header);
|
||||
if (!result) {
|
||||
--
|
||||
cgit v1.1
|
||||
|
63
Patches/Linux_CVEs/CVE-2014-9881/0.patch
Normal file
63
Patches/Linux_CVEs/CVE-2014-9881/0.patch
Normal file
@ -0,0 +1,63 @@
|
||||
From ba3f404a10b3bb7e9c20440837df3cd35c5d0c4b Mon Sep 17 00:00:00 2001
|
||||
From: Ayaz Ahmad <aahmad@codeaurora.org>
|
||||
Date: Thu, 31 Oct 2013 19:08:05 +0530
|
||||
Subject: radio: iris: Prevent probable overflow
|
||||
|
||||
casting a unsigned int into an integer, integer to
|
||||
unsigned int may cause buffer overflow.
|
||||
|
||||
Change-Id: I54be4d4c5470616a59a772c587fe6d5f32575c32
|
||||
CRs-Fixed: 539008
|
||||
Signed-off-by: Ayaz Ahmad <aahmad@codeaurora.org>
|
||||
---
|
||||
drivers/media/radio/radio-iris.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
|
||||
index bfb1088..12fd7cf 100644
|
||||
--- a/drivers/media/radio/radio-iris.c
|
||||
+++ b/drivers/media/radio/radio-iris.c
|
||||
@@ -3032,7 +3032,7 @@ static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
|
||||
struct v4l2_ext_controls *ctrl)
|
||||
{
|
||||
int retval = 0;
|
||||
- int bytes_to_copy;
|
||||
+ size_t bytes_to_copy;
|
||||
struct hci_fm_tx_ps tx_ps;
|
||||
struct hci_fm_tx_rt tx_rt;
|
||||
struct hci_fm_def_data_wr_req default_data;
|
||||
@@ -3041,14 +3041,20 @@ static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
|
||||
struct iris_device *radio = video_get_drvdata(video_devdata(file));
|
||||
char *data = NULL;
|
||||
|
||||
+ if ((ctrl == NULL) || (ctrl->controls == NULL)
|
||||
+ || (ctrl->count == 0)) {
|
||||
+ retval = -EINVAL;
|
||||
+ return retval;
|
||||
+ }
|
||||
+
|
||||
switch ((ctrl->controls[0]).id) {
|
||||
case V4L2_CID_RDS_TX_PS_NAME:
|
||||
FMDBG("In V4L2_CID_RDS_TX_PS_NAME\n");
|
||||
/*Pass a sample PS string */
|
||||
|
||||
memset(tx_ps.ps_data, 0, MAX_PS_LENGTH);
|
||||
- bytes_to_copy = min((int)(ctrl->controls[0]).size,
|
||||
- MAX_PS_LENGTH);
|
||||
+ bytes_to_copy = min_t(size_t, ctrl->controls[0].size,
|
||||
+ MAX_PS_LENGTH);
|
||||
data = (ctrl->controls[0]).string;
|
||||
|
||||
if (copy_from_user(tx_ps.ps_data,
|
||||
@@ -3065,7 +3071,7 @@ static int iris_vidioc_s_ext_ctrls(struct file *file, void *priv,
|
||||
break;
|
||||
case V4L2_CID_RDS_TX_RADIO_TEXT:
|
||||
bytes_to_copy =
|
||||
- min((int)(ctrl->controls[0]).size, MAX_RT_LENGTH);
|
||||
+ min_t(size_t, (ctrl->controls[0]).size, MAX_RT_LENGTH);
|
||||
data = (ctrl->controls[0]).string;
|
||||
|
||||
memset(tx_rt.rt_data, 0, MAX_RT_LENGTH);
|
||||
--
|
||||
cgit v1.1
|
||||
|
54
Patches/Linux_CVEs/CVE-2014-9882/0.patch
Normal file
54
Patches/Linux_CVEs/CVE-2014-9882/0.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From 3a4ebaac557a9e3fbcbab4561650abac8298a4d9 Mon Sep 17 00:00:00 2001
|
||||
From: Satish Kodishala <skodisha@codeaurora.org>
|
||||
Date: Thu, 10 Oct 2013 15:44:11 +0530
|
||||
Subject: radio: iris: Checking if driver's buffer is large enough.
|
||||
|
||||
Checking if driver's buffer is large enough to copy
|
||||
the data from user space.
|
||||
|
||||
Change-Id: I7b4eed81cf77ce2973669ce18ccd95a5df397d82
|
||||
CRs-fixed: 552329
|
||||
Signed-off-by: Satish Kodishala <skodisha@codeaurora.org>
|
||||
---
|
||||
drivers/media/radio/radio-iris.c | 23 ++++++++++++++++++-----
|
||||
1 file changed, 18 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
|
||||
index 5e056be..a9e25bd 100644
|
||||
--- a/drivers/media/radio/radio-iris.c
|
||||
+++ b/drivers/media/radio/radio-iris.c
|
||||
@@ -3472,13 +3472,26 @@ static int iris_vidioc_s_ctrl(struct file *file, void *priv,
|
||||
radio->riva_data_req.cmd_params.start_addr = ctrl->value;
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_IRIS_RIVA_ACCS_LEN:
|
||||
- radio->riva_data_req.cmd_params.length = ctrl->value;
|
||||
+ if ((ctrl->value > 0) &&
|
||||
+ (ctrl->value <= MAX_RIVA_PEEK_RSP_SIZE)) {
|
||||
+ radio->riva_data_req.cmd_params.length = ctrl->value;
|
||||
+ } else {
|
||||
+ FMDERR("Length %d is more than the buffer size %d\n",
|
||||
+ ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
|
||||
+ retval = -EINVAL;
|
||||
+ }
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
|
||||
- memcpy(radio->riva_data_req.data, (void *)ctrl->value,
|
||||
- radio->riva_data_req.cmd_params.length);
|
||||
- radio->riva_data_req.cmd_params.subopcode = RIVA_POKE_OPCODE;
|
||||
- retval = hci_poke_data(&radio->riva_data_req , radio->fm_hdev);
|
||||
+ if (radio->riva_data_req.cmd_params.length <= MAX_RIVA_PEEK_RSP_SIZE) {
|
||||
+ memcpy(radio->riva_data_req.data, (void *)ctrl->value,
|
||||
+ radio->riva_data_req.cmd_params.length);
|
||||
+ radio->riva_data_req.cmd_params.subopcode = RIVA_POKE_OPCODE;
|
||||
+ retval = hci_poke_data(&radio->riva_data_req , radio->fm_hdev);
|
||||
+ } else {
|
||||
+ FMDERR("Can not copy into driver's buffer. Length %d is more than"
|
||||
+ "the buffer size %d\n", ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
|
||||
+ retval = -EINVAL;
|
||||
+ }
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_IRIS_SSBI_ACCS_ADDR:
|
||||
radio->ssbi_data_accs.start_addr = ctrl->value;
|
||||
--
|
||||
cgit v1.1
|
||||
|
48
Patches/Linux_CVEs/CVE-2014-9882/1.patch
Normal file
48
Patches/Linux_CVEs/CVE-2014-9882/1.patch
Normal file
@ -0,0 +1,48 @@
|
||||
From 0f6afe815b1b3f920f3502be654c848bdfe5ef38 Mon Sep 17 00:00:00 2001
|
||||
From: Ayaz Ahmad <aahmad@codeaurora.org>
|
||||
Date: Tue, 8 Oct 2013 15:56:04 +0530
|
||||
Subject: radio: iris: Use kernel API to copy data from user space
|
||||
|
||||
Use copy_from_user kernel api to copy any data from user space
|
||||
to kernel space.
|
||||
|
||||
Change-Id: Ia3b7bb0f98180bd8792c1c18e930cb5609b8dc82
|
||||
CRs-Fixed: 540320
|
||||
Signed-off-by: Ayaz Ahmad <aahmad@codeaurora.org>
|
||||
---
|
||||
drivers/media/radio/radio-iris.c | 16 ++++++++++++----
|
||||
1 file changed, 12 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/drivers/media/radio/radio-iris.c b/drivers/media/radio/radio-iris.c
|
||||
index a554749..3bac006 100644
|
||||
--- a/drivers/media/radio/radio-iris.c
|
||||
+++ b/drivers/media/radio/radio-iris.c
|
||||
@@ -3623,13 +3623,21 @@ static int iris_vidioc_s_ctrl(struct file *file, void *priv,
|
||||
break;
|
||||
case V4L2_CID_PRIVATE_IRIS_RIVA_POKE:
|
||||
if (radio->riva_data_req.cmd_params.length <= MAX_RIVA_PEEK_RSP_SIZE) {
|
||||
- memcpy(radio->riva_data_req.data, (void *)ctrl->value,
|
||||
+ retval = copy_from_user(radio->riva_data_req.data,
|
||||
+ (void *)ctrl->value,
|
||||
radio->riva_data_req.cmd_params.length);
|
||||
- radio->riva_data_req.cmd_params.subopcode = RIVA_POKE_OPCODE;
|
||||
- retval = hci_poke_data(&radio->riva_data_req , radio->fm_hdev);
|
||||
+ if (retval == 0) {
|
||||
+ radio->riva_data_req.cmd_params.subopcode =
|
||||
+ RIVA_POKE_OPCODE;
|
||||
+ retval = hci_poke_data(&radio->riva_data_req,
|
||||
+ radio->fm_hdev);
|
||||
+ } else {
|
||||
+ retval = -EINVAL;
|
||||
+ }
|
||||
} else {
|
||||
FMDERR("Can not copy into driver's buffer. Length %d is more than"
|
||||
- "the buffer size %d\n", ctrl->value, MAX_RIVA_PEEK_RSP_SIZE);
|
||||
+ "the buffer size %d\n", radio->riva_data_req.cmd_params.length,
|
||||
+ MAX_RIVA_PEEK_RSP_SIZE);
|
||||
retval = -EINVAL;
|
||||
}
|
||||
break;
|
||||
--
|
||||
cgit v1.1
|
||||
|
58
Patches/Linux_CVEs/CVE-2014-9883/0.patch
Normal file
58
Patches/Linux_CVEs/CVE-2014-9883/0.patch
Normal file
@ -0,0 +1,58 @@
|
||||
From cbf79a67348e48557c0d0bb9bc58391b3f84bc46 Mon Sep 17 00:00:00 2001
|
||||
From: Katish Paran <kparan@codeaurora.org>
|
||||
Date: Tue, 24 Dec 2013 14:11:41 +0530
|
||||
Subject: diag: dci: Safeguard to prevent integer overflow
|
||||
|
||||
At certain point in diag driver there can be integer overflow
|
||||
thus can lead to memory leak. Added a safegaurd for it.
|
||||
|
||||
Change-Id: I9347405d8f1f95ed42fe0abf35cbf4c362281bdf
|
||||
CRs-fixed: 565160
|
||||
Signed-off-by: Katish Paran <kparan@codeaurora.org>
|
||||
---
|
||||
drivers/char/diag/diag_dci.c | 12 +++++++++---
|
||||
1 file changed, 9 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/drivers/char/diag/diag_dci.c b/drivers/char/diag/diag_dci.c
|
||||
index 2dbb2f5..7772ebe 100644
|
||||
--- a/drivers/char/diag/diag_dci.c
|
||||
+++ b/drivers/char/diag/diag_dci.c
|
||||
@@ -383,17 +383,23 @@ void extract_dci_events(unsigned char *buf)
|
||||
|
||||
void extract_dci_log(unsigned char *buf)
|
||||
{
|
||||
- uint16_t log_code, item_num;
|
||||
+ uint16_t log_code, item_num, log_length;
|
||||
uint8_t equip_id, *log_mask_ptr, byte_mask;
|
||||
unsigned int i, byte_index, byte_offset = 0;
|
||||
struct diag_dci_client_tbl *entry;
|
||||
|
||||
+ log_length = *(uint16_t *)(buf + 2);
|
||||
log_code = *(uint16_t *)(buf + 6);
|
||||
equip_id = LOG_GET_EQUIP_ID(log_code);
|
||||
item_num = LOG_GET_ITEM_NUM(log_code);
|
||||
byte_index = item_num/8 + 2;
|
||||
byte_mask = 0x01 << (item_num % 8);
|
||||
|
||||
+ if (log_length > USHRT_MAX - 4) {
|
||||
+ pr_err("diag: Integer overflow in %s, log_len:%d",
|
||||
+ __func__, log_length);
|
||||
+ return;
|
||||
+ }
|
||||
byte_offset = (equip_id * 514) + byte_index;
|
||||
if (byte_offset >= DCI_LOG_MASK_SIZE) {
|
||||
pr_err("diag: Invalid byte_offset %d in dci log\n",
|
||||
@@ -430,8 +436,8 @@ void extract_dci_log(unsigned char *buf)
|
||||
*(int *)(entry->dci_data+entry->data_len) =
|
||||
DCI_LOG_TYPE;
|
||||
memcpy(entry->dci_data + entry->data_len + 4,
|
||||
- buf + 4, *(uint16_t *)(buf + 2));
|
||||
- entry->data_len += 4 + *(uint16_t *)(buf + 2);
|
||||
+ buf + 4, log_length);
|
||||
+ entry->data_len += 4 + log_length;
|
||||
}
|
||||
mutex_unlock(&entry->data_mutex);
|
||||
mutex_unlock(&dci_health_mutex);
|
||||
--
|
||||
cgit v1.1
|
||||
|
151
Patches/Linux_CVEs/CVE-2014-9884/0.patch
Normal file
151
Patches/Linux_CVEs/CVE-2014-9884/0.patch
Normal file
@ -0,0 +1,151 @@
|
||||
From f4948193c46f75e16d4382c4472485ab12b7bd17 Mon Sep 17 00:00:00 2001
|
||||
From: Zhen Kong <zkong@codeaurora.org>
|
||||
Date: Mon, 25 Nov 2013 13:05:35 -0800
|
||||
Subject: qseecom: Add checks for user space buffer pointers
|
||||
|
||||
Validate pointers send from user space and pointers
|
||||
embedded within the mesasge sent from user space.
|
||||
|
||||
Change-Id: I1be54924ef3d301908af6e8d4e6506f2aa7f6428
|
||||
Signed-off-by: Mona Hossain <mhossain@codeaurora.org>
|
||||
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++-
|
||||
1 file changed, 60 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 0bc18fb..c5c0ce8 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -99,7 +99,7 @@ static DEFINE_MUTEX(clk_access_lock);
|
||||
struct qseecom_registered_listener_list {
|
||||
struct list_head list;
|
||||
struct qseecom_register_listener_req svc;
|
||||
- u8 *sb_reg_req;
|
||||
+ uint32_t user_virt_sb_base;
|
||||
u8 *sb_virt;
|
||||
s32 sb_phys;
|
||||
size_t sb_length;
|
||||
@@ -319,6 +319,10 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
|
||||
pr_err("copy_from_user failed\n");
|
||||
return ret;
|
||||
}
|
||||
+ if (!access_ok(VERIFY_WRITE, (void __user *)rcvd_lstnr.virt_sb_base,
|
||||
+ rcvd_lstnr.sb_size))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
data->listener.id = 0;
|
||||
if (!__qseecom_is_svc_unique(data, &rcvd_lstnr)) {
|
||||
pr_err("Service is not unique and is already registered\n");
|
||||
@@ -336,6 +340,7 @@ static int qseecom_register_listener(struct qseecom_dev_handle *data,
|
||||
|
||||
new_entry->svc.listener_id = rcvd_lstnr.listener_id;
|
||||
new_entry->sb_length = rcvd_lstnr.sb_size;
|
||||
+ new_entry->user_virt_sb_base = rcvd_lstnr.virt_sb_base;
|
||||
if (__qseecom_set_sb_memory(new_entry, data, &rcvd_lstnr)) {
|
||||
pr_err("qseecom_set_sb_memoryfailed\n");
|
||||
kzfree(new_entry);
|
||||
@@ -446,6 +451,10 @@ static int qseecom_set_client_mem_param(struct qseecom_dev_handle *data,
|
||||
req.ifd_data_fd, req.sb_len, req.virt_sb_base);
|
||||
return -EFAULT;
|
||||
}
|
||||
+ if (!access_ok(VERIFY_WRITE, (void __user *)req.virt_sb_base,
|
||||
+ req.sb_len))
|
||||
+ return -EFAULT;
|
||||
+
|
||||
/* Get the handle of the shared fd */
|
||||
data->client.ihandle = ion_import_dma_buf(qseecom.ion_clnt,
|
||||
req.ifd_data_fd);
|
||||
@@ -861,6 +870,13 @@ static uint32_t __qseecom_uvirt_to_kphys(struct qseecom_dev_handle *data,
|
||||
return data->client.sb_phys + (virt - data->client.user_virt_sb_base);
|
||||
}
|
||||
|
||||
+static uint32_t __qseecom_uvirt_to_kvirt(struct qseecom_dev_handle *data,
|
||||
+ uint32_t virt)
|
||||
+{
|
||||
+ return (uint32_t)data->client.sb_virt +
|
||||
+ (virt - data->client.user_virt_sb_base);
|
||||
+}
|
||||
+
|
||||
int __qseecom_process_rpmb_svc_cmd(struct qseecom_dev_handle *data_ptr,
|
||||
struct qseecom_send_svc_cmd_req *req_ptr,
|
||||
struct qseecom_client_send_service_ireq *send_svc_ireq_ptr)
|
||||
@@ -1269,6 +1285,24 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
|
||||
pr_err("copy_from_user failed\n");
|
||||
return ret;
|
||||
}
|
||||
+
|
||||
+ if (req.cmd_req_buf == NULL || req.resp_buf == NULL) {
|
||||
+ pr_err("cmd buffer or response buffer is null\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ if (((uint32_t)req.cmd_req_buf < data->client.user_virt_sb_base) ||
|
||||
+ ((uint32_t)req.cmd_req_buf >= (data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length))) {
|
||||
+ pr_err("cmd buffer address not within shared bufffer\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
+ if (((uint32_t)req.resp_buf < data->client.user_virt_sb_base) ||
|
||||
+ ((uint32_t)req.resp_buf >= (data->client.user_virt_sb_base +
|
||||
+ data->client.sb_length))){
|
||||
+ pr_err("response buffer address not within shared bufffer\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
send_cmd_req.cmd_req_buf = req.cmd_req_buf;
|
||||
send_cmd_req.cmd_req_len = req.cmd_req_len;
|
||||
send_cmd_req.resp_buf = req.resp_buf;
|
||||
@@ -1282,6 +1316,11 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
+ req.cmd_req_buf = (void *)__qseecom_uvirt_to_kvirt(data,
|
||||
+ (uint32_t)req.cmd_req_buf);
|
||||
+ req.resp_buf = (void *)__qseecom_uvirt_to_kvirt(data,
|
||||
+ (uint32_t)req.resp_buf);
|
||||
+
|
||||
ret = __qseecom_update_cmd_buf(&req, false, data, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -1877,11 +1916,20 @@ static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data,
|
||||
{
|
||||
struct qseecom_send_modfd_listener_resp resp;
|
||||
int i;
|
||||
+ struct qseecom_registered_listener_list *this_lstnr = NULL;
|
||||
|
||||
if (copy_from_user(&resp, argp, sizeof(resp))) {
|
||||
pr_err("copy_from_user failed");
|
||||
return -EINVAL;
|
||||
}
|
||||
+ this_lstnr = __qseecom_find_svc(data->listener.id);
|
||||
+ if (this_lstnr == NULL)
|
||||
+ return -EINVAL;
|
||||
+
|
||||
+ if (resp.resp_buf_ptr == NULL) {
|
||||
+ pr_err("Invalid resp_buf_ptr\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
/* validate offsets */
|
||||
for (i = 0; i < MAX_ION_FD; i++) {
|
||||
if (resp.ifd_data[i].cmd_buf_offset >= resp.resp_len) {
|
||||
@@ -1890,6 +1938,17 @@ static int qseecom_send_modfd_resp(struct qseecom_dev_handle *data,
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
+
|
||||
+ if (((uint32_t)resp.resp_buf_ptr <
|
||||
+ this_lstnr->user_virt_sb_base)
|
||||
+ || ((uint32_t)resp.resp_buf_ptr >=
|
||||
+ (this_lstnr->user_virt_sb_base +
|
||||
+ this_lstnr->sb_length))) {
|
||||
+ pr_err("resp_buf_ptr address not within shared buffer\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+ resp.resp_buf_ptr = (uint32_t)this_lstnr->sb_virt +
|
||||
+ (resp.resp_buf_ptr - this_lstnr->user_virt_sb_base);
|
||||
__qseecom_update_cmd_buf(&resp, false, data, true);
|
||||
qseecom.send_resp_flag = 1;
|
||||
wake_up_interruptible(&qseecom.send_resp_wq);
|
||||
--
|
||||
cgit v1.1
|
||||
|
30
Patches/Linux_CVEs/CVE-2014-9885/0.patch
Normal file
30
Patches/Linux_CVEs/CVE-2014-9885/0.patch
Normal file
@ -0,0 +1,30 @@
|
||||
From a1d5a4cbd5aa8656bc23b40c7cc43941e10f89c3 Mon Sep 17 00:00:00 2001
|
||||
From: Dipen Parmar <dipenp@codeaurora.org>
|
||||
Date: Fri, 18 Oct 2013 15:53:36 +0530
|
||||
Subject: thermal: qpnp-adc-tm: Fix format specifier in snprintf
|
||||
|
||||
Add format specifier in snprintf to avoid security
|
||||
vulnerability issues.
|
||||
|
||||
Change-Id: I6ea67633348341267e0646912a6b428709410c78
|
||||
Signed-off-by: Dipen Parmar <dipenp@codeaurora.org>
|
||||
---
|
||||
drivers/thermal/qpnp-adc-tm.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/drivers/thermal/qpnp-adc-tm.c b/drivers/thermal/qpnp-adc-tm.c
|
||||
index a90a042..b203ae3 100644
|
||||
--- a/drivers/thermal/qpnp-adc-tm.c
|
||||
+++ b/drivers/thermal/qpnp-adc-tm.c
|
||||
@@ -1886,7 +1886,7 @@ static int qpnp_adc_tm_probe(struct spmi_device *spmi)
|
||||
pr_debug("thermal node%x\n", btm_channel_num);
|
||||
chip->sensor[sen_idx].mode = THERMAL_DEVICE_DISABLED;
|
||||
chip->sensor[sen_idx].thermal_node = true;
|
||||
- snprintf(name, sizeof(name),
|
||||
+ snprintf(name, sizeof(name), "%s",
|
||||
chip->adc->adc_channels[sen_idx].name);
|
||||
chip->sensor[sen_idx].meas_interval =
|
||||
QPNP_ADC_TM_MEAS_INTERVAL;
|
||||
--
|
||||
cgit v1.1
|
||||
|
178
Patches/Linux_CVEs/CVE-2014-9886/0.patch
Normal file
178
Patches/Linux_CVEs/CVE-2014-9886/0.patch
Normal file
@ -0,0 +1,178 @@
|
||||
From 80be0e249c906704085d13d4ae446f73913fc225 Mon Sep 17 00:00:00 2001
|
||||
From: Baruch Eruchimovitch <baruche@codeaurora.org>
|
||||
Date: Mon, 14 Oct 2013 15:49:41 +0300
|
||||
Subject: msm: ultrasound: add verifications of some input parameters
|
||||
|
||||
Some security vulnerabilities were found.
|
||||
To fix them, additional verifications of some input parameters
|
||||
are required.
|
||||
|
||||
CRs-Fixed: 554575, 554560, 555030
|
||||
Change-Id: Ie87a433bcda89c3e462cfd511c168e8306056020
|
||||
Signed-off-by: Baruch Eruchimovitch <baruche@codeaurora.org>
|
||||
---
|
||||
arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c | 82 ++++++++++++++++++------------
|
||||
1 file changed, 49 insertions(+), 33 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
|
||||
index 1ea213a..01fcfd9 100644
|
||||
--- a/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
|
||||
+++ b/arch/arm/mach-msm/qdsp6v2/ultrasound/usf.c
|
||||
@@ -51,6 +51,11 @@
|
||||
#define Y_IND 1
|
||||
#define Z_IND 2
|
||||
|
||||
+/* Shared memory limits */
|
||||
+/* max_buf_size = (port_size(65535*2) * port_num(8) * group_size(3) */
|
||||
+#define USF_MAX_BUF_SIZE 3145680
|
||||
+#define USF_MAX_BUF_NUM 32
|
||||
+
|
||||
/* Place for opreation result, received from QDSP6 */
|
||||
#define APR_RESULT_IND 1
|
||||
|
||||
@@ -436,6 +441,15 @@ static int config_xx(struct usf_xx_type *usf_xx, struct us_xx_info_type *config)
|
||||
(config == NULL))
|
||||
return -EINVAL;
|
||||
|
||||
+ if ((config->buf_size == 0) ||
|
||||
+ (config->buf_size > USF_MAX_BUF_SIZE) ||
|
||||
+ (config->buf_num == 0) ||
|
||||
+ (config->buf_num > USF_MAX_BUF_NUM)) {
|
||||
+ pr_err("%s: wrong params: buf_size=%d; buf_num=%d\n",
|
||||
+ __func__, config->buf_size, config->buf_num);
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
data_map_size = sizeof(usf_xx->encdec_cfg.cfg_common.data_map);
|
||||
min_map_size = min(data_map_size, config->port_cnt);
|
||||
|
||||
@@ -748,6 +762,7 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||||
{
|
||||
uint32_t timeout = 0;
|
||||
struct us_detect_info_type detect_info;
|
||||
+ struct usm_session_cmd_detect_info *p_allocated_memory = NULL;
|
||||
struct usm_session_cmd_detect_info usm_detect_info;
|
||||
struct usm_session_cmd_detect_info *p_usm_detect_info =
|
||||
&usm_detect_info;
|
||||
@@ -774,12 +789,13 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||||
uint8_t *p_data = NULL;
|
||||
|
||||
detect_info_size += detect_info.params_data_size;
|
||||
- p_usm_detect_info = kzalloc(detect_info_size, GFP_KERNEL);
|
||||
- if (p_usm_detect_info == NULL) {
|
||||
+ p_allocated_memory = kzalloc(detect_info_size, GFP_KERNEL);
|
||||
+ if (p_allocated_memory == NULL) {
|
||||
pr_err("%s: detect_info[%d] allocation failed\n",
|
||||
__func__, detect_info_size);
|
||||
return -ENOMEM;
|
||||
}
|
||||
+ p_usm_detect_info = p_allocated_memory;
|
||||
p_data = (uint8_t *)p_usm_detect_info +
|
||||
sizeof(struct usm_session_cmd_detect_info);
|
||||
|
||||
@@ -789,7 +805,7 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||||
if (rc) {
|
||||
pr_err("%s: copy params from user; rc=%d\n",
|
||||
__func__, rc);
|
||||
- kfree(p_usm_detect_info);
|
||||
+ kfree(p_allocated_memory);
|
||||
return -EFAULT;
|
||||
}
|
||||
p_usm_detect_info->algorithm_cfg_size =
|
||||
@@ -806,9 +822,7 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||||
p_usm_detect_info,
|
||||
detect_info_size);
|
||||
if (rc || (detect_info.detect_timeout == USF_NO_WAIT_TIMEOUT)) {
|
||||
- if (detect_info_size >
|
||||
- sizeof(struct usm_session_cmd_detect_info))
|
||||
- kfree(p_usm_detect_info);
|
||||
+ kfree(p_allocated_memory);
|
||||
return rc;
|
||||
}
|
||||
|
||||
@@ -828,25 +842,24 @@ static int usf_set_us_detection(struct usf_type *usf, unsigned long arg)
|
||||
USF_US_DETECT_UNDEF),
|
||||
timeout);
|
||||
/* In the case of timeout, "no US" is assumed */
|
||||
- if (rc < 0) {
|
||||
+ if (rc < 0)
|
||||
pr_err("%s: Getting US detection failed rc[%d]\n",
|
||||
__func__, rc);
|
||||
- return rc;
|
||||
- }
|
||||
-
|
||||
- usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
|
||||
- detect_info.is_us = (usf_xx->us_detect_type == USF_US_DETECT_YES);
|
||||
- rc = copy_to_user((void __user *)arg,
|
||||
- &detect_info,
|
||||
- sizeof(detect_info));
|
||||
- if (rc) {
|
||||
- pr_err("%s: copy detect_info to user; rc=%d\n",
|
||||
- __func__, rc);
|
||||
- rc = -EFAULT;
|
||||
+ else {
|
||||
+ usf->usf_rx.us_detect_type = usf->usf_tx.us_detect_type;
|
||||
+ detect_info.is_us =
|
||||
+ (usf_xx->us_detect_type == USF_US_DETECT_YES);
|
||||
+ rc = copy_to_user((void __user *)arg,
|
||||
+ &detect_info,
|
||||
+ sizeof(detect_info));
|
||||
+ if (rc) {
|
||||
+ pr_err("%s: copy detect_info to user; rc=%d\n",
|
||||
+ __func__, rc);
|
||||
+ rc = -EFAULT;
|
||||
+ }
|
||||
}
|
||||
|
||||
- if (detect_info_size > sizeof(struct usm_session_cmd_detect_info))
|
||||
- kfree(p_usm_detect_info);
|
||||
+ kfree(p_allocated_memory);
|
||||
|
||||
return rc;
|
||||
} /* usf_set_us_detection */
|
||||
@@ -947,16 +960,14 @@ static int usf_set_rx_info(struct usf_type *usf, unsigned long arg)
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
- if (usf_xx->buffer_size && usf_xx->buffer_count) {
|
||||
- rc = q6usm_us_client_buf_alloc(
|
||||
- IN,
|
||||
- usf_xx->usc,
|
||||
- usf_xx->buffer_size,
|
||||
- usf_xx->buffer_count);
|
||||
- if (rc) {
|
||||
- (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
|
||||
- return rc;
|
||||
- }
|
||||
+ rc = q6usm_us_client_buf_alloc(
|
||||
+ IN,
|
||||
+ usf_xx->usc,
|
||||
+ usf_xx->buffer_size,
|
||||
+ usf_xx->buffer_count);
|
||||
+ if (rc) {
|
||||
+ (void)q6usm_cmd(usf_xx->usc, CMD_CLOSE);
|
||||
+ return rc;
|
||||
}
|
||||
|
||||
rc = q6usm_dec_cfg_blk(usf_xx->usc,
|
||||
@@ -1175,10 +1186,15 @@ static int usf_get_version(unsigned long arg)
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
- /* version_info.buf is pointer to place for the version string */
|
||||
+ if (version_info.buf_size < sizeof(DRV_VERSION)) {
|
||||
+ pr_err("%s: buf_size (%d) < version string size (%d)\n",
|
||||
+ __func__, version_info.buf_size, sizeof(DRV_VERSION));
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
rc = copy_to_user(version_info.pbuf,
|
||||
DRV_VERSION,
|
||||
- version_info.buf_size);
|
||||
+ sizeof(DRV_VERSION));
|
||||
if (rc) {
|
||||
pr_err("%s: copy to version_info.pbuf; rc=%d\n",
|
||||
__func__, rc);
|
||||
--
|
||||
cgit v1.1
|
||||
|
35
Patches/Linux_CVEs/CVE-2014-9887/0.patch
Normal file
35
Patches/Linux_CVEs/CVE-2014-9887/0.patch
Normal file
@ -0,0 +1,35 @@
|
||||
From b1bc773cf61265e0e3871b2e52bd6b3270ffc6c3 Mon Sep 17 00:00:00 2001
|
||||
From: Zhen Kong <zkong@codeaurora.org>
|
||||
Date: Thu, 27 Mar 2014 12:44:15 -0700
|
||||
Subject: qseecom: Validate pointer offset in qseecom_send_modfd_cmd
|
||||
|
||||
Validate cmd_req_buf pointer offset in qseecom_send_modfy_cmd, and
|
||||
make sure cmd buffer address to be within shared bufffer.
|
||||
|
||||
Change-Id: I431511a92ab2cccbc2daebc0cf76cc3872689a97
|
||||
Signed-off-by: Zhen Kong <zkong@codeaurora.org>
|
||||
---
|
||||
drivers/misc/qseecom.c | 7 +++++++
|
||||
1 file changed, 7 insertions(+)
|
||||
|
||||
diff --git a/drivers/misc/qseecom.c b/drivers/misc/qseecom.c
|
||||
index 5d2b64c..bce4994 100644
|
||||
--- a/drivers/misc/qseecom.c
|
||||
+++ b/drivers/misc/qseecom.c
|
||||
@@ -1635,6 +1635,13 @@ static int qseecom_send_modfd_cmd(struct qseecom_dev_handle *data,
|
||||
pr_err("response buffer address not within shared bufffer\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
+
|
||||
+ if (req.cmd_req_len == 0 || req.cmd_req_len > data->client.sb_length ||
|
||||
+ req.resp_len > data->client.sb_length) {
|
||||
+ pr_err("cmd or response buffer length not valid\n");
|
||||
+ return -EINVAL;
|
||||
+ }
|
||||
+
|
||||
send_cmd_req.cmd_req_buf = req.cmd_req_buf;
|
||||
send_cmd_req.cmd_req_len = req.cmd_req_len;
|
||||
send_cmd_req.resp_buf = req.resp_buf;
|
||||
--
|
||||
cgit v1.1
|
||||
|
37
Patches/Linux_CVEs/CVE-2014-9888/0.patch
Normal file
37
Patches/Linux_CVEs/CVE-2014-9888/0.patch
Normal file
@ -0,0 +1,37 @@
|
||||
From 0ea1ec713f04bdfac343c9702b21cd3a7c711826 Mon Sep 17 00:00:00 2001
|
||||
From: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
Date: Wed, 23 Oct 2013 16:14:59 +0100
|
||||
Subject: [PATCH] ARM: dma-mapping: don't allow DMA mappings to be marked
|
||||
executable
|
||||
|
||||
DMA mapping permissions were being derived from pgprot_kernel directly
|
||||
without using PAGE_KERNEL. This causes them to be marked with executable
|
||||
permission, which is not what we want. Fix this.
|
||||
|
||||
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
|
||||
---
|
||||
arch/arm/mm/dma-mapping.c | 4 ++--
|
||||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||||
|
||||
diff --git a/arch/arm/mm/dma-mapping.c b/arch/arm/mm/dma-mapping.c
|
||||
index f5e1a8471714c..57438506d5246 100644
|
||||
--- a/arch/arm/mm/dma-mapping.c
|
||||
+++ b/arch/arm/mm/dma-mapping.c
|
||||
@@ -687,7 +687,7 @@ static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
|
||||
void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
|
||||
gfp_t gfp, struct dma_attrs *attrs)
|
||||
{
|
||||
- pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
|
||||
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
|
||||
void *memory;
|
||||
|
||||
if (dma_alloc_from_coherent(dev, size, handle, &memory))
|
||||
@@ -700,7 +700,7 @@ void *arm_dma_alloc(struct device *dev, size_t size, dma_addr_t *handle,
|
||||
static void *arm_coherent_dma_alloc(struct device *dev, size_t size,
|
||||
dma_addr_t *handle, gfp_t gfp, struct dma_attrs *attrs)
|
||||
{
|
||||
- pgprot_t prot = __get_dma_pgprot(attrs, pgprot_kernel);
|
||||
+ pgprot_t prot = __get_dma_pgprot(attrs, PAGE_KERNEL);
|
||||
void *memory;
|
||||
|
||||
if (dma_alloc_from_coherent(dev, size, handle, &memory))
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user