Page 1 of 1

nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Wed Oct 15, 2008 4:52 pm
by law
I'm trying to develop a sane grsec policy for puppet (a changeconfig application based on cfengine), which is written in Ruby. Because puppet is basically going to be managing everything about a system, we want it to have unfettered access to pretty much everything. The only way the puppet client gets its 'instructions' is through a TLS-encrypted channel to the 'puppetmaster' server, so even if someone does get root (but not gradm admin) on the box they won't be able to tell the puppet client to do anything because they won't be communicating to it via the channel to the puppetmaster. Anyways, so my grsec acls under the 'root' role currently look like this:

We've got the ACL for /usr/bin/puppet:
subject /usr/bin/puppet rvka {
/ rwcdmlxi

/usr/bin/ruby1.8 rwcdmlxi
# Default connections: Allow to LDAP, DNS, NFS, and Puppetmaster

connect <ldap-servers>/24:636 stream tcp dgram udp
connect <puppetmaster>/32:8140 any_sock any_proto
connect <dns>/0:53 any_sock any_proto
connect <nfs subnet>/24:2049 any_sock any_proto
connect ! 0.0.0.0/0 any_sock any_proto
}

Then the ACL for the interprer/usr/bin/ruby1.8:
subject /usr/bin/ruby1.8 {

/etc/init.d r
/etc/passwd r
/etc/group r

/etc/puppet r

/usr/bin/ruby1.8 rx

/var/log/puppet rwcdl
/var/run/puppet rwcdl
/var/lib/puppet rwcdl
/var/state/puppet r

+CAP_SETUID

# Default connections: Allow to LDAP and DNS
connect <ldap>/24:636 stream tcp dgram udp
connect <dns>/0:53 any_sock any_proto
connect <nfs>/24:2049 any_sock any_proto
connect ! 0.0.0.0/0 any_sock any_proto
}

So with that set up, I dropped in a (testing!) nested ACL that I figure *should* give the puppet client the access it needs:
subject /usr/bin/puppet:/usr/bin/ruby1.8 rvka {
/ rwcdmlxi
connect <puppetmaster ip>/32:8140
}

and it promptly does a whole lot of nothing. I still get in my logs, on the puppet client startup, errors like the following:

[83091.156540] grsec: From <myhost>: (root:U:/usr/bin/ruby1.8) denied connect() to <puppetmaster IP> port 8140 sock type stream protocol tcp by /usr/bin/ruby1.8[ruby:8623] uid/euid:0/0 gid/egid:0/0, parent /sbin/init[init:1] uid/euid:0/0 gid/egid:0/0
[83091.164215] grsec: From <myhost>: (root:U:/usr/bin) denied executable mmap of /var/lib/dpkg/status by /usr/bin/dpkg-query[dpkg-query:8712] uid/euid:0/0 gid/egid:0/0, parent /usr/bin/ruby1.8[ruby:8623] uid/euid:0/0 gid/egid:0/0

The first one is showing that it cannot connect to the puppetmaster IP, even though it's explicitly allowed in the nested ACL and the /usr/bin/puppet ACL. The second error is showing that it can't get enumerate the packages listed in the system, despite the over-generous ACL permission set on the nested subject. What am I doing wrong?

Re: nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Fri Oct 17, 2008 9:34 am
by PaX Team
law wrote:[83091.156540] grsec: From <myhost>: (root:U:/usr/bin/ruby1.8) denied connect() to <puppetmaster IP> port 8140 sock type stream protocol tcp by /usr/bin/ruby1.8[ruby:8623] uid/euid:0/0 gid/egid:0/0, parent /sbin/init[init:1] uid/euid:0/0 gid/egid:0/0
according to this log, the parent process is not what your ACL assumes, so the nested subject doesn't apply (my guess is that this ruby instance daemonized itself, that's why init is its parent).
[83091.164215] grsec: From <myhost>: (root:U:/usr/bin) denied executable mmap of /var/lib/dpkg/status by /usr/bin/dpkg-query[dpkg-query:8712] uid/euid:0/0 gid/egid:0/0, parent /usr/bin/ruby1.8[ruby:8623] uid/euid:0/0 gid/egid:0/0
i think this comes from TPE. if status is a data file, then it should never be mmaped with PROT_EXEC, that's a bug in dpkg then (or maybe it comes from READ_IMPLIES_EXEC which in turn would come from the lack of the GNU_STACK program header in dpkg, check readelf -l and the forum for this problem).

Re: nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Fri Oct 17, 2008 4:10 pm
by law
Uh, ok. That doesn't make a whole lot of sense to me, but I'll see if I can work with it anyway. :D Running 'readelf -l' against dpkg-query gives me this:

