Commit d43db80d authored by Alex Tomlins's avatar Alex Tomlins Committed by Brian May

Fix deadlock with iptables with large ruleset

When running sshuttle with a large list of routes it's failing to clean
them up at exit. It returns the following:

$ sshuttle -r user@host.example.com -s /tmp/aws-cidrs.txt
user@host.example.com's password:
client: Connected.
^CAnother app is currently holding the xtables lock; still -9s 0us time ahead to have a chance to grab the lock...
Another app is currently holding the xtables lock; still -19s 0us time ahead to have a chance to grab the lock...
Another app is currently holding the xtables lock; still -29s 0us time ahead to have a chance to grab the lock...

This continues indefinitely. Looking in ps reveals that there are 2
iptables processes running. Killing -9 the first one, allows sshuttle to
continue and clean up successfully.

The problem lies with the use of Popen here. The function currently
returns as soon as it finds a match without consuming everything from
stdout. This means that if there's more output from iptables than will
fit in the buffer it doesn't exit, and therefore doesn't release the
kernel xtables lock.
parent 0b1a2604
...@@ -24,13 +24,12 @@ def ipt_chain_exists(family, table, name): ...@@ -24,13 +24,12 @@ def ipt_chain_exists(family, table, name):
'PATH': os.environ['PATH'], 'PATH': os.environ['PATH'],
'LC_ALL': "C", 'LC_ALL': "C",
} }
p = ssubprocess.Popen(argv, stdout=ssubprocess.PIPE, env=env) completed = ssubprocess.run(argv, stdout=ssubprocess.PIPE, env=env, encoding='ASCII')
for line in p.stdout: if completed.returncode:
if line.startswith(b'Chain %s ' % name.encode("ASCII")): raise Fatal('%r returned %d' % (argv, completed.returncode))
for line in completed.stdout.split('\n'):
if line.startswith('Chain %s ' % name):
return True return True
rv = p.wait()
if rv:
raise Fatal('%r returned %d' % (argv, rv))
def ipt(family, table, *args): def ipt(family, table, *args):
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment