OpenCores
URL https://opencores.org/ocsvn/or1k/or1k/trunk

Subversion Repositories or1k

[/] [or1k/] [trunk/] [linux/] [linux-2.4/] [net/] [ipv4/] [netfilter/] [ipt_unclean.c] - Blame information for rev 1765

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 1275 phoenix
/* Kernel module to match suspect packets. */
2
#include <linux/module.h>
3
#include <linux/skbuff.h>
4
#include <linux/ip.h>
5
#include <linux/udp.h>
6
#include <linux/tcp.h>
7
#include <linux/icmp.h>
8
#include <net/checksum.h>
9
 
10
#include <linux/netfilter_ipv4/ip_tables.h>
11
 
12
#define limpk(format, args...)                                           \
13
do {                                                                     \
14
        if (net_ratelimit())                                             \
15
                printk("ipt_unclean: %s" format,                         \
16
                       embedded ? "(embedded packet) " : "" , ## args);  \
17
} while(0)
18
 
19
enum icmp_error_status
20
{
21
        ICMP_MAY_BE_ERROR,
22
        ICMP_IS_ERROR,
23
        ICMP_NOT_ERROR
24
};
25
 
26
struct icmp_info
27
{
28
        size_t min_len, max_len;
29
        enum icmp_error_status err;
30
        u_int8_t min_code, max_code;
31
};
32
 
33
static int
34
check_ip(struct iphdr *iph, size_t length, int embedded);
35
 
36
/* ICMP-specific checks. */
37
static int
38
check_icmp(const struct icmphdr *icmph,
39
           u_int16_t datalen,
40
           unsigned int offset,
41
           int more_frags,
42
           int embedded)
43
{
44
        static struct icmp_info info[]
45
                = { [ICMP_ECHOREPLY]
46
                    = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
47
                    [ICMP_DEST_UNREACH]
48
                    = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 15 },
49
                    [ICMP_SOURCE_QUENCH]
50
                    = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 0 },
51
                    [ICMP_REDIRECT]
52
                    = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 3 },
53
                    [ICMP_ECHO]
54
                    = { 8, 65536, ICMP_NOT_ERROR, 0, 0  },
55
                    /* Router advertisement. */
56
                    [9]
57
                    = { 8, 8 + 255 * 8, ICMP_NOT_ERROR, 0, 0 },
58
                    /* Router solicitation. */
59
                    [10]
60
                    = { 8, 8, ICMP_NOT_ERROR, 0, 0 },
61
                    [ICMP_TIME_EXCEEDED]
62
                    = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1  },
63
                    [ICMP_PARAMETERPROB]
64
                    = { 8 + 28, 65536, ICMP_IS_ERROR, 0, 1 },
65
                    [ICMP_TIMESTAMP]
66
                    = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
67
                    [ICMP_TIMESTAMPREPLY]
68
                    = { 20, 20, ICMP_NOT_ERROR, 0, 0 },
69
                    [ICMP_INFO_REQUEST]
70
                    = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
71
                    [ICMP_INFO_REPLY]
72
                    = { 8, 65536, ICMP_NOT_ERROR, 0, 0 },
73
                    [ICMP_ADDRESS]
74
                    = { 12, 12, ICMP_NOT_ERROR, 0, 0 },
75
                    [ICMP_ADDRESSREPLY]
76
                    = { 12, 12, ICMP_NOT_ERROR, 0, 0 } };
77
 
78
        /* Can't do anything if it's a fragment. */
79
        if (offset)
80
                return 1;
81
 
82
        /* Must cover type and code. */
83
        if (datalen < 2) {
84
                limpk("ICMP len=%u too short\n", datalen);
85
                return 0;
86
        }
87
 
88
        /* If not embedded. */
