mirror of
https://github.com/torvalds/linux
synced 2024-11-05 18:23:50 +00:00
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
|
||||
|
||||
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
|
||||
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
|
||||
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:
|
||||
|
||||
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
|
||||
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
|
||||
# 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
|
||||
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
|
||||
in the smackfs filesystem. This pseudo-filesystem is usually
|
||||
mounted on /smack.
|
||||
in the smackfs filesystem. This pseudo-filesystem is mounted
|
||||
on /sys/fs/smackfs.
|
||||
|
||||
access
|
||||
This interface reports whether a subject with the specified
|
||||
|
@ -206,23 +213,30 @@ onlycap
|
|||
file or cleared by writing "-" to the file.
|
||||
ptrace
|
||||
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
|
||||
object. For the PTRACE_ATTACH a read-write access is required.
|
||||
1 - exact: this is the policy that limits PTRACE_ATTACH. Attach is
|
||||
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
|
||||
exception that it can't be overriden with CAP_SYS_PTRACE.
|
||||
exception that it can't be overridden with CAP_SYS_PTRACE.
|
||||
revoke-subject
|
||||
Writing a Smack label here sets the access to '-' for all access
|
||||
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:
|
||||
|
||||
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
|
||||
object with objectlabel. If there is no rule no access is allowed.
|
||||
|
||||
|
@ -318,8 +332,9 @@ each of the subject and the object.
|
|||
|
||||
Labels
|
||||
|
||||
Smack labels are ASCII character strings, one to twenty-three characters in
|
||||
length. Single character labels using special characters, that being anything
|
||||
Smack labels are ASCII character strings. They can be up to 255 characters
|
||||
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
|
||||
team. Smack labels are unstructured, case sensitive, and the only operation
|
||||
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 "web", a single at sign character.
|
||||
|
||||
Every task on a Smack system is assigned a label. System tasks, such as
|
||||
init(8) and systems daemons, are run with the floor ("_") label. User tasks
|
||||
are assigned labels according to the specification found in the
|
||||
/etc/smack/user configuration file.
|
||||
Every task on a Smack system is assigned a label. The Smack label
|
||||
of a process will usually be assigned by the system initialization
|
||||
mechanism.
|
||||
|
||||
Access Rules
|
||||
|
||||
|
@ -393,6 +407,7 @@ describe access modes:
|
|||
w: indicates that write access should be granted.
|
||||
x: indicates that execute access should be granted.
|
||||
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.
|
||||
Access mode specifications can be in any order. Examples of acceptable rules
|
||||
|
@ -402,6 +417,7 @@ are:
|
|||
Secret Unclass R
|
||||
Manager Game x
|
||||
User HR w
|
||||
Snap Crackle rwxatb
|
||||
New Old rRrRr
|
||||
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
|
||||
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
|
||||
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
|
||||
|
||||
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.
|
||||
Rules can be written to /smack/load at any time and take effect immediately.
|
||||
For any pair of subject and object labels there can be only 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.
|
||||
system startup. The contents are written to the special file
|
||||
/sys/fs/smackfs/load2. Rules can be added at any time and take effect
|
||||
immediately. For any pair of subject and object labels there can be only
|
||||
one rule, with the most recently specified overriding any earlier
|
||||
specification.
|
||||
|
||||
Task Attribute
|
||||
|
||||
|
@ -488,7 +499,10 @@ only be changed by a process with 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
|
||||
|
||||
|
@ -510,14 +524,14 @@ intervention. Unlabeled packets that come into the system will be given the
|
|||
ambient label.
|
||||
|
||||
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.
|
||||
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
|
||||
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
|
||||
discarded. The DOI is 3 by default. The value can be read from /smack/doi and
|
||||
can be changed by writing to /smack/doi.
|
||||
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
|
||||
/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
|
||||
/etc/smack/cipso.
|
||||
|
@ -539,15 +553,13 @@ The ":" and "," characters are permitted in a Smack label but have no special
|
|||
meaning.
|
||||
|
||||
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
|
||||
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.
|
||||
/sys/fs/smackfs/cipso2.
|
||||
|
||||
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
|
||||
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
|
||||
|
||||
|
@ -565,8 +577,8 @@ sockets.
|
|||
Smack Netlabel Exceptions
|
||||
|
||||
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
|
||||
add some exceptions in the form of :
|
||||
unlabeled world. To do this there's a special file /sys/fs/smackfs/netlabel
|
||||
where you can add some exceptions in the form of :
|
||||
@IP1 LABEL1 or
|
||||
@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
|
||||
access on LABEL2.
|
||||
|
||||
Entries in the /smack/netlabel file are matched by longest mask first, like in
|
||||
classless IPv4 routing.
|
||||
Entries in the /sys/fs/smackfs/netlabel file are matched by longest mask
|
||||
first, like in classless IPv4 routing.
|
||||
|
||||
A special label '@' and an option '-CIPSO' can be used there :
|
||||
@ means Internet, any application with any label has access to it
|
||||
-CIPSO means standard CIPSO networking
|
||||
|
||||
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 0.0.0.0/0 @ > /smack/netlabel
|
||||
echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/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
|
||||
Internet access, you can have :
|
||||
echo 127.0.0.1 -CIPSO > /smack/netlabel
|
||||
echo 192.168.0.0/16 -CIPSO > /smack/netlabel
|
||||
echo 0.0.0.0/0 @ > /smack/netlabel
|
||||
echo 127.0.0.1 -CIPSO > /sys/fs/smackfs/netlabel
|
||||
echo 192.168.0.0/16 -CIPSO > /sys/fs/smackfs/netlabel
|
||||
echo 0.0.0.0/0 @ > /sys/fs/smackfs/netlabel
|
||||
|
||||
|
||||
Writing Applications for Smack
|
||||
|
@ -676,7 +688,7 @@ Smack auditing
|
|||
If you want Smack auditing of security events, you need to set CONFIG_AUDIT
|
||||
in your kernel configuration.
|
||||
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
|
||||
1 : log denied (default)
|
||||
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
|
||||
that triggered the event, plus other pairs depending on the type of event
|
||||
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_TRANSMUTE 0x02 /* directory is transmuting */
|
||||
#define SMK_INODE_CHANGED 0x04 /* smack was transmuted */
|
||||
#define SMK_INODE_IMPURE 0x08 /* involved in an impure transaction */
|
||||
|
||||
/*
|
||||
* A label access rule.
|
||||
|
@ -193,6 +194,10 @@ struct smk_port_label {
|
|||
#define MAY_LOCK 0x00002000 /* Locks should be writes, but ... */
|
||||
#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
|
||||
*/
|
||||
|
@ -254,6 +259,9 @@ extern int smack_cipso_mapped;
|
|||
extern struct smack_known *smack_net_ambient;
|
||||
extern struct smack_known *smack_onlycap;
|
||||
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 int smack_ptrace_rule;
|
||||
|
||||
|
|
|
@ -130,7 +130,8 @@ int smk_access(struct smack_known *subject, struct smack_known *object,
|
|||
|
||||
/*
|
||||
* Hardcoded comparisons.
|
||||
*
|
||||
*/
|
||||
/*
|
||||
* A star subject can't access any object.
|
||||
*/
|
||||
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.
|
||||
*/
|
||||
if (may & MAY_BRINGUP)
|
||||
rc = MAY_BRINGUP;
|
||||
rc = SMACK_BRINGUP_ALLOW;
|
||||
#endif
|
||||
|
||||
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
|
||||
if (a)
|
||||
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,
|
||||
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];
|
||||
#endif
|
||||
struct smack_audit_data *sad;
|
||||
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 */
|
||||
if (result != 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
|
||||
if (result < 0 && (log_policy & SMACK_AUDIT_DENIED) == 0)
|
||||
return;
|
||||
if (result == 0 && (log_policy & SMACK_AUDIT_ACCEPT) == 0)
|
||||
return;
|
||||
|
@ -364,6 +372,21 @@ void smack_log(char *subject_label, char *object_label, int request,
|
|||
smack_str_from_perm(request_buffer, request);
|
||||
sad->subject = subject_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->result = result;
|
||||
|
||||
|
|
|
@ -57,6 +57,13 @@ static struct kmem_cache *smack_inode_cache;
|
|||
int smack_enabled;
|
||||
|
||||
#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)
|
||||
{
|
||||
int i = 0;
|
||||
|
@ -87,9 +94,11 @@ static int smk_bu_note(char *note, struct smack_known *sskp,
|
|||
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||
rc = 0;
|
||||
|
||||
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);
|
||||
return 0;
|
||||
}
|
||||
|
@ -106,9 +115,11 @@ static int smk_bu_current(char *note, struct smack_known *oskp,
|
|||
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||
rc = 0;
|
||||
|
||||
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,
|
||||
acc, current->comm, note);
|
||||
return 0;
|
||||
|
@ -126,9 +137,11 @@ static int smk_bu_task(struct task_struct *otp, int mode, int rc)
|
|||
|
||||
if (rc <= 0)
|
||||
return rc;
|
||||
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||
rc = 0;
|
||||
|
||||
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,
|
||||
current->comm, otp->comm);
|
||||
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)
|
||||
{
|
||||
struct task_smack *tsp = current_security();
|
||||
struct inode_smack *isp = inode->i_security;
|
||||
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)
|
||||
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);
|
||||
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);
|
||||
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 smack_known *sskp = tsp->smk_task;
|
||||
struct inode *inode = file_inode(file);
|
||||
struct inode_smack *isp = inode->i_security;
|
||||
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)
|
||||
return rc;
|
||||
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||
rc = 0;
|
||||
|
||||
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,
|
||||
inode->i_sb->s_id, inode->i_ino, file,
|
||||
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 smack_known *sskp = tsp->smk_task;
|
||||
struct inode *inode = file->f_inode;
|
||||
struct inode_smack *isp = inode->i_security;
|
||||
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)
|
||||
return rc;
|
||||
if (rc > SMACK_UNCONFINED_OBJECT)
|
||||
rc = 0;
|
||||
|
||||
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,
|
||||
inode->i_sb->s_id, inode->i_ino, file,
|
||||
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,
|
||||
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;
|
||||
/*
|
||||
* 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);
|
||||
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 */
|
||||
|
||||
/*
|
||||
|
@ -4310,6 +4392,7 @@ struct security_operations smack_ops = {
|
|||
.key_alloc = smack_key_alloc,
|
||||
.key_free = smack_key_free,
|
||||
.key_permission = smack_key_permission,
|
||||
.key_getsecurity = smack_key_getsecurity,
|
||||
#endif /* CONFIG_KEYS */
|
||||
|
||||
/* Audit hooks */
|
||||
|
|
|
@ -54,6 +54,9 @@ enum smk_inos {
|
|||
SMK_CHANGE_RULE = 19, /* change or add rules (long labels) */
|
||||
SMK_SYSLOG = 20, /* change syslog label) */
|
||||
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_ambient_lock);
|
||||
static DEFINE_MUTEX(smack_syslog_lock);
|
||||
static DEFINE_MUTEX(smk_netlbladdr_lock);
|
||||
|
||||
/*
|
||||
|
@ -95,6 +97,16 @@ int smack_cipso_mapped = SMACK_CIPSO_MAPPED_DEFAULT;
|
|||
*/
|
||||
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.
|
||||
* It can be reset via smackfs/syslog
|
||||
|
@ -1717,6 +1729,85 @@ static const struct file_operations smk_onlycap_ops = {
|
|||
.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
|
||||
* @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},
|
||||
[SMK_PTRACE] = {
|
||||
"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 */
|
||||
{""}
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue