'module' object has no attribute 'O_PATH'

Bug #1851806 reported by Karl-Philipp Richter on 2019-11-08
16
This bug affects 3 people
Affects Status Importance Assigned to Milestone
apport (Ubuntu)
High
Tiago Stürmer Daitx

Bug Description

I encountered the following exception in python-apport while encountering an exception `bup` which uses `python-apport`. I'm sure that the exception lies in the responsibility of `python-apport` (the `AttributeError` stacktrace is relevant):

```
Traceback (most recent call last):
  File "/usr/lib/bup/cmd/bup-index", line 269, in <module>
    update_index(rp, excluded_paths, exclude_rxs, xdev_exceptions=xexcept)
  File "/usr/lib/bup/cmd/bup-index", line 191, in update_index
    mi.close()
  File "/usr/lib/bup/bup/index.py", line 528, in close
    os.rename(self.tmpname, self.filename)
OSError: [Errno 13] Permission denied
Error in sys.excepthook:
Traceback (most recent call last):
  File "/usr/lib/bup/bup/helpers.py", line 916, in newhook
    return oldhook(exctype, value, traceback)
  File "/usr/lib/python2.7/dist-packages/apport_python_hook.py", line 109, in apport_excepthook
    pr.add_proc_info(extraenv=['PYTHONPATH', 'PYTHONHOME'])
  File "/usr/lib/python2.7/dist-packages/apport/report.py", line 544, in add_proc_info
    proc_pid_fd = os.open('/proc/%s' % pid, os.O_RDONLY | os.O_PATH | os.O_DIRECTORY)
AttributeError: 'module' object has no attribute 'O_PATH'

Original exception was:
Traceback (most recent call last):
  File "/usr/lib/bup/cmd/bup-index", line 269, in <module>
    update_index(rp, excluded_paths, exclude_rxs, xdev_exceptions=xexcept)
  File "/usr/lib/bup/cmd/bup-index", line 191, in update_index
    mi.close()
  File "/usr/lib/bup/bup/index.py", line 528, in close
    os.rename(self.tmpname, self.filename)
OSError: [Errno 13] Permission denied
```

ProblemType: Bug
DistroRelease: Ubuntu 19.10
Package: python-apport 2.20.11-0ubuntu8.2
ProcVersionSignature: Ubuntu 5.3.0-19.20-generic 5.3.1
Uname: Linux 5.3.0-19-generic x86_64
NonfreeKernelModules: zfs zunicode zavl icp zcommon znvpair
ApportLog: Error: [Errno 13] Keine Berechtigung: '/var/log/apport.log'
ApportVersion: 2.20.11-0ubuntu8.2
Architecture: amd64
CurrentDesktop: ubuntu:GNOME
Date: Fri Nov 8 10:43:02 2019
PackageArchitecture: all
SourcePackage: apport
UpgradeStatus: Upgraded to eoan on 2019-10-25 (13 days ago)

Related branches

Sebastien Bacher (seb128) wrote :

Thank you for your bug report. Could you give some steps to trigger the issue?

Changed in apport (Ubuntu):
status: New → Incomplete

I'm not exactly sure how to reproduce this bug, but I did encounter the same issue. It looks like the bug was recently introduced in this commit: https://git.launchpad.net/ubuntu/+source/apport/commit/?h=applied/ubuntu/xenial-security&id=ecd7418b02911c6649b69a592cca74cfbac8813d

```
@@ -510,22 +510,24 @@ class Report(problem_report.ProblemReport):
         - _LogindSession: logind cgroup path, if present (Used for filtering
           out crashes that happened in a session that is not running any more)
         '''
- if not pid:
- pid = self.pid or os.getpid()
- if not self.pid:
- self.pid = int(pid)
- pid = str(pid)
+ if not proc_pid_fd:
+ if not pid:
+ pid = self.pid or os.getpid()
+ if not self.pid:
+ self.pid = int(pid)
+ pid = str(pid)
+ proc_pid_fd = os.open('/proc/%s' % pid, os.O_RDONLY | os.O_PATH | os.O_DIRECTORY)

         try:
- self['ProcCwd'] = os.readlink('/proc/' + pid + '/cwd')
+ self['ProcCwd'] = os.readlink('cwd', dir_fd=proc_pid_fd)
         except OSError:
             pass
         self.add_proc_environ(pid, extraenv)
- self['ProcStatus'] = _read_file('/proc/' + pid + '/status')
- self['ProcCmdline'] = _read_file('/proc/' + pid + '/cmdline').rstrip('\0')
- self['ProcMaps'] = _read_maps(int(pid))
+ self['ProcStatus'] = _read_file('status', dir_fd=proc_pid_fd)
+ self['ProcCmdline'] = _read_file('cmdline', dir_fd=proc_pid_fd).rstrip('\0')
+ self['ProcMaps'] = _read_maps(proc_pid_fd)
         try:
- self['ExecutablePath'] = os.readlink('/proc/' + pid + '/exe')
+ self['ExecutablePath'] = os.readlink('exe', dir_fd=proc_pid_fd)
         except OSError as e:
             if e.errno == errno.ENOENT:
                 raise ValueError('invalid process')
```