89
        if (!embedded) {
90
                /* Bad checksum?  Don't print, just ignore. */
91
                if (!more_frags
92
                    && ip_compute_csum((unsigned char *) icmph, datalen) != 0)
93
                        return 0;
94
 
95
                /* CHECK: Truncated ICMP (even if first fragment). */
96
                if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
97
                    && info[icmph->type].min_len != 0
98
                    && datalen < info[icmph->type].min_len) {
99
                        limpk("ICMP type %u len %u too short\n",
100
                              icmph->type, datalen);
101
                        return 0;
102
                }
103
 
104
                /* CHECK: Check within known error ICMPs. */
105
                if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
106
                    && info[icmph->type].err == ICMP_IS_ERROR) {
107
                        /* CHECK: Embedded packet must be at least
108
                           length of iph + 8 bytes. */
109
                        struct iphdr *inner = (void *)icmph + 8;
110
 
111
                        /* datalen > 8 since all ICMP_IS_ERROR types
112
                           have min length > 8 */
113
                        if (datalen - 8 < sizeof(struct iphdr)) {
114
                                limpk("ICMP error internal way too short\n");
115
                                return 0;
116
                        }
117
                        if (datalen - 8 < inner->ihl*4 + 8) {
118
                                limpk("ICMP error internal too short\n");
119
                                return 0;
120
                        }
121
                        if (!check_ip(inner, datalen - 8, 1))
122
                                return 0;
123
                }
124
        } else {
125
                /* CHECK: Can't embed ICMP unless known non-error. */
126
                if (icmph->type >= sizeof(info)/sizeof(struct icmp_info)
127
                    || info[icmph->type].err != ICMP_NOT_ERROR) {
128
                        limpk("ICMP type %u not embeddable\n",
129
                              icmph->type);
130
                        return 0;
131
                }
132
        }
133
 
134
        /* CHECK: Invalid ICMP codes. */
135
        if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
136
            && (icmph->code < info[icmph->type].min_code
137
                || icmph->code > info[icmph->type].max_code)) {
138
                limpk("ICMP type=%u code=%u\n",
139
                      icmph->type, icmph->code);
140
                return 0;
141
        }
142
 
143
        /* CHECK: Above maximum length. */
144
        if (icmph->type < sizeof(info)/sizeof(struct icmp_info)
145
            && info[icmph->type].max_len != 0
146
            && datalen > info[icmph->type].max_len) {
147
                limpk("ICMP type=%u too long: %u bytes\n",
148
                      icmph->type, datalen);
149
                return 0;
150
        }
151
 
152
        switch (icmph->type) {
153
        case ICMP_PARAMETERPROB: {
154
                /* CHECK: Problem param must be within error packet's
155
                 * IP header. */
156
                struct iphdr *iph = (void *)icmph + 8;
157
                u_int32_t arg = ntohl(icmph->un.gateway);
158
 
159
                if (icmph->code == 0) {
160
                        /* Code 0 means that upper 8 bits is pointer
161
                           to problem. */
162
                        if ((arg >> 24) >= iph->ihl*4) {
163
                                limpk("ICMP PARAMETERPROB ptr = %u\n",
164
                                      ntohl(icmph->un.gateway) >> 24);
165
                                return 0;
166
                        }
167
                        arg &= 0x00FFFFFF;
168
                }
169
 
170
                /* CHECK: Rest must be zero. */
171
                if (arg) {
172
                        limpk("ICMP PARAMETERPROB nonzero arg = %u\n",
173
                              arg);
174
                        return 0;
175
                }
176
                break;
177
        }
178
 
179
        case ICMP_TIME_EXCEEDED:
180
        case ICMP_SOURCE_QUENCH:
181
                /* CHECK: Unused must be zero. */
182
                if (icmph->un.gateway != 0) {
183
                        limpk("ICMP type=%u unused = %u\n",
184
                              icmph->type, ntohl(icmph->un.gateway));
185
                        return 0;
186
                }
187
                break;
188
        }
189
 
190
        return 1;
191
}
192
 
