netfilter: nfnetlink_log: fix maximum packet length logged to userspace
authorFlorian Westphal <fw@strlen.de>
Thu, 23 Oct 2014 08:36:07 +0000 (10:36 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 21 Nov 2014 17:22:54 +0000 (09:22 -0800)
commit c1e7dc91eed0ed1a51c9b814d648db18bf8fc6e9 upstream.

don't try to queue payloads > 0xffff - NLA_HDRLEN, it does not work.
The nla length includes the size of the nla struct, so anything larger
results in u16 integer overflow.

This patch is similar to
9cefbbc9c8f9abe (netfilter: nfnetlink_queue: cleanup copy_range usage).

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
net/netfilter/nfnetlink_log.c

index 478b669500073f92e8a35cfe23d4e416a5d5c9b6..3d66b83a5c88d80cbb3df5780de4aa00919bf635 100644 (file)
@@ -45,7 +45,8 @@
 #define NFULNL_NLBUFSIZ_DEFAULT        NLMSG_GOODSIZE
 #define NFULNL_TIMEOUT_DEFAULT         100     /* every second */
 #define NFULNL_QTHRESH_DEFAULT         100     /* 100 packets */
-#define NFULNL_COPY_RANGE_MAX  0xFFFF  /* max packet size is limited by 16-bit struct nfattr nfa_len field */
+/* max packet size is limited by 16-bit struct nfattr nfa_len field */
+#define NFULNL_COPY_RANGE_MAX  (0xFFFF - NLA_HDRLEN)
 
 #define PRINTR(x, args...)     do { if (net_ratelimit()) \
                                     printk(x, ## args); } while (0);
@@ -255,6 +256,8 @@ nfulnl_set_mode(struct nfulnl_instance *inst, u_int8_t mode,
 
        case NFULNL_COPY_PACKET:
                inst->copy_mode = mode;
+               if (range == 0)
+                       range = NFULNL_COPY_RANGE_MAX;
                inst->copy_range = min_t(unsigned int,
                                         range, NFULNL_COPY_RANGE_MAX);
                break;
@@ -677,8 +680,7 @@ nfulnl_log_packet(struct net *net,
                break;
 
        case NFULNL_COPY_PACKET:
-               if (inst->copy_range == 0
-                   || inst->copy_range > skb->len)
+               if (inst->copy_range > skb->len)
                        data_len = skb->len;
                else
                        data_len = inst->copy_range;