# [Solved] Traversing mount requires group execute bit!

## Rexilion

This turned out to be a mistake, sorry for the noise   :Embarassed: 

The fix (or workaround) for this 'odity' is below, however I don't know why. Anyways, here we go:

Want to access file as user 'ipsec':

/home/secure/ronald/.vpn/cacerts/caCert.der

Permissions:

755 root:root /home

001 root:root /secure

701 ronald:ronald /ronald

100 ipsec:root /.vpn

-> 100 ipsec:root /cacerts

-> 400 ipsec:root /cacerts/caCert.der

-> 100 ipsec:root /private

-> 400 ipsec:root /private/charlieKey.der

I can access the file as the ipsec user using bash and ls

```
Alpha .vpn # sudo -u ipsec bash

bash: /dev/null/.bashrc: Not a directory

ipsec@Alpha /home/secure/ronald/.vpn $ ls -la /home/secure/ronald/.vpn/cacerts/caCert.der

-r-------- 1 ipsec root 887 Aug  9  2011 /home/secure/ronald/.vpn/cacerts/caCert.der
```

(cat /home/secure/ronald/.vpn/cacerts/caCert.der works too...)

Strongswan fails to access the file (as ipsec user) and this results

```
ipsec start

/etc/init.d/metalog restart && cat /var/log/everything/current | grep charon
```

 *Quote:*   

> Feb 24 10:57:04 [charon] 00[CFG]   loaded RSA private key from '/home/secure/ronald/.vpn/private/charlieKey.der'_
> 
> Feb 24 10:57:04 [charon] 00[DMN] loaded plugins: aes des sha1 sha2 md5 random x509 revocation constraints pubkey pkcs1 pkcs8 pgp pem openssl fips-prf gmp xcbc hmac attr kernel-netlink resolve socket-default stroke updown_
> 
> Feb 24 10:57:04 [charon] 00[JOB] spawning 16 worker threads_
> ...

 

However, when I change:

001 root:root /home/secure

to

011 root:root /home/secure

Both work!

What is the deal with /home/secure? It's a mountpoint.

Note that:

- Lightdm chokes on the exact same thing while GDM didn't have a problem

- Strongswan loads my private key (charlieKey.der) but fails to load the other key material which are under the *exact* same permissions

- The group execute bit that I need to add to /home/secure is *not* required to access the files

Is this a bug in the kernel? Is this a bug in strongswan and lightdm? Is this a 'technicality'? Am I going insane?Last edited by Rexilion on Sun Feb 26, 2012 5:52 pm; edited 5 times in total

----------

## papahuhn

Is ipsec in the root group? If so, 001 on /home/secure means that the group has no rights to do anything with it. The others' permissions are irrelevant.

----------

## Rexilion

 *papahuhn wrote:*   

> Is ipsec in the root group? If so, 001 on /home/secure means that the group has no rights to do anything with it. The others' permissions are irrelevant.

 

Good thinking, but that is not the case. Besides, if what you say is true, then:

/home/secure/ronald/.vpn/private/charlieKey.der

shouldn't load in strongswan as well and I wouldn't be able it to access it using bash.

Something seems to be wrong   :Shocked: 

 *Quote:*   

> Charlie ~ # sudo -u ipsec bash
> 
> bash: /dev/null/.bashrc: Not a directory
> 
> ipsec@Charlie /root $ id
> ...

 

 *Quote:*   

> Charlie ~ # cat /etc/group | grep -e root -e ipsec
> 
> root:x:0:root
> 
> bin:x:1:root,bin,daemon
> ...

 

----------

## papahuhn

Well, there is a possibility, but I have never used ipsec, strongswan or charon, so it's all speculation:

1. the ipsec executable is started as root, so its effective UID and effective GID is 0.

2. ipsec drops its root privileges by setting the effective UID to ipsec user's UID, but does not do the same for the effective GID, which remains 0.

3. the ipsec-process with EUID=ipsec,EGID=root fails to dive into the secure-subdirectory, because the effective group has no rights to do so.

You could try the following to verify my hypothesis:

Change the permissions to 011 and run ipsec. Then check the effective IDs of that process with "ps -eo pid,user,euser,ruser,egroup,rgroup,args".

----------

## Rexilion

