AppArmor file permission 'append' denies file creation

Bug #1339099 reported by Damian Gerow
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
AppArmor
Confirmed
Low
Unassigned
apparmor (Ubuntu)
Confirmed
Low
Unassigned

Bug Description

This bug started as a question, to make sure I know how to computer before filing a bug: https://answers.launchpad.net/ubuntu/+source/apparmor/+question/251315

All this work is being done on an up-to-date 14.04 server running apparmor{-profiles,-utils} 2.8.95~2430-0ubuntu5.

While trying to sort out the appropriate AppArmor bits to control logging, I'm seeing the file permission 'append' deny create access to a file, where I would have expected this to not be denied. It also denies 'file_perm', but it's unclear if this would be expected to work. I can fix the situation by updating the profile to use the 'write' permission instead of 'append', but this is less than ideal.

http://manpages.ubuntu.com/manpages/trusty/en/man5/apparmor.d.5.html indicates that the 'append' file permission "Allows the program to have a limited appending only write access to the file."

In addition, http://wiki.apparmor.net/index.php/AppArmor_Core_Policy_Reference explicitly states that 'append' grants "permission to create, and extend a file. The append permission is limited that it only gives permission for applications to open a file with O_APPEND, it can not be used to enforce a generic file write is append only."

From https://en.opensuse.org/Archive:AppArmor_2_3_changes#Minor_Semantic_Changes, it appears as though granting 'create' permissions to 'append' is new in AppArmor 2.3.

However, in writing up a simple test program in Go, I'm seeing AppArmor deny create permissions where 'append' is allowed.

The Go code:
-----
func main() {
        logFile, err = os.OpenFile("/opt/test/log/test.log", os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0644)
        n, err := logFile.WriteString("direct write\n")
        if err != nil {
                fmt.Println(n, err)
        }
        log.SetOutput(logFile)
        log.Println("Log file initialized.")
        logFile.Close()
}
-----

The AppArmor profile:
-----
#include <tunables/global>

/opt/test/bin/test {
  #include <abstractions/base>

  /opt/test/log/test.log a,
}
-----

When set to enforce, the program spits out an error:
-----
% /opt/test/bin/test
0 invalid argument
%
-----

And AppArmor logs the DENIED message:
-----
kernel: [ 5687.957758] type=1400 audit(1404743687.548:92): apparmor="DENIED" operation="open" profile="/opt/test/bin/test" name="/opt/test/log/test.log" pid=7766 comm="test" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
-----

When set to complain, the program works as expected (as expected):
-----
% /opt/test/bin/test
%
-----

And AppArmor logs three calls with which it has an issue:
-----
kernel: [ 5949.505626] type=1400 audit(1404743948.872:98): apparmor="ALLOWED" operation="open" profile="/opt/test/bin/test" name="/opt/test/log/test.log" pid=8158 comm="test" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
kernel: [ 5949.505643] type=1400 audit(1404743948.872:99): apparmor="ALLOWED" operation="file_perm" profile="/opt/test/bin/test" name="/opt/test/log/test.log" pid=8158 comm="test" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000
kernel: [ 5949.505758] type=1400 audit(1404743948.872:100): apparmor="ALLOWED" operation="file_perm" profile="/opt/test/bin/test" name="/opt/test/log/test.log" pid=8158 comm="test" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000
-----

I'm not sure what's going on with the 'file_perm' stuff either -- I thought that would have required 'chmod', but that doesn't appear to be the case.

Revision history for this message
Seth Arnold (seth-arnold) wrote :

I did some testing with C to ensure Go wasn't doing something behind our backs:

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>

int main(int argc, char* argv[]) {
 int fd, ret;

 fd = open("testing", O_WRONLY | O_APPEND
#if 1
         | O_CREAT , 0660);
#else
  );
#endif
 if (fd == -1) {
  perror("open");
  exit(1);
 } else {
  ret = write(fd, "hello\n", 6);
  if (ret != 6) {
   perror("write");
   exit(1);
  }
 }
 return 0;
}

Change the #if 1 to #if 0 to see the difference the O_CREAT flag has on the log output.

Here is the profile I used:

#include <tunables/global>

/home/sarnold/demos/append flags=(complain) {
  #include <abstractions/base>

  /home/sarnold/demos/append mr,
  /home/sarnold/demos/testing a,

}

Without O_CREAT here are the log messages:

type=AVC msg=audit(1404847907.250:4570): apparmor="ALLOWED" operation="file_perm" profile="/home/sarnold/demos/append" name="/home/sarnold/demos/testing" pid=4409 comm="append" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000

With O_CREAT here are the log messages:

type=AVC msg=audit(1404847924.482:4571): apparmor="ALLOWED" operation="open" profile="/home/sarnold/demos/append" name="/home/sarnold/demos/testing" pid=4419 comm="append" requested_mask="c" denied_mask="c" fsuid=1000 ouid=1000
type=AVC msg=audit(1404847924.482:4572): apparmor="ALLOWED" operation="file_perm" profile="/home/sarnold/demos/append" name="/home/sarnold/demos/testing" pid=4419 comm="append" requested_mask="w" denied_mask="w" fsuid=1000 ouid=1000

It sure feels like the semantics of the 'a' permission have changed.

Thanks

Revision history for this message
Seth Arnold (seth-arnold) wrote :

Ah, right, launchpad destroys formatting. So here's append.c source in an attachment to make it tolerable to view.

Changed in apparmor (Ubuntu):
status: New → Confirmed
importance: Undecided → Low
Changed in apparmor:
status: New → Confirmed
importance: Undecided → Low
tags: added: aa-kernel aa-parser
Revision history for this message
Christian Boltz (cboltz) wrote :

This bug could be the reason for bug 1324608

To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Related questions

Bug attachments

Remote bug watches

Bug watches keep track of this bug in other bug trackers.