From Fedora Project Wiki
No edit summary
(Describe O_NEEDEXEC in more detail.)
Line 38: Line 38:


An initial analysis suggests that we cannot use the existing x bits because those will confuse tools such as desktop file system browsers.  Python modules also have different behavior when run as a main program: they often run test code, and this code could have harmful effects.  If we reuse the x bit for this, accidental execution of scripts not intended to be executed by the end user seems likely.
An initial analysis suggests that we cannot use the existing x bits because those will confuse tools such as desktop file system browsers.  Python modules also have different behavior when run as a main program: they often run test code, and this code could have harmful effects.  If we reuse the x bit for this, accidental execution of scripts not intended to be executed by the end user seems likely.
Note that the noexec mount option does not clear the exec bits on files (it does not turn mode
0755 into mode 0644). It disables execve for such binaries, but the file permissions
are left unchanged. Current kernels provide a straightforward way to detect the noexec mount flag, but a new flag for the open family of system calls, say O_NEEDEXEC, seems reasonable for audit purposes. This is different from O_EXEC (as it exists on other non-Linux systems and as defined by POSIX) or O_PATH (defined on Linux) because it still provides a readable file descriptor, but requires that the file is executable, with checks similar to execve applied. The primary purpose of O_NEEDEXEC is for eventual policy enforcement in the kernel and distinguishing the case of "Opening the file with intent to execute it" and "Opening the file."


== Benefit to Fedora ==
== Benefit to Fedora ==
Line 45: Line 49:
== Scope ==
== Scope ==
* Proposal owners:
* Proposal owners:
** Kernel support is needed for the new <code>O_NEEDEXEC</code> flag for the <code>open</code> and <code>openat</code> system calls.  A security module which implements policy enforcement needs to be written.
** Kernel support is needed for the new <code>O_NEEDEXEC</code> flag for the <code>open</code> and <code>openat</code> system calls.  A security module which implements policy enforcement needs to be written. As an example the security module may cause <code>open</code> to fail if an "exec" filesystem attribute is not set for the file and <code>O_NEEDEXEC</code> is requested.
** glibc needs to provide support for the <code>O_NEEDEXEC</code> flag.
** glibc needs to provide support for the <code>O_NEEDEXEC</code> flag.
** Core script interpreters such as bash, Python, Perl, OpenJDK, Lua, RPM itself need to updated to implement the new policy.
** Core script interpreters such as bash, Python, Perl, OpenJDK, Lua, RPM itself need to updated to implement the new policy.

Revision as of 17:33, 30 March 2016

All script code must reside in executable files

Summary

All executable script code in the core system resides in files specifically marked as executable. Script interpreters will refuse to execute code which is loaded from the file system, but does not reside in such files.

Owner

TBD

Current status

  • Targeted release: Releases/25
  • Last updated: 2016-03-30
  • Tracker bug: <will be assigned by the Wrangler>

Detailed Description

The easiest way to describe this change is provide a few examples.

bash /path/to/some/script

requires a special bit on /path/to/some/script that indicates this file is whitelisted for execution.

Similarly, if you do

source /etc/sysconfig/init

in a shell script, /etc/sysconfig/init must be marked as executable. And if you execute

import argparse

in Python, the /usr/lib64/python3.4/__pycache__/argparse.cpython-34.pyc file (or whatever file is opened) needs this markup as well.

An initial analysis suggests that we cannot use the existing x bits because those will confuse tools such as desktop file system browsers. Python modules also have different behavior when run as a main program: they often run test code, and this code could have harmful effects. If we reuse the x bit for this, accidental execution of scripts not intended to be executed by the end user seems likely.

Note that the noexec mount option does not clear the exec bits on files (it does not turn mode 0755 into mode 0644). It disables execve for such binaries, but the file permissions are left unchanged. Current kernels provide a straightforward way to detect the noexec mount flag, but a new flag for the open family of system calls, say O_NEEDEXEC, seems reasonable for audit purposes. This is different from O_EXEC (as it exists on other non-Linux systems and as defined by POSIX) or O_PATH (defined on Linux) because it still provides a readable file descriptor, but requires that the file is executable, with checks similar to execve applied. The primary purpose of O_NEEDEXEC is for eventual policy enforcement in the kernel and distinguishing the case of "Opening the file with intent to execute it" and "Opening the file."

Benefit to Fedora

Downstreams will be able to continue building products which can be used in environments which require security certifications.

Scope

  • Proposal owners:
    • Kernel support is needed for the new O_NEEDEXEC flag for the open and openat system calls. A security module which implements policy enforcement needs to be written. As an example the security module may cause open to fail if an "exec" filesystem attribute is not set for the file and O_NEEDEXEC is requested.
    • glibc needs to provide support for the O_NEEDEXEC flag.
    • Core script interpreters such as bash, Python, Perl, OpenJDK, Lua, RPM itself need to updated to implement the new policy.
    • A tool has to be added to the coreutils package which allows setting the executable bit.
    • RPM needs to be updated to be able to mark executable code in RPM packages.
  • Other developers: All script interpreters need to be changed to open files with the new O_NEEDEXEC flag. Programs which create script files at run time (such as RPM) need to mark those script files as executable. Packages shipping script code need to be updated to mark the code as such.
  • Release engineering: There are no substantial changes how bits are delivered, although pervasive packaging changes are required.
  • Policies and guidelines: Package guidelines need to be updated to state that script files have to be marked as executable. Script interpreters must check that files containing script code are executable. The guidelines should be updated with the final design before the bulk of the implementation happens.
  • Trademark approval: N/A (not needed for this Change)

Upgrade/compatibility impact

System administrators will need to manually mark their existing scripts as executable.

How To Test

This command sequence should result in an error message:

cat > script.py <<EOF
print("Hello, world!")
EOF
python3 script.py

In particular, it should not print "Hello, world!".

Similar test cases need to be constructed for other script interpreters.

User Experience

Some common tasks, such as downloading a script with a web browser and executing it, will stop working. An additional step is needed to make the file executable first.

Dependencies

This change affects most packages in the distribution.

Contingency Plan

  • Contingency mechanism: TBD
  • Contingency deadline: TBD
  • Blocks release? TBD
  • Blocks product? No.

Documentation

TBD

Release Notes

TBD. This will have to be based on the documentation.