193
/* UDP-specific checks. */
194
static int
195
check_udp(const struct iphdr *iph,
196
          const struct udphdr *udph,
197
          u_int16_t datalen,
198
          unsigned int offset,
199
          int more_frags,
200
          int embedded)
201
{
202
        /* Can't do anything if it's a fragment. */
203
        if (offset)
204
                return 1;
205
 
206
        /* CHECK: Must cover UDP header. */
207
        if (datalen < sizeof(struct udphdr)) {
208
                limpk("UDP len=%u too short\n", datalen);
209
                return 0;
210
        }
211
 
212
        /* Bad checksum?  Don't print, just say it's unclean. */
213
        /* FIXME: SRC ROUTE packets won't match checksum --RR */
214
        if (!more_frags && !embedded && udph->check
215
            && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_UDP,
216
                                 csum_partial((char *)udph, datalen, 0)) != 0)
217
                return 0;
218
 
219
        /* CHECK: Destination port can't be zero. */
220
        if (!udph->dest) {
221
                limpk("UDP zero destination port\n");
222
                return 0;
223
        }
224
 
225
        if (!more_frags) {
226
                if (!embedded) {
227
                        /* CHECK: UDP length must match. */
228
                        if (ntohs(udph->len) != datalen) {
229
                                limpk("UDP len too short %u vs %u\n",
230
                                      ntohs(udph->len), datalen);
231
                                return 0;
232
                        }
233
                } else {
234
                        /* CHECK: UDP length be >= this truncated pkt. */
235
                        if (ntohs(udph->len) < datalen) {
236
                                limpk("UDP len too long %u vs %u\n",
237
                                      ntohs(udph->len), datalen);
238
                                return 0;
239
                        }
240
                }
241
        } else {
242
                /* CHECK: UDP length must be > this frag's length. */
243
                if (ntohs(udph->len) <= datalen) {
244
                        limpk("UDP fragment len too short %u vs %u\n",
245
                              ntohs(udph->len), datalen);
246
                        return 0;
247
                }
248
        }
249
 
250
        return 1;
251
}
252
 
253
#define TH_FIN  0x01
254
#define TH_SYN  0x02
255
#define TH_RST  0x04
256
#define TH_PUSH 0x08
257
#define TH_ACK  0x10
258
#define TH_URG  0x20
259
#define TH_ECE  0x40
260
#define TH_CWR  0x80
261
 
262
/* table of valid flag combinations - ECE and CWR are always valid */
263
static u8 tcp_valid_flags[(TH_FIN|TH_SYN|TH_RST|TH_PUSH|TH_ACK|TH_URG) + 1] =
264
{
265
        [TH_SYN]                        = 1,
266
        [TH_SYN|TH_ACK]                 = 1,
267
        [TH_RST]                        = 1,
268
        [TH_RST|TH_ACK]                 = 1,
269
        [TH_RST|TH_ACK|TH_PUSH]         = 1,
270
        [TH_FIN|TH_ACK]                 = 1,
271
        [TH_ACK]                        = 1,
272
        [TH_ACK|TH_PUSH]                = 1,
273
        [TH_ACK|TH_URG]                 = 1,
274
        [TH_ACK|TH_URG|TH_PUSH]         = 1,
275
        [TH_FIN|TH_ACK|TH_PUSH]         = 1,
276
        [TH_FIN|TH_ACK|TH_URG]          = 1,
277
        [TH_FIN|TH_ACK|TH_URG|TH_PUSH]  = 1
278
};
279
 
280
/* TCP-specific checks. */
281
static int
282
check_tcp(const struct iphdr *iph,
283
          const struct tcphdr *tcph,
284
          u_int16_t datalen,
285
          unsigned int offset,
286
          int more_frags,
287
          int embedded)
