Merge branch 'smack-for-4.1' of git://github.com/cschaufler/smack-next into next
This commit is contained in:
commit
4f9a60f5c7
5 changed files with 307 additions and 69 deletions
|
@ -33,11 +33,18 @@ The current git repository for Smack user space is:
|
||||||
git://github.com/smack-team/smack.git
|
git://github.com/smack-team/smack.git
|
||||||
|
|
||||||
This should make and install on most modern distributions.
|
This should make and install on most modern distributions.
|
||||||
There are three commands included in smackutil:
|
There are five commands included in smackutil:
|
||||||
|
|
||||||
smackload - properly formats data for writing to /smack/load
|
|
||||||
smackcipso - properly formats data for writing to /smack/cipso
|
|
||||||
chsmack - display or set Smack extended attribute values
|
chsmack - display or set Smack extended attribute values
|
||||||
|
smackctl - load the Smack access rules
|
||||||
|
smackaccess - report if a process with one label has access
|
||||||
|
to an object with another
|
||||||
|
|
||||||
|
These two commands are obsolete with the introduction of
|
||||||
|
the smackfs/load2 and smackfs/cipso2 interfaces.
|
||||||
|
|
||||||
|
smackload - properly formats data for writing to smackfs/load
|
||||||
|
smackcipso - properly formats data for writing to smackfs/cipso
|
||||||
|
|
||||||
In keeping with the intent of Smack, configuration data is
|
In keeping with the intent of Smack, configuration data is
|
||||||
minimal and not strictly required. The most important
|
minimal and not strictly required. The most important
|
||||||
|
@ -47,9 +54,9 @@ of this, but it can be manually as well.
|
||||||
|
|
||||||
Add this line to /etc/fstab:
|
Add this line to /etc/fstab:
|
||||||
|
|
||||||
smackfs /smack smackfs smackfsdef=* 0 0
|
smackfs /sys/fs/smackfs smackfs defaults 0 0
|
||||||
|
|
||||||
and create the /smack directory for mounting.
|
The /sys/fs/smackfs directory is created by the kernel.
|
||||||
|
|
||||||
Smack uses extended attributes (xattrs) to store labels on filesystem
|
Smack uses extended attributes (xattrs) to store labels on filesystem
|
||||||
objects. The attributes are stored in the extended attribute security
|
objects. The attributes are stored in the extended attribute security
|
||||||
|
@ -92,13 +99,13 @@ There are multiple ways to set a Smack label on a file:
|
||||||
# attr -S -s SMACK64 -V "value" path
|
# attr -S -s SMACK64 -V "value" path
|
||||||
# chsmack -a value path
|
# chsmack -a value path
|
||||||
|
|
||||||
A process can see the smack label it is running with by
|
A process can see the Smack label it is running with by
|
||||||
reading /proc/self/attr/current. A process with CAP_MAC_ADMIN
|
reading /proc/self/attr/current. A process with CAP_MAC_ADMIN
|
||||||
can set the process smack by writing there.
|
can set the process Smack by writing there.
|
||||||
|
|
||||||
Most Smack configuration is accomplished by writing to files
|
Most Smack configuration is accomplished by writing to files
|
||||||
in the smackfs filesystem. This pseudo-filesystem is usually
|
in the smackfs filesystem. This pseudo-filesystem is mounted
|
||||||
mounted on /smack.
|
on /sys/fs/smackfs.
|
||||||
|
|
||||||
access
|
access
|
||||||
This interface reports whether a subject with the specified
|
This interface reports whether a subject with the specified
|
||||||
|
@ -206,23 +213,30 @@ onlycap
|
||||||
file or cleared by writing "-" to the file.
|
file or cleared by writing "-" to the file.
|
||||||
ptrace
|
ptrace
|
||||||
This is used to define the current ptrace policy
|
This is used to define the current ptrace policy
|
||||||
0 - default: this is the policy that relies on smack access rules.
|
0 - default: this is the policy that relies on Smack access rules.
|
||||||
For the PTRACE_READ a subject needs to have a read access on
|
For the PTRACE_READ a subject needs to have a read access on
|
||||||
object. For the PTRACE_ATTACH a read-write access is required.
|
object. For the PTRACE_ATTACH a read-write access is required.
|
||||||
1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
|
1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
|
||||||
only allowed when subject's and object's labels are equal.
|
only allowed when subject's and object's labels are equal.
|
||||||
PTRACE_READ is not affected. Can be overriden with CAP_SYS_PTRACE.
|
PTRACE_READ is not affected. Can be overridden with CAP_SYS_PTRACE.
|
||||||
2 - draconian: this policy behaves like the 'exact' above with an
|
2 - draconian: this policy behaves like the 'exact' above with an
|
||||||
exception that it can't be overriden with CAP_SYS_PTRACE.
|
exception that it can't be overridden with CAP_SYS_PTRACE.
|
||||||
revoke-subject
|
revoke-subject
|
||||||
Writing a Smack label here sets the access to '-' for all access
|
Writing a Smack label here sets the access to '-' for all access
|
||||||
rules with that subject label.
|
rules with that subject label.
|
||||||
|
unconfined
|
||||||
|
If the kernel is configured with CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
a process with CAP_MAC_ADMIN can write a label into this interface.
|
||||||
|
Thereafter, accesses that involve that label will be logged and
|
||||||
|
the access permitted if it wouldn't be otherwise. Note that this
|
||||||
|
is dangerous and can ruin the proper labeling of your system.
|
||||||
|
It should never be used in production.
|
||||||
|
|
||||||
You can add access rules in /etc/smack/accesses. They take the form:
|
You can add access rules in /etc/smack/accesses. They take the form:
|
||||||
|
|
||||||
subjectlabel objectlabel access
|
subjectlabel objectlabel access
|
||||||
|
|
||||||
access is a combination of the letters rwxa which specify the
|
access is a combination of the letters rwxatb which specify the
|
||||||
kind of access permitted a subject with subjectlabel on an
|
kind of access permitted a subject with subjectlabel on an
|
||||||
object with objectlabel. If there is no rule no access is allowed.
|
object with objectlabel. If there is no rule no access is allowed.
|
||||||
|
|
||||||
|
@ -318,8 +332,9 @@ each of the subject and the object.
|
||||||
|
|
||||||
Labels
|
Labels
|
||||||
|
|
||||||
Smack labels are ASCII character strings, one to twenty-three characters in
|
Smack labels are ASCII character strings. They can be up to 255 characters
|
||||||
length. Single character labels using special characters, that being anything
|
long, but keeping them to twenty-three characters is recommended.
|
||||||
|
Single character labels using special characters, that being anything
|
||||||
other than a letter or digit, are reserved for use by the Smack development
|
other than a letter or digit, are reserved for use by the Smack development
|
||||||
team. Smack labels are unstructured, case sensitive, and the only operation
|
team. Smack labels are unstructured, case sensitive, and the only operation
|
||||||
ever performed on them is comparison for equality. Smack labels cannot
|
ever performed on them is comparison for equality. Smack labels cannot
|
||||||
|
@ -335,10 +350,9 @@ There are some predefined labels:
|
||||||
? Pronounced "huh", a single question mark character.
|
? Pronounced "huh", a single question mark character.
|
||||||
@ Pronounced "web", a single at sign character.
|
@ Pronounced "web", a single at sign character.
|
||||||
|
|
||||||
Every task on a Smack system is assigned a label. System tasks, such as
|
Every task on a Smack system is assigned a label. The Smack label
|
||||||
init(8) and systems daemons, are run with the floor ("_") label. User tasks
|
of a process will usually be assigned by the system initialization
|
||||||
are assigned labels according to the specification found in the
|
mechanism.
|
||||||
/etc/smack/user configuration file.
|
|
||||||
|
|
||||||
Access Rules
|
Access Rules
|
||||||
|
|
||||||
|
@ -393,6 +407,7 @@ describe access modes:
|
||||||
w: indicates that write access should be granted.
|
w: indicates that write access should be granted.
|
||||||
x: indicates that execute access should be granted.
|
x: indicates that execute access should be granted.
|
||||||
t: indicates that the rule requests transmutation.
|
t: indicates that the rule requests transmutation.
|
||||||
|
b: indicates that the rule should be reported for bring-up.
|
||||||
|
|
||||||
Uppercase values for the specification letters are allowed as well.
|
Uppercase values for the specification letters are allowed as well.
|
||||||
Access mode specifications can be in any order. Examples of acceptable rules
|
Access mode specifications can be in any order. Examples of acceptable rules
|
||||||
|
@ -402,6 +417,7 @@ are:
|
||||||
Secret Unclass R
|
Secret Unclass R
|
||||||
Manager Game x
|
Manager Game x
|
||||||
User HR w
|
User HR w
|
||||||
|
Snap Crackle rwxatb
|
||||||
New Old rRrRr
|
New Old rRrRr
|
||||||
Closed Off -
|
Closed Off -
|
||||||
|
|
||||||
|
@ -413,7 +429,7 @@ Examples of unacceptable rules are:
|
||||||
|
|
||||||
Spaces are not allowed in labels. Since a subject always has access to files
|
Spaces are not allowed in labels. Since a subject always has access to files
|
||||||
with the same label specifying a rule for that case is pointless. Only
|
with the same label specifying a rule for that case is pointless. Only
|
||||||
valid letters (rwxatRWXAT) and the dash ('-') character are allowed in
|
valid letters (rwxatbRWXATB) and the dash ('-') character are allowed in
|
||||||
access specifications. The dash is a placeholder, so "a-r" is the same
|
access specifications. The dash is a placeholder, so "a-r" is the same
|
||||||
as "ar". A lone dash is used to specify that no access should be allowed.
|
as "ar". A lone dash is used to specify that no access should be allowed.
|
||||||
|
|
||||||
|
@ -462,16 +478,11 @@ receiver. The receiver is not required to have read access to the sender.
|
||||||
Setting Access Rules
|
Setting Access Rules
|
||||||
|
|
||||||
The configuration file /etc/smack/accesses contains the rules to be set at
|
The configuration file /etc/smack/accesses contains the rules to be set at
|
||||||
system startup. The contents are written to the special file /smack/load.
|
system startup. The contents are written to the special file
|
||||||
Rules can be written to /smack/load at any time and take effect immediately.
|
/sys/fs/smackfs/load2. Rules can be added at any time and take effect
|
||||||
For any pair of subject and object labels there can be only one rule, with the
|
immediately. For any pair of subject and object labels there can be only
|
||||||
most recently specified overriding any earlier specification.
|
one rule, with the most recently specified overriding any earlier
|
||||||
|
specification.
|
||||||
The program smackload is provided to ensure data is formatted
|
|
||||||
properly when written to /smack/load. This program reads lines
|
|
||||||
of the form
|
|
||||||
|
|
||||||
subjectlabel objectlabel mode.
|
|
||||||
|
|
||||||
Task Attribute
|
Task Attribute
|
||||||
|
|
||||||
|
@ -488,7 +499,10 @@ only be changed by a process with privilege.
|
||||||
|
|
||||||
Privilege
|
Privilege
|
||||||
|
|
||||||
A process with CAP_MAC_OVERRIDE is privileged.
|
A process with CAP_MAC_OVERRIDE or CAP_MAC_ADMIN is privileged.
|
||||||
|
CAP_MAC_OVERRIDE allows the process access to objects it would
|
||||||
|
be denied otherwise. CAP_MAC_ADMIN allows a process to change
|
||||||
|
Smack data, including rules and attributes.
|
||||||
|
|
||||||
Smack Networking
|
Smack Networking
|
||||||
|
|
||||||
|
@ -510,14 +524,14 @@ intervention. Unlabeled packets that come into the system will be given the
|
||||||
ambient label.
|
ambient label.
|
||||||
|
|
||||||
Smack requires configuration in the case where packets from a system that is
|
Smack requires configuration in the case where packets from a system that is
|
||||||
not smack that speaks CIPSO may be encountered. Usually this will be a Trusted
|
not Smack that speaks CIPSO may be encountered. Usually this will be a Trusted
|
||||||
Solaris system, but there are other, less widely deployed systems out there.
|
Solaris system, but there are other, less widely deployed systems out there.
|
||||||
CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level,
|
CIPSO provides 3 important values, a Domain Of Interpretation (DOI), a level,
|
||||||
and a category set with each packet. The DOI is intended to identify a group
|
and a category set with each packet. The DOI is intended to identify a group
|
||||||
of systems that use compatible labeling schemes, and the DOI specified on the
|
of systems that use compatible labeling schemes, and the DOI specified on the
|
||||||
smack system must match that of the remote system or packets will be
|
Smack system must match that of the remote system or packets will be
|
||||||
discarded. The DOI is 3 by default. The value can be read from /smack/doi and
|
discarded. The DOI is 3 by default. The value can be read from
|
||||||
can be changed by writing to /smack/doi.
|
/sys/fs/smackfs/doi and can be changed by writing to /sys/fs/smackfs/doi.
|
||||||
|
|
||||||
The label and category set are mapped to a Smack label as defined in
|
The label and category set are mapped to a Smack label as defined in
|
||||||
/etc/smack/cipso.
|
/etc/smack/cipso.
|
||||||
|
@ -539,15 +553,13 @@ The ":" and "," characters are permitted in a Smack label but have no special
|
||||||
meaning.
|
meaning.
|
||||||
|
|
||||||
The mapping of Smack labels to CIPSO values is defined by writing to
|
The mapping of Smack labels to CIPSO values is defined by writing to
|
||||||
/smack/cipso. Again, the format of data written to this special file
|
/sys/fs/smackfs/cipso2.
|
||||||
is highly restrictive, so the program smackcipso is provided to
|
|
||||||
ensure the writes are done properly. This program takes mappings
|
|
||||||
on the standard input and sends them to /smack/cipso properly.
|
|
||||||
|
|
||||||
In addition to explicit mappings Smack supports direct CIPSO mappings. One
|
In addition to explicit mappings Smack supports direct CIPSO mappings. One
|
||||||
CIPSO level is used to indicate that the category set passed in the packet is
|
CIPSO level is used to indicate that the category set passed in the packet is
|
||||||
in fact an encoding of the Smack label. The level used is 250 by default. The
|
in fact an encoding of the Smack label. The level used is 250 by default. The
|
||||||
value can be read from /smack/direct and changed by writing to /smack/direct.
|
value can be read from /sys/fs/smackfs/direct and changed by writing to
|
||||||
|
/sys/fs/smackfs/direct.
|
||||||
|
|
||||||
Socket Attributes
|
Socket Attributes
|
||||||
|
|
||||||
|
@ -565,8 +577,8 @@ sockets.
|
||||||
Smack Netlabel Exceptions
|
Smack Netlabel Exceptions
|
||||||
|
|
||||||
You will often find that your labeled application has to talk to the outside,
|
You will often find that your labeled application has to talk to the outside,
|
||||||
unlabeled world. To do this there's a special file /smack/netlabel where you can
|
unlabeled world. To do this there's a special file /sys/fs/smackfs/netlabel
|
||||||
add some exceptions in the form of :
|
where you can add some exceptions in the form of :
|
||||||
@IP1 LABEL1 or
|
@IP1 LABEL1 or
|
||||||
@IP2/MASK LABEL2
|
@IP2/MASK LABEL2
|
||||||
|
|
||||||
|
@ -574,22 +586,22 @@ It means that your application will have unlabeled access to @IP1 if it has
|
||||||
write access on LABEL1, and access to the subnet @IP2/MASK if it has write
|
write access on LABEL1, and access to the subnet @IP2/MASK if it has write
|
||||||
access on LABEL2.
|
access on LABEL2.
|
||||||
|
|
||||||
Entries in the /smack/netlabel file are matched by longest mask first, like in
|
Entries in the /sys/fs/smackfs/netlabel file are matched by longest mask
|
||||||
classless IPv4 routing.
|
first, like in classless IPv4 routing.
|
||||||
|
|
||||||
A special label '@' and an option '-CIPSO' can be used there :
|
A special label '@' and an option '-CIPSO' can be used there :
|
||||||
@ means Internet, any application with any label has access to it
|
@ means Internet, any application with any label has access to it
|
||||||
-CIPSO means standard CIPSO networking
|
-CIPSO means standard CIPSO networking
|
||||||
|
|
||||||
If you don't know what CIPSO is and don't plan to use it, you can just do :
|
If you don't know what CIPSO is and don't plan to use it, you can just do :
|
||||||
echo 127.0.0.1 -CIPSO > /smack/netlabel
|
echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/netlabel
|
||||||
echo 0.0.0.0/0 @ > /smack/netlabel
|
echo 0.0.0.0/0 @ > /sys/fs/smackfs/netlabel
|
||||||
|
|
||||||
If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
|
If you use CIPSO on your 192.168.0.0/16 local network and need also unlabeled
|
||||||
Internet access, you can have :
|
Internet access, you can have :
|
||||||
echo 127.0.0.1 -CIPSO > /smack/netlabel
|
echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/netlabel
|
||||||
echo 192.168.0.0/16 -CIPSO > /smack/netlabel
|
echo 192.168.0.0/16 -CIPSO > /sys/fs/smackfs/netlabel
|
||||||
echo 0.0.0.0/0 @ > /smack/netlabel
|
echo 0.0.0.0/0 @ > /sys/fs/smackfs/netlabel
|
||||||
|
|
||||||
|
|
||||||
Writing Applications for Smack
|
Writing Applications for Smack
|
||||||
|
@ -676,7 +688,7 @@ Smack auditing
|
||||||
If you want Smack auditing of security events, you need to set CONFIG_AUDIT
|
If you want Smack auditing of security events, you need to set CONFIG_AUDIT
|
||||||
in your kernel configuration.
|
in your kernel configuration.
|
||||||
By default, all denied events will be audited. You can change this behavior by
|
By default, all denied events will be audited. You can change this behavior by
|
||||||
writing a single character to the /smack/logging file :
|
writing a single character to the /sys/fs/smackfs/logging file :
|
||||||
0 : no logging
|
0 : no logging
|
||||||
1 : log denied (default)
|
1 : log denied (default)
|
||||||
2 : log accepted
|
2 : log accepted
|
||||||
|
@ -686,3 +698,20 @@ Events are logged as 'key=value' pairs, for each event you at least will get
|
||||||
the subject, the object, the rights requested, the action, the kernel function
|
the subject, the object, the rights requested, the action, the kernel function
|
||||||
that triggered the event, plus other pairs depending on the type of event
|
that triggered the event, plus other pairs depending on the type of event
|
||||||
audited.
|
audited.
|
||||||
|
|
||||||
|
Bringup Mode
|
||||||
|
|
||||||
|
Bringup mode provides logging features that can make application
|
||||||
|
configuration and system bringup easier. Configure the kernel with
|
||||||
|
CONFIG_SECURITY_SMACK_BRINGUP to enable these features. When bringup
|
||||||
|
mode is enabled accesses that succeed due to rules marked with the "b"
|
||||||
|
access mode will logged. When a new label is introduced for processes
|
||||||
|
rules can be added aggressively, marked with the "b". The logging allows
|
||||||
|
tracking of which rules actual get used for that label.
|
||||||
|
|
||||||
|
Another feature of bringup mode is the "unconfined" option. Writing
|
||||||
|
a label to /sys/fs/smackfs/unconfined makes subjects with that label
|
||||||
|
able to access any object, and objects with that label accessible to
|
||||||
|
all subjects. Any access that is granted because a label is unconfined
|
||||||
|
is logged. This feature is dangerous, as files and directories may
|
||||||
|
be created in places they couldn't if the policy were being enforced.
|
||||||
|
|
|
@ -105,6 +105,7 @@ struct task_smack {
|
||||||
#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
|
#define SMK_INODE_INSTANT 0x01 /* inode is instantiated */
|
||||||
#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
|
#define SMK_INODE_TRANSMUTE 0x02 /* directory is transmuting */
|
||||||
#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */
|
#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */
|
||||||
|
#define SMK_INODE_IMPURE 0x08 /* involved in an impure transaction */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A label access rule.
|
* A label access rule.
|
||||||
|
@ -193,6 +194,10 @@ struct smk_port_label {
|
||||||
#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
|
#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
|
||||||
#define MAY_BRINGUP 0x00004000 /* Report use of this rule */
|
#define MAY_BRINGUP 0x00004000 /* Report use of this rule */
|
||||||
|
|
||||||
|
#define SMACK_BRINGUP_ALLOW 1 /* Allow bringup mode */
|
||||||
|
#define SMACK_UNCONFINED_SUBJECT 2 /* Allow unconfined label */
|
||||||
|
#define SMACK_UNCONFINED_OBJECT 3 /* Allow unconfined label */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Just to make the common cases easier to deal with
|
* Just to make the common cases easier to deal with
|
||||||
*/
|
*/
|
||||||
|
@ -254,6 +259,9 @@ extern int smack_cipso_mapped;
|
||||||
extern struct smack_known *smack_net_ambient;
|
extern struct smack_known *smack_net_ambient;
|
||||||
extern struct smack_known *smack_onlycap;
|
extern struct smack_known *smack_onlycap;
|
||||||
extern struct smack_known *smack_syslog_label;
|
extern struct smack_known *smack_syslog_label;
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
extern struct smack_known *smack_unconfined;
|
||||||
|
#endif
|
||||||
extern struct smack_known smack_cipso_option;
|
extern struct smack_known smack_cipso_option;
|
||||||
extern int smack_ptrace_rule;
|
extern int smack_ptrace_rule;
|
||||||
|
|
||||||
|
|
|
@ -130,7 +130,8 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Hardcoded comparisons.
|
* Hardcoded comparisons.
|
||||||
*
|
*/
|
||||||
|
/*
|
||||||
* A star subject can't access any object.
|
* A star subject can't access any object.
|
||||||
*/
|
*/
|
||||||
if (subject == &smack_known_star) {
|
if (subject == &smack_known_star) {
|
||||||
|
@ -189,10 +190,20 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
|
||||||
* succeed because of "b" rules.
|
* succeed because of "b" rules.
|
||||||
*/
|
*/
|
||||||
if (may & MAY_BRINGUP)
|
if (may & MAY_BRINGUP)
|
||||||
rc = MAY_BRINGUP;
|
rc = SMACK_BRINGUP_ALLOW;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
out_audit:
|
out_audit:
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
if (rc < 0) {
|
||||||
|
if (object == smack_unconfined)
|
||||||
|
rc = SMACK_UNCONFINED_OBJECT;
|
||||||
|
if (subject == smack_unconfined)
|
||||||
|
rc = SMACK_UNCONFINED_SUBJECT;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef CONFIG_AUDIT
|
#ifdef CONFIG_AUDIT
|
||||||
if (a)
|
if (a)
|
||||||
smack_log(subject->smk_known, object->smk_known,
|
smack_log(subject->smk_known, object->smk_known,
|
||||||
|
@ -338,19 +349,16 @@ static void smack_log_callback(struct audit_buffer *ab, void *a)
|
||||||
void smack_log(char *subject_label, char *object_label, int request,
|
void smack_log(char *subject_label, char *object_label, int request,
|
||||||
int result, struct smk_audit_info *ad)
|
int result, struct smk_audit_info *ad)
|
||||||
{
|
{
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
char request_buffer[SMK_NUM_ACCESS_TYPE + 5];
|
||||||
|
#else
|
||||||
char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
|
char request_buffer[SMK_NUM_ACCESS_TYPE + 1];
|
||||||
|
#endif
|
||||||
struct smack_audit_data *sad;
|
struct smack_audit_data *sad;
|
||||||
struct common_audit_data *a = &ad->a;
|
struct common_audit_data *a = &ad->a;
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
|
||||||
/*
|
|
||||||
* The result may be positive in bringup mode.
|
|
||||||
*/
|
|
||||||
if (result > 0)
|
|
||||||
result = 0;
|
|
||||||
#endif
|
|
||||||
/* check if we have to log the current event */
|
/* check if we have to log the current event */
|
||||||
if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
|
if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
|
||||||
return;
|
return;
|
||||||
if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
|
if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
|
||||||
return;
|
return;
|
||||||
|
@ -364,6 +372,21 @@ void smack_log(char *subject_label, char *object_label, int request,
|
||||||
smack_str_from_perm(request_buffer, request);
|
smack_str_from_perm(request_buffer, request);
|
||||||
sad->subject = subject_label;
|
sad->subject = subject_label;
|
||||||
sad->object = object_label;
|
sad->object = object_label;
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
/*
|
||||||
|
* The result may be positive in bringup mode.
|
||||||
|
* A positive result is an allow, but not for normal reasons.
|
||||||
|
* Mark it as successful, but don't filter it out even if
|
||||||
|
* the logging policy says to do so.
|
||||||
|
*/
|
||||||
|
if (result == SMACK_UNCONFINED_SUBJECT)
|
||||||
|
strcat(request_buffer, "(US)");
|
||||||
|
else if (result == SMACK_UNCONFINED_OBJECT)
|
||||||
|
strcat(request_buffer, "(UO)");
|
||||||
|
|
||||||
|
if (result > 0)
|
||||||
|
result = 0;
|
||||||
|
#endif
|
||||||
sad->request = request_buffer;
|
sad->request = request_buffer;
|
||||||
sad->result = result;
|
sad->result = result;
|
||||||
|
|
||||||
|
|
|
@ -57,6 +57,13 @@ static struct kmem_cache *smack_inode_cache;
|
||||||
int smack_enabled;
|
int smack_enabled;
|
||||||
|
|
||||||
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
static char *smk_bu_mess[] = {
|
||||||
|
"Bringup Error", /* Unused */
|
||||||
|
"Bringup", /* SMACK_BRINGUP_ALLOW */
|
||||||
|
"Unconfined Subject", /* SMACK_UNCONFINED_SUBJECT */
|
||||||
|
"Unconfined Object", /* SMACK_UNCONFINED_OBJECT */
|
||||||
|
};
|
||||||
|
|
||||||
static void smk_bu_mode(int mode, char *s)
|
static void smk_bu_mode(int mode, char *s)
|
||||||
{
|
{
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -87,9 +94,11 @@ static int smk_bu_note(char *note, struct smack_known *sskp,
|
||||||
|
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
smk_bu_mode(mode, acc);
|
smk_bu_mode(mode, acc);
|
||||||
pr_info("Smack Bringup: (%s %s %s) %s\n",
|
pr_info("Smack %s: (%s %s %s) %s\n", smk_bu_mess[rc],
|
||||||
sskp->smk_known, oskp->smk_known, acc, note);
|
sskp->smk_known, oskp->smk_known, acc, note);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -106,9 +115,11 @@ static int smk_bu_current(char *note, struct smack_known *oskp,
|
||||||
|
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
smk_bu_mode(mode, acc);
|
smk_bu_mode(mode, acc);
|
||||||
pr_info("Smack Bringup: (%s %s %s) %s %s\n",
|
pr_info("Smack %s: (%s %s %s) %s %s\n", smk_bu_mess[rc],
|
||||||
tsp->smk_task->smk_known, oskp->smk_known,
|
tsp->smk_task->smk_known, oskp->smk_known,
|
||||||
acc, current->comm, note);
|
acc, current->comm, note);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -126,9 +137,11 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
|
||||||
|
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
smk_bu_mode(mode, acc);
|
smk_bu_mode(mode, acc);
|
||||||
pr_info("Smack Bringup: (%s %s %s) %s to %s\n",
|
pr_info("Smack %s: (%s %s %s) %s to %s\n", smk_bu_mess[rc],
|
||||||
tsp->smk_task->smk_known, smk_task->smk_known, acc,
|
tsp->smk_task->smk_known, smk_task->smk_known, acc,
|
||||||
current->comm, otp->comm);
|
current->comm, otp->comm);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -141,14 +154,25 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
|
||||||
static int smk_bu_inode(struct inode *inode, int mode, int rc)
|
static int smk_bu_inode(struct inode *inode, int mode, int rc)
|
||||||
{
|
{
|
||||||
struct task_smack *tsp = current_security();
|
struct task_smack *tsp = current_security();
|
||||||
|
struct inode_smack *isp = inode->i_security;
|
||||||
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
||||||
|
|
||||||
|
if (isp->smk_flags & SMK_INODE_IMPURE)
|
||||||
|
pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
|
||||||
|
inode->i_sb->s_id, inode->i_ino, current->comm);
|
||||||
|
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||||
|
rc = 0;
|
||||||
|
if (rc == SMACK_UNCONFINED_SUBJECT &&
|
||||||
|
(mode & (MAY_WRITE | MAY_APPEND)))
|
||||||
|
isp->smk_flags |= SMK_INODE_IMPURE;
|
||||||
|
|
||||||
smk_bu_mode(mode, acc);
|
smk_bu_mode(mode, acc);
|
||||||
pr_info("Smack Bringup: (%s %s %s) inode=(%s %ld) %s\n",
|
|
||||||
tsp->smk_task->smk_known, smk_of_inode(inode)->smk_known, acc,
|
pr_info("Smack %s: (%s %s %s) inode=(%s %ld) %s\n", smk_bu_mess[rc],
|
||||||
|
tsp->smk_task->smk_known, isp->smk_inode->smk_known, acc,
|
||||||
inode->i_sb->s_id, inode->i_ino, current->comm);
|
inode->i_sb->s_id, inode->i_ino, current->comm);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -162,13 +186,20 @@ static int smk_bu_file(struct file *file, int mode, int rc)
|
||||||
struct task_smack *tsp = current_security();
|
struct task_smack *tsp = current_security();
|
||||||
struct smack_known *sskp = tsp->smk_task;
|
struct smack_known *sskp = tsp->smk_task;
|
||||||
struct inode *inode = file_inode(file);
|
struct inode *inode = file_inode(file);
|
||||||
|
struct inode_smack *isp = inode->i_security;
|
||||||
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
||||||
|
|
||||||
|
if (isp->smk_flags & SMK_INODE_IMPURE)
|
||||||
|
pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
|
||||||
|
inode->i_sb->s_id, inode->i_ino, current->comm);
|
||||||
|
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
smk_bu_mode(mode, acc);
|
smk_bu_mode(mode, acc);
|
||||||
pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n",
|
pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
|
||||||
sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
|
sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
|
||||||
inode->i_sb->s_id, inode->i_ino, file,
|
inode->i_sb->s_id, inode->i_ino, file,
|
||||||
current->comm);
|
current->comm);
|
||||||
|
@ -185,13 +216,20 @@ static int smk_bu_credfile(const struct cred *cred, struct file *file,
|
||||||
struct task_smack *tsp = cred->security;
|
struct task_smack *tsp = cred->security;
|
||||||
struct smack_known *sskp = tsp->smk_task;
|
struct smack_known *sskp = tsp->smk_task;
|
||||||
struct inode *inode = file->f_inode;
|
struct inode *inode = file->f_inode;
|
||||||
|
struct inode_smack *isp = inode->i_security;
|
||||||
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
char acc[SMK_NUM_ACCESS_TYPE + 1];
|
||||||
|
|
||||||
|
if (isp->smk_flags & SMK_INODE_IMPURE)
|
||||||
|
pr_info("Smack Unconfined Corruption: inode=(%s %ld) %s\n",
|
||||||
|
inode->i_sb->s_id, inode->i_ino, current->comm);
|
||||||
|
|
||||||
if (rc <= 0)
|
if (rc <= 0)
|
||||||
return rc;
|
return rc;
|
||||||
|
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||||
|
rc = 0;
|
||||||
|
|
||||||
smk_bu_mode(mode, acc);
|
smk_bu_mode(mode, acc);
|
||||||
pr_info("Smack Bringup: (%s %s %s) file=(%s %ld %pD) %s\n",
|
pr_info("Smack %s: (%s %s %s) file=(%s %ld %pD) %s\n", smk_bu_mess[rc],
|
||||||
sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
|
sskp->smk_known, smk_of_inode(inode)->smk_known, acc,
|
||||||
inode->i_sb->s_id, inode->i_ino, file,
|
inode->i_sb->s_id, inode->i_ino, file,
|
||||||
current->comm);
|
current->comm);
|
||||||
|
@ -2452,7 +2490,21 @@ static int smack_inode_setsecurity(struct inode *inode, const char *name,
|
||||||
static int smack_socket_post_create(struct socket *sock, int family,
|
static int smack_socket_post_create(struct socket *sock, int family,
|
||||||
int type, int protocol, int kern)
|
int type, int protocol, int kern)
|
||||||
{
|
{
|
||||||
if (family != PF_INET || sock->sk == NULL)
|
struct socket_smack *ssp;
|
||||||
|
|
||||||
|
if (sock->sk == NULL)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Sockets created by kernel threads receive web label.
|
||||||
|
*/
|
||||||
|
if (unlikely(current->flags & PF_KTHREAD)) {
|
||||||
|
ssp = sock->sk->sk_security;
|
||||||
|
ssp->smk_in = &smack_known_web;
|
||||||
|
ssp->smk_out = &smack_known_web;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (family != PF_INET)
|
||||||
return 0;
|
return 0;
|
||||||
/*
|
/*
|
||||||
* Set the outbound netlbl.
|
* Set the outbound netlbl.
|
||||||
|
@ -3986,6 +4038,36 @@ static int smack_key_permission(key_ref_t key_ref,
|
||||||
rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
|
rc = smk_bu_note("key access", tkp, keyp->security, request, rc);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* smack_key_getsecurity - Smack label tagging the key
|
||||||
|
* @key points to the key to be queried
|
||||||
|
* @_buffer points to a pointer that should be set to point to the
|
||||||
|
* resulting string (if no label or an error occurs).
|
||||||
|
* Return the length of the string (including terminating NUL) or -ve if
|
||||||
|
* an error.
|
||||||
|
* May also return 0 (and a NULL buffer pointer) if there is no label.
|
||||||
|
*/
|
||||||
|
static int smack_key_getsecurity(struct key *key, char **_buffer)
|
||||||
|
{
|
||||||
|
struct smack_known *skp = key->security;
|
||||||
|
size_t length;
|
||||||
|
char *copy;
|
||||||
|
|
||||||
|
if (key->security == NULL) {
|
||||||
|
*_buffer = NULL;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
copy = kstrdup(skp->smk_known, GFP_KERNEL);
|
||||||
|
if (copy == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
length = strlen(copy) + 1;
|
||||||
|
|
||||||
|
*_buffer = copy;
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_KEYS */
|
#endif /* CONFIG_KEYS */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -4310,6 +4392,7 @@ struct security_operations smack_ops = {
|
||||||
.key_alloc = smack_key_alloc,
|
.key_alloc = smack_key_alloc,
|
||||||
.key_free = smack_key_free,
|
.key_free = smack_key_free,
|
||||||
.key_permission = smack_key_permission,
|
.key_permission = smack_key_permission,
|
||||||
|
.key_getsecurity = smack_key_getsecurity,
|
||||||
#endif /* CONFIG_KEYS */
|
#endif /* CONFIG_KEYS */
|
||||||
|
|
||||||
/* Audit hooks */
|
/* Audit hooks */
|
||||||
|
|
|
@ -54,6 +54,9 @@ enum smk_inos {
|
||||||
SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
|
SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
|
||||||
SMK_SYSLOG = 20, /* change syslog label) */
|
SMK_SYSLOG = 20, /* change syslog label) */
|
||||||
SMK_PTRACE = 21, /* set ptrace rule */
|
SMK_PTRACE = 21, /* set ptrace rule */
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
SMK_UNCONFINED = 22, /* define an unconfined label */
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -61,7 +64,6 @@ enum smk_inos {
|
||||||
*/
|
*/
|
||||||
static DEFINE_MUTEX(smack_cipso_lock);
|
static DEFINE_MUTEX(smack_cipso_lock);
|
||||||
static DEFINE_MUTEX(smack_ambient_lock);
|
static DEFINE_MUTEX(smack_ambient_lock);
|
||||||
static DEFINE_MUTEX(smack_syslog_lock);
|
|
||||||
static DEFINE_MUTEX(smk_netlbladdr_lock);
|
static DEFINE_MUTEX(smk_netlbladdr_lock);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -95,6 +97,16 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
|
||||||
*/
|
*/
|
||||||
struct smack_known *smack_onlycap;
|
struct smack_known *smack_onlycap;
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
/*
|
||||||
|
* Allow one label to be unconfined. This is for
|
||||||
|
* debugging and application bring-up purposes only.
|
||||||
|
* It is bad and wrong, but everyone seems to expect
|
||||||
|
* to have it.
|
||||||
|
*/
|
||||||
|
struct smack_known *smack_unconfined;
|
||||||
|
#endif
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If this value is set restrict syslog use to the label specified.
|
* If this value is set restrict syslog use to the label specified.
|
||||||
* It can be reset via smackfs/syslog
|
* It can be reset via smackfs/syslog
|
||||||
|
@ -1717,6 +1729,85 @@ static const struct file_operations smk_onlycap_ops = {
|
||||||
.llseek = default_llseek,
|
.llseek = default_llseek,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
/**
|
||||||
|
* smk_read_unconfined - read() for smackfs/unconfined
|
||||||
|
* @filp: file pointer, not actually used
|
||||||
|
* @buf: where to put the result
|
||||||
|
* @cn: maximum to send along
|
||||||
|
* @ppos: where to start
|
||||||
|
*
|
||||||
|
* Returns number of bytes read or error code, as appropriate
|
||||||
|
*/
|
||||||
|
static ssize_t smk_read_unconfined(struct file *filp, char __user *buf,
|
||||||
|
size_t cn, loff_t *ppos)
|
||||||
|
{
|
||||||
|
char *smack = "";
|
||||||
|
ssize_t rc = -EINVAL;
|
||||||
|
int asize;
|
||||||
|
|
||||||
|
if (*ppos != 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (smack_unconfined != NULL)
|
||||||
|
smack = smack_unconfined->smk_known;
|
||||||
|
|
||||||
|
asize = strlen(smack) + 1;
|
||||||
|
|
||||||
|
if (cn >= asize)
|
||||||
|
rc = simple_read_from_buffer(buf, cn, ppos, smack, asize);
|
||||||
|
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* smk_write_unconfined - write() for smackfs/unconfined
|
||||||
|
* @file: file pointer, not actually used
|
||||||
|
* @buf: where to get the data from
|
||||||
|
* @count: bytes sent
|
||||||
|
* @ppos: where to start
|
||||||
|
*
|
||||||
|
* Returns number of bytes written or error code, as appropriate
|
||||||
|
*/
|
||||||
|
static ssize_t smk_write_unconfined(struct file *file, const char __user *buf,
|
||||||
|
size_t count, loff_t *ppos)
|
||||||
|
{
|
||||||
|
char *data;
|
||||||
|
int rc = count;
|
||||||
|
|
||||||
|
if (!smack_privileged(CAP_MAC_ADMIN))
|
||||||
|
return -EPERM;
|
||||||
|
|
||||||
|
data = kzalloc(count + 1, GFP_KERNEL);
|
||||||
|
if (data == NULL)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Should the null string be passed in unset the unconfined value.
|
||||||
|
* This seems like something to be careful with as usually
|
||||||
|
* smk_import only expects to return NULL for errors. It
|
||||||
|
* is usually the case that a nullstring or "\n" would be
|
||||||
|
* bad to pass to smk_import but in fact this is useful here.
|
||||||
|
*
|
||||||
|
* smk_import will also reject a label beginning with '-',
|
||||||
|
* so "-confine" will also work.
|
||||||
|
*/
|
||||||
|
if (copy_from_user(data, buf, count) != 0)
|
||||||
|
rc = -EFAULT;
|
||||||
|
else
|
||||||
|
smack_unconfined = smk_import_entry(data, count);
|
||||||
|
|
||||||
|
kfree(data);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct file_operations smk_unconfined_ops = {
|
||||||
|
.read = smk_read_unconfined,
|
||||||
|
.write = smk_write_unconfined,
|
||||||
|
.llseek = default_llseek,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_SECURITY_SMACK_BRINGUP */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* smk_read_logging - read() for /smack/logging
|
* smk_read_logging - read() for /smack/logging
|
||||||
* @filp: file pointer, not actually used
|
* @filp: file pointer, not actually used
|
||||||
|
@ -2384,6 +2475,10 @@ static int smk_fill_super(struct super_block *sb, void *data, int silent)
|
||||||
"syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
|
"syslog", &smk_syslog_ops, S_IRUGO|S_IWUSR},
|
||||||
[SMK_PTRACE] = {
|
[SMK_PTRACE] = {
|
||||||
"ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
|
"ptrace", &smk_ptrace_ops, S_IRUGO|S_IWUSR},
|
||||||
|
#ifdef CONFIG_SECURITY_SMACK_BRINGUP
|
||||||
|
[SMK_UNCONFINED] = {
|
||||||
|
"unconfined", &smk_unconfined_ops, S_IRUGO|S_IWUSR},
|
||||||
|
#endif
|
||||||
/* last one */
|
/* last one */
|
||||||
{""}
|
{""}
|
||||||
};
|
};
|
||||||
|
|
Loading…
Add table
Reference in a new issue