/mandos/release

To get this branch, use:
bzr branch http://bzr.recompile.se/loggerhead/mandos/release

« back to all changes in this revision

Viewing changes to network-hooks.d/bridge

  • Committer: teddy at recompile
  • Date: 2020-04-05 21:30:59 UTC
  • mto: This revision was merged to the branch mainline in revision 398.
  • Revision ID: teddy@recompile.se-20200405213059-fb2a61ckqynrmatk
Fix file descriptor leak in mandos-client

When the local network has Mandos servers announcing themselves using
real, globally reachable, IPv6 addresses (i.e. not link-local
addresses), but there is no router on the local network providing IPv6
RA (Router Advertisement) packets, the client cannot reach the server
by normal means, since the client only has a link-local IPv6 address,
and has no usable route to reach the server's global IPv6 address.
(This is not a common situation, and usually only happens when the
router itself reboots and runs a Mandos client, since it cannot then
give RA packets to itself.)  The client code has a solution for
this, which consists of adding a temporary local route to reach the
address of the server during communication, and removing this
temporary route afterwards.

This solution with a temporary route works, but has a file descriptor
leak; it leaks one file descriptor for each addition and for each
removal of a route.  If one server requiring an added route is present
on the network, but no servers gives a password, making the client
retry after the default ten seconds, and we furthermore assume a
default 1024 open files limit, the client runs out of file descriptors
after about 90 minutes, after which time the client process will be
useless and fail to retrieve any passwords, necessitating manual
password entry via the keyboard.

Fix this by eliminating the file descriptor leak in the client.

* plugins.d/mandos-client.c (add_delete_local_route): Do
  close(devnull) also in parent process, also if fork() fails, and on
  any failure in child process.

Show diffs side-by-side

added added

removed removed

Lines of Context:
6
6
# configuration file(s) should be copied into the
7
7
# /etc/mandos/network-hooks.d directory.
8
8
9
 
# Copyright © 2011 Teddy Hogeborn
10
 
# Copyright © 2011 Björn Påhlsson
 
9
# Copyright © 2012-2018 Teddy Hogeborn
 
10
# Copyright © 2012-2018 Björn Påhlsson
11
11
12
12
# Copying and distribution of this file, with or without modification,
13
13
# are permitted in any medium without royalty provided the copyright
20
20
 
21
21
addrtoif(){
22
22
    grep -liFe "$1" /sys/class/net/*/address \
23
 
        | sed -e 's,.*/\([^/]*\)/[^/]*,\1,'
 
23
        | sed -e 's,.*/\([^/]*\)/[^/]*,\1,' -e "/^${BRIDGE}\$/d"
24
24
}
25
25
 
26
26
# Read config file, which must set "BRIDGE", "PORT_ADDRESSES", and
29
29
    . "$CONFIG"
30
30
fi
31
31
 
32
 
if [ -z "$BRIDGE" -o -z "$PORT_ADDRESSES" ]; then
33
 
    exit
34
 
fi
35
 
 
36
 
if [ -n "$DEVICE" -a "$DEVICE" != "$BRIDGE" ]; then
37
 
    exit
38
 
fi
39
 
 
40
 
for b in /sbin/brctl /usr/sbin/brctl; do
 
32
if [ -z "$BRIDGE" ] || [ -z "$PORT_ADDRESSES" ]; then
 
33
    exit
 
34
fi
 
35
 
 
36
if [ -n "$DEVICE" ]; then
 
37
    case "$DEVICE" in
 
38
        *,"$BRIDGE"|*,"$BRIDGE",*|"$BRIDGE",*|"$BRIDGE") :;;
 
39
        *) exit;;
 
40
    esac
 
41
fi
 
42
 
 
43
brctl="/sbin/brctl"
 
44
for b in "$brctl" /usr/sbin/brctl; do
41
45
    if [ -e "$b" ]; then
42
46
        brctl="$b"
43
47
        break
44
48
    fi
45
49
done
46
50
 
47
 
case "$1" in
48
 
    start)
49
 
        "$brctl" addbr "$BRIDGE"
50
 
        for address in $PORT_ADDRESSES; do
51
 
            interface=`addrtoif "$address"`
52
 
            "$brctl" addif "$BRIDGE" "$interface"
53
 
            ip link set dev "$interface" up
54
 
        done
55
 
        ip link set dev "$BRIDGE" up
56
 
        sleep "$DELAY"
57
 
        if [ -n "$IPADDRS" ]; then
58
 
            for ipaddr in $IPADDRS; do
59
 
                ip addr add "$ipaddr" dev "$BRIDGE"
60
 
            done
61
 
        fi
62
 
        if [ -n "$ROUTES" ]; then
63
 
            for route in $ROUTES; do
64
 
                ip route add "$route" dev "$BRIDGE"
65
 
            done
66
 
        fi
67
 
        ;;
68
 
    stop)
69
 
        ip link set dev "$BRIDGE" down
70
 
        for address in $PORT_ADDRESSES; do
71
 
            interface=`addrtoif "$address"`
72
 
            ip link set dev "$interface" down
73
 
            "$brctl" delif "$BRIDGE" "$interface"
74
 
        done
75
 
        "$brctl" delbr "$BRIDGE"
 
51
do_start(){
 
52
    "$brctl" addbr "$BRIDGE"
 
53
    for address in $PORT_ADDRESSES; do
 
54
        interface=`addrtoif "$address"`
 
55
        "$brctl" addif "$BRIDGE" "$interface"
 
56
        ip link set dev "$interface" up
 
57
    done
 
58
    ip link set dev "$BRIDGE" up
 
59
    sleep "${DELAY%%.*}"
 
60
    if [ -n "$IPADDRS" ]; then
 
61
        for ipaddr in $IPADDRS; do
 
62
            ip addr add "$ipaddr" dev "$BRIDGE"
 
63
        done
 
64
    fi
 
65
    if [ -n "$ROUTES" ]; then
 
66
        for route in $ROUTES; do
 
67
            ip route add "$route" dev "$BRIDGE"
 
68
        done
 
69
    fi
 
70
}
 
71
 
 
72
do_stop(){
 
73
    ip link set dev "$BRIDGE" down
 
74
    for address in $PORT_ADDRESSES; do
 
75
        interface=`addrtoif "$address"`
 
76
        ip link set dev "$interface" down
 
77
        "$brctl" delif "$BRIDGE" "$interface"
 
78
    done
 
79
    "$brctl" delbr "$BRIDGE"
 
80
}
 
81
 
 
82
case "${MODE:-$1}" in
 
83
    start|stop)
 
84
        do_"${MODE:-$1}"
76
85
        ;;
77
86
    files)
78
87
        echo /bin/ip