Yes, interesting suggestion thanks. However, I did some more testing besides your suggestion. And it seems that:

Repeating the entire setup except using /home/secure as a mountpoint, this does not happen!

Here is the output of the command you suggested:

 *Quote:*   

> Charlie ~ # ps -eo pid,user,euser,ruser,egroup,rgroup,args | grep charon
> 
> 21761 ipsec    ipsec    ipsec    ipsec    ipsec    /usr/libexec/ipsec/charon --use-syslog
> 
> 22189 root     root     root     root     root     grep --colour=auto charon

 

All the instances of the word 'ipsec' indicate that the entire process has nothing to do with root anymore. So this rules out your suggestion, right?

----------

## papahuhn

 *Rexilion wrote:*   

> Yes, interesting suggestion thanks. However, I did some more testing besides your suggestion. And it seems that:
> 
> Repeating the entire setup except using /home/secure as a mountpoint, this does not happen!
> 
> Here is the output of the command you suggested:
> ...

 

Almost. Can you remove the root user from the root group in /etc/group? It is possible, that the supplementary group IDs were not dropped.

----------

## Rexilion

No dice, *exact* same symptoms. However, removing the root group from the root line in /etc/group didn't yield any difference when executing the 'id' command. Did I do it correctly? (I did a fresh reboot after modifying /etc/group and did the test).

However, as much as I really appreciate your effort, I think this outcome makes sense.

If it were an permission issue, then the exact same situation but without the /home/secure as mountpoint would have failed as well.

The only thing that seems to trigger this behaviour is the mountpoint located at /home/secure.

Thanks

----------

## papahuhn

Ok, so how does your no-mountpoint-scenario look like? Do you still have an intermediate directory with root:root and 001 permissions? If so, then my hypothesis is indeed wrong.

If not, consider this as a last effort:

```

hive UIDs # ls -ln

insgesamt 8

-rw-r--r-- 1 1000 1000 590 25. Feb 20:37 ipsec.pl

----r----- 1    0    0  14 25. Feb 20:19 secret.txt

hive UIDs # cat secret.txt 

All your base

hive UIDs # cat ipsec.pl 

#!/usr/bin/perl -w

use strict;

use POSIX;

use Unix::SavedIDs;

printf "RUID: %d, EUID: %d, SUID: %d, RGID: %d, EGID: %d, SGID: %d, sGIDs: %s\n\nps output:\n", getresuid(), getresgid(), join ', ', getgroups();

system "ps -p $$ -o pid,euid,ruid,egid,rgid,args";

print "\nDropping root privileges\n";

setgid(1000); setuid(1000);

printf "RUID: %d, EUID: %d, SUID: %d, RGID: %d, EGID: %d, SGID: %d, sGIDs: %s\n\nps output:\n", getresuid(), getresgid(), join ', ', getgroups();

system "ps -p $$ -o pid,euid,ruid,egid,rgid,args";

open T, '< secret.txt' or die "open failed\n"; print <T>; close T;

hive UIDs # perl ipsec.pl 

RUID: 0, EUID: 0, SUID: 0, RGID: 0, EGID: 0, SGID: 0, sGIDs: 0, 1, 2, 3, 4, 6, 10, 11, 26, 27

ps output:

  PID  EUID  RUID  EGID  RGID COMMAND

11589     0     0     0     0 perl ipsec.pl

Dropping root privileges

RUID: 1000, EUID: 1000, SUID: 1000, RGID: 1000, EGID: 1000, SGID: 1000, sGIDs: 1000, 0, 1, 2, 3, 4, 6, 10, 11, 26, 27

ps output:

  PID  EUID  RUID  EGID  RGID COMMAND

11589  1000  1000  1000  1000 perl ipsec.pl

All your base

hive UIDs # chmod g-r,o+r secret.txt 

hive UIDs # perl ipsec.pl 

RUID: 0, EUID: 0, SUID: 0, RGID: 0, EGID: 0, SGID: 0, sGIDs: 0, 1, 2, 3, 4, 6, 10, 11, 26, 27

ps output:

  PID  EUID  RUID  EGID  RGID COMMAND

11601     0     0     0     0 perl ipsec.pl

Dropping root privileges

RUID: 1000, EUID: 1000, SUID: 1000, RGID: 1000, EGID: 1000, SGID: 1000, sGIDs: 1000, 0, 1, 2, 3, 4, 6, 10, 11, 26, 27

ps output:

  PID  EUID  RUID  EGID  RGID COMMAND

11601  1000  1000  1000  1000 perl ipsec.pl

open failed

hive UIDs # cat /etc/group | head -n 1

root:x:0:

```

