diff options
| author | James Morris <james.l.morris@oracle.com> | 2014-08-02 08:58:02 -0400 |
|---|---|---|
| committer | James Morris <james.l.morris@oracle.com> | 2014-08-02 08:58:02 -0400 |
| commit | 103ae675b12dee75ec099abf3d22857d1384b3bc (patch) | |
| tree | a6b4f71bc911e7283b6573ee5833cd36a3ac2469 /security | |
| parent | a3d64df849bcb84220bf6db5773a10eee1fad4dc (diff) | |
| parent | 4fbe63d1c773cceef3fe1f6ed0c9c268f4f24760 (diff) | |
Merge branch 'next' of git://git.infradead.org/users/pcmoore/selinux into next
Diffstat (limited to 'security')
| -rw-r--r-- | security/selinux/ss/ebitmap.c | 133 | ||||
| -rw-r--r-- | security/selinux/ss/ebitmap.h | 8 | ||||
| -rw-r--r-- | security/smack/smack_access.c | 11 | ||||
| -rw-r--r-- | security/smack/smack_lsm.c | 6 | ||||
| -rw-r--r-- | security/smack/smackfs.c | 14 |
5 files changed, 70 insertions, 102 deletions
diff --git a/security/selinux/ss/ebitmap.c b/security/selinux/ss/ebitmap.c index 820313a04d49..afe6a269ec17 100644 --- a/security/selinux/ss/ebitmap.c +++ b/security/selinux/ss/ebitmap.c | |||
| @@ -86,51 +86,36 @@ int ebitmap_cpy(struct ebitmap *dst, struct ebitmap *src) | |||
| 86 | * | 86 | * |
| 87 | */ | 87 | */ |
| 88 | int ebitmap_netlbl_export(struct ebitmap *ebmap, | 88 | int ebitmap_netlbl_export(struct ebitmap *ebmap, |
| 89 | struct netlbl_lsm_secattr_catmap **catmap) | 89 | struct netlbl_lsm_catmap **catmap) |
| 90 | { | 90 | { |
| 91 | struct ebitmap_node *e_iter = ebmap->node; | 91 | struct ebitmap_node *e_iter = ebmap->node; |
| 92 | struct netlbl_lsm_secattr_catmap *c_iter; | 92 | unsigned long e_map; |
| 93 | u32 cmap_idx, cmap_sft; | 93 | u32 offset; |
| 94 | int i; | 94 | unsigned int iter; |
| 95 | 95 | int rc; | |
| 96 | /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, | ||
| 97 | * however, it is not always compatible with an array of unsigned long | ||
| 98 | * in ebitmap_node. | ||
| 99 | * In addition, you should pay attention the following implementation | ||
| 100 | * assumes unsigned long has a width equal with or less than 64-bit. | ||
| 101 | */ | ||
| 102 | 96 | ||
| 103 | if (e_iter == NULL) { | 97 | if (e_iter == NULL) { |
| 104 | *catmap = NULL; | 98 | *catmap = NULL; |
| 105 | return 0; | 99 | return 0; |
| 106 | } | 100 | } |
| 107 | 101 | ||
| 108 | c_iter = netlbl_secattr_catmap_alloc(GFP_ATOMIC); | 102 | if (*catmap != NULL) |
| 109 | if (c_iter == NULL) | 103 | netlbl_catmap_free(*catmap); |
| 110 | return -ENOMEM; | 104 | *catmap = NULL; |
| 111 | *catmap = c_iter; | ||
| 112 | c_iter->startbit = e_iter->startbit & ~(NETLBL_CATMAP_SIZE - 1); | ||
| 113 | 105 | ||
| 114 | while (e_iter) { | 106 | while (e_iter) { |
| 115 | for (i = 0; i < EBITMAP_UNIT_NUMS; i++) { | 107 | offset = e_iter->startbit; |
| 116 | unsigned int delta, e_startbit, c_endbit; | 108 | for (iter = 0; iter < EBITMAP_UNIT_NUMS; iter++) { |
| 117 | 109 | e_map = e_iter->maps[iter]; | |
| 118 | e_startbit = e_iter->startbit + i * EBITMAP_UNIT_SIZE; | 110 | if (e_map != 0) { |
| 119 | c_endbit = c_iter->startbit + NETLBL_CATMAP_SIZE; | 111 | rc = netlbl_catmap_setlong(catmap, |
| 120 | if (e_startbit >= c_endbit) { | 112 | offset, |
| 121 | c_iter->next | 113 | e_map, |
| 122 | = netlbl_secattr_catmap_alloc(GFP_ATOMIC); | 114 | GFP_ATOMIC); |
| 123 | if (c_iter->next == NULL) | 115 | if (rc != 0) |
| 124 | goto netlbl_export_failure; | 116 | goto netlbl_export_failure; |
| 125 | c_iter = c_iter->next; | ||
| 126 | c_iter->startbit | ||
| 127 | = e_startbit & ~(NETLBL_CATMAP_SIZE - 1); | ||
| 128 | } | 117 | } |
| 129 | delta = e_startbit - c_iter->startbit; | 118 | offset += EBITMAP_UNIT_SIZE; |
| 130 | cmap_idx = delta / NETLBL_CATMAP_MAPSIZE; | ||
| 131 | cmap_sft = delta % NETLBL_CATMAP_MAPSIZE; | ||
| 132 | c_iter->bitmap[cmap_idx] | ||
| 133 | |= e_iter->maps[i] << cmap_sft; | ||
| 134 | } | 119 | } |
| 135 | e_iter = e_iter->next; | 120 | e_iter = e_iter->next; |
| 136 | } | 121 | } |
| @@ -138,7 +123,7 @@ int ebitmap_netlbl_export(struct ebitmap *ebmap, | |||
| 138 | return 0; | 123 | return 0; |
| 139 | 124 | ||
| 140 | netlbl_export_failure: | 125 | netlbl_export_failure: |
| 141 | netlbl_secattr_catmap_free(*catmap); | 126 | netlbl_catmap_free(*catmap); |
| 142 | return -ENOMEM; | 127 | return -ENOMEM; |
| 143 | } | 128 | } |
| 144 | 129 | ||
| @@ -153,58 +138,44 @@ netlbl_export_failure: | |||
| 153 | * | 138 | * |
| 154 | */ | 139 | */ |
| 155 | int ebitmap_netlbl_import(struct ebitmap *ebmap, | 140 | int ebitmap_netlbl_import(struct ebitmap *ebmap, |
| 156 | struct netlbl_lsm_secattr_catmap *catmap) | 141 | struct netlbl_lsm_catmap *catmap) |
| 157 | { | 142 | { |
| 143 | int rc; | ||
| 158 | struct ebitmap_node *e_iter = NULL; | 144 | struct ebitmap_node *e_iter = NULL; |
| 159 | struct ebitmap_node *emap_prev = NULL; | 145 | struct ebitmap_node *e_prev = NULL; |
| 160 | struct netlbl_lsm_secattr_catmap *c_iter = catmap; | 146 | u32 offset = 0, idx; |
| 161 | u32 c_idx, c_pos, e_idx, e_sft; | 147 | unsigned long bitmap; |
| 162 | 148 | ||
| 163 | /* NetLabel's NETLBL_CATMAP_MAPTYPE is defined as an array of u64, | 149 | for (;;) { |
| 164 | * however, it is not always compatible with an array of unsigned long | 150 | rc = netlbl_catmap_getlong(catmap, &offset, &bitmap); |
| 165 | * in ebitmap_node. | 151 | if (rc < 0) |
| 166 | * In addition, you should pay attention the following implementation | 152 | goto netlbl_import_failure; |
| 167 | * assumes unsigned long has a width equal with or less than 64-bit. | 153 | if (offset == (u32)-1) |
| 168 | */ | 154 | return 0; |
| 169 | |||
| 170 | do { | ||
| 171 | for (c_idx = 0; c_idx < NETLBL_CATMAP_MAPCNT; c_idx++) { | ||
| 172 | unsigned int delta; | ||
| 173 | u64 map = c_iter->bitmap[c_idx]; | ||
| 174 | |||
| 175 | if (!map) | ||
| 176 | continue; | ||
| 177 | 155 | ||
| 178 | c_pos = c_iter->startbit | 156 | if (e_iter == NULL || |
| 179 | + c_idx * NETLBL_CATMAP_MAPSIZE; | 157 | offset >= e_iter->startbit + EBITMAP_SIZE) { |
| 180 | if (!e_iter | 158 | e_prev = e_iter; |
| 181 | || c_pos >= e_iter->startbit + EBITMAP_SIZE) { | 159 | e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); |
| 182 | e_iter = kzalloc(sizeof(*e_iter), GFP_ATOMIC); | 160 | if (e_iter == NULL) |
| 183 | if (!e_iter) | 161 | goto netlbl_import_failure; |
| 184 | goto netlbl_import_failure; | 162 | e_iter->startbit = offset & ~(EBITMAP_SIZE - 1); |
| 185 | e_iter->startbit | 163 | if (e_prev == NULL) |
| 186 | = c_pos - (c_pos % EBITMAP_SIZE); | 164 | ebmap->node = e_iter; |
| 187 | if (emap_prev == NULL) | 165 | else |
| 188 | ebmap->node = e_iter; | 166 | e_prev->next = e_iter; |
| 189 | else | 167 | ebmap->highbit = e_iter->startbit + EBITMAP_SIZE; |
| 190 | emap_prev->next = e_iter; | ||
| 191 | emap_prev = e_iter; | ||
| 192 | } | ||
| 193 | delta = c_pos - e_iter->startbit; | ||
| 194 | e_idx = delta / EBITMAP_UNIT_SIZE; | ||
| 195 | e_sft = delta % EBITMAP_UNIT_SIZE; | ||
| 196 | while (map) { | ||
| 197 | e_iter->maps[e_idx++] |= map & (-1UL); | ||
| 198 | map = EBITMAP_SHIFT_UNIT_SIZE(map); | ||
| 199 | } | ||
| 200 | } | 168 | } |
| 201 | c_iter = c_iter->next; | ||
| 202 | } while (c_iter); | ||
| 203 | if (e_iter != NULL) | ||
| 204 | ebmap->highbit = e_iter->startbit + EBITMAP_SIZE; | ||
| 205 | else | ||
| 206 | ebitmap_destroy(ebmap); | ||
| 207 | 169 | ||
| 170 | /* offset will always be aligned to an unsigned long */ | ||
| 171 | idx = EBITMAP_NODE_INDEX(e_iter, offset); | ||
| 172 | e_iter->maps[idx] = bitmap; | ||
| 173 | |||
| 174 | /* next */ | ||
| 175 | offset += EBITMAP_UNIT_SIZE; | ||
| 176 | } | ||
| 177 | |||
| 178 | /* NOTE: we should never reach this return */ | ||
| 208 | return 0; | 179 | return 0; |
| 209 | 180 | ||
| 210 | netlbl_import_failure: | 181 | netlbl_import_failure: |