vpuppet01:~# readelf -l /usr/bin/dpkg-query

Elf file type is EXEC (Executable file)
Entry point 0x8049980
There are 7 program headers, starting at offset 52

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4
INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x11cc4 0x11cc4 R E 0x1000
LOAD 0x012000 0x0805a000 0x0805a000 0x00318 0x8b6a8 RW 0x1000
DYNAMIC 0x012014 0x0805a014 0x0805a014 0x000c8 0x000c8 RW 0x4
NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag
06

As for /var/lib/dpkg/status, that's a flat text file that lists various information about installed packages. So, given the above, is there anything I can do to either fix my policy or work around the weirdness of ruby/dpkg?

Re: nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Thu Oct 23, 2008 6:16 pm
by PaX Team
law wrote:As for /var/lib/dpkg/status, that's a flat text file that lists various information about installed packages. So, given the above, is there anything I can do to either fix my policy or work around the weirdness of ruby/dpkg?
so, dpkg looks clean, then it may very well be a parent process, ruby, bash, etc, check them as well for the GNU_STACK header.

Re: nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Sun Oct 26, 2008 2:40 pm
by law
Hrm, strangely enough, both /usr/bin/ruby1.8 and /bin/bash have that GNU_STACK line on them:

vpuppet01:~# readelf -l /bin/bash

Elf file type is EXEC (Executable file)
Entry point 0x805be30
There are 8 program headers, starting at offset 52

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x00100 0x00100 R E 0x4
INTERP 0x000134 0x08048134 0x08048134 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0xa0520 0xa0520 R E 0x1000
LOAD 0x0a0520 0x080e9520 0x080e9520 0x04b44 0x09728 RW 0x1000
DYNAMIC 0x0a0534 0x080e9534 0x080e9534 0x000d8 0x000d8 RW 0x4
NOTE 0x000148 0x08048148 0x08048148 0x00020 0x00020 R 0x4
GNU_EH_FRAME 0x0a0458 0x080e8458 0x080e8458 0x0002c 0x0002c R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag
06 .eh_frame_hdr
07
vpuppet01:~# readelf -l /usr/bin/ru
ruby ruby1.8 runcon run-mailcap
vpuppet01:~# readelf -l /usr/bin/ru
ruby ruby1.8 runcon run-mailcap
vpuppet01:~# readelf -l /usr/bin/ruby1.8

Elf file type is EXEC (Executable file)
Entry point 0x8048520
There are 7 program headers, starting at offset 52

Program Headers:
Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align
PHDR 0x000034 0x08048034 0x08048034 0x000e0 0x000e0 R E 0x4
INTERP 0x000114 0x08048114 0x08048114 0x00013 0x00013 R 0x1
[Requesting program interpreter: /lib/ld-linux.so.2]
LOAD 0x000000 0x08048000 0x08048000 0x0072c 0x0072c R E 0x1000
LOAD 0x00072c 0x0804972c 0x0804972c 0x00134 0x00138 RW 0x1000
DYNAMIC 0x000740 0x08049740 0x08049740 0x000f0 0x000f0 RW 0x4
NOTE 0x000128 0x08048128 0x08048128 0x00020 0x00020 R 0x4
GNU_STACK 0x000000 0x00000000 0x00000000 0x00000 0x00000 RW 0x4

Section to Segment mapping:
Segment Sections...
00
01 .interp
02 .interp .note.ABI-tag .hash .dynsym .dynstr .gnu.version .gnu.version_r .rel.dyn .rel.plt .init .plt .text .fini .rodata .eh_frame
03 .ctors .dtors .jcr .dynamic .got .got.plt .data .bss
04 .dynamic
05 .note.ABI-tag
06

Could I just be nesting my subjects incorrectly or 'sub-optimally'?

--Lee

Re: nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Mon Oct 27, 2008 6:05 am
by PaX Team
law wrote:Hrm, strangely enough, both /usr/bin/ruby1.8 and /bin/bash have that GNU_STACK line on them:
hmm and i guess so does init/login/whatever else comes before them... can you strace dpkg itself then to see how it mmaps that file?

Re: nested inheritance and interpreters (ruby, perl, etc)

PostPosted: Mon Oct 27, 2008 11:05 am
by spender
Be careful when using the "i" inheritance object flag. In the case in which you were using it for puppet, you had everything executed by puppet inheriting the puppet subject, which would prevent any nested subject from taking effect. Also note that in the case of interpreted scripts, the subject for the script only applies if it is executed directly (that is, directly as /usr/bin/puppet and not: python /usr/bin/puppet).

-Brad