Merge remote-tracking branch 'tizen/upstream' into tizen 24/33424/1
authorRafal Krypa <r.krypa@samsung.com>
Fri, 9 Jan 2015 10:41:44 +0000 (11:41 +0100)
committerRafal Krypa <r.krypa@samsung.com>
Fri, 9 Jan 2015 10:42:38 +0000 (11:42 +0100)
Change-Id: Ib8d978e8e9f223c8b76b52e6e0e04ce0949cf5a2

1  2 
libsmack/libsmack.c

diff --combined libsmack/libsmack.c
@@@ -30,7 -30,6 +30,7 @@@
  #include <sys/socket.h>
  #include <sys/stat.h>
  #include <sys/types.h>
 +#include <sys/xattr.h>
  #include <unistd.h>
  #include <sys/xattr.h>
  
  #define LEVEL_MAX 255
  #define NUM_LEN 4
  #define BUF_SIZE 512
- #define CAT_MAX_COUNT 240
- #define CAT_MAX_VALUE 63
+ #define CAT_MAX_COUNT 184
  #define CIPSO_POS(i)   (SMACK_LABEL_LEN + 1 + NUM_LEN + NUM_LEN + i * NUM_LEN)
  #define CIPSO_MAX_SIZE CIPSO_POS(CAT_MAX_COUNT)
  #define CIPSO_NUM_LEN_STR "%-4d"
  
+ #define BITMASK(b)    (1 << ((b) & 7))
+ #define BITSLOT(b)    ((b) >> 3)
+ #define BITSET(a, b)  ((a)[BITSLOT(b)] |= BITMASK(b))
+ #define BITTEST(a, b) ((a)[BITSLOT(b)] & BITMASK(b))
+ #define BITNSLOTS(nb) ((nb + 7) >> 3)
  #define ACCESS_TYPE_R 0x01
  #define ACCESS_TYPE_W 0x02
  #define ACCESS_TYPE_X 0x04
