All of lore.kernel.org
 help / color / mirror / Atom feed
From: Tom Parkin <tparkin@katalix.com>
To: netdev <netdev@vger.kernel.org>
Subject: kmemleak complaints in ip6mr.c
Date: Tue, 29 Jan 2013 18:51:27 +0000	[thread overview]
Message-ID: <20130129185127.GA31811@raven> (raw)

[-- Attachment #1: Type: text/plain, Size: 5737 bytes --]

I've discovered what may be a memory leak in ip6mr when using network
namespaces.  Here's the kmemleak backtrace:


unreferenced object 0xf0d4a180 (size 96):
  comm "ip", pid 6735, jiffies 4294949643 (age 73.268s)
  hex dump (first 32 bytes):
    68 a1 d4 f0 00 02 20 00 01 00 00 00 00 00 00 00  h..... .........
    00 00 00 00 00 00 00 00 00 00 00 00 ff 7f 00 00  ................
  backtrace:
    [<c159b50c>] kmemleak_alloc+0x2c/0x60
    [<c1139c23>] __kmalloc+0x1c3/0x240
    [<c14e2627>] fib_default_rule_add+0x27/0x70
    [<c157f8df>] ip6mr_net_init+0x6f/0x140
    [<c14c4129>] ops_init+0x39/0x110
    [<c14c425f>] setup_net+0x5f/0xf0
    [<c14c46e4>] copy_net_ns+0x74/0xf0
    [<c105fc81>] create_new_namespaces+0xd1/0x160
    [<c105fedf>] unshare_nsproxy_namespaces+0x5f/0xa0
    [<c1038a94>] sys_unshare+0x114/0x280
    [<c15b7ecd>] sysenter_do_call+0x12/0x28
    [<ffffffff>] 0xffffffff


I've reproduced this on a recent net-next kernel (master as of this
Monday or so, git hash cef401de7be8c4e155c6746bfccf721a4fa5fab9),
using the script attached inline below.  The script is a trimmed down
version of something I have been using to stress test some l2tp_core
changes, but the ip6mr issue appears to exist on master as well as my
branch.  To get this to show up on my AMD64x2 I typically have to run
the script twice -- the first time around I get a bunch of modprobe
complaints from kmemleak, and the second time around I get ip6mr
complaints.

I'm not sure whether the trace above represents a false positive or
not -- any thoughts?

Thanks,
Tom

#!/bin/bash

BRIDGE=br0
BASE_IP=172.16.0.0
PREFIX=24
MAX_CHILDREN=300

log() { echo -e "[$(date)] $@"; }
err() { log "ERROR: $@" 1>&2; false; }
die() { err "$@"; exit 1; }
dbg() { test -n "$DEBUG" && log "$@" 1>&2; }

# $1 -- ip as a dotted quad
ip_to_decimal()
{
        local o1=${1%%.*}
        local o2=$(echo "$1" | cut -d. -f2)
        local o3=$(echo "$1" | cut -d. -f3)
        local o4=${1##*.}
        echo "($o1*(2^24)) + ($o2*(2^16)) + ($o3*(2^8)) + ($o4)" | bc
}

# $1 -- ip as a decimal number
decimal_to_ip()
{
        local h=$(printf "%08x" "$1")
        echo $(printf "%i" 0x${h:0:2}).$(printf "%i" 0x${h:2:2}).$(printf "%i" 0x${h:4:2}).$(printf "%i" 0x${h:6:2})
}

# $1 -- base
# $2 -- netmask
# $3 -- subnet index
offset_min_ipaddr()
{
        local nwoff=$(echo "$3 * (2^(32-$2))" | bc)
        local base=$(ip_to_decimal "$1")
        decimal_to_ip $((base+nwoff+1))
}

#$1 -- lower bound
#$2 -- upper bound
brand() {
        local r=$((RANDOM%$2))
        test $r -lt $1 && r=$(brand $1 $2)
        echo $r
}

# $1 -- network interface name
# $2 -- id
gen_script() {
        local laddr=$(offset_min_ipaddr $BASE_IP $PREFIX $2)
        local sleepfor=$(brand 0 5)

        dbg "$2 : $1 : sleepfor $sleepfor"

        cat << __EOF__
#!/bin/bash
ip addr add $laddr/255.255.0.0 dev $1 || exit 1
ip link set $1 up || exit 1
sleep $sleepfor
ip link set $1 down
__EOF__
}

# $1 -- netns
# $2 -- ve0
# $3 -- ve1
nsup() {
        local netns="$1"
        local ve0="$2"
        local ve1="$3"
        local ret=1

        ip netns add $netns || return $ret

        ip link add name $ve0 type veth peer name $ve1 && \
                ip link set $ve1 netns $netns && \
                brctl addif $BRIDGE $ve0 && \
                ip link set $ve0 up && ret=0 || \
                ip netns delete $netns
                return $ret
}

# $1 -- netns
# $2 -- ve0
# $3 -- ve1
nsdown() {
        local netns="$1"
        local ve0="$2"
        local ve1="$3"
        ip link set $ve0 down
        brctl delif $BRIDGE $ve0
        ip link del $ve0
        ip netns delete $netns
}

# $1 -- id
# $2 -- netns
do_netns() {
        local id="$1"
        local netns="$2"
        local runscript=/tmp/${netns}_run.sh
        local ve0=$(echo $netns | cut -d- -f1)-0
        local ve1=$(echo $netns | cut -d- -f1)-1

        dbg "$id : $netns"

        if nsup $netns $ve0 $ve1
        then
                gen_script $ve1 $id > $runscript && chmod +x $runscript && \
                        ip netns exec $netns $runscript || \
                        err "$id : $netns failed to gen/exec ns script"
                while ! nsdown $netns $ve0 $ve1 &> /dev/null; do sleep 1; done
                rm $runscript
        else
                err "$id : $netns failed to come up"
        fi
}

waitforchildren() {
        local p=""
        log "Wait for $(echo "$cpids" | wc -w) child scripts to complete"
        dbg "cpids = $cpids"
        for p in $cpids; do wait $p; done
        cpids=""
}

#
# Entry point
#
trap waitforchildren EXIT

if ! brctl show | grep -q $BRIDGE
then
        brctl addbr $BRIDGE || die "Failed to create bridge $BRIDGE"
        ip link set $BRIDGE up || die "Failed to bring $BRIDGE up"
fi

c=0
cpids=""
while true
do
        nchildren=$(brand 1 $MAX_CHILDREN)
        echo clear > /sys/kernel/debug/kmemleak
        log "Spawn $nchildren network namespaces"
        for ((i=0;i<$nchildren;i++))
        do
                c=$((c+1))
                netns=$(uuidgen)
                ( cpids=""; do_netns $c $netns ) &
                cpids="$cpids $!"
        done

        waitforchildren
        echo scan > /sys/kernel/debug/kmemleak
        if test $(wc -l /sys/kernel/debug/kmemleak | cut -d" " -f1) -gt 0
        then
                die "Kernel memory leak detected: see /sys/kernel/debug/kmemleak"
        fi
done


-- 
Tom Parkin
Katalix Systems Ltd
http://www.katalix.com
Catalysts for your Embedded Linux software development

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 490 bytes --]

             reply	other threads:[~2013-01-29 18:51 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-01-29 18:51 Tom Parkin [this message]
2013-01-29 18:59 ` kmemleak complaints in ip6mr.c David Miller
2013-01-30  8:22   ` Cong Wang
2013-01-30  9:49   ` Tom Parkin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20130129185127.GA31811@raven \
    --to=tparkin@katalix.com \
    --cc=netdev@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.