Skip to content

Commit 71430be

Browse files
committed
selinux: beef up isvalid checks
Check that an ID does not refer to a gap in the global array of definitions. Constify parameters of isvalid() function and change return type to bool. Signed-off-by: Christian Göttsche <cgzones@googlemail.com>
1 parent 3e48627 commit 71430be

File tree

8 files changed

+88
-62
lines changed

8 files changed

+88
-62
lines changed

security/selinux/ss/hashtab.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,11 @@ static inline int hashtab_insert(struct hashtab *h, void *key, void *datum,
9494
* Returns NULL if no entry has the specified key or
9595
* the datum of the entry otherwise.
9696
*/
97-
static inline void *hashtab_search(struct hashtab *h, const void *key,
97+
static inline void *hashtab_search(const struct hashtab *h, const void *key,
9898
struct hashtab_key_params key_params)
9999
{
100100
u32 hvalue;
101-
struct hashtab_node *cur;
101+
const struct hashtab_node *cur;
102102

103103
if (!h->size)
104104
return NULL;

security/selinux/ss/mls.c

Lines changed: 42 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
int mls_compute_context_len(struct policydb *p, struct context *context)
3333
{
3434
int i, l, len, head, prev;
35-
char *nm;
35+
const char *nm;
3636
struct ebitmap *e;
3737
struct ebitmap_node *node;
3838

@@ -86,7 +86,8 @@ int mls_compute_context_len(struct policydb *p, struct context *context)
8686
void mls_sid_to_context(struct policydb *p, struct context *context,
8787
char **scontext)
8888
{
89-
char *scontextp, *nm;
89+
const char *nm;
90+
char *scontextp;
9091
int i, l, head, prev;
9192
struct ebitmap *e;
9293
struct ebitmap_node *node;
@@ -155,60 +156,77 @@ void mls_sid_to_context(struct policydb *p, struct context *context,
155156
*scontext = scontextp;
156157
}
157158

158-
int mls_level_isvalid(struct policydb *p, struct mls_level *l)
159+
bool mls_level_isvalid(const struct policydb *p, const struct mls_level *l)
159160
{
160-
struct level_datum *levdatum;
161+
const char *name;
162+
const struct level_datum *levdatum;
163+
struct ebitmap_node *node;
164+
u32 bit;
165+
int rc;
161166

162167
if (!l->sens || l->sens > p->p_levels.nprim)
163-
return 0;
164-
levdatum = symtab_search(&p->p_levels,
165-
sym_name(p, SYM_LEVELS, l->sens - 1));
168+
return false;
169+
170+
name = sym_name(p, SYM_LEVELS, l->sens - 1);
171+
if (!name)
172+
return false;
173+
174+
levdatum = symtab_search(&p->p_levels, name);
166175
if (!levdatum)
167-
return 0;
176+
return false;
168177

169178
/*
170-
* Return 1 iff all the bits set in l->cat are also be set in
179+
* Validate that all bits set in l->cat are also be set in
171180
* levdatum->level->cat and no bit in l->cat is larger than
172181
* p->p_cats.nprim.
173182
*/
174-
return ebitmap_contains(&levdatum->level.cat, &l->cat,
175-
p->p_cats.nprim);
183+
rc = ebitmap_contains(&levdatum->level.cat, &l->cat,
184+
p->p_cats.nprim);
185+
if (!rc)
186+
return false;
187+
188+
ebitmap_for_each_positive_bit(&levdatum->level.cat, node, bit) {
189+
if (!sym_name(p, SYM_CATS, bit))
190+
return false;
191+
}
192+
193+
return true;
176194
}
177195

178-
int mls_range_isvalid(struct policydb *p, struct mls_range *r)
196+
bool mls_range_isvalid(const struct policydb *p, const struct mls_range *r)
179197
{
180198
return (mls_level_isvalid(p, &r->level[0]) &&
181199
mls_level_isvalid(p, &r->level[1]) &&
182200
mls_level_dom(&r->level[1], &r->level[0]));
183201
}
184202

185203
/*
186-
* Return 1 if the MLS fields in the security context
204+
* Return true if the MLS fields in the security context
187205
* structure `c' are valid. Return 0 otherwise.
188206
*/
189-
int mls_context_isvalid(struct policydb *p, struct context *c)
207+
bool mls_context_isvalid(const struct policydb *p, const struct context *c)
190208
{
191-
struct user_datum *usrdatum;
209+
const struct user_datum *usrdatum;
192210

193211
if (!p->mls_enabled)
194-
return 1;
212+
return true;
195213

196214
if (!mls_range_isvalid(p, &c->range))
197-
return 0;
215+
return false;
198216

199217
if (c->role == OBJECT_R_VAL)
200-
return 1;
218+
return true;
201219

202220
/*
203221
* User must be authorized for the MLS range.
204222
*/
205223
if (!c->user || c->user > p->p_users.nprim)
206-
return 0;
224+
return false;
207225
usrdatum = p->user_val_to_struct[c->user - 1];
208-
if (!mls_range_contains(usrdatum->range, c->range))
209-
return 0; /* user may not be associated with range */
226+
if (!usrdatum || !mls_range_contains(usrdatum->range, c->range))
227+
return false; /* user may not be associated with range */
210228

211-
return 1;
229+
return true;
212230
}
213231

214232
/*
@@ -449,8 +467,8 @@ int mls_convert_context(struct policydb *oldp, struct policydb *newp,
449467
return 0;
450468

451469
for (l = 0; l < 2; l++) {
452-
char *name = sym_name(oldp, SYM_LEVELS,
453-
oldc->range.level[l].sens - 1);
470+
const char *name = sym_name(oldp, SYM_LEVELS,
471+
oldc->range.level[l].sens - 1);
454472

455473
levdatum = symtab_search(&newp->p_levels, name);
456474

security/selinux/ss/mls.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@
2727
int mls_compute_context_len(struct policydb *p, struct context *context);
2828
void mls_sid_to_context(struct policydb *p, struct context *context,
2929
char **scontext);
30-
int mls_context_isvalid(struct policydb *p, struct context *c);
31-
int mls_range_isvalid(struct policydb *p, struct mls_range *r);
32-
int mls_level_isvalid(struct policydb *p, struct mls_level *l);
30+
bool mls_context_isvalid(const struct policydb *p, const struct context *c);
31+
bool mls_range_isvalid(const struct policydb *p, const struct mls_range *r);
32+
bool mls_level_isvalid(const struct policydb *p, const struct mls_level *l);
3333

3434
int mls_context_to_sid(struct policydb *p, char oldc, char *scontext,
3535
struct context *context, struct sidtab *s, u32 def_sid);

security/selinux/ss/policydb.c

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -923,51 +923,59 @@ int policydb_load_isids(struct policydb *p, struct sidtab *s)
923923
return 0;
924924
}
925925

926-
int policydb_class_isvalid(struct policydb *p, u16 class)
926+
bool policydb_class_isvalid(const struct policydb *p, u16 class)
927927
{
928928
if (!class || class > p->p_classes.nprim)
929-
return 0;
930-
return 1;
929+
return false;
930+
if (!p->sym_val_to_name[SYM_CLASSES][class - 1])
931+
return false;
932+
return true;
931933
}
932934

933-
int policydb_role_isvalid(struct policydb *p, unsigned int role)
935+
bool policydb_role_isvalid(const struct policydb *p, u32 role)
934936
{
935937
if (!role || role > p->p_roles.nprim)
936-
return 0;
937-
return 1;
938+
return false;
939+
if (!p->sym_val_to_name[SYM_ROLES][role - 1])
940+
return false;
941+
return true;
938942
}
939943

940-
int policydb_type_isvalid(struct policydb *p, unsigned int type)
944+
bool policydb_type_isvalid(const struct policydb *p, u32 type)
941945
{
942946
if (!type || type > p->p_types.nprim)
943-
return 0;
944-
return 1;
947+
return false;
948+
if (!p->sym_val_to_name[SYM_TYPES][type - 1])
949+
return false;
950+
return true;
945951
}
946952

947-
int policydb_boolean_isvalid(const struct policydb *p, u32 boolean)
953+
bool policydb_boolean_isvalid(const struct policydb *p, u32 boolean)
948954
{
949955
if (!boolean || boolean > p->p_bools.nprim)
950-
return 0;
951-
return 1;
956+
return false;
957+
if (!p->sym_val_to_name[SYM_BOOLS][boolean - 1])
958+
return false;
959+
return true;
952960
}
953961

954962
/*
955-
* Return 1 if the fields in the security context
963+
* Return true if the fields in the security context
956964
* structure `c' are valid. Return 0 otherwise.
957965
*/
958-
int policydb_context_isvalid(struct policydb *p, struct context *c)
966+
bool policydb_context_isvalid(const struct policydb *p, const struct context *c)
959967
{
960-
struct role_datum *role;
961-
struct user_datum *usrdatum;
968+
const struct role_datum *role;
969+
const struct user_datum *usrdatum;
962970

963971
if (!c->role || c->role > p->p_roles.nprim)
964-
return 0;
972+
return false;
965973

966974
if (!c->user || c->user > p->p_users.nprim)
967-
return 0;
975+
return false;
968976

969977
if (!c->type || c->type > p->p_types.nprim)
970-
return 0;
978+
return false;
971979

972980
if (c->role != OBJECT_R_VAL) {
973981
/*
@@ -976,24 +984,24 @@ int policydb_context_isvalid(struct policydb *p, struct context *c)
976984
role = p->role_val_to_struct[c->role - 1];
977985
if (!role || !ebitmap_get_bit(&role->types, c->type - 1))
978986
/* role may not be associated with type */
979-
return 0;
987+
return false;
980988

981989
/*
982990
* User must be authorized for the role.
983991
*/
984992
usrdatum = p->user_val_to_struct[c->user - 1];
985993
if (!usrdatum)
986-
return 0;
994+
return false;
987995

988996
if (!ebitmap_get_bit(&usrdatum->roles, c->role - 1))
989997
/* user may not be associated with role */
990-
return 0;
998+
return false;
991999
}
9921000

9931001
if (!mls_context_isvalid(p, c))
994-
return 0;
1002+
return false;
9951003

996-
return 1;
1004+
return true;
9971005
}
9981006

9991007
/*

security/selinux/ss/policydb.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -320,11 +320,11 @@ struct policy_file {
320320

321321
extern void policydb_destroy(struct policydb *p);
322322
extern int policydb_load_isids(struct policydb *p, struct sidtab *s);
323-
extern int policydb_context_isvalid(struct policydb *p, struct context *c);
324-
extern int policydb_class_isvalid(struct policydb *p, u16 class);
325-
extern int policydb_type_isvalid(struct policydb *p, unsigned int type);
326-
extern int policydb_role_isvalid(struct policydb *p, unsigned int role);
327-
extern int policydb_boolean_isvalid(const struct policydb *p, u32 boolean);
323+
extern bool policydb_context_isvalid(const struct policydb *p, const struct context *c);
324+
extern bool policydb_class_isvalid(const struct policydb *p, u16 class);
325+
extern bool policydb_type_isvalid(const struct policydb *p, u32 type);
326+
extern bool policydb_role_isvalid(const struct policydb *p, u32 role);
327+
extern bool policydb_boolean_isvalid(const struct policydb *p, u32 boolean);
328328
extern int policydb_read(struct policydb *p, struct policy_file *fp);
329329
extern int policydb_write(struct policydb *p, struct policy_file *fp);
330330

@@ -395,7 +395,7 @@ static inline int put_entry(const void *buf, size_t bytes, size_t num,
395395
return 0;
396396
}
397397

398-
static inline char *sym_name(struct policydb *p, unsigned int sym_num,
398+
static inline const char *sym_name(const struct policydb *p, unsigned int sym_num,
399399
unsigned int element_nr)
400400
{
401401
return p->sym_val_to_name[sym_num][element_nr];

security/selinux/ss/services.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -463,7 +463,7 @@ static void security_dump_masked_av(struct policydb *policydb,
463463
struct common_datum *common_dat;
464464
struct class_datum *tclass_dat;
465465
struct audit_buffer *ab;
466-
char *tclass_name;
466+
const char *tclass_name;
467467
char *scontext_name = NULL;
468468
char *tcontext_name = NULL;
469469
char *permission_names[SEL_VEC_MAX];

security/selinux/ss/symtab.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ int symtab_insert(struct symtab *s, char *name, void *datum)
5050
return hashtab_insert(&s->table, name, datum, symtab_key_params);
5151
}
5252

53-
void *symtab_search(struct symtab *s, const char *name)
53+
void *symtab_search(const struct symtab *s, const char *name)
5454
{
5555
return hashtab_search(&s->table, name, symtab_key_params);
5656
}

security/selinux/ss/symtab.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,6 @@ struct symtab {
2121
int symtab_init(struct symtab *s, u32 size);
2222

2323
int symtab_insert(struct symtab *s, char *name, void *datum);
24-
void *symtab_search(struct symtab *s, const char *name);
24+
void *symtab_search(const struct symtab *s, const char *name);
2525

2626
#endif /* _SS_SYMTAB_H_ */

0 commit comments

Comments
 (0)