Discussion:
[tomoyo-users-en 637] minimal policy for embedded system
Roman Yeryomin
2016-06-05 08:28:22 UTC
Permalink
Hello!

I'm trying to build a minimal policy for my embedded system where all
read/write requests to /dev/mtd* should be blocked except for several
programs.
In profile.conf I have:

<kernel> PROFILE_VERSION=20110903
<kernel> 0-COMMENT=-----Disabled Mode-----
<kernel> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
<kernel> 1-COMMENT=-----Learning Mode-----
<kernel> 1-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 1-CONFIG={ mode=learning grant_log=no reject_log=yes }
<kernel> 2-COMMENT=-----Permissive Mode-----
<kernel> 2-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 2-CONFIG={ mode=permissive grant_log=no reject_log=yes }
<kernel> 3-COMMENT=-----Enforcing Mode-----
<kernel> 3-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes }
<kernel> 4-COMMENT=-----Enforcing Mode-----
<kernel> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</bin/dd> PROFILE_VERSION=20110903
</bin/dd> 4-COMMENT=-----Enforcing Mode-----
</bin/dd> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
</bin/dd> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</sbin/the-tool> PROFILE_VERSION=20110903
</sbin/the-tool> 0-COMMENT=-----Disabled Mode-----
</sbin/the-tool> 0-PREFERENCE={ max_audit_log=1024
max_learning_entry=2048 enforcing_penalty=0 }
</sbin/the-tool> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }

in exception_policy.conf:

reset_domain /sbin/the-tool from any
reset_domain /bin/dd from any
keep_domain any from </sbin/the-tool>
keep_domain any from </bin/dd>
keep_domain any from <kernel>
path_group ALMOST_ANY_FILE /\*
path_group ALMOST_ANY_FILE /\*/\*\-mtd\?\*
path_group ALMOST_ANY_FILE /\*/\*/\*/\*
path_group ALMOST_ANY_FILE /\*/\*/\{\*\}/\*
path_group ALMOST_ANY_FILE \*:/\*
path_group ALMOST_ANY_FILE \*:/\{\*\}/\*
path_group ALMOST_ANY_FILE \*:[\$]
path_group ANY_FILE /\*
path_group ANY_FILE /\{\*\}/\*
path_group ANY_FILE \*:/\*
path_group ANY_FILE \*:/\{\*\}/\*
path_group ANY_FILE \*:[\$]
path_group ANY_DIR /
path_group ANY_DIR /\{\*\}/
path_group ANY_DIR \*:/
path_group ANY_DIR \*:/\{\*\}/

and in domain_policy.conf

<kernel>
use_profile 4
use_group 0
file read/write/append @ANY_DIR
file read/write/append @ALMOST_ANY_FILE
file read/write socket:[family=\$:type=\$:protocol=\$]

</bin/dd>
use_profile 4
use_group 0
file read/write/append @ANY_DIR
file read @ANY_FILE
file write/append @ALMOST_ANY_FILE
file read/write socket:[family=\$:type=\$:protocol=\$]

</sbin/the-tool>
use_profile 0
use_group 0


As I understand from domain transition logic described here
http://tomoyo.osdn.jp/2.5/policy-specification/domain-transition-procedure.html.en#transition_by_execute
it should work
But neither dd no the-tool don't have even read access to /dev/mtdX

Any pointers on what am I doing wrong?
Thanks in advance!


Regards,
Roman
Tetsuo Handa
2016-06-05 10:37:09 UTC
Permalink
Hello.
Post by Roman Yeryomin
Hello!
I'm trying to build a minimal policy for my embedded system where all
read/write requests to /dev/mtd* should be blocked except for several
programs.
<kernel> PROFILE_VERSION=20110903
<kernel> 0-COMMENT=-----Disabled Mode-----
<kernel> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
<kernel> 1-COMMENT=-----Learning Mode-----
<kernel> 1-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 1-CONFIG={ mode=learning grant_log=no reject_log=yes }
<kernel> 2-COMMENT=-----Permissive Mode-----
<kernel> 2-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 2-CONFIG={ mode=permissive grant_log=no reject_log=yes }
<kernel> 3-COMMENT=-----Enforcing Mode-----
<kernel> 3-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes }
<kernel> 4-COMMENT=-----Enforcing Mode-----
<kernel> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</bin/dd> PROFILE_VERSION=20110903
</bin/dd> 4-COMMENT=-----Enforcing Mode-----
</bin/dd> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
</bin/dd> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</sbin/the-tool> PROFILE_VERSION=20110903
</sbin/the-tool> 0-COMMENT=-----Disabled Mode-----
</sbin/the-tool> 0-PREFERENCE={ max_audit_log=1024
max_learning_entry=2048 enforcing_penalty=0 }
</sbin/the-tool> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
reset_domain /sbin/the-tool from any
reset_domain /bin/dd from any
keep_domain any from </sbin/the-tool>
keep_domain any from </bin/dd>
keep_domain any from <kernel>
path_group ALMOST_ANY_FILE /\*
path_group ALMOST_ANY_FILE /\*/\*\-mtd\?\*
path_group ALMOST_ANY_FILE /\*/\*/\*/\*
path_group ALMOST_ANY_FILE /\*/\*/\{\*\}/\*
path_group ALMOST_ANY_FILE \*:/\*
path_group ALMOST_ANY_FILE \*:/\{\*\}/\*
path_group ALMOST_ANY_FILE \*:[\$]
path_group ANY_FILE /\*
path_group ANY_FILE /\{\*\}/\*
path_group ANY_FILE \*:/\*
path_group ANY_FILE \*:/\{\*\}/\*
path_group ANY_FILE \*:[\$]
path_group ANY_DIR /
path_group ANY_DIR /\{\*\}/
path_group ANY_DIR \*:/
path_group ANY_DIR \*:/\{\*\}/
and in domain_policy.conf
<kernel>
use_profile 4
use_group 0
file read/write socket:[family=\$:type=\$:protocol=\$]
</bin/dd>
use_profile 4
use_group 0
file read/write socket:[family=\$:type=\$:protocol=\$]
</sbin/the-tool>
use_profile 0
use_group 0
This is a situation where CaitSith will fit better.

Since Memory Technology Device is a character device with major = 90,
you will be able to define CaitSith's rule like below.

----------------------------------------
10 read path.type=char path.dev_major=90
10 allow task.exe="/bin/dd"
20 allow task.exe="/sbin/fw-tool"
30 deny

10 write path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny

10 append path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
----------------------------------------

If you need to use TOMOYO 2.5, you can still use file's attributes
like below (though it is less flexible than CaitSith).

----------------------------------------
<kernel>
use_profile 4
file read @ANY_DIR
file read/write/append @ANY_FILE path1.type!=char
file read/write/append @ANY_FILE path1.type=char path1.dev_major!=90

</bin/dd>
use_profile 4
file read @ANY_DIR
file read @ANY_FILE
file write/append @ANY_FILE path1.type!=char
file write/append @ANY_FILE path1.type=char path1.dev_major!=90

</sbin/fw-tool>
use_profile 0
file read @ANY_DIR
file read/write/append @ANY_FILE
----------------------------------------

Please be aware that the programs you want to allow access to specific
resource (i.e. /bin/dd and /sbin/fw-tool in your case) might be disguised
unless you also restrict operations which modify directory entries and/or
mount namespace. For example, doing

# mount --bind /bin/cat /sbin/fw-tools

or

# mv /sbin/fw-tool /sbin/fw-tool.orig
# ln /bin/cat /sbin/fw-tool