I also know now how to get the supplementary GIDs for a running process (not with ps).

Run ipsec with 011 permissions, get the $PID via ps, and look into /proc/$PID/status grepping for "Groups".

----------

## papahuhn

Couldn't resist to try on my own. Fortunately, there is no need to configure anything for ipsec and charon to run.

```

hive ~ # ps -eo pid,euser,ruser,egroup,rgroup,args | grep charon

 6320 ipsec    ipsec    ipsec    ipsec    /usr/libexec/ipsec/charon --use-syslog

13637 root     root     root     root     grep --colour=auto charon

hive ~ # cat /proc/6320/status | grep Groups

Groups:   0 1 2 3 6 10 11 19 26 27 408 

```

----------

## Rexilion

 *papahuhn wrote:*   

> Ok, so how does your no-mountpoint-scenario look like? Do you still have an intermediate directory with root:root and 001 permissions? If so, then my hypothesis is indeed wrong.

 

Below, I'll post another approach. In a nutshell, the following happens: Using the exact same permissions on a file path, makes certain programs fail. The only thing that is changed, is the fact whether this filepath traverses a mountpoint. Stuff fails, when /home/secure is a mountpoint. While all succeed when /home/secure is just a regular directory.

Here is the relevant lay-out (the same across all tests):

755 root:root        /home 

001 root:root        /home/secure

701 ronald:ronald /home/secure/ronald

100 ipsec:root       /home/secure/ronald/.vpn 

100 ipsec:root       /home/secure/ronald/.vpn/cacerts 

400 ipsec:root       /home/secure/ronald/.vpn/cacerts/caCert.der 

100 ipsec:root       /home/secure/ronald/.vpn/private 

400 ipsec:root       /home/secure/ronald/.vpn/private/charlieKey.der 

There are two situations (this is the *only* thing I vary):

Situation 1: /home/secure is a dm-crypt mountpoint (everything 'below' this directory is on another partition)

Situation 2: /home/secure is not a dm-crypt mountpoint (everything 'below' this directory is also on rootfs just like /home)

So, when /home/secure has 001 as permissions:

Ipsec fails for Situation 1

Ipsec succeeds for Situation 2

However, approaching the relevant files using sudo, bash and ls (or cat), just works under both situations.

However, when I change:

001 root:root        /home/secure

to

011 root:root        /home/secure

In the above situation, everything works. And with your tests, we have confirmed that this cannot be explained by the permissions under which the programs run.

Now here is the weird thing, the group execute bit on /home/secure is not important at all! As we have confirmed with your tests as well. Really nothing explains why I need to use 011 instead of 001

Hence this post...

----------

## papahuhn

Hi,

the group exec bit is not irrelevant, and for me, the results for situation 1 make perfect sense.

I just can't believe that there is really a different result for situation 2, although you say that the permissions and ownership is exactly the same.

I experimented with ipsec today and tried your two situations (even have cryptsetupped). With 001 on /home/secure both scenarios fail, as it should be. This is because the charon-process has GID 0 as one of its supplementary groups. When experimenting with "sudo -u ipsec /bin/bash" the access does not fail, because bash drops all supplementary groups upon execution!

So I cannot believe that in your situations 1 and 2 everything is the same. Are you sure that permissions *and* owners/groups are the same?

Isn't it possible that "/home/secure/ronald" has a different group in both of your scenarios?

----------

## Rexilion

I don't believe it either, in the output below I remount my root so I can look 'under' /home/secure (when it's mounted). Then I execute several commands to view file/folder permissions and ownership. They look the same to me...

Please don't get this wrong, I'm posting the entire terminal output below for an unbiased view...