@@@ -109,7 -113,7 +114,7 @@@ struct smack_accesses 
  
  struct cipso_mapping {
        char label[SMACK_LABEL_LEN + 1];
-       int cats[CAT_MAX_VALUE];
+       uint8_t cats[BITNSLOTS(CAT_MAX_COUNT)];
        int ncats;
        int level;
        struct cipso_mapping *next;
@@@ -121,12 -125,6 +126,12 @@@ struct smack_cipso 
        struct cipso_mapping *last;
  };
  
 +typedef int (*getxattr_func)(void*, const char*, void*, size_t);
 +typedef int (*setxattr_func)(const void*, const char*, const void*, size_t, int);
 +typedef int (*removexattr_func)(void*, const char*);
 +
 +static inline char* get_xattr_name(enum smack_label_type type);
 +
  struct smack_file_buffer {
        int fd;
        int pos;
@@@ -470,9 -468,11 +475,11 @@@ int smack_cipso_apply(struct smack_cips
                sprintf(&buf[offset], CIPSO_NUM_LEN_STR, m->ncats);
                offset += NUM_LEN;
  
-               for (i = 0; i < m->ncats; i++){
-                       sprintf(&buf[offset], CIPSO_NUM_LEN_STR, m->cats[i]);
-                       offset += NUM_LEN;
+               for (i = 0; i < CAT_MAX_COUNT; i++) {
+                       if (BITTEST(m->cats, i)) {
+                               sprintf(&buf[offset], CIPSO_NUM_LEN_STR, i + 1);
+                               offset += NUM_LEN;
+                       }
                }
  
                if (write(fd, buf, offset) < 0) {
@@@ -539,16 -539,17 +546,17 @@@ int smack_cipso_add_from_file(struct sm
                        if (errno)
                                goto err_out;
  
-                       if (val < 0 || val > CAT_MAX_VALUE)
+                       if (val <= 0 || val > CAT_MAX_COUNT)
                                goto err_out;
  
-                       mapping->cats[i] = val;
+                       if (!BITTEST(mapping->cats, val - 1)) {
+                               BITSET(mapping->cats, val - 1);
+                               ++(mapping->ncats);
+                       }
  
                        cat = strtok_r(NULL, " \t\n", &ptr);
                }
  
-               mapping->ncats = i;
                if (cipso->first == NULL) {
                        cipso->first = cipso->last = mapping;
                } else {
@@@ -697,99 -698,6 +705,99 @@@ int smack_revoke_subject(const char *su
        return (ret < 0) ? -1 : 0;
  }
  
 +static int internal_getlabel(void* file, char** label,
 +              enum smack_label_type type,
 +              getxattr_func getfunc)
 +{
 +      char* xattr_name = get_xattr_name(type);
 +      char value[SMACK_LABEL_LEN + 1];
 +      int ret;
 +
 +      ret = getfunc(file, xattr_name, value, SMACK_LABEL_LEN + 1);
 +      if (ret == -1) {
 +              if (errno == ENODATA) {
 +                      *label = NULL;
 +                      return 0;
 +              }
 +              return -1;
 +      }
 +
 +      value[ret] = '\0';
 +      *label = calloc(ret + 1, 1);
 +      if (*label == NULL)
 +              return -1;
 +      strncpy(*label, value, ret);
 +      return 0;
 +}
 +
 +static int internal_setlabel(void* file, const char* label,
 +              enum smack_label_type type,
 +              setxattr_func setfunc, removexattr_func removefunc)
 +{
 +      char* xattr_name = get_xattr_name(type);
 +
 +      /* Check validity of labels for LABEL_TRANSMUTE */
 +      if (type == SMACK_LABEL_TRANSMUTE && label != NULL) {
 +              if (!strcmp(label, "0"))
 +                      label = NULL;
 +              else if (!strcmp(label, "1"))
 +                      label = "TRUE";
 +              else
 +                      return -1;
 +      }
 +
 +      if (label == NULL || label[0] == '\0') {
 +              return removefunc(file, xattr_name);
 +      } else {
 +              int len = strnlen(label, SMACK_LABEL_LEN + 1);
 +              if (len > SMACK_LABEL_LEN)
 +                      return -1;
 +              return setfunc(file, xattr_name, label, len, 0);
 +      }
 +}
 +
 +int smack_getlabel(const char *path, char** label,
 +              enum smack_label_type type)
 +{
 +      return internal_getlabel((void*) path, label, type,
 +                      (getxattr_func) getxattr);
 +}
 +
 +int smack_lgetlabel(const char *path, char** label,
 +              enum smack_label_type type)
 +{
 +      return internal_getlabel((void*) path, label, type,
 +                      (getxattr_func) lgetxattr);
 +}
 +
 +int smack_fgetlabel(int fd, char** label,
 +              enum smack_label_type type)
 +{
 +      return internal_getlabel((void*) ((unsigned long) fd), label, type,
 +                      (getxattr_func) fgetxattr);
 +}
 +
 +int smack_setlabel(const char *path, const char* label,
 +              enum smack_label_type type)
 +{
 +      return internal_setlabel((void*) path, label, type,
 +                      (setxattr_func) setxattr, (removexattr_func) removexattr);
 +}
 +
 +int smack_lsetlabel(const char *path, const char* label,
 +              enum smack_label_type type)
 +{
 +      return internal_setlabel((void*) path, label, type,
 +                      (setxattr_func) lsetxattr, (removexattr_func) lremovexattr);
 +}
 +
 +int smack_fsetlabel(int fd, const char* label,
 +              enum smack_label_type type)
 +{
 +      return internal_setlabel((void*) ((unsigned long) fd), label, type,
 +                      (setxattr_func) fsetxattr, (removexattr_func) fremovexattr);
 +}
 +
  static int open_smackfs_file(const char *long_name, const char *short_name,
                             mode_t mode, int *use_long)
  {
@@@ -1111,27 -1019,6 +1119,27 @@@ static inline void access_code_to_str(u
        str[6] = '\0';
  }
  
 +static inline char* get_xattr_name(enum smack_label_type type)
 +{
 +      switch (type) {
 +      case SMACK_LABEL_ACCESS:
 +              return "security.SMACK64";
 +      case SMACK_LABEL_EXEC:
 +              return "security.SMACK64EXEC";
 +      case SMACK_LABEL_MMAP:
 +              return "security.SMACK64MMAP";
 +      case SMACK_LABEL_TRANSMUTE:
 +              return "security.SMACK64TRANSMUTE";
 +      case SMACK_LABEL_IPIN:
 +              return "security.SMACK64IPIN";
 +      case SMACK_LABEL_IPOUT:
 +              return "security.SMACK64IPOUT";
 +      default:
 +              /* Should not reach this point */
 +              return NULL;
 +      }
 +}
 +
  static inline struct smack_label *
  is_label_known(struct smack_accesses *handle, const char *label, int hash)
  {