)]}'
{"oslo_rootwrap/filters.py":[{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"f797834a0d2893e11bae28599340aff56ed2ecca","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def is_ip_netns_exec(userargs):"},{"line_number":35,"context_line":"    return bool(IPNETNSEXEC_RE.match(\u0027 \u0027.join(userargs)))"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class CommandFilter(object):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_7590b14f","line":35,"updated":"2018-04-27 09:39:57.000000000","message":"I dislike \u0027 \u0027.join(userargs). It doesn\u0027t seem to be safe to me. I would prefer to match arguments as a list.","commit_id":"e0750fb6679e8df367312d421485be8fa9dd2658"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"ffc0bd20e0804ed5ee13196740ff6d291f7a40d7","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def is_ip_netns_exec(userargs):"},{"line_number":35,"context_line":"    return bool(IPNETNSEXEC_RE.match(\u0027 \u0027.join(userargs)))"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class CommandFilter(object):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_fc74a600","line":35,"in_reply_to":"9f6a8fd7_7590b14f","updated":"2018-04-27 14:08:44.000000000","message":"You mean that one can pass \u0027ip \"netns exec\"\u0027 as a command and that will match IpNetnsExecFilter instead of IpFilter? Or what is the other reason behind avoiding using join()?","commit_id":"e0750fb6679e8df367312d421485be8fa9dd2658"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"2ab71080864912711616fd5cd716ae63b7c0fea9","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def is_ip_netns_exec(userargs):"},{"line_number":35,"context_line":"    return bool(IPNETNSEXEC_RE.match(\u0027 \u0027.join(userargs)))"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class CommandFilter(object):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_7534e4fb","line":35,"in_reply_to":"9f6a8fd7_eea374ff","updated":"2018-05-02 10:09:57.000000000","message":"Done","commit_id":"e0750fb6679e8df367312d421485be8fa9dd2658"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"a7bc316f5defc7f35629425f46954327a425c68b","unresolved":false,"context_lines":[{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"def is_ip_netns_exec(userargs):"},{"line_number":35,"context_line":"    return bool(IPNETNSEXEC_RE.match(\u0027 \u0027.join(userargs)))"},{"line_number":36,"context_line":""},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"class CommandFilter(object):"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_eea374ff","line":35,"in_reply_to":"9f6a8fd7_fc74a600","updated":"2018-04-30 07:27:00.000000000","message":"The test returns true if it gets [\u0027ip netns exec\u0027, ...] no? It doesn\u0027t seem correct, since it\u0027s a different command.\n\nIt\u0027s unlikely to have a program \u0027/usr/bin/ip netns exec\u0027, but who knows? It may allow another kind of attack.","commit_id":"e0750fb6679e8df367312d421485be8fa9dd2658"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"3a1b4996efdf64b0d266c39f48e82a7da3dd1622","unresolved":false,"context_lines":[{"line_number":19,"context_line":"import sys"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"NETNS_RE \u003d re.compile(r\u0027\\s*netn?s?\\s*$\u0027)"},{"line_number":22,"context_line":"EXEC_RE \u003d re.compile(r\u0027\\s*e?x?e?c?\\s*$\u0027)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"if sys.platform !\u003d \u0027win32\u0027:"},{"line_number":25,"context_line":"    # NOTE(claudiub): pwd is a Linux-specific library, and currently there is"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_700872d8","line":22,"updated":"2018-05-02 10:30:07.000000000","message":"Why do you want to accept spaces?\n\n\"ip\" \"  exec\" \"netns\" \"...\" seems weird to me.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"fba880538c6a7b11995a71d4a088de63e3c41e74","unresolved":false,"context_lines":[{"line_number":19,"context_line":"import sys"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"NETNS_RE \u003d re.compile(r\u0027\\s*netn?s?\\s*$\u0027)"},{"line_number":22,"context_line":"EXEC_RE \u003d re.compile(r\u0027\\s*e?x?e?c?\\s*$\u0027)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"if sys.platform !\u003d \u0027win32\u0027:"},{"line_number":25,"context_line":"    # NOTE(claudiub): pwd is a Linux-specific library, and currently there is"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_f0ca426c","line":22,"in_reply_to":"9f6a8fd7_700872d8","updated":"2018-05-02 10:39:31.000000000","message":"can one pass \"ip  netns exec\" or should that be banned. Bash accepts spaces between args.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"65e686b5116afb7bfdc256563a72237cbf4d642e","unresolved":false,"context_lines":[{"line_number":19,"context_line":"import sys"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"NETNS_RE \u003d re.compile(r\u0027\\s*netn?s?\\s*$\u0027)"},{"line_number":22,"context_line":"EXEC_RE \u003d re.compile(r\u0027\\s*e?x?e?c?\\s*$\u0027)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"if sys.platform !\u003d \u0027win32\u0027:"},{"line_number":25,"context_line":"    # NOTE(claudiub): pwd is a Linux-specific library, and currently there is"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_0481bb4a","line":22,"in_reply_to":"9f6a8fd7_d0761ed9","updated":"2018-05-02 11:32:16.000000000","message":"Done","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b3878a575eede3d516380214f6639f5672f2fd03","unresolved":false,"context_lines":[{"line_number":19,"context_line":"import sys"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"NETNS_RE \u003d re.compile(r\u0027\\s*netn?s?\\s*$\u0027)"},{"line_number":22,"context_line":"EXEC_RE \u003d re.compile(r\u0027\\s*e?x?e?c?\\s*$\u0027)"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"if sys.platform !\u003d \u0027win32\u0027:"},{"line_number":25,"context_line":"    # NOTE(claudiub): pwd is a Linux-specific library, and currently there is"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_d0761ed9","line":22,"in_reply_to":"9f6a8fd7_f0ca426c","updated":"2018-05-02 11:09:12.000000000","message":"I don\u0027t see why oslo.rootwrap accepts a command as a string. It seems like oslo.rootwrap is properly designed to only accept a command as a list of strings. No shell is used in oslo.rootwrap.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"3a1b4996efdf64b0d266c39f48e82a7da3dd1622","unresolved":false,"context_lines":[{"line_number":35,"context_line":"def is_ip_netns_exec(userargs):"},{"line_number":36,"context_line":"    try:"},{"line_number":37,"context_line":"        ip \u003d userargs[0]"},{"line_number":38,"context_line":"    except IndexError:"},{"line_number":39,"context_line":"        return False"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_d0693ebe","line":38,"updated":"2018-05-02 10:30:07.000000000","message":"You may check the length. For example:\n\n# ip netns exec arg\nif len(userargs) \u003c 4:\n   return False","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"fba880538c6a7b11995a71d4a088de63e3c41e74","unresolved":false,"context_lines":[{"line_number":35,"context_line":"def is_ip_netns_exec(userargs):"},{"line_number":36,"context_line":"    try:"},{"line_number":37,"context_line":"        ip \u003d userargs[0]"},{"line_number":38,"context_line":"    except IndexError:"},{"line_number":39,"context_line":"        return False"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_10ab3689","line":38,"in_reply_to":"9f6a8fd7_d0693ebe","updated":"2018-05-02 10:39:31.000000000","message":"I could but I assume case where arguments are actually passed surpasses case with empty list significantly :)","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"3a1b4996efdf64b0d266c39f48e82a7da3dd1622","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    except IndexError:"},{"line_number":39,"context_line":"        return False"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_d0ae1ee6","line":41,"updated":"2018-05-02 10:30:07.000000000","message":"Why do you accept spaces? userargs[0] \u003d\u003d \u0027ip\u0027 seems safer.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"65e686b5116afb7bfdc256563a72237cbf4d642e","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    except IndexError:"},{"line_number":39,"context_line":"        return False"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_a497af90","line":41,"in_reply_to":"9f6a8fd7_30ae7a98","updated":"2018-05-02 11:32:16.000000000","message":"Done","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"fba880538c6a7b11995a71d4a088de63e3c41e74","unresolved":false,"context_lines":[{"line_number":38,"context_line":"    except IndexError:"},{"line_number":39,"context_line":"        return False"},{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_30ae7a98","line":41,"in_reply_to":"9f6a8fd7_d0ae1ee6","updated":"2018-05-02 10:39:31.000000000","message":"Same as before but if commands like \"ip  netns exec foo\" should not be accepted, then I can make a change.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"3a1b4996efdf64b0d266c39f48e82a7da3dd1622","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"},{"line_number":45,"context_line":"                if NETNS_RE.match(arg) and EXEC_RE.match(args_iter.next()):"},{"line_number":46,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_f092429f","line":43,"updated":"2018-05-02 10:30:07.000000000","message":"Do you want to accept other parameters between ip and netns? Maybe only skip arguments starting with \"-\"? Otherwise, the filter accepts any ip command which contains \"netns exec\" somewhere, even if \"netns exec\" is a comment or is ignored.\n\nSomething like:\n\ni \u003d 1\n# skip options like \"-6\"\nwhile len(userargs)-i \u003e\u003d 2 and userargs[i].startswith(\u0027-\u0027):\n  i +\u003d 1\nif userargs[i] not in (\u0027net\u0027, \u0027netn\u0027, \u0027netns\u0027):\n  return False\nif userargs[i+1] not in (\u0027e\u0027, \u0027ex\u0027, \u0027exe\u0027 ,\u0027exec\u0027):\n  return False\n\nMaybe we should require full command names \"ip netns exec\" to avoid bad surprised. For example, \"ip ne\" is \"ip neigh\", not \"ip netnfs\". What if a new netns command starting with \"e\" is added? Which one will win?\n\n\"ip net exec\" and \"ip netns exec\" seems reasonable, other shorter commands seem unsafe to me.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"65e686b5116afb7bfdc256563a72237cbf4d642e","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"},{"line_number":45,"context_line":"                if NETNS_RE.match(arg) and EXEC_RE.match(args_iter.next()):"},{"line_number":46,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_44d6d329","line":43,"in_reply_to":"9f6a8fd7_1014964d","updated":"2018-05-02 11:32:16.000000000","message":"Regarding batch - yes, it is! It\u0027s another way to become root on the box:\n[11:30:35]\nvagrant@controller:/tmp\n$ echo \"net e test-13380a2a-36b0-41a0-b52e-f201b99d1c11 whoami\" \u003e commands\n[11:30:50]\nvagrant@controller:/tmp\n$ sudo ip -batch commands netns exec\nroot\n\nRegarding -family - that\u0027s to keep previous functionality. This patch was about fixing bypassing \"ip net e\" usage in rootwrap so attacker won\u0027t be able to get root permissions on box filesystem anymore.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":9107,"name":"Victor Stinner","email":"vstinner@redhat.com","username":"haypo"},"change_message_id":"b3878a575eede3d516380214f6639f5672f2fd03","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"},{"line_number":45,"context_line":"                if NETNS_RE.match(arg) and EXEC_RE.match(args_iter.next()):"},{"line_number":46,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_1014964d","line":43,"in_reply_to":"9f6a8fd7_10b256e7","updated":"2018-05-02 11:09:12.000000000","message":"How about -batch FILENAME?\n\n\"Read commands from provided file or standard input and invoke them.  First failure will cause termination of ip.\"\n\nIt seems like a way to escape the sandbox, no?\n\nThe -loops option only applies to the \u0027ip address flush\u0027 logic.\n\nDo you see any use case which needs -family with ip netns exec? -family has no impact on this command, does it?","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"0ba1242e1f504a5c0be03938f8c4352b4c279aad","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"},{"line_number":45,"context_line":"                if NETNS_RE.match(arg) and EXEC_RE.match(args_iter.next()):"},{"line_number":46,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_0470dbdb","line":43,"in_reply_to":"9f6a8fd7_44d6d329","updated":"2018-05-02 11:53:39.000000000","message":"The bug is also in IpFilter:\n\n$ echo netns exec test-13380a2a-36b0-41a0-b52e-f201b99d1c11 whoami | sudo oslo-rootwrap /etc/neutron/rootwrap.conf ip -b - link\nroot","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"fba880538c6a7b11995a71d4a088de63e3c41e74","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"    if ip.strip() \u003d\u003d \u0027ip\u0027:"},{"line_number":42,"context_line":"        args_iter \u003d iter(userargs[1:])"},{"line_number":43,"context_line":"        for arg in args_iter:"},{"line_number":44,"context_line":"            try:"},{"line_number":45,"context_line":"                if NETNS_RE.match(arg) and EXEC_RE.match(args_iter.next()):"},{"line_number":46,"context_line":"                    return True"}],"source_content_type":"text/x-python","patch_set":4,"id":"9f6a8fd7_10b256e7","line":43,"in_reply_to":"9f6a8fd7_f092429f","updated":"2018-05-02 10:39:31.000000000","message":"How about case \"ip -l 42 netns exec\" ? My thinking about this is, filter the ip netns command, if it doesn\u0027t make sense, it will fail during execution anyway. We shouldn\u0027t filter particular parameters for ip command in the rootwrap filter. That\u0027s not its job.\n\nIf new \u0027netns\u0027 command starting with \u0027e\u0027 is added and it changes the \"ip netns e\" behavior, then someone in iplib should get kicked right square in the balls because of backward compatibility. :) Most of user scripts will stop working.","commit_id":"3b5ae06d58c149f8c7453bdbafe19ec29eeb911c"}],"oslo_rootwrap/tests/test_rootwrap.py":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"a61538f3ae26ed5c8ad754e074c407534fcd5aeb","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        self.assertTrue(f.match([\u0027ip\u0027, \u0027net\u0027, \u0027e\u0027, \u0027foo\u0027, \u0027bar\u0027]))"},{"line_number":354,"context_line":"        self.assertTrue(f.match([\u0027ip\u0027, \u0027net\u0027, \u0027exe\u0027, \u0027foo\u0027, \u0027bar\u0027]))"},{"line_number":355,"context_line":"        self.assertTrue(f.match([\u0027ip\u0027, \u0027net\u0027, \u0027exe\u0027, \u0027foo\u0027, \u0027bar\u0027]))"},{"line_number":356,"context_line":"        self.assertTrue(f.match([\u0027ip\u0027, \u0027-s\u0027, \u0027netns\u0027, \u0027exec\u0027]))"},{"line_number":357,"context_line":"        self.assertTrue(f.match([\u0027ip\u0027, \u0027-l\u0027, \u002742\u0027, \u0027netns\u0027, \u0027exec\u0027]))"},{"line_number":358,"context_line":""},{"line_number":359,"context_line":"    def test_IpNetnsExecFilter_nomatch(self):"},{"line_number":360,"context_line":"        f \u003d filters.IpNetnsExecFilter(self._ip, \u0027root\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"9f6a8fd7_74a8c1da","line":357,"range":{"start_line":356,"start_character":0,"end_line":357,"end_character":69},"updated":"2018-04-26 19:11:40.000000000","message":"I\u0027m actually not sure if we should allow this. If not, we\u0027ll need to have two regexps.","commit_id":"e0750fb6679e8df367312d421485be8fa9dd2658"}]}
