Add smack_label_length() function
authorJanusz Kozerski <j.kozerski@samsung.com>
Wed, 2 Oct 2013 07:52:23 +0000 (09:52 +0200)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Fri, 25 Oct 2013 12:37:07 +0000 (15:37 +0300)
Kernel does not validate the Smack label - instead the label will be
cut on the first incorrect character (after parsing at least one
correct character).

This function gives the user possibility to verify the correctness
of the Smack label before use and calculate labels length.

Additionally, all string length calculations are replaces with this
function to make implementation safer.

[jarkko.sakkinen@linux.intel.com:
 did some modifications:
 - smack_is_label_valid() -> smack_label_length()
 - libsmack.c:
   * return length
   * loop invariant had off-by-one error
   * cosmetic: "++i" not "i++"
 - libsmack.h:
   * updated documentation
   * cosmetic: formatting errors in  @param and @return]
(cherry picked from commit 8b083a8c67219c5d1dbfbf2ad1082c1954f9c9fa)

doc/Makefile.am
doc/smack_have_access.3
doc/smack_label_length.3 [new file with mode: 0644]
libsmack/libsmack.c
libsmack/libsmack.sym
libsmack/sys/smack.h

index 37dc95a..2cc31e6 100644 (file)
@@ -34,6 +34,7 @@ man_MANS = smackaccess.1 \
           smack_new_label_from_socket.3 \
           smack_new_label_from_path.3 \
           smack_set_label_for_self.3 \
+          smack_label_length.3 \
           smack_revoke_subject.3 \
           chsmack.8 \
           smackcipso.8 \
index 2f6e535..a517d2e 100644 (file)
@@ -19,7 +19,7 @@
 .\"
 .TH "SMACK_HAVE_ACCESS" "3" "06/20/2012" "Libsmack 1\&.0"
 .SH NAME
-smack_have_access, smack_new_label_from_self, smack_new_label_from_socket \- Userspace interaction with Smack
+smack_have_access, smack_new_label_from_self, smack_new_label_from_socket, smack_label_length \- Userspace interaction with Smack
 .SH SYNOPSIS
 .B #include <sys/smack.h>
 .sp
@@ -30,6 +30,8 @@ smack_have_access, smack_new_label_from_self, smack_new_label_from_socket \- Use
 .BI "int smack_set_label_for_self(char **" label ");"
 .br
 .BI "int smack_new_label_from_socket(int " fd ", char **" label ");"
+.br
+.BI "int smack_label_length(const char *" label ");"
 .sp
 .SH DESCRIPTION
 Smack is a Mandatory Access Control (MAC) based security mechanism for the Linux kernel.  It works on the basis of context, which is stored as a label in the extended attributes (xattr) of a file.  When a process is started the kernel ensures that this context is assigned to the running process.  By default a process can only interact with processes and filesystem objects that have the same context as itself and is denied access to all other contexts.  Rules can be created to grant access to other contexts, these are generally created on package installation and can only be modified by a process that has the CAP_MAC_ADMIN capability.
@@ -72,6 +74,11 @@ of the socket and determines it's context and creates a new storage for this whi
 on return.  It is the callers responsibility to free
 .I label
 when it is no longer required.
+.PP
+.BR smack_label_length ()
+calculates length of
+.IR label ,
+and validates it.
 .SH RETURN VALUE
 .BR smack_new_label_from_self ()
 and
@@ -84,3 +91,8 @@ is set appropriately).
 returns 1 if allowed, 0 if no access and \-1 on error (in which case,
 .I errno
 is set appropriately).
+
+.BR smack_label_length ()
+returns length of
+.I label
+if it is valid and negative value if it's not.
diff --git a/doc/smack_label_length.3 b/doc/smack_label_length.3
new file mode 100644 (file)
index 0000000..5040587
--- /dev/null
@@ -0,0 +1 @@
+.so man3/smack_have_access.3
index 1adc68e..1a29cdc 100644 (file)
@@ -739,4 +739,25 @@ static inline void parse_access_type(const char *in, char out[ACC_LEN + 1])
                }
 }
 
+int smack_label_length(const char *label)
+{
+       int i;
+
+       if (!label || label[0] == '\0' || label[0] == '-')
+               return 0;
+
+       for (i = 0; i < (SMACK_LABEL_LEN + 1) && label[i]; i++) {
+               switch (label[i]) {
+               case ' ':
+               case '/':
+               case '"':
+               case '\\':
+               case '\'':
+                       return -1;
+               default:
+                       break;
+               }
+       }
 
+       return i < (SMACK_LABEL_LEN + 1) ? i : -1;
+}
index acd8dc0..f0a49d3 100644 (file)
@@ -22,3 +22,10 @@ global:
 local:
        *;
 };
+
+LIBSMACK_1.1 {
+global:
+       smack_label_length;
+local:
+       *;
+} LIBSMACK_1.0;
index 912c769..61c37d9 100644 (file)
@@ -246,6 +246,14 @@ int smack_set_label_for_self(const char *label);
  */
 int smack_revoke_subject(const char *subject);
 
+/*!
+ * Validate a SMACK label and calculate its length.
+ *
+ * @param label label to verify
+ * @return Returns length of the label on success and negative on failure.
+ */
+int smack_label_length(const char *label);
+
 #ifdef __cplusplus
 }
 #endif