Open Quuxplusone opened 13 years ago
Attached report-8Sjxxe.html
(638864 bytes, text/html): tcp_input.c null deref 1
Attached report-p5Ikh3.html
(639421 bytes, text/html): another false positive
_This bug has been marked as a duplicate of bug 6150_
Why was this marked a duplicate? Please don't dup static analyzer radars without justification or diagnosis. While false positives may seem similar, they can often be from different causes. If there is reason to suspect this is the same issue, that should be documented in the PR.
cloned to rdar://problem/9057893
It is the same IMHO, i.e when clang goes inside a function, and then a constant
is given differing values by clang switching around.
But I get your point, it might be processed in different files or a different
section of the file.
Sorry for that. Btw, this is the cause of a number of false positives when
analyzing userland of OpenBSD, and it looks to be old cause. Please look if
possible before 2.9 lock.
Thanks for you time
I need an actual preprocessed file to diagnose this issue, not the html bug reports.
Attached clang_tcp_input.i.pre
(279139 bytes, application/octet-stream): preprocessed output of tcp_input.c
Full command line used to generate preprocessed output.
Note, it does not include -Wstack-larger-than-2047 because of clang error.
As you can see switch (sc->sc_src.sa.sa_family) has two cases: case 2 and case 24 for TCP version 4 and TCP version 6 respectively.
clang -Werror -Wall -Wstrict-prototypes -Wmissing-prototypes -Wno-main -Wno-uninitialized -Wno-format -mcmodel=kernel -mno-red-zone -mno-sse2 -mno-sse -mno-3dnow -mno-mmx -msoft-float -fno-omit-frame-pointer -fno-builtin-printf -fno-builtin-snprintf -fno-builtin-vsnprintf -fno-builtin-log -fno-builtin-log2 -fno-builtin-malloc -O2 -pipe -nostdinc -I. -I../../../.. -I../../../../arch -DDDB -DDIAGNOSTIC -DKTRACE -DACCOUNTING -DKMEMSTATS -DPTRACE -DPOOL_DEBUG -DCRYPTO -DSYSVMSG -DSYSVSEM -DSYSVSHM -DUVM_SWAP_ENCRYPT -DCOMPAT_43 -DCOMPAT_O47 -DLKM -DFFS -DFFS2 -DFFS_SOFTUPDATES -DUFS_DIRHASH -DQUOTA -DEXT2FS -DMFS -DNNPFS -DNFSCLIENT -DNFSSERVER -DCD9660 -DUDF -DMSDOSFS -DFIFO -DSOCKET_SPLICE -DTCP_SACK -DTCP_ECN -DTCP_SIGNATURE -DINET -DALTQ -DINET6 -DIPSEC -DPPP_BSDCOMP -DPPP_DEFLATE -DMROUTING -DMPLS -DBOOT_CONFIG -DUSER_PCICONF -DAPERTURE -DMTRR -DNTFS -DPCIVERBOSE -DUSBVERBOSE -DWSDISPLAY_COMPAT_USL -DWSDISPLAY_COMPAT_RAWKBD -DWSDISPLAY_DEFAULTSCREENS="6" -DWSDISPLAY_COMPAT_PCVT -DX86EMU -DONEWIREVERBOSE -DMULTIPROCESSOR -DMAXUSERS=80 -D_KERNEL -E ../../../../netinet/tcp_input.c > clang_tcp_input.i.pre
I'm looking at the first case, in tcp_sack_option(). What I see:
p = cur;
...
while (cur) // take false branch; both p and cur are null
...
p->next = ... // p is null
The control-flow logic is rather confusing here, so there may be some control-
dependencies the analyzer is not handling, but it's not clear why this is a
false positive.
I will say the analyzer cannot handle reason about:
(sack.start)-(cur->start) > 0
The issue here is that both variables have symbolic values, and we aren't
tracking linear constraints (yet) between symbolic values. That's covered by
PR 4550.
The second issue is in tcp_mss_adv:
int
tcp_mss_adv(struct ifnet *ifp, int af)
{
int mss = 0;
int iphlen;
switch (af) { // ANALYZER : take default branch
case 2:
if (ifp != 0L)
mss = ifp->if_data.ifi_mtu;
iphlen = sizeof(struct ip);
break;
case 24:
if (ifp != 0L)
mss = (((((struct in6_ifextra *)(ifp)->if_afdata[24])->nd_ifinfo)->linkmtu && (((struct in6_ifextra *)(ifp)->if_afdata[24])->nd_ifinfo)->linkmtu < (ifp)->if_data.ifi_mtu) ? (((struct in6_ifextra *)(ifp)->if_afdata[24])->nd_ifinfo)->linkmtu : (((((struct in6_ifextra *)(ifp)->if_afdata[24])->nd_ifinfo)->maxmtu && (((struct in6_ifextra *)(ifp)->if_afdata[24])->nd_ifinfo)->maxmtu < (ifp)->if_data.ifi_mtu) ? (((struct in6_ifextra *)(ifp)->if_afdata[24])->nd_ifinfo)->maxmtu : (ifp)->if_data.ifi_mtu));
iphlen = sizeof(struct ip6_hdr);
break;
}
mss = mss - iphlen - sizeof(struct tcphdr); // ANALYZER: iphlen is still uninitialized
return (max(mss, tcp_mssdflt));
}
Why is this a false positive? The analyzer doesn't know that the only possible
cases are are '2' and '24' (if that is the case). To document that (if that is
the case), add an assertion, e.g.:
default:
assert(0 && "cannot be reached);
The analyzer will prune the path at the assert() call.
In 'syn_cache_add()', the branches involved are:
if (optp || (tp->t_flags & 0x0400)) {
...
switch (src->sa_family) {
..
default:
ipopts = 0L;
...
if ((sc = syn_cache_lookup(src, dst, &scp, ((struct inpcb *)(so)->so_pcb)->inp_rtableid))
!= 0L) {
...
if (ipopts) {
...
sc->sc_timestamp = tb.ts_recent; // ERROR
While the analyzer isn't being clever about 'tp->t_flags & 0x400', I don't see
any logic here that the analyzer should understand to establish any control-
dependencies between these branches. Looks like a legit warning to me. If
there is a control-dependency, you'll need to add an assertion.
(In reply to comment #0)
> Created an attachment (
(In reply to comment #0)
>
> Please look at attachment to easily figure out the problem, looking at the
> switch(sc->sc_src.sa.sa_family). There are 4 more attachments all in this same
> function. Can't add multiple attachments?
Looks like the constraint on 'sa_family' isn't getting tracked because the
symbolic store is returning a value of "unknown" for the load in the switch
statement.
This like the analyzer's current lack of reasoning for 'unions'.
(In reply to comment #13)
> (In reply to comment #0)
> >
> > Please look at attachment to easily figure out the problem, looking at the
> > switch(sc->sc_src.sa.sa_family). There are 4 more attachments all in this
same
> > function. Can't add multiple attachments?
>
> Looks like the constraint on 'sa_family' isn't getting tracked because the
> symbolic store is returning a value of "unknown" for the load in the switch
> statement.
>
> This like the analyzer's current lack of reasoning for 'unions'.
More specifically:
struct syn_cache {
<SNIP>
union syn_cache_sa sc_src; // <-- union
<SNIP>
};
Hi Ted,
Thanks for your time in investigating this. And hoping for a fix!
--amit
report-8Sjxxe.html
(638864 bytes, text/html)report-p5Ikh3.html
(639421 bytes, text/html)clang_tcp_input.i.pre
(279139 bytes, application/octet-stream)