Loading Documentation/security/Smack.txt +79 −50 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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. Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading @@ -402,6 +417,7 @@ are: Secret Unclass R Manager Game x User HR w Snap Crackle rwxatb New Old rRrRr Closed Off - Loading @@ -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. Loading Loading @@ -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 Loading @@ -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 Loading @@ -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. Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading @@ -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. security/smack/smack.h +8 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 */ Loading Loading @@ -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; Loading security/smack/smack_access.c +33 −10 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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, Loading Loading @@ -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; Loading @@ -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; Loading security/smack/smack_lsm.c +91 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading @@ -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); Loading @@ -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); Loading Loading @@ -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. Loading Loading @@ -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 */ /* Loading Loading @@ -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 */ Loading security/smack/smackfs.c +96 −1 Original line number Diff line number Diff line Loading @@ -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 }; /* Loading @@ -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); /* Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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 Loading
Documentation/security/Smack.txt +79 −50 Original line number Diff line number Diff line Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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. Loading Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading @@ -402,6 +417,7 @@ are: Secret Unclass R Manager Game x User HR w Snap Crackle rwxatb New Old rRrRr Closed Off - Loading @@ -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. Loading Loading @@ -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 Loading @@ -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 Loading @@ -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. Loading @@ -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 Loading @@ -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 Loading @@ -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 Loading Loading @@ -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 Loading @@ -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.
security/smack/smack.h +8 −0 Original line number Diff line number Diff line Loading @@ -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. Loading Loading @@ -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 */ Loading Loading @@ -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; Loading
security/smack/smack_access.c +33 −10 Original line number Diff line number Diff line Loading @@ -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) { Loading Loading @@ -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, Loading Loading @@ -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; Loading @@ -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; Loading
security/smack/smack_lsm.c +91 −8 Original line number Diff line number Diff line Loading @@ -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; Loading Loading @@ -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; } Loading @@ -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; Loading @@ -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; Loading @@ -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; } Loading @@ -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); Loading @@ -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); Loading Loading @@ -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. Loading Loading @@ -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 */ /* Loading Loading @@ -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 */ Loading
security/smack/smackfs.c +96 −1 Original line number Diff line number Diff line Loading @@ -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 }; /* Loading @@ -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); /* Loading Loading @@ -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 Loading Loading @@ -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 Loading Loading @@ -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