allows the attacker to run in </sbin/fw-tool> domain while its functionality
would be still /bin/cat . Therefore, it is recommended to restrict operations
which modify directory entries and/or mount namespace in addition to
restricting read/write/append operations.
Post by Roman Yeryomin
As I understand from domain transition logic described here
http://tomoyo.osdn.jp/2.5/policy-specification/domain-transition-procedure.html.en#transition_by_execute
it should work
But neither dd no the-tool don't have even read access to /dev/mtdX
Any pointers on what am I doing wrong?
Thanks in advance!
I guess that /bin/dd and /sbin/fw-tool are running in the <kernel> domain.
If you can run /usr/sbin/tomoyo-queryd , please see how to use it
at http://tomoyo.osdn.jp/2.5/chapter-7.html#7.3 .

If you cannot run /usr/sbin/tomoyo-queryd , please check what the reject
log says.

If you are running /usr/sbin/tomoyo-auditd with

# Save rejected logs with profile=4 to /var/log/tomoyo/reject_004.log
header.contains profile=4
destination /var/log/tomoyo/reject_004.log

lines appended to /etc/tomoyo/tools/auditd.conf , you can examine
/var/log/tomoyo/reject_*.log . If you are not running /usr/sbin/tomoyo-auditd ,
you can examine /sys/kernel/security/tomoyo/audit interface (please be sure to
mount securityfs on /sys/kernel/security/ if it is not mounted yet).
Post by Roman Yeryomin
Regards,
Roman
_______________________________________________
tomoyo-users-en mailing list
http://lists.osdn.me/mailman/listinfo/tomoyo-users-en
Roman Yeryomin
2016-06-05 20:36:26 UTC
Permalink
On 5 June 2016 at 13:37, Tetsuo Handa
Post by Tetsuo Handa
Hello.
Post by Roman Yeryomin
Hello!
I'm trying to build a minimal policy for my embedded system where all
read/write requests to /dev/mtd* should be blocked except for several
programs.
<kernel> PROFILE_VERSION=20110903
<kernel> 0-COMMENT=-----Disabled Mode-----
<kernel> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
<kernel> 1-COMMENT=-----Learning Mode-----
<kernel> 1-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 1-CONFIG={ mode=learning grant_log=no reject_log=yes }
<kernel> 2-COMMENT=-----Permissive Mode-----
<kernel> 2-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 2-CONFIG={ mode=permissive grant_log=no reject_log=yes }
<kernel> 3-COMMENT=-----Enforcing Mode-----
<kernel> 3-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes }
<kernel> 4-COMMENT=-----Enforcing Mode-----
<kernel> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
<kernel> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</bin/dd> PROFILE_VERSION=20110903
</bin/dd> 4-COMMENT=-----Enforcing Mode-----
</bin/dd> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048
enforcing_penalty=0 }
</bin/dd> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</sbin/the-tool> PROFILE_VERSION=20110903
</sbin/the-tool> 0-COMMENT=-----Disabled Mode-----
</sbin/the-tool> 0-PREFERENCE={ max_audit_log=1024
max_learning_entry=2048 enforcing_penalty=0 }
</sbin/the-tool> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
reset_domain /sbin/the-tool from any
reset_domain /bin/dd from any
keep_domain any from </sbin/the-tool>
keep_domain any from </bin/dd>
keep_domain any from <kernel>
path_group ALMOST_ANY_FILE /\*
path_group ALMOST_ANY_FILE /\*/\*\-mtd\?\*
path_group ALMOST_ANY_FILE /\*/\*/\*/\*
path_group ALMOST_ANY_FILE /\*/\*/\{\*\}/\*
path_group ALMOST_ANY_FILE \*:/\*
path_group ALMOST_ANY_FILE \*:/\{\*\}/\*
path_group ALMOST_ANY_FILE \*:[\$]
path_group ANY_FILE /\*
path_group ANY_FILE /\{\*\}/\*
path_group ANY_FILE \*:/\*
path_group ANY_FILE \*:/\{\*\}/\*
path_group ANY_FILE \*:[\$]
path_group ANY_DIR /
path_group ANY_DIR /\{\*\}/
path_group ANY_DIR \*:/
path_group ANY_DIR \*:/\{\*\}/
and in domain_policy.conf
<kernel>
use_profile 4
use_group 0
file read/write socket:[family=\$:type=\$:protocol=\$]
</bin/dd>
use_profile 4
use_group 0
file read/write socket:[family=\$:type=\$:protocol=\$]
</sbin/the-tool>
use_profile 0
use_group 0
This is a situation where CaitSith will fit better.
Since Memory Technology Device is a character device with major = 90,
you will be able to define CaitSith's rule like below.
----------------------------------------
10 read path.type=char path.dev_major=90
10 allow task.exe="/bin/dd"
20 allow task.exe="/sbin/fw-tool"
30 deny
10 write path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
10 append path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
----------------------------------------
Thank you for this pointer, I will certainly look closer at CaitSith!
Post by Tetsuo Handa
If you need to use TOMOYO 2.5, you can still use file's attributes
like below (though it is less flexible than CaitSith).
----------------------------------------
<kernel>
use_profile 4
</bin/dd>
use_profile 4
</sbin/fw-tool>
use_profile 0
----------------------------------------
Please be aware that the programs you want to allow access to specific
resource (i.e. /bin/dd and /sbin/fw-tool in your case) might be disguised
unless you also restrict operations which modify directory entries and/or
mount namespace. For example, doing
# mount --bind /bin/cat /sbin/fw-tools
or
# mv /sbin/fw-tool /sbin/fw-tool.orig
# ln /bin/cat /sbin/fw-tool
allows the attacker to run in </sbin/fw-tool> domain while its functionality
would be still /bin/cat . Therefore, it is recommended to restrict operations
which modify directory entries and/or mount namespace in addition to
restricting read/write/append operations.
I was going to develop this policy further and restrict ssh (the only
access method) to only several configuration files.
Would this solve the problem?
Post by Tetsuo Handa
Post by Roman Yeryomin
As I understand from domain transition logic described here
http://tomoyo.osdn.jp/2.5/policy-specification/domain-transition-procedure.html.en#transition_by_execute
it should work
But neither dd no the-tool don't have even read access to /dev/mtdX
Any pointers on what am I doing wrong?
Thanks in advance!
I guess that /bin/dd and /sbin/fw-tool are running in the <kernel> domain.
It seems you are right.
tomoyo-queryd showed that the-tool runs with profile 4 while
</sbin/the-tool> domain is configured as profile 0.
But then I don't understand how domain transition (exception policy) rules work.
Will they always match the most "hungry"/vague rule? not the first one?
Like in my config it looks like any /sbin/the-tool instance will match
"keep_domain any from <kernel>" not "reset_domain /sbin/the-tool from
any" as I was expecting.
And adding "no_keep_domain /sbin/the-tool from any" also doesn't help.
So I'm confused here.


Regards,
Roman
Tetsuo Handa
2016-06-06 12:52:40 UTC
Permalink
Post by Roman Yeryomin
Post by Tetsuo Handa
This is a situation where CaitSith will fit better.
Since Memory Technology Device is a character device with major = 90,
you will be able to define CaitSith's rule like below.
----------------------------------------
10 read path.type=char path.dev_major=90
10 allow task.exe="/bin/dd"
20 allow task.exe="/sbin/fw-tool"
30 deny
10 write path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
10 append path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
----------------------------------------
Thank you for this pointer, I will certainly look closer at CaitSith!
I forgot to add "acl" keyword in the example above.
Anyway, here is what I guess you want to try if you use CaitSith.

---------- /etc/caitsith/policy/current ----------
quota memory audit 16777216
quota memory query 1048576
quota audit[0] allowed=0 denied=1024 unmatched=0

10 acl read path.type=char path.dev_major=90
audit 0
10 allow task.exe="/usr/bin/dd"
20 allow task.exe="/sbin/the-tool"
30 deny

10 acl read path.fsmagic=0x9FA0 path="proc:/mtd"
audit 0
10 allow task.exe="/sbin/the-tool"
20 deny

10 acl write path.type=char path.dev_major=90
audit 0
10 allow task.exe="/sbin/the-tool"
20 deny

