12e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert# Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
22e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert# Use of this source code is governed by a BSD-style license that can be
32e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert# found in the LICENSE file.
42e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
52e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertimport logging
62e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertimport os
72e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertimport re
82e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertimport stat
92e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertimport subprocess
102e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
113bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obesfrom autotest_lib.client.bin import test
122e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertfrom autotest_lib.client.common_lib import error
13e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obesfrom autotest_lib.client.cros import asan
142e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
152e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebertclass security_OpenFDs(test.test):
16e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes    """Checks a number of sensitive processes on Chrome OS for unexpected open
17e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes    file descriptors.
18e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes    """
193ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes
20e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes    version = 1
213ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes
22e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes    @staticmethod
23e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes    def _S_ISANONFD(mode):
2464ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        """
25e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Returns whether |mode| represents an "anonymous inode" file descriptor.
26e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Python does not expose a type-checking macro for anonymous inode fds.
27e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Implements the same interface as stat.S_ISREG(x).
2864ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert
29e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param mode: mode bits, usually from 'stat(path).st_mode'
3064ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        """
31e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        return 0 == (mode & 0770000)
323ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes
333ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes
3464ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert    def get_fds(self, pid, typechecker):
352e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
36e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Returns the set of open file descriptors for |pid|.
37e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Each open fd is represented as 'mode path', e.g.: '0500 /dev/random'.
38e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
39e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param pid: pid of process
40e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param typechecker: callback restricting allowed fd types
412e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
422e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        proc_fd_dir = os.path.join('/proc/', pid, 'fd')
432e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        fd_perms = set([])
442e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        for link in os.listdir(proc_fd_dir):
452e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            link_path = os.path.join(proc_fd_dir, link)
462e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            target = os.readlink(link_path)
4764ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            # The "mode" on the link tells us if the file is
4864ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            # opened for read/write. We are more interested
4964ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            # in that than the permissions of the file on the fs.
5064ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            link_st_mode = os.lstat(link_path).st_mode
5164ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            # On the other hand, we need the type information
5264ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            # off the real file, otherwise we're going to get
5364ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            # S_ISLNK for everything.
5464ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            real_st_mode = os.stat(link_path).st_mode
5564ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            if not typechecker(real_st_mode):
5664ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert                raise error.TestFail('Pid %s has fd for %s, disallowed type' %
5764ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert                                     (pid, target))
5864ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            mode = stat.S_IMODE(link_st_mode)
592e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            fd_perms.add('%s %s' % (oct(mode), target))
602e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        return fd_perms
612e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
622e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
632e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert    def snapshot_system(self):
642e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
652e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        Dumps a systemwide snapshot of open-fd and process table
662e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        information into the results directory, to assist with any
672e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        triage/debug later.
682e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
692e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        subprocess.call('ps -ef > "%s/ps-ef.txt"' % self.resultsdir,
702e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                        shell=True)
712e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        subprocess.call('ls -l /proc/*[0-9]*/fd > "%s/proc-fd.txt"' %
722e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                        self.resultsdir, shell=True)
732e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
742e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
752e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert    def apply_filters(self, fds, filters):
762e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
77e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Removes every item in |fds| matching any of the regexes in |filters|.
782e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        This modifies the set in-place, and returns a list containing
792e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        any regexes which did not match anything.
80e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
81e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param fds: set of 'mode path' strings representing open fds
82e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param filters: list of regexes to filter open fds with
832e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
842e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        failed_filters = set()
852e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        for filter_re in filters:
862e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            expected_fds = set([fd_perm for fd_perm in fds
872e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                                if re.match(filter_re, fd_perm)])
882e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            if not expected_fds:
892e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                failed_filters.add(filter_re)
902e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            fds -= expected_fds
912e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        return failed_filters
922e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
932e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
942e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert    def find_pids(self, process, arg_regex):
952e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
96e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Finds all pids for |process| whose command line arguments
97e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        match |arg_regex|. Returns a list of pids.
98e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
99e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param process: process name
100e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param arg_regex: regex to match command line arguments
1012e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
1022e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        p1 = subprocess.Popen(['ps', '-C', process, '-o', 'pid,command'],
1032e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                              stdout=subprocess.PIPE)
104b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        # We're adding '--ignored= --type=renderer' to the GPU process cmdline
105e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        # to fix crbug.com/129884.
106b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        # This process has different characteristics, so we need to avoid
107b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        # finding it when we find --type=renderer tests processes.
108b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        p2 = subprocess.Popen(['grep', '-v', '--',
109b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert                               '--ignored=.*%s' % arg_regex],
110b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert                              stdin=p1.stdout, stdout=subprocess.PIPE)
111b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        p3 = subprocess.Popen(['grep', arg_regex], stdin=p2.stdout,
1122e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                              stdout=subprocess.PIPE)
113b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        p4 = subprocess.Popen(['awk', '{print $1}'], stdin=p3.stdout,
1142e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                              stdout=subprocess.PIPE)
115b34a060eb62f32f1837fe4a7000de5601319ca36Jim Hebert        output = p4.communicate()[0]
1162e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        return output.splitlines()
1172e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
1182e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
11964ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert    def check_process(self, process, args, filters, typechecker):
1202e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
121e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Checks a process for unexpected open file descriptors:
122e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        * Identifies all instances (pids) of |process|.
123e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        * Identifies all file descriptors open by those pids.
124e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        * Reports any fds not accounted for by regexes in |filters|.
125e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        * Reports any filters which fail to match any open fds.
126e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
127e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        If there were any fds unaccounted for, or failed filters,
128e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        mark the test failed.
129e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
130e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param process: process name
131e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param args: regex to match command line arguments
132e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param filters: list of regexes to filter open fds with
133e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        @param typechecker: callback restricting allowed fd types
1342e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
1353bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obes        logging.debug('Checking %s %s', process, args)
1362e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        test_pass = True
1372e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        for pid in self.find_pids(process, args):
1383bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obes            logging.debug('Found pid %s for %s', pid, process)
13964ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert            fds = self.get_fds(pid, typechecker)
1402e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            failed_filters = self.apply_filters(fds, filters)
141e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes            # Log failed filters to allow pruning the list.
1422e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            if failed_filters:
1433bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obes                logging.error('Some filter(s) failed to match any fds: %s',
1442e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                              repr(failed_filters))
1452e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert            if fds:
1463bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obes                logging.error('Found unexpected fds in %s %s: %s',
1473bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obes                              process, args, repr(fds))
1482e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                test_pass = False
1492e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        return test_pass
1502e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
1512e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
1522e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert    def run_once(self):
1532e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
154e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        Checks a number of sensitive processes on Chrome OS for
155e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        unexpected open file descriptors.
1562e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        """
1572e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        self.snapshot_system()
158e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
1592e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        passes = []
16064ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        filters = [r'0700 anon_inode:\[event.*\]',
1612e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                   r'0[35]00 pipe:.*',
1622e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                   r'0[57]00 socket:.*',
16354876d4fa2af23a2446cb7f082008d7ca2b0e97bJim Hebert                   r'0500 /dev/null',
1642e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                   r'0[57]00 /dev/urandom',
1652e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                   r'0300 /var/log/chrome/chrome_.*',
16654876d4fa2af23a2446cb7f082008d7ca2b0e97bJim Hebert                   r'0[37]00 /var/log/ui/ui.*',
1672e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                  ]
16864ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert
16964ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        # Whitelist fd-type check, suitable for Chrome processes.
17064ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        # Notably, this omits S_ISDIR.
171e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        allowed_fd_type_check = lambda x: (stat.S_ISREG(x) or
172e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes                                           stat.S_ISCHR(x) or
173e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes                                           stat.S_ISSOCK(x) or
174e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes                                           stat.S_ISFIFO(x) or
175e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes                                           security_OpenFDs._S_ISANONFD(x))
176e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes
177e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        # TODO(jorgelo): revisit this and potentially remove.
178e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes        if asan.running_on_asan():
1793ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes            # On ASan, allow all fd types and opening /proc
1803ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes            logging.info("Running on ASan, allowing /proc")
181e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes            allowed_fd_type_check = lambda x: True
1823ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes            filters.append(r'0500 /proc')
1833ceb659202e33df4ba45bd0cf9cffc1d50d129c7Jorge Lucangeli Obes
18464ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        passes.append(self.check_process('chrome', 'type=plugin', filters,
185e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes                                         allowed_fd_type_check))
1862e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
1873bd4e23c6eba1722e319b89f58dc82b339c94efbJorge Lucangeli Obes        filters.extend([r'0[57]00 /dev/shm/..*',
18823a63b062f3730b50b1ffc4e1fcafec81e1849e1Jim Hebert                        r'0500 /opt/google/chrome/.*.pak',
1898c7b99e7fe600e9795d4b0e74158372e3adfcb96Jorge Lucangeli Obes                        r'0500 /opt/google/chrome/icudtl.dat',
19024178b16488537f91b00e62df3d7a43a844b814dJorge Lucangeli Obes                        # These used to be bundled with the Chrome binary.
19124178b16488537f91b00e62df3d7a43a844b814dJorge Lucangeli Obes                        # See crbug.com/475170.
19224178b16488537f91b00e62df3d7a43a844b814dJorge Lucangeli Obes                        r'0500 /opt/google/chrome/natives_blob.bin',
19324178b16488537f91b00e62df3d7a43a844b814dJorge Lucangeli Obes                        r'0500 /opt/google/chrome/snapshot_blob.bin',
19409dd045a05297c576fa2d4dd3868e0a372c46c86Jorge Lucangeli Obes                        # Font files can be kept open in renderers
19509dd045a05297c576fa2d4dd3868e0a372c46c86Jorge Lucangeli Obes                        # for performance reasons.
19609dd045a05297c576fa2d4dd3868e0a372c46c86Jorge Lucangeli Obes                        # See crbug.com/452227.
19709dd045a05297c576fa2d4dd3868e0a372c46c86Jorge Lucangeli Obes                        r'0500 /usr/share/fonts/.*',
198fe14f5801ce9e0a27e227b5e20de73a0f34d7a6fIlja H. Friedel                        # Zero-copy texture uploads. crbug.com/607632.
19937aee5eaff86749891ebcde3454a4e9617c7a214Ilja H. Friedel                        r'0700 anon_inode:dmabuf',
2002e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert                       ])
201741fb665935bb552c36ec67754f2cc3d352e1314Jorge Lucangeli Obes        try:
2020c187b54d5e1df70be7e0788b212c2192f9f43baMichael Spang            # Renderers have access to DRM vgem device for graphics tile upload.
2030c187b54d5e1df70be7e0788b212c2192f9f43baMichael Spang            # See crbug.com/537474.
204741fb665935bb552c36ec67754f2cc3d352e1314Jorge Lucangeli Obes            filters.append(r'0700 /dev/dri/%s' % os.readlink('/dev/dri/vgem'))
205741fb665935bb552c36ec67754f2cc3d352e1314Jorge Lucangeli Obes        except OSError:
206741fb665935bb552c36ec67754f2cc3d352e1314Jorge Lucangeli Obes            # /dev/dri/vgem doesn't exist.
207741fb665935bb552c36ec67754f2cc3d352e1314Jorge Lucangeli Obes            pass
208741fb665935bb552c36ec67754f2cc3d352e1314Jorge Lucangeli Obes
20964ed5cc34066bee4e2869941fa9a52bdb418e9fdJim Hebert        passes.append(self.check_process('chrome', 'type=renderer', filters,
210e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes                                         allowed_fd_type_check))
2112e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert
2122e04d94f9631e20004a20bba3acfd477e58b4f5aJim Hebert        if False in passes:
213e84e15447cf806211afc5a48f74c4fe5223af277Jorge Lucangeli Obes            raise error.TestFail("Unexpected open file descriptors.")
214