--- /dev/null
+From 3dc9acb67600393249a795934ccdfc291a200e6b Mon Sep 17 00:00:00 2001
+From: Linus Torvalds <torvalds@linux-foundation.org>
+Date: Fri, 20 Dec 2013 05:11:12 +0900
+Subject: aio: clean up and fix aio_setup_ring page mapping
+
+From: Linus Torvalds <torvalds@linux-foundation.org>
+
+commit 3dc9acb67600393249a795934ccdfc291a200e6b upstream.
+
+Since commit 36bc08cc01709 ("fs/aio: Add support to aio ring pages
+migration") the aio ring setup code has used a special per-ring backing
+inode for the page allocations, rather than just using random anonymous
+pages.
+
+However, rather than remembering the pages as it allocated them, it
+would allocate the pages, insert them into the file mapping (dirty, so
+that they couldn't be free'd), and then forget about them. And then to
+look them up again, it would mmap the mapping, and then use
+"get_user_pages()" to get back an array of the pages we just created.
+
+Now, not only is that incredibly inefficient, it also leaked all the
+pages if the mmap failed (which could happen due to excessive number of
+mappings, for example).
+
+So clean it all up, making it much more straightforward. Also remove
+some left-overs of the previous (broken) mm_populate() usage that was
+removed in commit d6c355c7dabc ("aio: fix race in ring buffer page
+lookup introduced by page migration support") but left the pointless and
+now misleading MAP_POPULATE flag around.
+
+Tested-and-acked-by: Benjamin LaHaise <bcrl@kvack.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/aio.c | 58 +++++++++++++++++++++++-----------------------------------
+ 1 file changed, 23 insertions(+), 35 deletions(-)
+
+--- a/fs/aio.c
++++ b/fs/aio.c
+@@ -326,7 +326,7 @@ static int aio_setup_ring(struct kioctx
+ struct aio_ring *ring;
+ unsigned nr_events = ctx->max_reqs;
+ struct mm_struct *mm = current->mm;
+- unsigned long size, populate;
++ unsigned long size, unused;
+ int nr_pages;
+ int i;
+ struct file *file;
+@@ -347,6 +347,20 @@ static int aio_setup_ring(struct kioctx
+ return -EAGAIN;
+ }
+
++ ctx->aio_ring_file = file;
++ nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring))
++ / sizeof(struct io_event);
++
++ ctx->ring_pages = ctx->internal_pages;
++ if (nr_pages > AIO_RING_PAGES) {
++ ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *),
++ GFP_KERNEL);
++ if (!ctx->ring_pages) {
++ put_aio_ring_file(ctx);
++ return -ENOMEM;
++ }
++ }
++
+ for (i = 0; i < nr_pages; i++) {
+ struct page *page;
+ page = find_or_create_page(file->f_inode->i_mapping,
+@@ -358,19 +372,14 @@ static int aio_setup_ring(struct kioctx
+ SetPageUptodate(page);
+ SetPageDirty(page);
+ unlock_page(page);
++
++ ctx->ring_pages[i] = page;
+ }
+- ctx->aio_ring_file = file;
+- nr_events = (PAGE_SIZE * nr_pages - sizeof(struct aio_ring))
+- / sizeof(struct io_event);
++ ctx->nr_pages = i;
+
+- ctx->ring_pages = ctx->internal_pages;
+- if (nr_pages > AIO_RING_PAGES) {
+- ctx->ring_pages = kcalloc(nr_pages, sizeof(struct page *),
+- GFP_KERNEL);
+- if (!ctx->ring_pages) {
+- put_aio_ring_file(ctx);
+- return -ENOMEM;
+- }
++ if (unlikely(i != nr_pages)) {
++ aio_free_ring(ctx);
++ return -EAGAIN;
+ }
+
+ ctx->mmap_size = nr_pages * PAGE_SIZE;
+@@ -379,9 +388,9 @@ static int aio_setup_ring(struct kioctx
+ down_write(&mm->mmap_sem);
+ ctx->mmap_base = do_mmap_pgoff(ctx->aio_ring_file, 0, ctx->mmap_size,
+ PROT_READ | PROT_WRITE,
+- MAP_SHARED | MAP_POPULATE, 0, &populate);
++ MAP_SHARED, 0, &unused);
++ up_write(&mm->mmap_sem);
+ if (IS_ERR((void *)ctx->mmap_base)) {
+- up_write(&mm->mmap_sem);
+ ctx->mmap_size = 0;
+ aio_free_ring(ctx);
+ return -EAGAIN;
+@@ -389,27 +398,6 @@ static int aio_setup_ring(struct kioctx
+
+ pr_debug("mmap address: 0x%08lx\n", ctx->mmap_base);
+
+- /* We must do this while still holding mmap_sem for write, as we
+- * need to be protected against userspace attempting to mremap()
+- * or munmap() the ring buffer.
+- */
+- ctx->nr_pages = get_user_pages(current, mm, ctx->mmap_base, nr_pages,
+- 1, 0, ctx->ring_pages, NULL);
+-
+- /* Dropping the reference here is safe as the page cache will hold
+- * onto the pages for us. It is also required so that page migration
+- * can unmap the pages and get the right reference count.
+- */
+- for (i = 0; i < ctx->nr_pages; i++)
+- put_page(ctx->ring_pages[i]);
+-
+- up_write(&mm->mmap_sem);
+-
+- if (unlikely(ctx->nr_pages != nr_pages)) {
+- aio_free_ring(ctx);
+- return -EAGAIN;
+- }
+-
+ ctx->user_id = ctx->mmap_base;
+ ctx->nr_events = nr_events; /* trusted copy */
+
--- /dev/null
+From 8e321fefb0e60bae4e2a28d20fc4fa30758d27c6 Mon Sep 17 00:00:00 2001
+From: Benjamin LaHaise <bcrl@kvack.org>
+Date: Sat, 21 Dec 2013 17:56:08 -0500
+Subject: aio/migratepages: make aio migrate pages sane
+
+From: Benjamin LaHaise <bcrl@kvack.org>
+
+commit 8e321fefb0e60bae4e2a28d20fc4fa30758d27c6 upstream.
+
+The arbitrary restriction on page counts offered by the core
+migrate_page_move_mapping() code results in rather suspicious looking
+fiddling with page reference counts in the aio_migratepage() operation.
+To fix this, make migrate_page_move_mapping() take an extra_count parameter
+that allows aio to tell the code about its own reference count on the page
+being migrated.
+
+While cleaning up aio_migratepage(), make it validate that the old page
+being passed in is actually what aio_migratepage() expects to prevent
+misbehaviour in the case of races.
+
+Signed-off-by: Benjamin LaHaise <bcrl@kvack.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ fs/aio.c | 52 ++++++++++++++++++++++++++++++++++++++++--------
+ include/linux/migrate.h | 3 +-
+ mm/migrate.c | 13 ++++++------
+ 3 files changed, 53 insertions(+), 15 deletions(-)
+
+--- a/fs/aio.c
++++ b/fs/aio.c
+@@ -244,9 +244,14 @@ static void aio_free_ring(struct kioctx
+ int i;
+
+ for (i = 0; i < ctx->nr_pages; i++) {
++ struct page *page;
+ pr_debug("pid(%d) [%d] page->count=%d\n", current->pid, i,
+ page_count(ctx->ring_pages[i]));
+- put_page(ctx->ring_pages[i]);
++ page = ctx->ring_pages[i];
++ if (!page)
++ continue;
++ ctx->ring_pages[i] = NULL;
++ put_page(page);
+ }
+
+ put_aio_ring_file(ctx);
+@@ -280,18 +285,38 @@ static int aio_migratepage(struct addres
+ unsigned long flags;
+ int rc;
+
++ rc = 0;
++
++ /* Make sure the old page hasn't already been changed */
++ spin_lock(&mapping->private_lock);
++ ctx = mapping->private_data;
++ if (ctx) {
++ pgoff_t idx;
++ spin_lock_irqsave(&ctx->completion_lock, flags);
++ idx = old->index;
++ if (idx < (pgoff_t)ctx->nr_pages) {
++ if (ctx->ring_pages[idx] != old)
++ rc = -EAGAIN;
++ } else
++ rc = -EINVAL;
++ spin_unlock_irqrestore(&ctx->completion_lock, flags);
++ } else
++ rc = -EINVAL;
++ spin_unlock(&mapping->private_lock);
++
++ if (rc != 0)
++ return rc;
++
+ /* Writeback must be complete */
+ BUG_ON(PageWriteback(old));
+- put_page(old);
++ get_page(new);
+
+- rc = migrate_page_move_mapping(mapping, new, old, NULL, mode);
++ rc = migrate_page_move_mapping(mapping, new, old, NULL, mode, 1);
+ if (rc != MIGRATEPAGE_SUCCESS) {
+- get_page(old);
++ put_page(new);
+ return rc;
+ }
+
+- get_page(new);
+-
+ /* We can potentially race against kioctx teardown here. Use the
+ * address_space's private data lock to protect the mapping's
+ * private_data.
+@@ -303,13 +328,24 @@ static int aio_migratepage(struct addres
+ spin_lock_irqsave(&ctx->completion_lock, flags);
+ migrate_page_copy(new, old);
+ idx = old->index;
+- if (idx < (pgoff_t)ctx->nr_pages)
+- ctx->ring_pages[idx] = new;
++ if (idx < (pgoff_t)ctx->nr_pages) {
++ /* And only do the move if things haven't changed */
++ if (ctx->ring_pages[idx] == old)
++ ctx->ring_pages[idx] = new;
++ else
++ rc = -EAGAIN;
++ } else
++ rc = -EINVAL;
+ spin_unlock_irqrestore(&ctx->completion_lock, flags);
+ } else
+ rc = -EBUSY;
+ spin_unlock(&mapping->private_lock);
+
++ if (rc == MIGRATEPAGE_SUCCESS)
++ put_page(old);
++ else
++ put_page(new);
++
+ return rc;
+ }
+ #endif
+--- a/include/linux/migrate.h
++++ b/include/linux/migrate.h
+@@ -55,7 +55,8 @@ extern int migrate_huge_page_move_mappin
+ struct page *newpage, struct page *page);
+ extern int migrate_page_move_mapping(struct address_space *mapping,
+ struct page *newpage, struct page *page,
+- struct buffer_head *head, enum migrate_mode mode);
++ struct buffer_head *head, enum migrate_mode mode,
++ int extra_count);
+ #else
+
+ static inline void putback_lru_pages(struct list_head *l) {}
+--- a/mm/migrate.c
++++ b/mm/migrate.c
+@@ -315,14 +315,15 @@ static inline bool buffer_migrate_lock_b
+ */
+ int migrate_page_move_mapping(struct address_space *mapping,
+ struct page *newpage, struct page *page,
+- struct buffer_head *head, enum migrate_mode mode)
++ struct buffer_head *head, enum migrate_mode mode,
++ int extra_count)
+ {
+- int expected_count = 0;
++ int expected_count = 1 + extra_count;
+ void **pslot;
+
+ if (!mapping) {
+ /* Anonymous page without mapping */
+- if (page_count(page) != 1)
++ if (page_count(page) != expected_count)
+ return -EAGAIN;
+ return MIGRATEPAGE_SUCCESS;
+ }
+@@ -332,7 +333,7 @@ int migrate_page_move_mapping(struct add
+ pslot = radix_tree_lookup_slot(&mapping->page_tree,
+ page_index(page));
+
+- expected_count = 2 + page_has_private(page);
++ expected_count += 1 + page_has_private(page);
+ if (page_count(page) != expected_count ||
+ radix_tree_deref_slot_protected(pslot, &mapping->tree_lock) != page) {
+ spin_unlock_irq(&mapping->tree_lock);
+@@ -525,7 +526,7 @@ int migrate_page(struct address_space *m
+
+ BUG_ON(PageWriteback(page)); /* Writeback must be complete */
+
+- rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode);
++ rc = migrate_page_move_mapping(mapping, newpage, page, NULL, mode, 0);
+
+ if (rc != MIGRATEPAGE_SUCCESS)
+ return rc;
+@@ -552,7 +553,7 @@ int buffer_migrate_page(struct address_s
+
+ head = page_buffers(page);
+
+- rc = migrate_page_move_mapping(mapping, newpage, page, head, mode);
++ rc = migrate_page_move_mapping(mapping, newpage, page, head, mode, 0);
+
+ if (rc != MIGRATEPAGE_SUCCESS)
+ return rc;
--- /dev/null
+From 85dc6ee1237c8a4a7742e6abab96a20389b7d682 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@altera.com>
+Date: Tue, 10 Dec 2013 19:49:18 +0100
+Subject: clocksource: dw_apb_timer_of: Fix read_sched_clock
+
+From: Dinh Nguyen <dinguyen@altera.com>
+
+commit 85dc6ee1237c8a4a7742e6abab96a20389b7d682 upstream.
+
+The read_sched_clock should return the ~value because the clock is a
+countdown implementation. read_sched_clock() should be the same as
+ __apbt_read_clocksource().
+
+Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clocksource/dw_apb_timer_of.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/clocksource/dw_apb_timer_of.c
++++ b/drivers/clocksource/dw_apb_timer_of.c
+@@ -108,7 +108,7 @@ static void add_clocksource(struct devic
+
+ static u32 read_sched_clock(void)
+ {
+- return __raw_readl(sched_io_base);
++ return ~__raw_readl(sched_io_base);
+ }
+
+ static const struct of_device_id sptimer_ids[] __initconst = {
--- /dev/null
+From 9ab4727c1d41e50b67aecde4bf11879560a3ca78 Mon Sep 17 00:00:00 2001
+From: Dinh Nguyen <dinguyen@altera.com>
+Date: Tue, 10 Dec 2013 19:49:18 +0100
+Subject: clocksource: dw_apb_timer_of: Fix support for dts binding "snps,dw-apb-timer"
+
+From: Dinh Nguyen <dinguyen@altera.com>
+
+commit 9ab4727c1d41e50b67aecde4bf11879560a3ca78 upstream.
+
+In commit 620f5e1cbf (dts: Rename DW APB timer compatible strings), both
+"snps,dw-apb-timer-sp" and "snps,dw-apb-timer-osc" were deprecated in place
+of "snps,dw-apb-timer". But the driver also needs to be udpated in order to
+support this new binding "snps,dw-apb-timer".
+
+Signed-off-by: Dinh Nguyen <dinguyen@altera.com>
+Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ drivers/clocksource/dw_apb_timer_of.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/drivers/clocksource/dw_apb_timer_of.c
++++ b/drivers/clocksource/dw_apb_timer_of.c
+@@ -113,7 +113,6 @@ static u32 read_sched_clock(void)
+
+ static const struct of_device_id sptimer_ids[] __initconst = {
+ { .compatible = "picochip,pc3x2-rtc" },
+- { .compatible = "snps,dw-apb-timer-sp" },
+ { /* Sentinel */ },
+ };
+
+@@ -153,4 +152,6 @@ static void __init dw_apb_timer_init(str
+ num_called++;
+ }
+ CLOCKSOURCE_OF_DECLARE(pc3x2_timer, "picochip,pc3x2-timer", dw_apb_timer_init);
+-CLOCKSOURCE_OF_DECLARE(apb_timer, "snps,dw-apb-timer-osc", dw_apb_timer_init);
++CLOCKSOURCE_OF_DECLARE(apb_timer_osc, "snps,dw-apb-timer-osc", dw_apb_timer_init);
++CLOCKSOURCE_OF_DECLARE(apb_timer_sp, "snps,dw-apb-timer-sp", dw_apb_timer_init);
++CLOCKSOURCE_OF_DECLARE(apb_timer, "snps,dw-apb-timer", dw_apb_timer_init);
--- /dev/null
+From 817eff718dca4e54d5721211ddde0914428fbb7c Mon Sep 17 00:00:00 2001
+From: Paul Moore <pmoore@redhat.com>
+Date: Tue, 10 Dec 2013 14:57:54 -0500
+Subject: selinux: look for IPsec labels on both inbound and outbound packets
+
+From: Paul Moore <pmoore@redhat.com>
+
+commit 817eff718dca4e54d5721211ddde0914428fbb7c upstream.
+
+Previously selinux_skb_peerlbl_sid() would only check for labeled
+IPsec security labels on inbound packets, this patch enables it to
+check both inbound and outbound traffic for labeled IPsec security
+labels.
+
+Reported-by: Janak Desai <Janak.Desai@gtri.gatech.edu>
+Signed-off-by: Paul Moore <pmoore@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/hooks.c | 2 -
+ security/selinux/include/xfrm.h | 9 +++---
+ security/selinux/xfrm.c | 53 +++++++++++++++++++++++++++++++---------
+ 3 files changed, 48 insertions(+), 16 deletions(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -3792,7 +3792,7 @@ static int selinux_skb_peerlbl_sid(struc
+ u32 nlbl_sid;
+ u32 nlbl_type;
+
+- selinux_skb_xfrm_sid(skb, &xfrm_sid);
++ selinux_xfrm_skb_sid(skb, &xfrm_sid);
+ selinux_netlbl_skbuff_getsid(skb, family, &nlbl_type, &nlbl_sid);
+
+ err = security_net_peersid_resolve(nlbl_sid, nlbl_type, xfrm_sid, sid);
+--- a/security/selinux/include/xfrm.h
++++ b/security/selinux/include/xfrm.h
+@@ -47,6 +47,7 @@ int selinux_xfrm_sock_rcv_skb(u32 sid, s
+ int selinux_xfrm_postroute_last(u32 isec_sid, struct sk_buff *skb,
+ struct common_audit_data *ad, u8 proto);
+ int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall);
++int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid);
+
+ static inline void selinux_xfrm_notify_policyload(void)
+ {
+@@ -85,12 +86,12 @@ static inline int selinux_xfrm_decode_se
+ static inline void selinux_xfrm_notify_policyload(void)
+ {
+ }
+-#endif
+
+-static inline void selinux_skb_xfrm_sid(struct sk_buff *skb, u32 *sid)
++static inline int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
+ {
+- int err = selinux_xfrm_decode_session(skb, sid, 0);
+- BUG_ON(err);
++ *sid = SECSID_NULL;
++ return 0;
+ }
++#endif
+
+ #endif /* _SELINUX_XFRM_H_ */
+--- a/security/selinux/xfrm.c
++++ b/security/selinux/xfrm.c
+@@ -152,21 +152,13 @@ int selinux_xfrm_state_pol_flow_match(st
+ return rc;
+ }
+
+-/*
+- * LSM hook implementation that checks and/or returns the xfrm sid for the
+- * incoming packet.
+- */
+-
+-int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
++static int selinux_xfrm_skb_sid_ingress(struct sk_buff *skb,
++ u32 *sid, int ckall)
+ {
+- struct sec_path *sp;
++ struct sec_path *sp = skb->sp;
+
+ *sid = SECSID_NULL;
+
+- if (skb == NULL)
+- return 0;
+-
+- sp = skb->sp;
+ if (sp) {
+ int i, sid_set = 0;
+
+@@ -190,6 +182,45 @@ int selinux_xfrm_decode_session(struct s
+ return 0;
+ }
+
++static u32 selinux_xfrm_skb_sid_egress(struct sk_buff *skb)
++{
++ struct dst_entry *dst = skb_dst(skb);
++ struct xfrm_state *x;
++
++ if (dst == NULL)
++ return SECSID_NULL;
++ x = dst->xfrm;
++ if (x == NULL || !selinux_authorizable_xfrm(x))
++ return SECSID_NULL;
++
++ return x->security->ctx_sid;
++}
++
++/*
++ * LSM hook implementation that checks and/or returns the xfrm sid for the
++ * incoming packet.
++ */
++
++int selinux_xfrm_decode_session(struct sk_buff *skb, u32 *sid, int ckall)
++{
++ if (skb == NULL) {
++ *sid = SECSID_NULL;
++ return 0;
++ }
++ return selinux_xfrm_skb_sid_ingress(skb, sid, ckall);
++}
++
++int selinux_xfrm_skb_sid(struct sk_buff *skb, u32 *sid)
++{
++ int rc;
++
++ rc = selinux_xfrm_skb_sid_ingress(skb, sid, 0);
++ if (rc == 0 && *sid == SECSID_NULL)
++ *sid = selinux_xfrm_skb_sid_egress(skb);
++
++ return rc;
++}
++
+ /*
+ * Security blob allocation for xfrm_policy and xfrm_state
+ * CTX does not have a meaningful value on input
--- /dev/null
+From c0828e50485932b7e019df377a6b0a8d1ebd3080 Mon Sep 17 00:00:00 2001
+From: Paul Moore <pmoore@redhat.com>
+Date: Tue, 10 Dec 2013 14:58:01 -0500
+Subject: selinux: process labeled IPsec TCP SYN-ACK packets properly in selinux_ip_postroute()
+
+From: Paul Moore <pmoore@redhat.com>
+
+commit c0828e50485932b7e019df377a6b0a8d1ebd3080 upstream.
+
+Due to difficulty in arriving at the proper security label for
+TCP SYN-ACK packets in selinux_ip_postroute(), we need to check packets
+while/before they are undergoing XFRM transforms instead of waiting
+until afterwards so that we can determine the correct security label.
+
+Reported-by: Janak Desai <Janak.Desai@gtri.gatech.edu>
+Signed-off-by: Paul Moore <pmoore@redhat.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ security/selinux/hooks.c | 43 ++++++++++++++++++++++++++++++++++++-------
+ 1 file changed, 36 insertions(+), 7 deletions(-)
+
+--- a/security/selinux/hooks.c
++++ b/security/selinux/hooks.c
+@@ -4811,22 +4811,32 @@ static unsigned int selinux_ip_postroute
+ * as fast and as clean as possible. */
+ if (!selinux_policycap_netpeer)
+ return selinux_ip_postroute_compat(skb, ifindex, family);
++
++ secmark_active = selinux_secmark_enabled();
++ peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
++ if (!secmark_active && !peerlbl_active)
++ return NF_ACCEPT;
++
++ sk = skb->sk;
++
+ #ifdef CONFIG_XFRM
+ /* If skb->dst->xfrm is non-NULL then the packet is undergoing an IPsec
+ * packet transformation so allow the packet to pass without any checks
+ * since we'll have another chance to perform access control checks
+ * when the packet is on it's final way out.
+ * NOTE: there appear to be some IPv6 multicast cases where skb->dst
+- * is NULL, in this case go ahead and apply access control. */
+- if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL)
++ * is NULL, in this case go ahead and apply access control.
++ * is NULL, in this case go ahead and apply access control.
++ * NOTE: if this is a local socket (skb->sk != NULL) that is in the
++ * TCP listening state we cannot wait until the XFRM processing
++ * is done as we will miss out on the SA label if we do;
++ * unfortunately, this means more work, but it is only once per
++ * connection. */
++ if (skb_dst(skb) != NULL && skb_dst(skb)->xfrm != NULL &&
++ !(sk != NULL && sk->sk_state == TCP_LISTEN))
+ return NF_ACCEPT;
+ #endif
+- secmark_active = selinux_secmark_enabled();
+- peerlbl_active = netlbl_enabled() || selinux_xfrm_enabled();
+- if (!secmark_active && !peerlbl_active)
+- return NF_ACCEPT;
+
+- sk = skb->sk;
+ if (sk == NULL) {
+ /* Without an associated socket the packet is either coming
+ * from the kernel or it is being forwarded; check the packet
+@@ -4854,6 +4864,25 @@ static unsigned int selinux_ip_postroute
+ struct sk_security_struct *sksec = sk->sk_security;
+ if (selinux_skb_peerlbl_sid(skb, family, &skb_sid))
+ return NF_DROP;
++ /* At this point, if the returned skb peerlbl is SECSID_NULL
++ * and the packet has been through at least one XFRM
++ * transformation then we must be dealing with the "final"
++ * form of labeled IPsec packet; since we've already applied
++ * all of our access controls on this packet we can safely
++ * pass the packet. */
++ if (skb_sid == SECSID_NULL) {
++ switch (family) {
++ case PF_INET:
++ if (IPCB(skb)->flags & IPSKB_XFRM_TRANSFORMED)
++ return NF_ACCEPT;
++ break;
++ case PF_INET6:
++ if (IP6CB(skb)->flags & IP6SKB_XFRM_TRANSFORMED)
++ return NF_ACCEPT;
++ default:
++ return NF_DROP_ERR(-ECONNREFUSED);
++ }
++ }
+ if (selinux_conn_sid(sksec->sid, skb_sid, &peer_sid))
+ return NF_DROP;
+ secmark_perm = PACKET__SEND;
gpio-twl4030-fix-regression-for-twl-gpio-led-output.patch
gpio-msm-fix-irq-mask-unmask-by-writing-bits-instead-of-numbers.patch
sh-always-link-in-helper-functions-extracted-from-libgcc.patch
+selinux-look-for-ipsec-labels-on-both-inbound-and-outbound-packets.patch
+selinux-process-labeled-ipsec-tcp-syn-ack-packets-properly-in-selinux_ip_postroute.patch
+clocksource-dw_apb_timer_of-fix-read_sched_clock.patch
+clocksource-dw_apb_timer_of-fix-support-for-dts-binding-snps-dw-apb-timer.patch
+aio-clean-up-and-fix-aio_setup_ring-page-mapping.patch
+aio-migratepages-make-aio-migrate-pages-sane.patch