10 acl append path.type=char path.dev_major=90
audit 0
10 allow task.exe="/sbin/the-tool"
20 deny

100 acl mount
audit 1
10 deny task.exe!="/bin/mount"
20 allow target="/proc/" fstype="proc" flags=0x0
30 allow target="/sys/" fstype="sysfs" flags=0x0
40 deny

0 acl modify_policy
audit 0
10 deny
---------- /etc/caitsith/policy/current ----------

Since /proc/mtd is recognized as proc:/mtd (because proc filesystem
does not support rename operation), /\*/\*\-mtd\?\* will not match
/proc/mtd .

The "0 acl modify_policy" block in CaitSith corresponds to
/etc/tomoyo/policy/current/manager.conf in TOMOYO 2.5.
In the above example, no programs can modify policy (i.e.
production state).

The "100 acl mount" block is for preventing attackers from disguising
programs using e.g. "mount --bind" request.
If you can make partitions for programs being mounted as read-only,
you will be able to omit e.g. "acl rename" blocks. If you cannot,
you can define e.g. "acl rename" blocks in order to control ranges
attackers can tamper the system.
Post by Roman Yeryomin
Post by Tetsuo Handa
If you need to use TOMOYO 2.5, you can still use file's attributes
like below (though it is less flexible than CaitSith).
----------------------------------------
<kernel>
use_profile 4
</bin/dd>
use_profile 4
</sbin/fw-tool>
use_profile 0
----------------------------------------
Below is similar rule using TOMOYO 2.5.

---------- /etc/tomoyo/policy/current/profile.conf ----------
<kernel> PROFILE_VERSION=20110903
<kernel> 0-COMMENT=-----Disabled Mode-----
<kernel> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
<kernel> 0-CONFIG={ mode=disabled grant_log=no reject_log=yes }
<kernel> 1-COMMENT=-----Learning Mode-----
<kernel> 1-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
<kernel> 1-CONFIG={ mode=learning grant_log=no reject_log=yes }
<kernel> 2-COMMENT=-----Permissive Mode-----
<kernel> 2-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
<kernel> 2-CONFIG={ mode=permissive grant_log=no reject_log=yes }
<kernel> 3-COMMENT=-----Enforcing Mode-----
<kernel> 3-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
<kernel> 3-CONFIG={ mode=enforcing grant_log=no reject_log=yes }
<kernel> 4-COMMENT=-----Enforcing Mode (File Open Only)-----
<kernel> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
<kernel> 4-CONFIG={ mode=disabled grant_log=no reject_log=no }
<kernel> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</usr/bin/dd> PROFILE_VERSION=20110903
</usr/bin/dd> 4-COMMENT=-----Enforcing Mode (File Open Only)-----
</usr/bin/dd> 4-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
</usr/bin/dd> 4-CONFIG={ mode=disabled grant_log=no reject_log=no }
</usr/bin/dd> 4-CONFIG::file::open={ mode=enforcing grant_log=no reject_log=yes }
</sbin/the-tool> PROFILE_VERSION=20110903
</sbin/the-tool> 0-COMMENT=-----Disabled Mode-----
</sbin/the-tool> 0-PREFERENCE={ max_audit_log=1024 max_learning_entry=2048 }
</sbin/the-tool> 0-CONFIG={ mode=disabled grant_log=no reject_log=no }
---------- /etc/tomoyo/policy/current/profile.conf ----------

---------- /etc/tomoyo/policy/current/exception_policy.conf ----------
<kernel> aggregator proc:/self/exe /proc/self/exe
<kernel> reset_domain /sbin/the-tool from any
<kernel> reset_domain /usr/bin/dd from any
<kernel> keep_domain any from any
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD /
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD /\*
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD /\{\*\}/
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD /\{\*\}/\*
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD \*:/
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD \*:\-proc:/\*
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD proc:/\*\-mtd
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD \*:/\{\*\}/
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD \*:/\{\*\}/\*
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD \*:[\$]
<kernel> path_group ANY_PATHNAME_BUT_PROC_MTD socket:[family=\$:type=\$:protocol=\$]
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD /
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD /\*
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD /\{\*\}/
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD /\{\*\}/\*
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD \*:/
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD \*:\-proc:/\*
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD proc:/\*\-mtd
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD \*:/\{\*\}/
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD \*:/\{\*\}/\*
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD \*:[\$]
</usr/bin/dd> path_group ANY_PATHNAME_BUT_PROC_MTD socket:[family=\$:type=\$:protocol=\$]
</usr/bin/dd> path_group ANY_PATHNAME /
</usr/bin/dd> path_group ANY_PATHNAME /\*
</usr/bin/dd> path_group ANY_PATHNAME /\{\*\}/
</usr/bin/dd> path_group ANY_PATHNAME /\{\*\}/\*
</usr/bin/dd> path_group ANY_PATHNAME \*:/
</usr/bin/dd> path_group ANY_PATHNAME \*:/\*
</usr/bin/dd> path_group ANY_PATHNAME \*:/\{\*\}/
</usr/bin/dd> path_group ANY_PATHNAME \*:/\{\*\}/\*
</usr/bin/dd> path_group ANY_PATHNAME \*:[\$]
</usr/bin/dd> path_group ANY_PATHNAME socket:[family=\$:type=\$:protocol=\$]
---------- /etc/tomoyo/policy/current/exception_policy.conf ----------

---------- /etc/tomoyo/policy/current/domain_policy.conf ----------
<kernel>
use_profile 4
use_group 0

file read/write/append @ANY_PATHNAME_BUT_PROC_MTD path1.type!=char
file read/write/append @ANY_PATHNAME_BUT_PROC_MTD path1.type=char path1.dev_major!=90

</usr/bin/dd>
use_profile 4
use_group 0

file read @ANY_PATHNAME_BUT_PROC_MTD
file write/append @ANY_PATHNAME path1.type!=char
file write/append @ANY_PATHNAME path1.type=char path1.dev_major!=90

</sbin/the-tool>
use_profile 0
use_group 0
---------- /etc/tomoyo/policy/current/domain_policy.conf ----------
Post by Roman Yeryomin
Post by Tetsuo Handa
Please be aware that the programs you want to allow access to specific
resource (i.e. /bin/dd and /sbin/fw-tool in your case) might be disguised
unless you also restrict operations which modify directory entries and/or
mount namespace. For example, doing
# mount --bind /bin/cat /sbin/fw-tools
or
# mv /sbin/fw-tool /sbin/fw-tool.orig
# ln /bin/cat /sbin/fw-tool
allows the attacker to run in </sbin/fw-tool> domain while its functionality
would be still /bin/cat . Therefore, it is recommended to restrict operations
which modify directory entries and/or mount namespace in addition to
restricting read/write/append operations.
I was going to develop this policy further and restrict ssh (the only
access method) to only several configuration files.
Would this solve the problem?
What do you think about other programs which can issue such requests
when exploited? Any process running as root user would be able to issue
above requests (even without using shell, by directly using system calls).
Post by Roman Yeryomin
Post by Tetsuo Handa
Post by Roman Yeryomin
As I understand from domain transition logic described here
http://tomoyo.osdn.jp/2.5/policy-specification/domain-transition-procedure.html.en#transition_by_execute
it should work
But neither dd no the-tool don't have even read access to /dev/mtdX
Any pointers on what am I doing wrong?
Thanks in advance!
I guess that /bin/dd and /sbin/fw-tool are running in the <kernel> domain.
It seems you are right.
tomoyo-queryd showed that the-tool runs with profile 4 while
</sbin/the-tool> domain is configured as profile 0.
But then I don't understand how domain transition (exception policy) rules work.
Will they always match the most "hungry"/vague rule? not the first one?
It should match as described in the link above.
Post by Roman Yeryomin
Like in my config it looks like any /sbin/the-tool instance will match
"keep_domain any from <kernel>" not "reset_domain /sbin/the-tool from
any" as I was expecting.
And adding "no_keep_domain /sbin/the-tool from any" also doesn't help.
So I'm confused here.
I think you can try how domain transition tree would look like, by
removing reset_domain / keep_domain entries and generating via usual
learning steps. You might find that the pathnames you assumed /bin/dd and
/sbin/fw-tool might be recognized as different names (e.g. if /sbin is
a symlink to /usr/sbin , /sbin/fw-tool will be recognized as
/usr/sbin/fw-tool ). After TOMOYO generated domains as detail as possible,
you can design which domains should be compressed.