```
ronald@Charlie ~ :) $ su -

Wachtwoord: 

Charlie ~ # dmsetup table

securehome: 0 97687934 crypt aes-xts-benbi 0000000000000000000000000000000000000000000000000000000000000000 0 8:4 2056

Charlie ~ # mount | grep securehome

/dev/mapper/securehome on /home/secure type ext4 (rw,nosuid,nodev,noatime,nodiratime,noacl,errors=remount-ro,nobh,nouser_xattr,barrier=1,commit=3600)

Charlie ~ # ls -la /home/secure | grep ronald

drwx-----x 52 ronald ronald  4096 Feb 26 13:04 ronald

Charlie ~ # mkdir /mnt/temp

Charlie ~ # mount -o bind / /mnt/temp

Charlie ~ # ls -la /mnt/temp/home/secure | grep ronald

drwx-----x 23 ronald ronald 4096 Feb 26 09:53 ronald

Charlie ~ # ls -la /home /mnt/temp/home

/home:

total 84

drwxr-xr-x  4 root      root       4096 Jan 29 21:00 .

drwxr-xr-x 20 root      root      69632 Jan 24 12:44 ..

-rw-r--r--  1 root      root          0 Dec  8 05:39 .keep

drwxrwx--- 36 gebruiker gebruiker  4096 Feb 26 12:43 gebruiker

d-----x--x  5 root      root       4096 Aug 11  2011 secure

/mnt/temp/home:

total 84

drwxr-xr-x  4 root      root       4096 Jan 29 21:00 .

drwxr-xr-x 20 root      root      69632 Jan 24 12:44 ..

-rw-r--r--  1 root      root          0 Dec  8 05:39 .keep

drwxrwx--- 36 gebruiker gebruiker  4096 Feb 26 12:43 gebruiker

d-----x--x  3 root      root       4096 Feb 24 11:56 secure

Charlie ~ # ls -la /home/secure /mnt/temp/secure

ls: cannot access /mnt/temp/secure: No such file or directory

/home/secure:

total 32

d-----x--x  5 root   root    4096 Aug 11  2011 .

drwxr-xr-x  4 root   root    4096 Jan 29 21:00 ..

d--------x  4 root   root    4096 Jun 24  2010 Gedeeld

d---------  2 root   root   16384 Jan 20  2011 lost+found

drwx-----x 52 ronald ronald  4096 Feb 26 13:04 ronald

Charlie ~ # ls -la /home/secure /mnt/temp/home/secure

/home/secure:

total 32

d-----x--x  5 root   root    4096 Aug 11  2011 .

drwxr-xr-x  4 root   root    4096 Jan 29 21:00 ..

d--------x  4 root   root    4096 Jun 24  2010 Gedeeld

d---------  2 root   root   16384 Jan 20  2011 lost+found

drwx-----x 52 ronald ronald  4096 Feb 26 13:04 ronald

/mnt/temp/home/secure:

total 12

d-----x--x  3 root   root   4096 Feb 24 11:56 .

drwxr-xr-x  4 root   root   4096 Jan 29 21:00 ..

drwx-----x 23 ronald ronald 4096 Feb 26 09:53 ronald

Charlie ~ # ls -la /home/secure/ronald /mnt/temp/home/secure/ronald | grep \.vpn

ls: cannot access /home/secure/ronald/.gvfs: Permission denied

d--x------  6 ipsec  root    4096 Aug  9  2011 .vpn

d--x------  5 ipsec  root   4096 Feb 24 11:56 .vpn

Charlie ~ # tree -fugpa /home/secure/ronald/.vpn/                                   

/home/secure/ronald/.vpn

|-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/bad

|   |-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/bad/cacerts

|   |   `-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/bad/cacerts/caCert.der

|   |-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/bad/certs

|   |   |-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/bad/certs/alphaCert.der

|   |   `-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/bad/certs/charlieCert.der

|   `-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/bad/private

|       `-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/bad/private/charlieKey.der

|-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/cacerts

|   `-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/cacerts/caCert.der

|-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/certs

|   |-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/certs/alphaCert.der