288
{
289
        u_int8_t *opt = (u_int8_t *)tcph;
290
        u_int8_t *endhdr = (u_int8_t *)tcph + tcph->doff * 4;
291
        u_int8_t tcpflags;
292
        int end_of_options = 0;
293
        size_t i;
294
 
295
        /* CHECK: Can't have offset=1: used to override TCP syn-checks. */
296
        /* In fact, this is caught below (offset < 516). */
297
 
298
        /* Can't do anything if it's a fragment. */
299
        if (offset)
300
                return 1;
301
 
302
        /* CHECK: Smaller than minimal TCP hdr. */
303
        if (datalen < sizeof(struct tcphdr)) {
304
                if (!embedded) {
305
                        limpk("Packet length %u < TCP header.\n", datalen);
306
                        return 0;
307
                }
308
                /* Must have ports available (datalen >= 8), from
309
                   check_icmp which set embedded = 1 */
310
                /* CHECK: TCP ports inside ICMP error */
311
                if (!tcph->source || !tcph->dest) {
312
                        limpk("Zero TCP ports %u/%u.\n",
313
                              htons(tcph->source), htons(tcph->dest));
314
                        return 0;
315
                }
316
                return 1;
317
        }
318
 
319
        /* CHECK: Smaller than actual TCP hdr. */
320
        if (datalen < tcph->doff * 4) {
321
                if (!embedded) {
322
                        limpk("Packet length %u < actual TCP header.\n",
323
                              datalen);
324
                        return 0;
325
                } else
326
                        return 1;
327
        }
328
 
329
        /* Bad checksum?  Don't print, just say it's unclean. */
330
        /* FIXME: SRC ROUTE packets won't match checksum --RR */
331
        if (!more_frags && !embedded
332
            && csum_tcpudp_magic(iph->saddr, iph->daddr, datalen, IPPROTO_TCP,
333
                                 csum_partial((char *)tcph, datalen, 0)) != 0)
334
                return 0;
335
 
336
        /* CHECK: TCP ports non-zero */
337
        if (!tcph->source || !tcph->dest) {
338
                limpk("Zero TCP ports %u/%u.\n",
339
                      htons(tcph->source), htons(tcph->dest));
340
                return 0;
341
        }
342
 
343
        /* CHECK: TCP reserved bits zero. */
344
        if(tcp_flag_word(tcph) & TCP_RESERVED_BITS) {
345
                limpk("TCP reserved bits not zero\n");
346
                return 0;
347
        }
348
 
349
        /* CHECK: TCP flags. */
350
        tcpflags = (((u_int8_t *)tcph)[13] & ~(TH_ECE|TH_CWR));
351
        if (!tcp_valid_flags[tcpflags]) {
352
                limpk("TCP flags bad: %u\n", tcpflags);
353
                return 0;
354
        }
355
 
356
        for (i = sizeof(struct tcphdr); i < tcph->doff * 4; ) {
357
                switch (opt[i]) {
358
                case 0:
359
                        end_of_options = 1;
360
                        i++;
361
                        break;
362
                case 1:
363
                        i++;
364
                        break;
365
                default:
366
                        /* CHECK: options after EOO. */
367
                        if (end_of_options) {
368
                                limpk("TCP option %u after end\n",
369
                                      opt[i]);
370
                                return 0;
371
                        }
372
                        /* CHECK: options at tail. */
373
                        else if (i+1 >= tcph->doff * 4) {
374
                                limpk("TCP option %u at tail\n",
375
                                      opt[i]);
376
                                return 0;
377
                        }
378
                        /* CHECK: zero-length options. */
379
                        else if (opt[i+1] == 0) {
380
                                limpk("TCP option %u 0 len\n",
381
                                      opt[i]);
382
                                return 0;
383
                        }
384
                        /* CHECK: oversize options. */
385
                        else if (&opt[i] + opt[i+1] > endhdr) {
386
                                limpk("TCP option %u at %Zu too long\n",
387
                                      (unsigned int) opt[i], i);
388
                                return 0;
389
                        }
390
                        /* Move to next option */
391
                        i += opt[i+1];
392
                }
393
        }
394
 
395
        return 1;
396
}
397
 