Also, as far as I saw, you don't need to use policy namespace.
If you don't have reason to use policy namespace, you will be able to
replace reset_domain with initialize_domain .
Post by Roman Yeryomin
Regards,
Roman
_______________________________________________
tomoyo-users-en mailing list
http://lists.osdn.me/mailman/listinfo/tomoyo-users-en
Roman Yeryomin
2016-06-06 17:21:07 UTC
Permalink
On 6 June 2016 at 15:52, Tetsuo Handa
Post by Tetsuo Handa
Post by Roman Yeryomin
Post by Tetsuo Handa
This is a situation where CaitSith will fit better.
Since Memory Technology Device is a character device with major = 90,
you will be able to define CaitSith's rule like below.
----------------------------------------
10 read path.type=char path.dev_major=90
10 allow task.exe="/bin/dd"
20 allow task.exe="/sbin/fw-tool"
30 deny
10 write path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
10 append path.type=char path.dev_major=90
10 allow task.exe="/sbin/fw-tool"
20 deny
----------------------------------------
Thank you for this pointer, I will certainly look closer at CaitSith!
I forgot to add "acl" keyword in the example above.
Anyway, here is what I guess you want to try if you use CaitSith.
---------- /etc/caitsith/policy/current ----------
quota memory audit 16777216
quota memory query 1048576
quota audit[0] allowed=0 denied=1024 unmatched=0
10 acl read path.type=char path.dev_major=90
audit 0
10 allow task.exe="/usr/bin/dd"
20 allow task.exe="/sbin/the-tool"
30 deny
10 acl read path.fsmagic=0x9FA0 path="proc:/mtd"
audit 0
10 allow task.exe="/sbin/the-tool"
20 deny
10 acl write path.type=char path.dev_major=90
audit 0
10 allow task.exe="/sbin/the-tool"
20 deny
10 acl append path.type=char path.dev_major=90
audit 0
10 allow task.exe="/sbin/the-tool"
20 deny
100 acl mount
audit 1
10 deny task.exe!="/bin/mount"
20 allow target="/proc/" fstype="proc" flags=0x0
30 allow target="/sys/" fstype="sysfs" flags=0x0
40 deny
0 acl modify_policy
audit 0
10 deny
---------- /etc/caitsith/policy/current ----------
Just tried CaitSith on 4.1 kernel and getting this:

[ 10.403615] ------------[ cut here ]------------
[ 10.408411] WARNING: CPU: 0 PID: 1 at mm/page_alloc.c:2668
__alloc_pages_nodemask+0x164/0x624()
[ 10.417430] Modules linked in: ohci_platform ohci_hcd ehci_platform
ehci_hcd gpio_button_hotplug usbcore nls_base usb_common crc16 aead
crypto_hash
[ 10.431202] CPU: 0 PID: 1 Comm: procd Not tainted 4.1.16 #46
[ 10.437037] Stack : 803a6480 00000000 00000001 803f0000 87828278
803e6b0b 80386024 00000001
8045357c 87454f68 87ba0c00 00400000 87b29988 800a689c
803f6304 803e0000
00000003 87454f68 80389894 8781782c 87b29988 800a4eb0
00000000 00000000
00000001 80450000 00000000 00000000 00000000 00000000
00000000 00000000
00000000 00000000 00000000 00000000 00000000 00000000
00000000 00000000
...
[ 10.474068] Call Trace:
[ 10.476610] [<800720bc>] show_stack+0x50/0x84
[ 10.481127] [<800817b4>] warn_slowpath_common+0xa0/0xd0
[ 10.486519] [<80081868>] warn_slowpath_null+0x18/0x24
[ 10.491743] [<800d3cdc>] __alloc_pages_nodemask+0x164/0x624
[ 10.497500] [<800e646c>] kmalloc_order+0x14/0x48
[ 10.502280] [<801862a8>] cs_realpath+0x90/0x380
[ 10.506976] [<8017dfb4>] cs_populate_patharg+0x60/0xc4
[ 10.512289] [<8017e2c4>] cs_cond2arg+0x2ac/0x644
[ 10.517056] [<8017e700>] cs_condition+0xa4/0x6c8
[ 10.521831] [<8017edc8>] cs_check_acl+0xa4/0x21c
[ 10.526604] [<8018055c>] cs_open_permission+0xdc/0x108
[ 10.531939] [<8017b684>] security_file_open+0x40/0xac
[ 10.537171] [<800fe8fc>] do_dentry_open+0x198/0x358
[ 10.542219] [<800ffc50>] dentry_open+0x58/0xac
[ 10.546818] [<8017015c>] ovl_dir_open+0x54/0xb0
[ 10.551507] [<800fe984>] do_dentry_open+0x220/0x358
[ 10.556548] [<8010dc80>] do_last.isra.11+0x974/0xc2c
[ 10.561683] [<8010e120>] path_openat+0x1e8/0x530
[ 10.566453] [<8010f508>] do_filp_open+0x3c/0xa4
[ 10.571139] [<800fffe4>] do_sys_open+0x18c/0x234
[ 10.575912] [<80062b3c>] handle_sys+0x11c/0x140
[ 10.580588]
[ 10.582136] ---[ end trace cc67026967ada591 ]---
[ 10.586902] ERROR: Out of memory at cs_realpath.
[ 10.591679] CaitSith: Rejecting access request due to out of memory.


Any idea why?
Didn't have this problem with Tomoyo