|   `-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/certs/charlieCert.der

`-- [d--x------ ipsec    root    ]  /home/secure/ronald/.vpn/private

    `-- [-r-------- ipsec    root    ]  /home/secure/ronald/.vpn/private/charlieKey.der

7 directories, 8 files

Charlie ~ # tree -fugpa /mnt/temp/home/secure/ronald/.vpn/

/mnt/temp/home/secure/ronald/.vpn

|-- [d--x------ ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/cacerts

|   `-- [-r-------- ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/cacerts/caCert.der

|-- [d--x------ ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/certs

|   |-- [-r-------- ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/certs/alphaCert.der

|   `-- [-r-------- ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/certs/charlieCert.der

`-- [d--x------ ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/private

    `-- [-r-------- ipsec    root    ]  /mnt/temp/home/secure/ronald/.vpn/private/charlieKey.der

3 directories, 4 files

Charlie ~ # 
```

----------

## papahuhn

Ok, I give up. Don't know how situation 2 is possible. I would be interested if you found out eventually.

----------

## Rexilion

Sure thing, I'll let you know.

----------

## Rexilion

I just figured it out, it seemed that my PAM scripts scrambled my testing which caused me to conclude the wrong stuff!

However, I still wanted to know why the group execute bit was important.

It's ipsec starter, it feeds /etc/ipsec.conf and my keys to charon (which also initially is started as root).

Ipsec starter and charon (initially) runs as uid:root and gid:root, so that process would 'hang' at the mountpoint.

Thank you for your time and effort, I'm sorry I wasted it   :Crying or Very sad: 

----------

## papahuhn

Hi,

how does this explain the different results of the mountpoint and no-mountpoint scenario? Why does the starter hang at the mountpoint? Its not the permissions; UID 0 processes do not care about file permissions.

----------

## Hu

 *papahuhn wrote:*   

> UID 0 processes do not care about file permissions.

 This is not strictly true.  Processes with the capability to override file DACLs do not care about file permissions.  For legacy reasons, processes with UID 0 are usually started with all known capabilities.  However, a process can have UID 0 and not have the capability to override file DACLs.

----------

## papahuhn

 *Hu wrote:*   

>  *papahuhn wrote:*   UID 0 processes do not care about file permissions. This is not strictly true.  Processes with the capability to override file DACLs do not care about file permissions.  For legacy reasons, processes with UID 0 are usually started with all known capabilities.  However, a process can have UID 0 and not have the capability to override file DACLs.

 

Aha! So it is possible that in scenario 2, strongswan dropped its UID and GID, but kept the supplementary GIDs and some DAC specific capability. /proc/PID/status tells me "CapEff: 0000000000001000" here, which I interpret as CAP_FOWNER. I don't know if that covers the bypassed 001 permission, maybe. However, I still do not see, how this can produce different results for mountpoint/no-mountpoint directories?

----------

## Rexilion

Ipsec requires CAP_FOWNER to use the XFRM interface as an unprivileged user. I don't think this is directly related.

 *Quote:*   

> /* Overrides all restrictions about allowed operations on files, where
> 
>    file owner ID must be equal to the user ID, except where CAP_FSETID
> 
>    is applicable. It doesn't override MAC and DAC restrictions. */

 

The header mentions files, not directory's. And in our case, the files are owned by the UID ipsec, under which the process runs.

----------

## Hu

 *papahuhn wrote:*   

> /proc/PID/status tells me "CapEff: 0000000000001000" here, which I interpret as CAP_FOWNER.

 Are you sure that is the right capability?  According to /sbin/capsh (from sys-libs/libcap), that is cap_net_admin:

```
# /sbin/capsh --decode=0x1000

0x0000000000001000=cap_net_admin
```

----------

## papahuhn

 *Hu wrote:*   

>  *papahuhn wrote:*   /proc/PID/status tells me "CapEff: 0000000000001000" here, which I interpret as CAP_FOWNER. Are you sure that is the right capability?  According to /sbin/capsh (from sys-libs/libcap), that is cap_net_admin:
> 
> ```
> # /sbin/capsh --decode=0x1000
> 
> ...

 

/usr/include/linux/capability.h defines CAP_FOWNER as 3, which I interpreted as the fourth bit in the CapEff mask. Good to know there is a decode tool.

----------

## Hu

 *papahuhn wrote:*   

> /usr/include/linux/capability.h defines CAP_FOWNER as 3, which I interpreted as the fourth bit in the CapEff mask. Good to know there is a decode tool.

 That field is a hexadecimal dump, so bit 0 is 0x1, bit 1 is 0x2, and bit 3 is 0x8.

----------