The problem is that os.O_PATH does not exist in python2, and only exists in python3. However, python-apport is a python2 package.

```
bcurtiss@bcurtiss-laptop:~$ python3 -c 'import os; print(os.O_PATH)'
2097152
bcurtiss@bcurtiss-laptop:~$ python -c 'import os; print(os.O_PATH)'
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute 'O_PATH'
bcurtiss@bcurtiss-laptop:~$
```

Here's a reproduction of the error:

bcurtiss@bcurtiss-laptop:~$ ipython
Python 2.7.12 (default, Oct 8 2019, 14:14:10)
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]: import apport_python_hook; apport_python_hook.apport_excepthook(Exception, Exception(), None)
Exception
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-1-e8f288b62cb1> in <module>()
----> 1 import apport_python_hook; apport_python_hook.apport_excepthook(Exception, Exception(), None)

/usr/lib/python2.7/dist-packages/apport_python_hook.pyc in apport_excepthook(exc_type, exc_obj, exc_tb)
    107 traceback.print_exception(exc_type, exc_obj, exc_tb, file=tb_file)
    108 pr['Traceback'] = tb_file.getvalue().strip()
--> 109 pr.add_proc_info(extraenv=['PYTHONPATH', 'PYTHONHOME'])
    110 pr.add_user_info()
    111 # override the ExecutablePath with the script that was actually running

/usr/lib/python2.7/dist-packages/apport/report.pyc in add_proc_info(self, pid, proc_pid_fd, extraenv)
    517 self.pid = int(pid)
    518 pid = str(pid)
--> 519 proc_pid_fd = os.open('/proc/%s' % pid, os.O_RDONLY | os.O_PATH | os.O_DIRECTORY)
    520
    521 try:

AttributeError: 'module' object has no attribute 'O_PATH'

In [2]: exit
bcurtiss@bcurtiss-laptop:~$ ipython3
Python 3.5.2 (default, Oct 8 2019, 13:06:37)
Type "copyright", "credits" or "license" for more information.

IPython 2.4.1 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.

In [1]: import apport_python_hook; apport_python_hook.apport_excepthook(Exception, Exception(), None)
Exception

In [2]: exit
bcurtiss@bcurtiss-laptop:~$

tags: added: regression-update
Changed in apport (Ubuntu):
status: Incomplete → New
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in apport (Ubuntu):
status: New → Confirmed
Albert Pool (albertpool) wrote :

Simply removing O_PATH from the line in question leads to:

Traceback (most recent call last):
  File "/usr/share/apport/apport-gtk", line 597, in <module>
    app.run_argv()
  File "/usr/lib/python2.7/dist-packages/apport/ui.py", line 661, in run_argv
    return self.run_update_report()
  File "/usr/lib/python2.7/dist-packages/apport/ui.py", line 559, in run_update_report
    self.report.add_proc_environ()
  File "/usr/lib/python2.7/dist-packages/apport/report.py", line 592, in add_proc_environ
    env = _read_file('environ', dir_fd=proc_pid_fd).replace('\n', '\\n')
  File "/usr/lib/python2.7/dist-packages/apport/report.py", line 73, in _read_file
    with open(path, 'rb', opener=lambda path, mode: os.open(path, mode, dir_fd=dir_fd)) as fd:
TypeError: 'opener' is an invalid keyword argument for this function

(Linux Mint 18.2, python-apport 2.20.1-0ubuntu2.21)

Albert Pool (albertpool) wrote :

The above looks like some Python 3 code ended up in a Python 2.7 document, given opener= was added in Python 3.3 it seems.

tags: added: id-5dd454a1dd84728273703743
Changed in apport (Ubuntu):
assignee: nobody → Tiago Stürmer Daitx (tdaitx)
importance: Undecided → High
status: Confirmed → In Progress
Launchpad Janitor (janitor) wrote :

This bug was fixed in the package apport - 2.20.11-0ubuntu16

---------------
apport (2.20.11-0ubuntu16) focal; urgency=medium

  * SECURITY REGRESSION: 'module' object has no attribute 'O_PATH'
    (LP: #1851806)
    - apport/report.py, apport/ui.py: use file descriptors for /proc/pid
      directory access only when running under python 3; prevent reading /proc
      maps under python 2 as it does not provide a secure way to do so; use
      io.open for better compatibility between python 2 and 3.
  * data/apport: fix number of arguments passed through socks into a container.
  * test/test_report.py: test login session with both pid and proc_pid_fd.

 -- Tiago Stürmer Daitx <email address hidden> Mon, 06 Jan 2020 13:28:40 +0000

Changed in apport (Ubuntu):
status: In Progress → Fix Released
tags: added: id-5e540609ebb75b15e089ff0e
To post a comment you must log in.
This report contains Public information  Edit
Everyone can see this information.

Other bug subscribers