Regards,
Roman
Tetsuo Handa
2016-06-07 10:32:15 UTC
Permalink
Post by Roman Yeryomin
[ 10.403615] ------------[ cut here ]------------
[ 10.408411] WARNING: CPU: 0 PID: 1 at mm/page_alloc.c:2668 __alloc_pages_nodemask+0x164/0x624()
(...snipped...)
Post by Roman Yeryomin
[ 10.586902] ERROR: Out of memory at cs_realpath.
[ 10.591679] CaitSith: Rejecting access request due to out of memory.
Thank you for reporting this problem. I think this is a bug which occurs
when using CaitSith on Linux 3.17 and later kernels with overlayfs. I fixed
this problem ( https://osdn.jp/projects/caitsith/scm/svn/commits/186 ).

I tested with

----------
# mkdir -p /mnt/a /mnt/b
# mount -t xfs /dev/sdb1 /mnt/a/
# mount -t tmpfs none /mnt/b/
# mkdir /mnt/b/rw
# mkdir /mnt/b/work
# mount -t overlay -o lowerdir=/mnt/a/,upperdir=/mnt/b/rw/,workdir=/mnt/b/work/ overlayfs /mnt/
----------

and a rule

----------
quota audit[1] allowed=0 denied=1024 unmatched=1024
10 acl read path.type=directory
audit 1
----------

and got similar one.

----------
[ 157.480446] ------------[ cut here ]------------
[ 157.486088] WARNING: CPU: 3 PID: 1175 at mm/slab_common.c:766 kmalloc_slab+0x85/0xa0()
[ 157.495795] Modules linked in: caitsith(O) ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_raw iptable_filter ppdev vmw_vmci pcspkr coretemp i2c_piix4 parport_pc parport shpchp ip_tables xfs libcrc32c sd_mod sr_mod cdrom ata_generic pata_acpi mptspi scsi_transport_spi mptscsih serio_raw e1000 vmwgfx drm_kms_helper ttm drm ata_piix mptbase libata i2c_core
[ 157.537349] CPU: 3 PID: 1175 Comm: bash Tainted: G O 4.1.16 #10
[ 157.541707] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
[ 157.548571] 0000000000000497 000000006717d855 ffffffff81794cce ffffffff8152828c
[ 157.553372] 0000000000000000 ffffffff810578b7 ffff88003b000000 0000000000000050
[ 157.558121] ffff8800394979b8 ffff88003d57b000 ffff880039497670 ffffffff8111bec5
[ 157.562855] Call Trace:
[ 157.564423] [<ffffffff8152828c>] ? dump_stack+0x40/0x50
[ 157.568007] [<ffffffff810578b7>] ? warn_slowpath_common+0x77/0xb0
[ 157.571794] [<ffffffff8111bec5>] ? kmalloc_slab+0x85/0xa0
[ 157.575154] [<ffffffff8114a1d1>] ? __kmalloc+0x11/0x150
[ 157.578853] [<ffffffffa0278891>] ? cs_realpath+0x61/0x4c0 [caitsith]
[ 157.583213] [<ffffffff8117801a>] ? prepend_path+0xda/0x2d0
[ 157.587198] [<ffffffffa026fae1>] ? cs_populate_patharg+0x81/0xb0 [caitsith]
[ 157.591994] [<ffffffffa02749f8>] ? cs_init_log+0x1088/0x12d0 [caitsith]
[ 157.596581] [<ffffffffa0278025>] ? cs_audit_log+0x85/0x4a0 [caitsith]
[ 157.601269] [<ffffffffa0270c0c>] ? cs_check_acl+0x11c/0x220 [caitsith]
[ 157.605768] [<ffffffffa027131c>] ? cs_open_permission+0xfc/0x140 [caitsith]
[ 157.610537] [<ffffffffa0279d88>] ? cs_file_open+0x18/0x50 [caitsith]
[ 157.614941] [<ffffffff811fbbe4>] ? security_file_open+0x14/0x70
[ 157.619066] [<ffffffff8115fd92>] ? do_dentry_open+0xb2/0x320
[ 157.623053] [<ffffffff811ea180>] ? ovl_dir_fsync+0x130/0x130
[ 157.627027] [<ffffffff8116108f>] ? dentry_open+0x3f/0xb0
[ 157.630804] [<ffffffff8114a580>] ? kmem_cache_alloc+0x120/0x130
[ 157.634933] [<ffffffff811ea1d2>] ? ovl_dir_open+0x52/0xc0
[ 157.638756] [<ffffffff8115feea>] ? do_dentry_open+0x20a/0x320
[ 157.642781] [<ffffffff8116e29e>] ? do_last+0x41e/0xfc0
[ 157.646596] [<ffffffff8114a580>] ? kmem_cache_alloc+0x120/0x130
[ 157.650725] [<ffffffff81170a0e>] ? path_openat+0x8e/0x630
[ 157.654532] [<ffffffff8117218e>] ? do_filp_open+0x3e/0xa0
[ 157.658337] [<ffffffff8117e24c>] ? __alloc_fd+0x7c/0x120
[ 157.662290] [<ffffffff811613f8>] ? do_sys_open+0x148/0x230
[ 157.666140] [<ffffffff8152e157>] ? system_call_fastpath+0x12/0x6a
[ 157.670365] ---[ end trace ff1fe2bff03c9b4d ]---
[ 157.673671] ERROR: Out of memory at cs_realpath.
----------
Post by Roman Yeryomin
Any idea why?
Didn't have this problem with Tomoyo
Since overlayfs combines underlying mounts, not only pathname seen from
the overlayfs but also pathnames seen from underlying mounts are subjected
for permission checks. But d_absolute_path() for underlying mounts was
returning -EINVAL error. While TOMOYO has a fallback to calculate local
pathname, I forgot to apply it to CaitSith for Linux 3.17 and later kernels.



I don't know how partitions are mounted in your environment, but according
to https://wiki.openwrt.org/doc/techref/flash.layout , it seems to me that
overlayfs is mounted on / after SquashFS is mounted on /rom and JFFS2 is
mounted on /overlay . If so, applications cannot directly access pathnames
under /rom and /overlay , which means that it makes little sense to check
permissions for pathnames seen from SquashFS and JFFS2. In that case, you
might want to check permissions for only pathname seen from overlayfs using
filesystem magic number for overlayfs (i.e. 0x794C7630) like

10 acl read path.fsmagic=0x794C7630

instead of

10 acl read

.
Roman Yeryomin
2016-06-12 08:02:37 UTC
Permalink
On 7 June 2016 at 13:32, Tetsuo Handa
Post by Tetsuo Handa
Post by Roman Yeryomin
[ 10.403615] ------------[ cut here ]------------
[ 10.408411] WARNING: CPU: 0 PID: 1 at mm/page_alloc.c:2668 __alloc_pages_nodemask+0x164/0x624()
(...snipped...)
Post by Roman Yeryomin
[ 10.586902] ERROR: Out of memory at cs_realpath.
[ 10.591679] CaitSith: Rejecting access request due to out of memory.
Thank you for reporting this problem. I think this is a bug which occurs
when using CaitSith on Linux 3.17 and later kernels with overlayfs. I fixed
this problem ( https://osdn.jp/projects/caitsith/scm/svn/commits/186 ).
I tested with
----------
# mkdir -p /mnt/a /mnt/b
# mount -t xfs /dev/sdb1 /mnt/a/
# mount -t tmpfs none /mnt/b/
# mkdir /mnt/b/rw
# mkdir /mnt/b/work
# mount -t overlay -o lowerdir=/mnt/a/,upperdir=/mnt/b/rw/,workdir=/mnt/b/work/ overlayfs /mnt/
----------
and a rule
----------
quota audit[1] allowed=0 denied=1024 unmatched=1024
10 acl read path.type=directory
audit 1
----------
and got similar one.
----------
[ 157.480446] ------------[ cut here ]------------
[ 157.486088] WARNING: CPU: 3 PID: 1175 at mm/slab_common.c:766 kmalloc_slab+0x85/0xa0()
[ 157.495795] Modules linked in: caitsith(O) ip6t_rpfilter ip6t_REJECT nf_reject_ipv6 ipt_REJECT nf_reject_ipv4 xt_conntrack ebtable_nat ebtable_broute bridge stp llc ebtable_filter ebtables ip6table_nat nf_conntrack_ipv6 nf_defrag_ipv6 nf_nat_ipv6 ip6table_mangle ip6table_raw ip6table_filter ip6_tables iptable_nat nf_conntrack_ipv4 nf_defrag_ipv4 nf_nat_ipv4 nf_nat nf_conntrack iptable_mangle iptable_raw iptable_filter ppdev vmw_vmci pcspkr coretemp i2c_piix4 parport_pc parport shpchp ip_tables xfs libcrc32c sd_mod sr_mod cdrom ata_generic pata_acpi mptspi scsi_transport_spi mptscsih serio_raw e1000 vmwgfx drm_kms_helper ttm drm ata_piix mptbase libata i2c_core
[ 157.537349] CPU: 3 PID: 1175 Comm: bash Tainted: G O 4.1.16 #10
[ 157.541707] Hardware name: VMware, Inc. VMware Virtual Platform/440BX Desktop Reference Platform, BIOS 6.00 07/31/2013
[ 157.548571] 0000000000000497 000000006717d855 ffffffff81794cce ffffffff8152828c
[ 157.553372] 0000000000000000 ffffffff810578b7 ffff88003b000000 0000000000000050
[ 157.558121] ffff8800394979b8 ffff88003d57b000 ffff880039497670 ffffffff8111bec5
[ 157.564423] [<ffffffff8152828c>] ? dump_stack+0x40/0x50
[ 157.568007] [<ffffffff810578b7>] ? warn_slowpath_common+0x77/0xb0
[ 157.571794] [<ffffffff8111bec5>] ? kmalloc_slab+0x85/0xa0
[ 157.575154] [<ffffffff8114a1d1>] ? __kmalloc+0x11/0x150
[ 157.578853] [<ffffffffa0278891>] ? cs_realpath+0x61/0x4c0 [caitsith]
[ 157.583213] [<ffffffff8117801a>] ? prepend_path+0xda/0x2d0
[ 157.587198] [<ffffffffa026fae1>] ? cs_populate_patharg+0x81/0xb0 [caitsith]
[ 157.591994] [<ffffffffa02749f8>] ? cs_init_log+0x1088/0x12d0 [caitsith]
[ 157.596581] [<ffffffffa0278025>] ? cs_audit_log+0x85/0x4a0 [caitsith]
[ 157.601269] [<ffffffffa0270c0c>] ? cs_check_acl+0x11c/0x220 [caitsith]
[ 157.605768] [<ffffffffa027131c>] ? cs_open_permission+0xfc/0x140 [caitsith]
[ 157.610537] [<ffffffffa0279d88>] ? cs_file_open+0x18/0x50 [caitsith]
[ 157.614941] [<ffffffff811fbbe4>] ? security_file_open+0x14/0x70
[ 157.619066] [<ffffffff8115fd92>] ? do_dentry_open+0xb2/0x320
[ 157.623053] [<ffffffff811ea180>] ? ovl_dir_fsync+0x130/0x130
[ 157.627027] [<ffffffff8116108f>] ? dentry_open+0x3f/0xb0
[ 157.630804] [<ffffffff8114a580>] ? kmem_cache_alloc+0x120/0x130
[ 157.634933] [<ffffffff811ea1d2>] ? ovl_dir_open+0x52/0xc0
[ 157.638756] [<ffffffff8115feea>] ? do_dentry_open+0x20a/0x320
[ 157.642781] [<ffffffff8116e29e>] ? do_last+0x41e/0xfc0
[ 157.646596] [<ffffffff8114a580>] ? kmem_cache_alloc+0x120/0x130
[ 157.650725] [<ffffffff81170a0e>] ? path_openat+0x8e/0x630
[ 157.654532] [<ffffffff8117218e>] ? do_filp_open+0x3e/0xa0
[ 157.658337] [<ffffffff8117e24c>] ? __alloc_fd+0x7c/0x120
[ 157.662290] [<ffffffff811613f8>] ? do_sys_open+0x148/0x230
[ 157.666140] [<ffffffff8152e157>] ? system_call_fastpath+0x12/0x6a
[ 157.670365] ---[ end trace ff1fe2bff03c9b4d ]---
[ 157.673671] ERROR: Out of memory at cs_realpath.
----------
Post by Roman Yeryomin
Any idea why?
Didn't have this problem with Tomoyo
Since overlayfs combines underlying mounts, not only pathname seen from
the overlayfs but also pathnames seen from underlying mounts are subjected
for permission checks. But d_absolute_path() for underlying mounts was
returning -EINVAL error. While TOMOYO has a fallback to calculate local
pathname, I forgot to apply it to CaitSith for Linux 3.17 and later kernels.
I don't know how partitions are mounted in your environment, but according
to https://wiki.openwrt.org/doc/techref/flash.layout , it seems to me that
overlayfs is mounted on / after SquashFS is mounted on /rom and JFFS2 is
mounted on /overlay . If so, applications cannot directly access pathnames
under /rom and /overlay , which means that it makes little sense to check
permissions for pathnames seen from SquashFS and JFFS2. In that case, you
might want to check permissions for only pathname seen from overlayfs using
filesystem magic number for overlayfs (i.e. 0x794C7630) like
10 acl read path.fsmagic=0x794C7630
instead of
10 acl read
Thank you for fixing this!
Although I will probably stick with Tomoyo for some time I will
probably migrate to CaitSith in the future as it seems more powerful
and flexible.

Regards,
Roman

Roman Yeryomin
2016-06-12 07:59:02 UTC
Permalink
On 6 June 2016 at 15:52, Tetsuo Handa
Post by Tetsuo Handa
Post by Roman Yeryomin
Post by Tetsuo Handa
Post by Roman Yeryomin
As I understand from domain transition logic described here
http://tomoyo.osdn.jp/2.5/policy-specification/domain-transition-procedure.html.en#transition_by_execute
it should work
But neither dd no the-tool don't have even read access to /dev/mtdX
Any pointers on what am I doing wrong?
Thanks in advance!
I guess that /bin/dd and /sbin/fw-tool are running in the <kernel> domain.
It seems you are right.
tomoyo-queryd showed that the-tool runs with profile 4 while
</sbin/the-tool> domain is configured as profile 0.
But then I don't understand how domain transition (exception policy) rules work.
Will they always match the most "hungry"/vague rule? not the first one?
It should match as described in the link above.
OK, it seems I've resolved my problems.
Thank you for your examples!
Post by Tetsuo Handa
Post by Roman Yeryomin
Like in my config it looks like any /sbin/the-tool instance will match
"keep_domain any from <kernel>" not "reset_domain /sbin/the-tool from
any" as I was expecting.
And adding "no_keep_domain /sbin/the-tool from any" also doesn't help.
So I'm confused here.
I think you can try how domain transition tree would look like, by
removing reset_domain / keep_domain entries and generating via usual
learning steps. You might find that the pathnames you assumed /bin/dd and
/sbin/fw-tool might be recognized as different names (e.g. if /sbin is
a symlink to /usr/sbin , /sbin/fw-tool will be recognized as
/usr/sbin/fw-tool ). After TOMOYO generated domains as detail as possible,
you can design which domains should be compressed.
Also, as far as I saw, you don't need to use policy namespace.
If you don't have reason to use policy namespace, you will be able to
replace reset_domain with initialize_domain .
Yes, I'm now using only one namespace, initialize_domain and
keep_domain for few things.


Regards,
Roman
Kyle Sallee
2016-06-05 16:12:31 UTC
Permalink
I would not normally respond,
however this request seems potentially similar
to my domain rules.
Domain automatic transition with program execution is disabled.
By a few domains ; various access levels are provided.
By writing to /sys/kernel/security/tomoyo/self_domain
a more restricted access domain can be selected.
However, for an embedded system, perhaps 2 domains would suffice?

Conceptually POSIX capabilities seem similar.
However, by Tomoyo rules adequate customization becomes possible.
Yet the following question seems solicited.
Could dropping some POSIX capabilities suffice?
Since I do not do that; I would not know.
Therefore, a potential Tomoyo solution will be discussed.

By exception policy path_groups
for nearly each device node write access is individual provided.
However, for read access lines such as following two lines are used.

path_group firm-read /dev/\*\-mapper/\*
path_group firm-read /dev/\*\-autofs\-btrfs-control\-dm\*\-hd\*\-kmem\-md
\*\-sd\*\-snapshot\-zram\*

In Roman Yeryomin's example the following line occurs.

path_group ALMOST_ANY_FILE /\*/\*\-mtd\?\*

At first something about that line looks odd.
But it looks okay.
More often rules contain /\{\*\}/ to match any directory depth.
When seeing /\*/ then a mistake is surmised.
But it seems adequate above.

Would
path_group ALMOST_ANY_FILE /dev/\*\-mtd\*
suffice?

Any device name which starts with mtd would be excluded.
Therefore, /dev/mtd15 and /dev/mtdr0 also would be excluded.
Do /dev/mtdr* devices become?
Should their content be hidden?

Because a device node can be accessed by any process
mitigating /bin/dd only access might not suffice?
And only if within that domain the domain rules apply.
read < /sys/kernel/security/tomoyo/self_domain; echo "$REPLY"
might be useful.
If the Tomoyo domain is added to the shell prompt
then that also can be useful.

Even if the rules are tight, by the presence of a kernel command line
parameter
Tomoyo activation could be precluded, prevented, thwarted?
That may be worth consideration.

To simply avert curious eyes, could device node deletion suffice?

To all processes, except perhaps the hotplug process,
the ability to create device nodes can be denied.
For example, by a domain almost every action
except file mkblock and file mkchar can be approved.
That consideration might be prudent.

# mknod /dev/alt-mtd0 b 90 0
and the C equivalent mknod function are easily invoked.

A hot plug implementation should be easy.
On an embedded system udev would not be used.
To write a hotplug program the following documentation may be useful.

/usr/src/linux/Documentation/networking/netlink_mmap.txt
and
https://www.kernel.org/doc/pending/hotplug.txt

However the hotplug.txt document is slightly old.
Therefore, by the kernel when hot plug events are reported
a bit more information such as MODALIAS= is provided.

Using a netlink socket for handling hot plug events may be superior.
By the traditional method any environment variables could be set
and then /sbin/hotplug could be invoked.
Therefore, if the traditional method is used
a progenitor process ID check may be prudent.
Perhaps 0 or 1 would become?
Otherwise a hot plug event could be simulated.
Since the netlink socket method was used;
how to secure a traditional method is surmised and not tested.

# ls -lah /sbin/hotplugd
-rwxr-xr-x 1 root root 7.0K May 27 16:38 /sbin/hotplugd

# file /sbin/hotplugd
/sbin/hotplugd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux
4.0.0, stripped

To handle hot plug an incredibly large and complex program is not required.

If uninterested in self coding:
by https://www.busybox.net/
an excellent self decompressing embedded system tool kit is provided.
With uClibc; busybox can be statically linked.
A bootable glibc free embedded system is possible.
However, at least by me, uClibc statically linked tomoyo-tools has not been
attempted.

Good luck with the embedded system design and implementation.
Post by Roman Yeryomin
Hello!
I'm trying to build a minimal policy for my embedded system where all
read/write requests to /dev/mtd* should be blocked except for several
programs.
Roman Yeryomin
2016-06-05 20:55:45 UTC
Permalink
Post by Kyle Sallee
I would not normally respond,
however this request seems potentially similar
to my domain rules.
Domain automatic transition with program execution is disabled.
By a few domains ; various access levels are provided.
By writing to /sys/kernel/security/tomoyo/self_domain
a more restricted access domain can be selected.
However, for an embedded system, perhaps 2 domains would suffice?
This is what I'm trying to achieve: keep number of rules as minimal as possible.
Post by Kyle Sallee
Conceptually POSIX capabilities seem similar.
However, by Tomoyo rules adequate customization becomes possible.
Yet the following question seems solicited.
Could dropping some POSIX capabilities suffice?
Since I do not do that; I would not know.
Not sure what you mean here.
Post by Kyle Sallee
Therefore, a potential Tomoyo solution will be discussed.
By exception policy path_groups
for nearly each device node write access is individual provided.
However, for read access lines such as following two lines are used.
path_group firm-read /dev/\*\-mapper/\*
path_group firm-read /dev/\*\-autofs\-btrfs-control\-dm\*\-hd\*\-kmem\-md
\*\-sd\*\-snapshot\-zram\*
wow... how does this (second rule) work?
is it everything in /dev/, except for
autofs
btrfs-control
dm*
hd*
kmem
md*
sd*
snapshot
zram*

am I guessing right?
Post by Kyle Sallee
In Roman Yeryomin's example the following line occurs.
path_group ALMOST_ANY_FILE /\*/\*\-mtd\?\*
At first something about that line looks odd.
But it looks okay.
More often rules contain /\{\*\}/ to match any directory depth.
When seeing /\*/ then a mistake is surmised.
But it seems adequate above.
Would
path_group ALMOST_ANY_FILE /dev/\*\-mtd\*
suffice?
Any device name which starts with mtd would be excluded.
Therefore, /dev/mtd15 and /dev/mtdr0 also would be excluded.
Do /dev/mtdr* devices become?
Should their content be hidden?
Since there is only mtdX and mtdblockX using "/\*/\*\-mtd\?\*" is ok
for me (I only wanted to exclude /proc/mtd from this match)
But after I saw your rule above I think I can improve this.
Post by Kyle Sallee
Because a device node can be accessed by any process
mitigating /bin/dd only access might not suffice?
And only if within that domain the domain rules apply.
read < /sys/kernel/security/tomoyo/self_domain; echo "$REPLY"
might be useful.
If the Tomoyo domain is added to the shell prompt
then that also can be useful.
Even if the rules are tight, by the presence of a kernel command line
parameter
Tomoyo activation could be precluded, prevented, thwarted?
That may be worth consideration.
To simply avert curious eyes, could device node deletion suffice?
To all processes, except perhaps the hotplug process,
the ability to create device nodes can be denied.
For example, by a domain almost every action
except file mkblock and file mkchar can be approved.
That consideration might be prudent.
# mknod /dev/alt-mtd0 b 90 0
and the C equivalent mknod function are easily invoked.
A hot plug implementation should be easy.
On an embedded system udev would not be used.
To write a hotplug program the following documentation may be useful.
/usr/src/linux/Documentation/networking/netlink_mmap.txt
and
https://www.kernel.org/doc/pending/hotplug.txt
However the hotplug.txt document is slightly old.
Therefore, by the kernel when hot plug events are reported
a bit more information such as MODALIAS= is provided.
Using a netlink socket for handling hot plug events may be superior.
By the traditional method any environment variables could be set
and then /sbin/hotplug could be invoked.
Therefore, if the traditional method is used
a progenitor process ID check may be prudent.
Perhaps 0 or 1 would become?
Otherwise a hot plug event could be simulated.
Since the netlink socket method was used;
how to secure a traditional method is surmised and not tested.
# ls -lah /sbin/hotplugd
-rwxr-xr-x 1 root root 7.0K May 27 16:38 /sbin/hotplugd
# file /sbin/hotplugd
/sbin/hotplugd: ELF 64-bit LSB executable, x86-64, version 1 (SYSV),
dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux
4.0.0, stripped
To handle hot plug an incredibly large and complex program is not required.
by https://www.busybox.net/
an excellent self decompressing embedded system tool kit is provided.
With uClibc; busybox can be statically linked.
A bootable glibc free embedded system is possible.
However, at least by me, uClibc statically linked tomoyo-tools has not been
attempted.
Good luck with the embedded system design and implementation.
I'm using OpenWrt as base, with busybox and musl, tomoyo-tools also work.
Post by Kyle Sallee
Post by Roman Yeryomin
Hello!
I'm trying to build a minimal policy for my embedded system where all
read/write requests to /dev/mtd* should be blocked except for several
programs.
Kyle Sallee
2016-06-06 13:16:58 UTC
Permalink
Post by Roman Yeryomin
This is what I'm trying to achieve: keep number of rules as minimal as possible.
In retrospect; please disregard what I wrote concerning Tomoyo.
Caitsith seems worth trying.
However, a below a few other potentially useful tips were included.

Although I have not tried; something about use_group might be useful;
as whatever is assigned to a group could be used by multiple domains.
But I haven't tried.

If Linux is configured with:
CONFIG_SECURITY_TOMOYO_ACTIVATION_TRIGGER="/init"
then by /init or whatever runs soon after
the tomoyo domain can be set
by writing the domain to
/sys/kernel/security/tomoyo/self_domain

"<kernel> //tomoyo\n"
By mere program execution the above domain can not be reached.
With Tomoyo rules almost anything must be explicitly enabled,
except domain transition, which can be explicitly disabled.
As an exception rule
keep_domain any from any
Then, to manually enter a domain as a domain rule

<kernel> //tomoyo
task manual_domain_transition <kernel> //other

And now from <kernel> //tomoyo
manual domain transition to <kernel> //other is possible

Keeping at least 1 profile 0 domain, no rules enforced domain, can be
useful.
However, allowing transition from a more restrictive domain to a less
restrictive domain
might not be desirable.
Post by Roman Yeryomin
Conceptually POSIX capabilities seem similar.
Not sure what you mean here.
If only someone who used them could explain.
Try the capabilities section 7 manual page.
man 7 capabilities
By man-pages available from
https://www.kernel.org/pub/linux/docs/man-pages
the manual page is provided.
Imagine root account omnipotence as a supreme pizza.
By POSIX capabilities certain pizza toppings can be omitted.
For example, to omit the mushrooms CAP_SYS_BOOT could be discarded.
Then execution of reboot and kexec_load are denied.
While probably not too difficult to manually set;
a libcap library is provided.
http://www.kernel.org//pub/linux/libs/security/linux-privs/libcap2/
http://people.redhat.com/sgrubb/libcap-ng

systemd might use capabilities, but since I do not use it; who knows

One of the most salient sentences of the capabilities manual page follows.
"If a thread drops a capability from its permitted set, it can
never reacquire that capability (unless it execve(2)s either a
set-user-ID-root program, or a program whose associated file
capabilities grant that capability)."

A main gripe concerning security is that
by the proliferation of UID owned SUID executable files
a castle with many secret entrances is created.
With some solid Tomoyo domain rules
a process can be locked in the box
and by SUID escape is not possible.

However, on an embedded system perhaps
many SUID executable files can be omitted or mitigated?

For security enhancement Tomoyo is like a hair net.
Provided nothing is unexpected mount --bind, it works.
Therefore, to mitigate mount --bind
careful rules regarding file mount may be useful.

However, even while within a chroot all rules are checked
as if the root was still the original / rootfs.
For example if access to file /chroot_dir/init is logged
then following chroot /chroot_dir
access to file /chroot_dir/init will still be logged.
That is desirable.

However, for /bin /sbin /lib /etc if rules exist
and if the following two commands are executed:
mount --bind / /chroot_dir; chroot /chroot_dir is executed
then the rules from /bin /sbin /lib /etc within /chroot_dir do not apply.
For fascist rules design to blind a service
a problem does not become.
But for a general purpose domain which can host almost any process
then some consideration might be useful.

For incredibly reasonable memory consumption,
by Tomoyo awesome MAC, mandatory access control, can be provided.
Yet the possibility of mount --bind must be anticipated and/or mitigated.
Post by Roman Yeryomin
Post by Kyle Sallee
Therefore, a potential Tomoyo solution will be discussed.
By exception policy path_groups
for nearly each device node write access is individual provided.
However, for read access lines such as following two lines are used.
path_group firm-read /dev/\*\-mapper/\*
path_group firm-read /dev/\*\-autofs\-btrfs-control\-dm\*\-hd\*\-kmem\-md
\*\-sd\*\-snapshot\-zram\*
wow... how does this (second rule) work?
is it everything in /dev/, except for
autofs
btrfs-control
dm*
hd*
kmem
md*
sd*
snapshot
zram*
am I guessing right?
Something like that.
Deciding exactly where to allow writing is easier.
For any device node type new rules can be added.
However, for device reading, hmmm.
Certain devices probably should not be read.
So some of those can be listed that way
while to those not explicitly listed read permission is granted.
For creating device rules /usr/src/linux/Documentation/devices.txt
and the mounted devtmpfs content are useful.
What was provided above was not intended to be a fantastic perfect rule,
but an example of how to compromise caution and leniency.

Medieval castle defense similar defense Tomoyo rules can be implemented.
For example; in a medieval castle a moat, a main wall, and an inner keep
could exist.
Where service customized Tomoyo domains are not used;
a castle approach can be used where a domain outside of central keep is
used.
While to the keep only;
the very sensitive security matters, such as read/write access to /dev/sd*
to be able to partition and initialize file systems, is delegated.
So for example, a couple layers beyond the keep,
in a domain used by services,
the system installed file system areas are read only.
If a service in that domain is compromised
then root kit installation would not be possible.

The easy cheesy way of accomplishing somethings similar;
that other administrators have done in the past
is to remount file systems or portions as read only.
Of course without Tomoyo; and without a drop of CAP_SYS_ADMIN
by any process those file systems portions could be remounted read/write.
That makes it a bit like security through obscurity,
since if the obstacle is not surmised
then it is not surmounted.
However, if anticipated; it is too easily circumvented.


Since there is only mtdX and mtdblockX using "/\*/\*\-mtd\?\*" is ok
Post by Roman Yeryomin
for me (I only wanted to exclude /proc/mtd from this match)
But after I saw your rule above I think I can improve this.
It probably goes without saying, but....

/sbin/\*\-tomoyo-\*\-reboot\-shutdown

If tomoyo-editpolicy can be executed or
if tomoyo-loadpolicy can be executed
then domain and exception rules can be arbitrarily changed.


I'm using OpenWrt as base, with busybox and musl, tomoyo-tools also work.
Not sure. OpenWrt and musl seem new.

If signed modules are used
then arbitrary trojaned module loading can be prevented.
However, module compression ratio suffers, slightly.
If the system will boot and run mostly from rootFS
them within kernel zram could be useful.
For CPIO file compression xz is excellent.
By ordering files by type, as identified by the file command,
by a few percents the compression ratio can improve.

https://caitsith.osdn.jp/
http://i-love.sakura.ne.jp/tomoyo/CaitSith-en.pdf

CaitSith supports a blacklisting approach.
With blacklisting capability an absurd looking rule with all the \- could
be avoided?

Is CaitSith the next evolutionary step?
Should we be changing our domain and exception rules to caitsith?
Sweet work, Tetsuo Handa.

Just read the follow up message regarding:
"The "100 acl mount" block is for preventing attackers from disguising
programs using e.g. "mount --bind" request."
Nice.

In the future, without an additional patch
by the vanilla kernel without an additional patch
will caitsith be provided?
Because caitsith is external;
at least for me caitsith escaped notice.

OpenWrt is firewall/router niche POSIX.

https://www.musl-libc.org/
Excellent, an alternate libc implementation.
http://www.etalabs.net/compare_libcs.html
Wow that looks sweet.

And according to the gcc manual page:
" -mmusl
Use the musl C library. This is the default on *-*-linux-*musl*
targets"

Looks good.
Perhaps a gcc patch will not be required.
Maybe a tool chain also will not be required?
Without a tool chain uClibc also can be used.
However, warning messages print.

Thanks for the info.
How did I not notice it?
I have not been paying attention.
musl looks fun.
Especially, for coreutils, grep, sed and other utilities
that tend to be excessively used by libtool and during compilation
by a faster launch greater performance can be achieved.
And a statically linked /init also can be useful.

The entire POSIX is linked with musl and not glibc?
For any programs does a problem become?
In lieu of glibc; as a complete drop in replacement uClibc does not suffice.
However, for uClibc overall glibc compatibility is good.

After musl is installed; support for unshared name spaces
and other newer Linux fun support can be tested.
Thanks again.

P.S.
By a custom Linux kernel config; a good bit of space can be saved.
And before modules are signed;
module stripping with parameter --strip-unneeded is possible.
The modules load, work, and when loaded and while in file system
for each module file less space is required.
Also by cpio xz compression where module files are not individually
compressed;
a far better overall compression ratio can be achieved.

Technically, after boot with otherwise idle processor cycles;
by lzop individual module files could be rapidly compressed
and some space on the rootFS can be reclaimed.
While doing so might seem backwards at first
the ISO9660 file size will be smaller,
and by the boot loader
the smaller compressed CPIO InitRAMFS can load faster.

Good luck making an awesome embedded POSIX.

If I rudely butted into conversation, please forgive.
I also concur that for Roman Yeryomin's task,
caitsith looks awesome.
Loading...