I'm looking for oks on this diff to commit it.

* Leonardo Guardati <leona...@guardati.it> [2012-05-10 21:29]:
> Hi,
>   here is a solution to the problem I posted on bugs@ about pf logging
> incoming UDP packets to port 0 as pass while being blocked instead.
> 
> action is added to pflog_packet() arguments.
> 
> I tried it and works.
> 
> 
> Here are the diffs:
> --- if_pflog.c        2012-05-10 20:04:40.164000084 +0200
> +++ if_pflog-new.c    2012-05-10 15:21:23.000000000 +0200
> @@ -215,7 +215,7 @@ pflogioctl(struct ifnet *ifp, u_long cmd
>  }
> 
>  int
> -pflog_packet(struct pf_pdesc *pd, u_int8_t reason, struct pf_rule *rm,
> +pflog_packet(struct pf_pdesc *pd, u_int8_t reason, u_int8_t action,
> struct pf_rule *rm,
>      struct pf_rule *am, struct pf_ruleset *ruleset)
>  {
>  #if NBPFILTER > 0
> @@ -230,7 +230,7 @@ pflog_packet(struct pf_pdesc *pd, u_int8
> 
>       bzero(&hdr, sizeof(hdr));
>       hdr.length = PFLOG_REAL_HDRLEN;
> -     hdr.action = rm->action;
> +     hdr.action = action;
>       hdr.reason = reason;
>       memcpy(hdr.ifname, pd->kif->pfik_name, sizeof(hdr.ifname));
> --- if_pflog.h        2012-05-10 20:04:46.806000082 +0200
> +++ if_pflog-new.h    2012-05-10 15:22:25.000000000 +0200
> @@ -71,9 +71,9 @@ struct pfloghdr {
>  void pflog_bpfcopy(const void *, void *, size_t);
> 
>  #if NPFLOG > 0
> -#define      PFLOG_PACKET(a,b,c,d,e) pflog_packet(a,b,c,d,e)
> +#define      PFLOG_PACKET(a,b,c,d,e,f) pflog_packet(a,b,c,d,e,f)
>  #else
> -#define      PFLOG_PACKET(a,b,c,d,e) ((void)0)
> +#define      PFLOG_PACKET(a,b,c,d,e,f) ((void)0)
>  #endif /* NPFLOG > 0 */
>  #endif /* _KERNEL */
>  #endif /* _NET_IF_PFLOG_H_ */
> --- pfvar.h   2012-05-10 20:05:05.316000084 +0200
> +++ pfvar-new.h       2012-05-10 15:40:37.000000000 +0200
> @@ -1795,7 +1795,7 @@ void    pf_addr_inc(struct pf_addr *, sa_fa
>  void   *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *,
>           sa_family_t);
>  void pf_change_a(void *, u_int16_t *, u_int32_t, u_int8_t);
> -int  pflog_packet(struct pf_pdesc *, u_int8_t, struct pf_rule *,
> +int  pflog_packet(struct pf_pdesc *, u_int8_t, u_int8_t, struct pf_rule *,
>           struct pf_rule *, struct pf_ruleset *);
>  void pf_send_deferred_syn(struct pf_state *);
>  int  pf_match_addr(u_int8_t, struct pf_addr *, struct pf_addr *,
> --- pf.c      2012-05-10 20:05:04.902000084 +0200
> +++ pf-new.c  2012-05-10 16:15:46.000000000 +0200
> @@ -3492,14 +3492,16 @@ pf_test_rule(struct pf_pdesc *pd, struct
>                                       goto cleanup;
>                               }
>                               if (r->log || act.log & PF_LOG_MATCHES)
> -                                     PFLOG_PACKET(pd, reason, r, a, ruleset);
> +                                     PFLOG_PACKET(pd, reason, r->action, r,
> +                                         a, ruleset);
>                       } else {
>                               match = 1;
>                               *rm = r;
>                               *am = a;
>                               *rsm = ruleset;
>                               if (act.log & PF_LOG_MATCHES)
> -                                     PFLOG_PACKET(pd, reason, r, a, ruleset);
> +                                     PFLOG_PACKET(pd, reason, r->action, r,
> +                                         a, ruleset);
>                       }
> 
>                       if ((*rm)->quick)
> @@ -3529,7 +3531,7 @@ pf_test_rule(struct pf_pdesc *pd, struct
>       REASON_SET(&reason, PFRES_MATCH);
> 
>       if (r->log || act.log & PF_LOG_MATCHES)
> -             PFLOG_PACKET(pd, reason, r, a, ruleset);
> +             PFLOG_PACKET(pd, reason, r->action, r, a, ruleset);
> 
>       if (pd->virtual_proto != PF_VPROTO_FRAGMENT &&
>           (r->action == PF_DROP) &&
> @@ -6951,12 +6953,12 @@ done:
>               struct pf_rule_item     *ri;
> 
>               if (pd.pflog & PF_LOG_FORCE || r->log & PF_LOG_ALL)
> -                     PFLOG_PACKET(&pd, reason, r, a, ruleset);
> +                     PFLOG_PACKET(&pd, reason, action, r, a, ruleset);
>               if (s) {
>                       SLIST_FOREACH(ri, &s->match_rules, entry)
>                               if (ri->r->log & PF_LOG_ALL)
> -                                     PFLOG_PACKET(&pd, reason, ri->r, a,
> -                                         ruleset);
> +                                     PFLOG_PACKET(&pd, reason, action,
> +                                         ri->r, a, ruleset);
>               }
>       }
> Are they ok?
> 
> Leonardo.
> 
> 
> 
> -------- Original Message --------
> Subject: pf logs: def/(short) pass in ,  but should say block
> Date: Wed, 09 May 2012 01:29:16 +0200
> From: Leonardo Guardati <leona...@guardati.it>
> To: b...@openbsd.org
> 
> Hi,
>  here is the setup ( I saw this on 5.0, 5.1, 5.1-current).
> 
> On a fresh installation.
> 
> /etc/pf.conf:
>       block log all
> 
> I send to the machine an UDP packet to port 0. I used from another machine:
>       nmap -Pn -sU -pU:0 target_ip
> 
> pf will log the packet as pass.
>       ... rule def/(short) pass in on ...
> 
> I tried to debug the code.
> 
> I see the packet is dropped (pf_test() returns PF_DROP), but
> pflog_packet() doesn't know it.
> 
> Here is what I saw:
> 
> in net/pf.c:6557 pf_setup_desc() decides to return (PF_DROP); because
> uh->hu_dport==0. (reason PFRES_SHORT).
> 
> in net/pf.c:6716:  action = pf_setup_desc(); is set and goto done;
> 
> then in net/pf.c:6954
>       PFLOG_PACKET(&pd, reason, r, a, ruleset) is called.
> 
> pflog_packet() gets the 'reason' code, but doesn't get the 'action'
> value set in net/pf.c:7616, also there is no rule match ( goto done;
> right after setting action=PF_DROP), so 'r' still points to
> pf_default_rule (which has a default PF_PASS).
> 
> The outcome is: I read a pass in the logs, while the packet is blocked
> instead.
> 
> I tried to think to possible solutions, but this is the first time I
> look into the OpenBSD kernel, so I'm just not aware of the code
> interconnections and how things should be.
> For example: why UDP destintation port 0 doesn't match 'block log all'
> rule in the first place?
> 
> Anyway I say what I think:
>       - could it be possible to add the 'action' variable to pflog_packet()
> arguments and then if 'r' points to pf_default_rule, 'action' is considered?
>       - could make sense specialize the pf_default_rule default action based
> on the reason code? ( in this case, PF_SHORT should imply a PF_DROP)
> (maybe using a switch(reason) in net/if_pflog.c:233 )
> 
> Another thing I noticed; in net/pf.c:6950 happen the logging, but after
> that there are other assignments to action. So I suppose there could be
> other ways to log a packet as block or pass with a different effective
> action.
> 
> Leonardo.

Reply via email to