398
/* Returns 1 if ok */
399
/* Standard IP checks. */
400
static int
401
check_ip(struct iphdr *iph, size_t length, int embedded)
402
{
403
        u_int8_t *opt = (u_int8_t *)iph;
404
        u_int8_t *endhdr = (u_int8_t *)iph + iph->ihl * 4;
405
        int end_of_options = 0;
406
        void *protoh;
407
        size_t datalen;
408
        unsigned int i;
409
        unsigned int offset;
410
 
411
        /* Should only happen for local outgoing raw-socket packets. */
412
        /* CHECK: length >= ip header. */
413
        if (length < sizeof(struct iphdr) || length < iph->ihl * 4) {
414
                limpk("Packet length %Zu < IP header.\n", length);
415
                return 0;
416
        }
417
 
418
        offset = ntohs(iph->frag_off) & IP_OFFSET;
419
        protoh = (void *)iph + iph->ihl * 4;
420
        datalen = length - iph->ihl * 4;
421
 
422
        /* CHECK: Embedded fragment. */
423
        if (embedded && offset) {
424
                limpk("Embedded fragment.\n");
425
                return 0;
426
        }
427
 
428
        for (i = sizeof(struct iphdr); i < iph->ihl * 4; ) {
429
                switch (opt[i]) {
430
                case 0:
431
                        end_of_options = 1;
432
                        i++;
433
                        break;
434
                case 1:
435
                        i++;
436
                        break;
437
                default:
438
                        /* CHECK: options after EOO. */
439
                        if (end_of_options) {
440
                                limpk("IP option %u after end\n",
441
                                      opt[i]);
442
                                return 0;
443
                        }
444
                        /* CHECK: options at tail. */
445
                        else if (i+1 >= iph->ihl * 4) {
446
                                limpk("IP option %u at tail\n",
447
                                      opt[i]);
448
                                return 0;
449
                        }
450
                        /* CHECK: zero-length or one-length options. */
451
                        else if (opt[i+1] < 2) {
452
                                limpk("IP option %u %u len\n",
453
                                      opt[i], opt[i+1]);
454
                                return 0;
455
                        }
456
                        /* CHECK: oversize options. */
457
                        else if (&opt[i] + opt[i+1] > endhdr) {
458
                                limpk("IP option %u at %u too long\n",
459
                                      opt[i], i);
460
                                return 0;
461
                        }
462
                        /* Move to next option */
463
                        i += opt[i+1];
464
                }
465
        }
466
 
467
        /* Fragment checks. */
468
 
469
        /* CHECK: More fragments, but doesn't fill 8-byte boundary. */
470
        if ((ntohs(iph->frag_off) & IP_MF)
471
            && (ntohs(iph->tot_len) % 8) != 0) {
472
                limpk("Truncated fragment %u long.\n", ntohs(iph->tot_len));
473
                return 0;
474
        }
475
 
476
        /* CHECK: Oversize fragment a-la Ping of Death. */
477
        if (offset * 8 + datalen > 65535) {
478
                limpk("Oversize fragment to %u.\n", offset * 8);
479
                return 0;
480
        }
481
 
482
        /* CHECK: DF set and offset or MF set. */
483
        if ((ntohs(iph->frag_off) & IP_DF)
484
            && (offset || (ntohs(iph->frag_off) & IP_MF))) {
485
                limpk("DF set and offset=%u, MF=%u.\n",
486
                      offset, ntohs(iph->frag_off) & IP_MF);
487
                return 0;
488
        }
489
 
490
        /* CHECK: Zero-sized fragments. */
491
        if ((offset || (ntohs(iph->frag_off) & IP_MF))
492
            && datalen == 0) {
493
                limpk("Zero size fragment offset=%u\n", offset);
494
                return 0;
495
        }
496
 
497
        /* Note: we can have even middle fragments smaller than this:
498
           consider a large packet passing through a 600MTU then
499
           576MTU link: this gives a fragment of 24 data bytes.  But
500
           everyone packs fragments largest first, hence a fragment
501
           can't START before 576 - MAX_IP_HEADER_LEN. */
502
 
503
        /* Used to be min-size 576: I recall Alan Cox saying ax25 goes
504
           down to 128 (576 taken from RFC 791: All hosts must be
505
           prepared to accept datagrams of up to 576 octets).  Use 128
506
           here. */
507
#define MIN_LIKELY_MTU 128
508
        /* CHECK: Min size of first frag = 128. */
509
        if ((ntohs(iph->frag_off) & IP_MF)
510
            && offset == 0
511
            && ntohs(iph->tot_len) < MIN_LIKELY_MTU) {
512
                limpk("First fragment size %u < %u\n", ntohs(iph->tot_len),
513
                      MIN_LIKELY_MTU);
514
                return 0;
515
        }
516
 
517
        /* CHECK: Min offset of frag = 128 - IP hdr len. */
518
        if (offset && offset * 8 < MIN_LIKELY_MTU - iph->ihl * 4) {
519
                limpk("Fragment starts at %u < %u\n", offset * 8,
520
                      MIN_LIKELY_MTU - iph->ihl * 4);
521
                return 0;
522
        }
523
 
524
        /* CHECK: Protocol specification non-zero. */
525
        if (iph->protocol == 0) {
526
                limpk("Zero protocol\n");
527
                return 0;
528
        }
529
 
530
        /* CHECK: Do not use what is unused.
531
         * First bit of fragmentation flags should be unused.
532
         * May be used by OS fingerprinting tools.
533
         * 04 Jun 2002, Maciej Soltysiak, solt@dns.toxicfilms.tv
534
         */
535
        if (ntohs(iph->frag_off)>>15) {
536
                limpk("IP unused bit set\n");
537
                return 0;
538
        }
539
 
540
        /* Per-protocol checks. */
541
        switch (iph->protocol) {
542
        case IPPROTO_ICMP:
543
                return check_icmp(protoh, datalen, offset,
544
                                  (ntohs(iph->frag_off) & IP_MF),
545
                                  embedded);
546
 
547
        case IPPROTO_UDP:
548
                return check_udp(iph, protoh, datalen, offset,
549
                                 (ntohs(iph->frag_off) & IP_MF),
550
                                 embedded);
551
 
552
        case IPPROTO_TCP:
553
                return check_tcp(iph, protoh, datalen, offset,
554
                                 (ntohs(iph->frag_off) & IP_MF),
555
                                 embedded);
556
        default:
557
                /* Ignorance is bliss. */
558
                return 1;
559
        }
560
}
561
 
562
static int
563
match(const struct sk_buff *skb,
564
      const struct net_device *in,
565
      const struct net_device *out,
566
      const void *matchinfo,
567
      int offset,
568
      const void *hdr,
569
      u_int16_t datalen,
570
      int *hotdrop)
571
{
572
        return !check_ip(skb->nh.iph, skb->len, 0);
573
}
574
 
575
/* Called when user tries to insert an entry of this type. */
576
static int
577
checkentry(const char *tablename,
578
           const struct ipt_ip *ip,
579
           void *matchinfo,
580
           unsigned int matchsize,
581
           unsigned int hook_mask)
582
{
583
        if (matchsize != IPT_ALIGN(0))
584
                return 0;
585
 
586
        return 1;
587
}
588
 
589
static struct ipt_match unclean_match
590
= { { NULL, NULL }, "unclean", &match, &checkentry, NULL, THIS_MODULE };
591
 
592
static int __init init(void)
593
{
594
        return ipt_register_match(&unclean_match);
595
}
596
 
597
static void __exit fini(void)
598
{
599
        ipt_unregister_match(&unclean_match);
600
}
601
 
602
module_init(init);
603
module_exit(fini);
604
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.