Message ID | 20200116200136.19687-1-sds@tycho.nsa.gov (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | libsepol,checkpolicy: remove use of hardcoded security class values | expand |
On 1/16/20 3:01 PM, Stephen Smalley wrote: > libsepol carried its own (outdated) copy of flask.h with the generated > security class and initial SID values for use by the policy > compiler and the forked copy of the security server code > leveraged by tools such as audit2why. Convert libsepol and > checkpolicy entirely to looking up class values from the policy, > remove the SECCLASS_* definitions from its flask.h header, and move > the header with its remaining initial SID definitions private to > libsepol. While we are here, fix the sepol_compute_sid() logic to > properly support features long since added to the policy and kernel, > although there are no users of it other than checkpolicy -d (debug) > and it is not exported to users of the shared library. There > are still some residual differences between the kernel logic and > libsepol. > > Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> I see that this fails travis-ci; looks like the problem is that it trades using hardcoded values for SECCLASS_PROCESS and _DIR and the PROCESS__TRANSITION/DYNTRANSITION permissions for requiring the strings to be present in the policy and that isn't true of some test policies. The kernel does require at least the process class and perms to be present or it will reject the policy at load time presently (when it was likewise converted long ago as part of dynamic class/perm support). Options: - Weaken the restrictions in libsepol's policydb_read and accept the fact that the class/perm values may be zero subsequently within libsepol. - Change the test policies to at least provide this minimal set. The "dir" class isn't currently mapped at load time by the kernel but it unmaps it for genfs_sid() matching so it still expects it to be present. > --- > checkpolicy/checkmodule.c | 1 - > checkpolicy/checkpolicy.c | 1 - > checkpolicy/policy_define.c | 26 +++-- > checkpolicy/policy_parse.y | 1 - > checkpolicy/test/dismod.c | 1 - > libsepol/cil/src/cil_binary.c | 1 - > libsepol/include/sepol/policydb/flask.h | 94 ------------------- > libsepol/include/sepol/policydb/flask_types.h | 4 +- > libsepol/include/sepol/policydb/policydb.h | 5 + > libsepol/src/flask.h | 38 ++++++++ > libsepol/src/kernel_to_cil.c | 1 - > libsepol/src/kernel_to_conf.c | 1 - > libsepol/src/mls.c | 3 +- > libsepol/src/policydb.c | 70 +++++++++++++- > libsepol/src/services.c | 87 ++++++++++------- > libsepol/src/sidtab.c | 2 +- > libsepol/src/write.c | 25 +++-- > 17 files changed, 196 insertions(+), 165 deletions(-) > delete mode 100644 libsepol/include/sepol/policydb/flask.h > create mode 100644 libsepol/src/flask.h > > diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c > index c9efaf8b442b..ba7a911b14df 100644 > --- a/checkpolicy/checkmodule.c > +++ b/checkpolicy/checkmodule.c > @@ -25,7 +25,6 @@ > #include <sepol/policydb/policydb.h> > #include <sepol/policydb/services.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/hierarchy.h> > #include <sepol/policydb/expand.h> > #include <sepol/policydb/link.h> > diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c > index 7c5b63f82212..ed1516a6aa6a 100644 > --- a/checkpolicy/checkpolicy.c > +++ b/checkpolicy/checkpolicy.c > @@ -85,7 +85,6 @@ > #include <sepol/policydb/services.h> > #include <sepol/policydb/conditional.h> > #include <sepol/policydb/hierarchy.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/expand.h> > #include <sepol/policydb/link.h> > > diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c > index e295bc523258..c6733fa469c5 100644 > --- a/checkpolicy/policy_define.c > +++ b/checkpolicy/policy_define.c > @@ -53,7 +53,6 @@ > #include <sepol/policydb/policydb.h> > #include <sepol/policydb/services.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/hierarchy.h> > #include <sepol/policydb/polcaps.h> > #include "queue.h" > @@ -5509,7 +5508,9 @@ int define_genfs_context_helper(char *fstype, int has_type) > { > struct genfs *genfs_p, *genfs, *newgenfs; > ocontext_t *newc, *c, *head, *p; > + class_datum_t *cladatum; > char *type = NULL; > + const char *sclass; > int len, len2; > > if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { > @@ -5571,30 +5572,39 @@ int define_genfs_context_helper(char *fstype, int has_type) > } > switch (type[0]) { > case 'b': > - newc->v.sclass = SECCLASS_BLK_FILE; > + sclass = "blk_file"; > break; > case 'c': > - newc->v.sclass = SECCLASS_CHR_FILE; > + sclass = "chr_file"; > break; > case 'd': > - newc->v.sclass = SECCLASS_DIR; > + sclass = "dir"; > break; > case 'p': > - newc->v.sclass = SECCLASS_FIFO_FILE; > + sclass = "fifo_file"; > break; > case 'l': > - newc->v.sclass = SECCLASS_LNK_FILE; > + sclass = "lnk_file"; > break; > case 's': > - newc->v.sclass = SECCLASS_SOCK_FILE; > + sclass = "sock_file"; > break; > case '-': > - newc->v.sclass = SECCLASS_FILE; > + sclass = "file"; > break; > default: > yyerror2("invalid type %s", type); > goto fail; > } > + > + cladatum = hashtab_search(policydbp->p_classes.table, > + sclass); > + if (!cladatum) { > + yyerror2("could not find class %s for " > + "genfscon statement", sclass); > + goto fail; > + } > + newc->v.sclass = cladatum->s.value; > } > if (parse_security_context(&newc->context[0])) > goto fail; > diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y > index abb7d88557e4..6098eb504d0c 100644 > --- a/checkpolicy/policy_parse.y > +++ b/checkpolicy/policy_parse.y > @@ -46,7 +46,6 @@ > #include <sepol/policydb/policydb.h> > #include <sepol/policydb/services.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/hierarchy.h> > #include <sepol/policydb/polcaps.h> > #include "queue.h" > diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c > index 996cf33fff0e..8d6be2ff9522 100644 > --- a/checkpolicy/test/dismod.c > +++ b/checkpolicy/test/dismod.c > @@ -30,7 +30,6 @@ > #include <sepol/policydb/policydb.h> > #include <sepol/policydb/services.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/link.h> > #include <sepol/policydb/module.h> > #include <sepol/policydb/util.h> > diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c > index 4cf6f481fe76..f8e20d32f9f1 100644 > --- a/libsepol/cil/src/cil_binary.c > +++ b/libsepol/cil/src/cil_binary.c > @@ -42,7 +42,6 @@ > #include <sepol/policydb/polcaps.h> > #include <sepol/policydb/conditional.h> > #include <sepol/policydb/constraint.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/expand.h> > #include <sepol/policydb/hierarchy.h> > > diff --git a/libsepol/include/sepol/policydb/flask.h b/libsepol/include/sepol/policydb/flask.h > deleted file mode 100644 > index 3134284b579f..000000000000 > --- a/libsepol/include/sepol/policydb/flask.h > +++ /dev/null > @@ -1,94 +0,0 @@ > -/* This file is automatically generated. Do not edit. */ > -#ifndef _SEPOL_POLICYDB_FLASK_H_ > -#define _SEPOL_POLICYDB_FLASK_H_ > - > -/* > - * Security object class definitions > - */ > -#define SECCLASS_SECURITY 1 > -#define SECCLASS_PROCESS 2 > -#define SECCLASS_SYSTEM 3 > -#define SECCLASS_CAPABILITY 4 > -#define SECCLASS_FILESYSTEM 5 > -#define SECCLASS_FILE 6 > -#define SECCLASS_DIR 7 > -#define SECCLASS_FD 8 > -#define SECCLASS_LNK_FILE 9 > -#define SECCLASS_CHR_FILE 10 > -#define SECCLASS_BLK_FILE 11 > -#define SECCLASS_SOCK_FILE 12 > -#define SECCLASS_FIFO_FILE 13 > -#define SECCLASS_SOCKET 14 > -#define SECCLASS_TCP_SOCKET 15 > -#define SECCLASS_UDP_SOCKET 16 > -#define SECCLASS_RAWIP_SOCKET 17 > -#define SECCLASS_NODE 18 > -#define SECCLASS_NETIF 19 > -#define SECCLASS_NETLINK_SOCKET 20 > -#define SECCLASS_PACKET_SOCKET 21 > -#define SECCLASS_KEY_SOCKET 22 > -#define SECCLASS_UNIX_STREAM_SOCKET 23 > -#define SECCLASS_UNIX_DGRAM_SOCKET 24 > -#define SECCLASS_SEM 25 > -#define SECCLASS_MSG 26 > -#define SECCLASS_MSGQ 27 > -#define SECCLASS_SHM 28 > -#define SECCLASS_IPC 29 > -#define SECCLASS_PASSWD 30 > -#define SECCLASS_DRAWABLE 31 > -#define SECCLASS_WINDOW 32 > -#define SECCLASS_GC 33 > -#define SECCLASS_FONT 34 > -#define SECCLASS_COLORMAP 35 > -#define SECCLASS_PROPERTY 36 > -#define SECCLASS_CURSOR 37 > -#define SECCLASS_XCLIENT 38 > -#define SECCLASS_XINPUT 39 > -#define SECCLASS_XSERVER 40 > -#define SECCLASS_XEXTENSION 41 > -#define SECCLASS_PAX 42 > -#define SECCLASS_NETLINK_ROUTE_SOCKET 43 > -#define SECCLASS_NETLINK_FIREWALL_SOCKET 44 > -#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45 > -#define SECCLASS_NETLINK_NFLOG_SOCKET 46 > -#define SECCLASS_NETLINK_XFRM_SOCKET 47 > -#define SECCLASS_NETLINK_SELINUX_SOCKET 48 > -#define SECCLASS_NETLINK_AUDIT_SOCKET 49 > -#define SECCLASS_NETLINK_IP6FW_SOCKET 50 > -#define SECCLASS_NETLINK_DNRT_SOCKET 51 > -#define SECCLASS_DBUS 52 > - > -/* > - * Security identifier indices for initial entities > - */ > -#define SECINITSID_KERNEL 1 > -#define SECINITSID_SECURITY 2 > -#define SECINITSID_UNLABELED 3 > -#define SECINITSID_FS 4 > -#define SECINITSID_FILE 5 > -#define SECINITSID_FILE_LABELS 6 > -#define SECINITSID_INIT 7 > -#define SECINITSID_ANY_SOCKET 8 > -#define SECINITSID_PORT 9 > -#define SECINITSID_NETIF 10 > -#define SECINITSID_NETMSG 11 > -#define SECINITSID_NODE 12 > -#define SECINITSID_IGMP_PACKET 13 > -#define SECINITSID_ICMP_SOCKET 14 > -#define SECINITSID_TCP_SOCKET 15 > -#define SECINITSID_SYSCTL_MODPROBE 16 > -#define SECINITSID_SYSCTL 17 > -#define SECINITSID_SYSCTL_FS 18 > -#define SECINITSID_SYSCTL_KERNEL 19 > -#define SECINITSID_SYSCTL_NET 20 > -#define SECINITSID_SYSCTL_NET_UNIX 21 > -#define SECINITSID_SYSCTL_VM 22 > -#define SECINITSID_SYSCTL_DEV 23 > -#define SECINITSID_KMOD 24 > -#define SECINITSID_POLICY 25 > -#define SECINITSID_SCMP_PACKET 26 > -#define SECINITSID_DEVNULL 27 > - > -#define SECINITSID_NUM 27 > - > -#endif > diff --git a/libsepol/include/sepol/policydb/flask_types.h b/libsepol/include/sepol/policydb/flask_types.h > index 714176fd2a44..a2f7c0bff3ba 100644 > --- a/libsepol/include/sepol/policydb/flask_types.h > +++ b/libsepol/include/sepol/policydb/flask_types.h > @@ -41,9 +41,7 @@ typedef uint32_t sepol_access_vector_t; > > /* > * Each object class is identified by a fixed-size value. > - * The set of security classes is specified in flask/security_classes, > - * with the corresponding constants defined in the automatically > - * generated header file flask.h. > + * The set of security classes is specified in policy. > */ > typedef uint16_t sepol_security_class_t; > #define SEPOL_SECCLASS_NULL 0x0000 /* no class */ > diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h > index b0d2fdfc43f8..81b63fefbb20 100644 > --- a/libsepol/include/sepol/policydb/policydb.h > +++ b/libsepol/include/sepol/policydb/policydb.h > @@ -605,6 +605,11 @@ typedef struct policydb { > unsigned policyvers; > > unsigned handle_unknown; > + > + sepol_security_class_t process_class; > + sepol_security_class_t dir_class; > + sepol_access_vector_t process_trans; > + sepol_access_vector_t process_trans_dyntrans; > } policydb_t; > > struct sepol_policydb { > diff --git a/libsepol/src/flask.h b/libsepol/src/flask.h > new file mode 100644 > index 000000000000..b4130bbcf544 > --- /dev/null > +++ b/libsepol/src/flask.h > @@ -0,0 +1,38 @@ > +/* This file is automatically generated. Do not edit. */ > +#ifndef _SEPOL_POLICYDB_FLASK_H_ > +#define _SEPOL_POLICYDB_FLASK_H_ > + > +/* > + * Security identifier indices for initial entities > + */ > +#define SECINITSID_KERNEL 1 > +#define SECINITSID_SECURITY 2 > +#define SECINITSID_UNLABELED 3 > +#define SECINITSID_FS 4 > +#define SECINITSID_FILE 5 > +#define SECINITSID_FILE_LABELS 6 > +#define SECINITSID_INIT 7 > +#define SECINITSID_ANY_SOCKET 8 > +#define SECINITSID_PORT 9 > +#define SECINITSID_NETIF 10 > +#define SECINITSID_NETMSG 11 > +#define SECINITSID_NODE 12 > +#define SECINITSID_IGMP_PACKET 13 > +#define SECINITSID_ICMP_SOCKET 14 > +#define SECINITSID_TCP_SOCKET 15 > +#define SECINITSID_SYSCTL_MODPROBE 16 > +#define SECINITSID_SYSCTL 17 > +#define SECINITSID_SYSCTL_FS 18 > +#define SECINITSID_SYSCTL_KERNEL 19 > +#define SECINITSID_SYSCTL_NET 20 > +#define SECINITSID_SYSCTL_NET_UNIX 21 > +#define SECINITSID_SYSCTL_VM 22 > +#define SECINITSID_SYSCTL_DEV 23 > +#define SECINITSID_KMOD 24 > +#define SECINITSID_POLICY 25 > +#define SECINITSID_SCMP_PACKET 26 > +#define SECINITSID_DEVNULL 27 > + > +#define SECINITSID_NUM 27 > + > +#endif > diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c > index ca2e4a9b265b..108767573e28 100644 > --- a/libsepol/src/kernel_to_cil.c > +++ b/libsepol/src/kernel_to_cil.c > @@ -18,7 +18,6 @@ > > #include <sepol/policydb/avtab.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/hashtab.h> > #include <sepol/policydb/polcaps.h> > #include <sepol/policydb/policydb.h> > diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c > index b49661625e03..1c7b7d226e9e 100644 > --- a/libsepol/src/kernel_to_conf.c > +++ b/libsepol/src/kernel_to_conf.c > @@ -17,7 +17,6 @@ > > #include <sepol/policydb/avtab.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/hashtab.h> > #include <sepol/policydb/polcaps.h> > #include <sepol/policydb/policydb.h> > diff --git a/libsepol/src/mls.c b/libsepol/src/mls.c > index 6ff9a8468879..1ee90cf8dee1 100644 > --- a/libsepol/src/mls.c > +++ b/libsepol/src/mls.c > @@ -29,7 +29,6 @@ > > #include <sepol/policydb/policydb.h> > #include <sepol/policydb/services.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/context.h> > > #include <stdlib.h> > @@ -649,7 +648,7 @@ int mls_compute_sid(policydb_t * policydb, > > /* Fallthrough */ > case AVTAB_CHANGE: > - if (tclass == SECCLASS_PROCESS) > + if (tclass == policydb->process_class) > /* Use the process MLS attributes. */ > return mls_copy_context(newcontext, scontext); > else > diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c > index 67037b6d7760..ccc4b34c15d4 100644 > --- a/libsepol/src/policydb.c > +++ b/libsepol/src/policydb.c > @@ -49,7 +49,6 @@ > #include <sepol/policydb/conditional.h> > #include <sepol/policydb/avrule_block.h> > #include <sepol/policydb/util.h> > -#include <sepol/policydb/flask.h> > > #include "kernel_to_common.h" > #include "private.h" > @@ -2562,7 +2561,7 @@ int role_trans_read(policydb_t *p, struct policy_file *fp) > return -1; > tr->tclass = le32_to_cpu(buf[0]); > } else > - tr->tclass = SECCLASS_PROCESS; > + tr->tclass = p->process_class; > ltr = tr; > } > return 0; > @@ -3457,7 +3456,7 @@ static int range_read(policydb_t * p, struct policy_file *fp) > goto err; > rt->target_class = le32_to_cpu(buf[0]); > } else > - rt->target_class = SECCLASS_PROCESS; > + rt->target_class = p->process_class; > r = calloc(1, sizeof(*r)); > if (!r) > goto err; > @@ -3586,7 +3585,7 @@ static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r, > if (ebitmap_read(&tr->classes, fp)) > return -1; > } else { > - if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 1, 1)) > + if (ebitmap_set_bit(&tr->classes, p->process_class - 1, 1)) > return -1; > } > > @@ -3963,6 +3962,51 @@ static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) > return -1; > } > > +static sepol_security_class_t policydb_string_to_security_class( > + struct policydb *policydb, > + const char *class_name) > +{ > + class_datum_t *tclass_datum; > + > + tclass_datum = hashtab_search(policydb->p_classes.table, > + (hashtab_key_t) class_name); > + if (!tclass_datum) > + return 0; > + return tclass_datum->s.value; > +} > + > +static sepol_access_vector_t policydb_string_to_av_perm( > + struct policydb *policydb, > + sepol_security_class_t tclass, > + const char *perm_name) > +{ > + class_datum_t *tclass_datum; > + perm_datum_t *perm_datum; > + > + if (!tclass || tclass > policydb->p_classes.nprim) > + return 0; > + tclass_datum = policydb->class_val_to_struct[tclass - 1]; > + > + perm_datum = (perm_datum_t *) > + hashtab_search(tclass_datum->permissions.table, > + (hashtab_key_t)perm_name); > + if (perm_datum != NULL) > + return 0x1U << (perm_datum->s.value - 1); > + > + if (tclass_datum->comdatum == NULL) > + return 0; > + > + perm_datum = (perm_datum_t *) > + hashtab_search(tclass_datum->comdatum->permissions.table, > + (hashtab_key_t)perm_name); > + > + if (perm_datum != NULL) > + return 0x1U << (perm_datum->s.value - 1); > + > + return 0; > +} > + > + > /* > * Read the configuration data from a policy database binary > * representation file into a policy database structure. > @@ -4190,6 +4234,14 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) > p->symtab[i].nprim = nprim; > } > > + p->process_class = policydb_string_to_security_class(p, "process"); > + if (!p->process_class) > + goto bad; > + > + p->dir_class = policydb_string_to_security_class(p, "dir"); > + if (!p->dir_class) > + goto bad; > + > if (policy_type == POLICY_KERN) { > if (avtab_read(&p->te_avtab, fp, r_policyvers)) > goto bad; > @@ -4233,6 +4285,16 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) > if (policydb_index_classes(p)) > goto bad; > > + p->process_trans = policydb_string_to_av_perm(p, p->process_class, > + "transition"); > + if (!p->process_trans) > + goto bad; > + p->process_trans_dyntrans = p->process_trans | > + policydb_string_to_av_perm(p, p->process_class, > + "dyntransition"); > + if (!p->process_trans_dyntrans) > + goto bad; > + > if (policydb_index_others(fp->handle, p, verbose)) > goto bad; > > diff --git a/libsepol/src/services.c b/libsepol/src/services.c > index 3758436f8e34..9dbba5673dfc 100644 > --- a/libsepol/src/services.c > +++ b/libsepol/src/services.c > @@ -1,4 +1,3 @@ > - > /* > * Author : Stephen Smalley, <sds@tycho.nsa.gov> > */ > @@ -59,7 +58,6 @@ > #include <sepol/policydb/sidtab.h> > #include <sepol/policydb/services.h> > #include <sepol/policydb/conditional.h> > -#include <sepol/policydb/flask.h> > #include <sepol/policydb/util.h> > > #include "debug.h" > @@ -68,6 +66,7 @@ > #include "av_permissions.h" > #include "dso.h" > #include "mls.h" > +#include "flask.h" > > #define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) > #define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) > @@ -989,8 +988,8 @@ static int context_struct_compute_av(context_struct_t * scontext, > * role is changing, then check the (current_role, new_role) > * pair. > */ > - if (tclass == SECCLASS_PROCESS && > - (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && > + if (tclass == policydb->process_class && > + (avd->allowed & policydb->process_trans_dyntrans) && > scontext->role != tcontext->role) { > for (ra = policydb->role_allow; ra; ra = ra->next) { > if (scontext->role == ra->role && > @@ -998,8 +997,7 @@ static int context_struct_compute_av(context_struct_t * scontext, > break; > } > if (!ra) > - avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | > - PROCESS__DYNTRANSITION); > + avd->allowed &= ~policydb->process_trans_dyntrans; > } > > if (requested & ~avd->allowed) { > @@ -1361,6 +1359,7 @@ static int sepol_compute_sid(sepol_security_id_t ssid, > sepol_security_class_t tclass, > uint32_t specified, sepol_security_id_t * out_sid) > { > + struct class_datum *cladatum = NULL; > context_struct_t *scontext = 0, *tcontext = 0, newcontext; > struct role_trans *roletr = 0; > avtab_key_t avkey; > @@ -1381,14 +1380,22 @@ static int sepol_compute_sid(sepol_security_id_t ssid, > goto out; > } > > + if (tclass && tclass <= policydb->p_classes.nprim) > + cladatum = policydb->class_val_to_struct[tclass - 1]; > + > context_init(&newcontext); > > /* Set the user identity. */ > switch (specified) { > case AVTAB_TRANSITION: > case AVTAB_CHANGE: > - /* Use the process user identity. */ > - newcontext.user = scontext->user; > + if (cladatum && cladatum->default_user == DEFAULT_TARGET) { > + newcontext.user = tcontext->user; > + } else { > + /* notice this gets both DEFAULT_SOURCE and unset */ > + /* Use the process user identity. */ > + newcontext.user = scontext->user; > + } > break; > case AVTAB_MEMBER: > /* Use the related object owner. */ > @@ -1396,18 +1403,31 @@ static int sepol_compute_sid(sepol_security_id_t ssid, > break; > } > > - /* Set the role and type to default values. */ > - switch (tclass) { > - case SECCLASS_PROCESS: > - /* Use the current role and type of process. */ > + /* Set the role to default values. */ > + if (cladatum && cladatum->default_role == DEFAULT_SOURCE) { > newcontext.role = scontext->role; > + } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { > + newcontext.role = tcontext->role; > + } else { > + if (tclass == policydb->process_class) > + newcontext.role = scontext->role; > + else > + newcontext.role = OBJECT_R_VAL; > + } > + > + /* Set the type to default values. */ > + if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { > newcontext.type = scontext->type; > - break; > - default: > - /* Use the well-defined object role. */ > - newcontext.role = OBJECT_R_VAL; > - /* Use the type of the related object. */ > + } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { > newcontext.type = tcontext->type; > + } else { > + if (tclass == policydb->process_class) { > + /* Use the type of process. */ > + newcontext.type = scontext->type; > + } else { > + /* Use the type of the related object. */ > + newcontext.type = tcontext->type; > + } > } > > /* Look for a type transition/member/change rule. */ > @@ -1435,23 +1455,18 @@ static int sepol_compute_sid(sepol_security_id_t ssid, > } > > /* Check for class-specific changes. */ > - switch (tclass) { > - case SECCLASS_PROCESS: > - if (specified & AVTAB_TRANSITION) { > - /* Look for a role transition rule. */ > - for (roletr = policydb->role_tr; roletr; > - roletr = roletr->next) { > - if (roletr->role == scontext->role && > - roletr->type == tcontext->type) { > - /* Use the role transition rule. */ > - newcontext.role = roletr->new_role; > - break; > - } > + if (specified & AVTAB_TRANSITION) { > + /* Look for a role transition rule. */ > + for (roletr = policydb->role_tr; roletr; > + roletr = roletr->next) { > + if (roletr->role == scontext->role && > + roletr->type == tcontext->type && > + roletr->tclass == tclass) { > + /* Use the role transition rule. */ > + newcontext.role = roletr->new_role; > + break; > } > } > - break; > - default: > - break; > } > > /* Set the MLS attributes. > @@ -2203,10 +2218,10 @@ int hidden sepol_get_user_sids(sepol_security_id_t fromsid, > continue; > > rc = context_struct_compute_av(fromcon, &usercon, > - SECCLASS_PROCESS, > - PROCESS__TRANSITION, > + policydb->process_class, > + policydb->process_trans, > &avd, &reason, NULL, 0); > - if (rc || !(avd.allowed & PROCESS__TRANSITION)) > + if (rc || !(avd.allowed & policydb->process_trans)) > continue; > rc = sepol_sidtab_context_to_sid(sidtab, &usercon, > &sid); > @@ -2321,7 +2336,7 @@ int hidden sepol_fs_use(const char *fstype, > } > *sid = c->sid[0]; > } else { > - rc = sepol_genfs_sid(fstype, "/", SECCLASS_DIR, sid); > + rc = sepol_genfs_sid(fstype, "/", policydb->dir_class, sid); > if (rc) { > *behavior = SECURITY_FS_USE_NONE; > rc = 0; > diff --git a/libsepol/src/sidtab.c b/libsepol/src/sidtab.c > index 23b2e8f33630..e6bf57161e52 100644 > --- a/libsepol/src/sidtab.c > +++ b/libsepol/src/sidtab.c > @@ -14,7 +14,7 @@ > > #include <sepol/policydb/sidtab.h> > > -#include <sepol/policydb/flask.h> > +#include "flask.h" > > #define SIDTAB_HASH(sid) \ > (sid & SIDTAB_HASH_MASK) > diff --git a/libsepol/src/write.c b/libsepol/src/write.c > index c6be2be2562e..ab5bc25889d4 100644 > --- a/libsepol/src/write.c > +++ b/libsepol/src/write.c > @@ -40,7 +40,6 @@ > #include <sepol/policydb/policydb.h> > #include <sepol/policydb/conditional.h> > #include <sepol/policydb/expand.h> > -#include <sepol/policydb/flask.h> > > #include "debug.h" > #include "private.h" > @@ -514,7 +513,7 @@ static int role_trans_write(policydb_t *p, struct policy_file *fp) > > nel = 0; > for (tr = r; tr; tr = tr->next) > - if(new_roletr || tr->tclass == SECCLASS_PROCESS) > + if(new_roletr || tr->tclass == p->process_class) > nel++; > > buf[0] = cpu_to_le32(nel); > @@ -522,7 +521,7 @@ static int role_trans_write(policydb_t *p, struct policy_file *fp) > if (items != 1) > return POLICYDB_ERROR; > for (tr = r; tr; tr = tr->next) { > - if (!new_roletr && tr->tclass != SECCLASS_PROCESS) { > + if (!new_roletr && tr->tclass != p->process_class) { > if (!warning_issued) > WARN(fp->handle, "Discarding role_transition " > "rules for security classes other than " > @@ -1574,6 +1573,7 @@ struct rangetrans_write_args { > size_t nel; > int new_rangetr; > struct policy_file *fp; > + struct policydb *p; > }; > > static int rangetrans_count(hashtab_key_t key, > @@ -1582,11 +1582,12 @@ static int rangetrans_count(hashtab_key_t key, > { > struct range_trans *rt = (struct range_trans *)key; > struct rangetrans_write_args *args = ptr; > + struct policydb *p = args->p; > > /* all range_transitions are written for the new format, only > process related range_transitions are written for the old > format, so count accordingly */ > - if (args->new_rangetr || rt->target_class == SECCLASS_PROCESS) > + if (args->new_rangetr || rt->target_class == p->process_class) > args->nel++; > return 0; > } > @@ -1598,12 +1599,13 @@ static int range_write_helper(hashtab_key_t key, void *data, void *ptr) > struct mls_range *r = data; > struct rangetrans_write_args *args = ptr; > struct policy_file *fp = args->fp; > + struct policydb *p = args->p; > int new_rangetr = args->new_rangetr; > size_t items; > static int warning_issued = 0; > int rc; > > - if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) { > + if (!new_rangetr && rt->target_class != p->process_class) { > if (!warning_issued) > WARN(fp->handle, "Discarding range_transition " > "rules for security classes other than " > @@ -1642,6 +1644,7 @@ static int range_write(policydb_t * p, struct policy_file *fp) > args.nel = 0; > args.new_rangetr = new_rangetr; > args.fp = fp; > + args.p = p; > rc = hashtab_map(p->range_tr, rangetrans_count, &args); > if (rc) > return rc; > @@ -1766,13 +1769,15 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules, > return POLICYDB_SUCCESS; > } > > -static int only_process(ebitmap_t *in) > +static int only_process(ebitmap_t *in, struct policydb *p) > { > - unsigned int i; > + unsigned int i, value; > ebitmap_node_t *node; > > + value = p->process_class - 1; > + > ebitmap_for_each_positive_bit(in, node, i) { > - if (i != SECCLASS_PROCESS - 1) > + if (i != value) > return 0; > } > return 1; > @@ -1789,7 +1794,7 @@ static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, > int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS; > > for (tr = t; tr; tr = tr->next) > - if (new_role || only_process(&tr->classes)) > + if (new_role || only_process(&tr->classes, p)) > nel++; > > buf[0] = cpu_to_le32(nel); > @@ -1797,7 +1802,7 @@ static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, > if (items != 1) > return POLICYDB_ERROR; > for (tr = t; tr; tr = tr->next) { > - if (!new_role && !only_process(&tr->classes)) { > + if (!new_role && !only_process(&tr->classes, p)) { > if (!warned) > WARN(fp->handle, "Discarding role_transition " > "rules for security classes other than " >
On 1/16/20 3:34 PM, Stephen Smalley wrote: > On 1/16/20 3:01 PM, Stephen Smalley wrote: >> libsepol carried its own (outdated) copy of flask.h with the generated >> security class and initial SID values for use by the policy >> compiler and the forked copy of the security server code >> leveraged by tools such as audit2why. Convert libsepol and >> checkpolicy entirely to looking up class values from the policy, >> remove the SECCLASS_* definitions from its flask.h header, and move >> the header with its remaining initial SID definitions private to >> libsepol. While we are here, fix the sepol_compute_sid() logic to >> properly support features long since added to the policy and kernel, >> although there are no users of it other than checkpolicy -d (debug) >> and it is not exported to users of the shared library. There >> are still some residual differences between the kernel logic and >> libsepol. >> >> Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> > > I see that this fails travis-ci; looks like the problem is that it > trades using hardcoded values for SECCLASS_PROCESS and _DIR and the > PROCESS__TRANSITION/DYNTRANSITION permissions for requiring the strings > to be present in the policy and that isn't true of some test policies. > The kernel does require at least the process class and perms to be > present or it will reject the policy at load time presently (when it was > likewise converted long ago as part of dynamic class/perm support). > Options: > - Weaken the restrictions in libsepol's policydb_read and accept the > fact that the class/perm values may be zero subsequently within libsepol. > - Change the test policies to at least provide this minimal set. > > The "dir" class isn't currently mapped at load time by the kernel but it > unmaps it for genfs_sid() matching so it still expects it to be present. I guess if nothing else it ought to be conditional on SEPOL_TARGET_SELINUX to avoid breaking Xen policies.
diff --git a/checkpolicy/checkmodule.c b/checkpolicy/checkmodule.c index c9efaf8b442b..ba7a911b14df 100644 --- a/checkpolicy/checkmodule.c +++ b/checkpolicy/checkmodule.c @@ -25,7 +25,6 @@ #include <sepol/policydb/policydb.h> #include <sepol/policydb/services.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/hierarchy.h> #include <sepol/policydb/expand.h> #include <sepol/policydb/link.h> diff --git a/checkpolicy/checkpolicy.c b/checkpolicy/checkpolicy.c index 7c5b63f82212..ed1516a6aa6a 100644 --- a/checkpolicy/checkpolicy.c +++ b/checkpolicy/checkpolicy.c @@ -85,7 +85,6 @@ #include <sepol/policydb/services.h> #include <sepol/policydb/conditional.h> #include <sepol/policydb/hierarchy.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/expand.h> #include <sepol/policydb/link.h> diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index e295bc523258..c6733fa469c5 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -53,7 +53,6 @@ #include <sepol/policydb/policydb.h> #include <sepol/policydb/services.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/hierarchy.h> #include <sepol/policydb/polcaps.h> #include "queue.h" @@ -5509,7 +5508,9 @@ int define_genfs_context_helper(char *fstype, int has_type) { struct genfs *genfs_p, *genfs, *newgenfs; ocontext_t *newc, *c, *head, *p; + class_datum_t *cladatum; char *type = NULL; + const char *sclass; int len, len2; if (policydbp->target_platform != SEPOL_TARGET_SELINUX) { @@ -5571,30 +5572,39 @@ int define_genfs_context_helper(char *fstype, int has_type) } switch (type[0]) { case 'b': - newc->v.sclass = SECCLASS_BLK_FILE; + sclass = "blk_file"; break; case 'c': - newc->v.sclass = SECCLASS_CHR_FILE; + sclass = "chr_file"; break; case 'd': - newc->v.sclass = SECCLASS_DIR; + sclass = "dir"; break; case 'p': - newc->v.sclass = SECCLASS_FIFO_FILE; + sclass = "fifo_file"; break; case 'l': - newc->v.sclass = SECCLASS_LNK_FILE; + sclass = "lnk_file"; break; case 's': - newc->v.sclass = SECCLASS_SOCK_FILE; + sclass = "sock_file"; break; case '-': - newc->v.sclass = SECCLASS_FILE; + sclass = "file"; break; default: yyerror2("invalid type %s", type); goto fail; } + + cladatum = hashtab_search(policydbp->p_classes.table, + sclass); + if (!cladatum) { + yyerror2("could not find class %s for " + "genfscon statement", sclass); + goto fail; + } + newc->v.sclass = cladatum->s.value; } if (parse_security_context(&newc->context[0])) goto fail; diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y index abb7d88557e4..6098eb504d0c 100644 --- a/checkpolicy/policy_parse.y +++ b/checkpolicy/policy_parse.y @@ -46,7 +46,6 @@ #include <sepol/policydb/policydb.h> #include <sepol/policydb/services.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/hierarchy.h> #include <sepol/policydb/polcaps.h> #include "queue.h" diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c index 996cf33fff0e..8d6be2ff9522 100644 --- a/checkpolicy/test/dismod.c +++ b/checkpolicy/test/dismod.c @@ -30,7 +30,6 @@ #include <sepol/policydb/policydb.h> #include <sepol/policydb/services.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/link.h> #include <sepol/policydb/module.h> #include <sepol/policydb/util.h> diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index 4cf6f481fe76..f8e20d32f9f1 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -42,7 +42,6 @@ #include <sepol/policydb/polcaps.h> #include <sepol/policydb/conditional.h> #include <sepol/policydb/constraint.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/expand.h> #include <sepol/policydb/hierarchy.h> diff --git a/libsepol/include/sepol/policydb/flask.h b/libsepol/include/sepol/policydb/flask.h deleted file mode 100644 index 3134284b579f..000000000000 --- a/libsepol/include/sepol/policydb/flask.h +++ /dev/null @@ -1,94 +0,0 @@ -/* This file is automatically generated. Do not edit. */ -#ifndef _SEPOL_POLICYDB_FLASK_H_ -#define _SEPOL_POLICYDB_FLASK_H_ - -/* - * Security object class definitions - */ -#define SECCLASS_SECURITY 1 -#define SECCLASS_PROCESS 2 -#define SECCLASS_SYSTEM 3 -#define SECCLASS_CAPABILITY 4 -#define SECCLASS_FILESYSTEM 5 -#define SECCLASS_FILE 6 -#define SECCLASS_DIR 7 -#define SECCLASS_FD 8 -#define SECCLASS_LNK_FILE 9 -#define SECCLASS_CHR_FILE 10 -#define SECCLASS_BLK_FILE 11 -#define SECCLASS_SOCK_FILE 12 -#define SECCLASS_FIFO_FILE 13 -#define SECCLASS_SOCKET 14 -#define SECCLASS_TCP_SOCKET 15 -#define SECCLASS_UDP_SOCKET 16 -#define SECCLASS_RAWIP_SOCKET 17 -#define SECCLASS_NODE 18 -#define SECCLASS_NETIF 19 -#define SECCLASS_NETLINK_SOCKET 20 -#define SECCLASS_PACKET_SOCKET 21 -#define SECCLASS_KEY_SOCKET 22 -#define SECCLASS_UNIX_STREAM_SOCKET 23 -#define SECCLASS_UNIX_DGRAM_SOCKET 24 -#define SECCLASS_SEM 25 -#define SECCLASS_MSG 26 -#define SECCLASS_MSGQ 27 -#define SECCLASS_SHM 28 -#define SECCLASS_IPC 29 -#define SECCLASS_PASSWD 30 -#define SECCLASS_DRAWABLE 31 -#define SECCLASS_WINDOW 32 -#define SECCLASS_GC 33 -#define SECCLASS_FONT 34 -#define SECCLASS_COLORMAP 35 -#define SECCLASS_PROPERTY 36 -#define SECCLASS_CURSOR 37 -#define SECCLASS_XCLIENT 38 -#define SECCLASS_XINPUT 39 -#define SECCLASS_XSERVER 40 -#define SECCLASS_XEXTENSION 41 -#define SECCLASS_PAX 42 -#define SECCLASS_NETLINK_ROUTE_SOCKET 43 -#define SECCLASS_NETLINK_FIREWALL_SOCKET 44 -#define SECCLASS_NETLINK_TCPDIAG_SOCKET 45 -#define SECCLASS_NETLINK_NFLOG_SOCKET 46 -#define SECCLASS_NETLINK_XFRM_SOCKET 47 -#define SECCLASS_NETLINK_SELINUX_SOCKET 48 -#define SECCLASS_NETLINK_AUDIT_SOCKET 49 -#define SECCLASS_NETLINK_IP6FW_SOCKET 50 -#define SECCLASS_NETLINK_DNRT_SOCKET 51 -#define SECCLASS_DBUS 52 - -/* - * Security identifier indices for initial entities - */ -#define SECINITSID_KERNEL 1 -#define SECINITSID_SECURITY 2 -#define SECINITSID_UNLABELED 3 -#define SECINITSID_FS 4 -#define SECINITSID_FILE 5 -#define SECINITSID_FILE_LABELS 6 -#define SECINITSID_INIT 7 -#define SECINITSID_ANY_SOCKET 8 -#define SECINITSID_PORT 9 -#define SECINITSID_NETIF 10 -#define SECINITSID_NETMSG 11 -#define SECINITSID_NODE 12 -#define SECINITSID_IGMP_PACKET 13 -#define SECINITSID_ICMP_SOCKET 14 -#define SECINITSID_TCP_SOCKET 15 -#define SECINITSID_SYSCTL_MODPROBE 16 -#define SECINITSID_SYSCTL 17 -#define SECINITSID_SYSCTL_FS 18 -#define SECINITSID_SYSCTL_KERNEL 19 -#define SECINITSID_SYSCTL_NET 20 -#define SECINITSID_SYSCTL_NET_UNIX 21 -#define SECINITSID_SYSCTL_VM 22 -#define SECINITSID_SYSCTL_DEV 23 -#define SECINITSID_KMOD 24 -#define SECINITSID_POLICY 25 -#define SECINITSID_SCMP_PACKET 26 -#define SECINITSID_DEVNULL 27 - -#define SECINITSID_NUM 27 - -#endif diff --git a/libsepol/include/sepol/policydb/flask_types.h b/libsepol/include/sepol/policydb/flask_types.h index 714176fd2a44..a2f7c0bff3ba 100644 --- a/libsepol/include/sepol/policydb/flask_types.h +++ b/libsepol/include/sepol/policydb/flask_types.h @@ -41,9 +41,7 @@ typedef uint32_t sepol_access_vector_t; /* * Each object class is identified by a fixed-size value. - * The set of security classes is specified in flask/security_classes, - * with the corresponding constants defined in the automatically - * generated header file flask.h. + * The set of security classes is specified in policy. */ typedef uint16_t sepol_security_class_t; #define SEPOL_SECCLASS_NULL 0x0000 /* no class */ diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index b0d2fdfc43f8..81b63fefbb20 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -605,6 +605,11 @@ typedef struct policydb { unsigned policyvers; unsigned handle_unknown; + + sepol_security_class_t process_class; + sepol_security_class_t dir_class; + sepol_access_vector_t process_trans; + sepol_access_vector_t process_trans_dyntrans; } policydb_t; struct sepol_policydb { diff --git a/libsepol/src/flask.h b/libsepol/src/flask.h new file mode 100644 index 000000000000..b4130bbcf544 --- /dev/null +++ b/libsepol/src/flask.h @@ -0,0 +1,38 @@ +/* This file is automatically generated. Do not edit. */ +#ifndef _SEPOL_POLICYDB_FLASK_H_ +#define _SEPOL_POLICYDB_FLASK_H_ + +/* + * Security identifier indices for initial entities + */ +#define SECINITSID_KERNEL 1 +#define SECINITSID_SECURITY 2 +#define SECINITSID_UNLABELED 3 +#define SECINITSID_FS 4 +#define SECINITSID_FILE 5 +#define SECINITSID_FILE_LABELS 6 +#define SECINITSID_INIT 7 +#define SECINITSID_ANY_SOCKET 8 +#define SECINITSID_PORT 9 +#define SECINITSID_NETIF 10 +#define SECINITSID_NETMSG 11 +#define SECINITSID_NODE 12 +#define SECINITSID_IGMP_PACKET 13 +#define SECINITSID_ICMP_SOCKET 14 +#define SECINITSID_TCP_SOCKET 15 +#define SECINITSID_SYSCTL_MODPROBE 16 +#define SECINITSID_SYSCTL 17 +#define SECINITSID_SYSCTL_FS 18 +#define SECINITSID_SYSCTL_KERNEL 19 +#define SECINITSID_SYSCTL_NET 20 +#define SECINITSID_SYSCTL_NET_UNIX 21 +#define SECINITSID_SYSCTL_VM 22 +#define SECINITSID_SYSCTL_DEV 23 +#define SECINITSID_KMOD 24 +#define SECINITSID_POLICY 25 +#define SECINITSID_SCMP_PACKET 26 +#define SECINITSID_DEVNULL 27 + +#define SECINITSID_NUM 27 + +#endif diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c index ca2e4a9b265b..108767573e28 100644 --- a/libsepol/src/kernel_to_cil.c +++ b/libsepol/src/kernel_to_cil.c @@ -18,7 +18,6 @@ #include <sepol/policydb/avtab.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/hashtab.h> #include <sepol/policydb/polcaps.h> #include <sepol/policydb/policydb.h> diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c index b49661625e03..1c7b7d226e9e 100644 --- a/libsepol/src/kernel_to_conf.c +++ b/libsepol/src/kernel_to_conf.c @@ -17,7 +17,6 @@ #include <sepol/policydb/avtab.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/hashtab.h> #include <sepol/policydb/polcaps.h> #include <sepol/policydb/policydb.h> diff --git a/libsepol/src/mls.c b/libsepol/src/mls.c index 6ff9a8468879..1ee90cf8dee1 100644 --- a/libsepol/src/mls.c +++ b/libsepol/src/mls.c @@ -29,7 +29,6 @@ #include <sepol/policydb/policydb.h> #include <sepol/policydb/services.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/context.h> #include <stdlib.h> @@ -649,7 +648,7 @@ int mls_compute_sid(policydb_t * policydb, /* Fallthrough */ case AVTAB_CHANGE: - if (tclass == SECCLASS_PROCESS) + if (tclass == policydb->process_class) /* Use the process MLS attributes. */ return mls_copy_context(newcontext, scontext); else diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index 67037b6d7760..ccc4b34c15d4 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -49,7 +49,6 @@ #include <sepol/policydb/conditional.h> #include <sepol/policydb/avrule_block.h> #include <sepol/policydb/util.h> -#include <sepol/policydb/flask.h> #include "kernel_to_common.h" #include "private.h" @@ -2562,7 +2561,7 @@ int role_trans_read(policydb_t *p, struct policy_file *fp) return -1; tr->tclass = le32_to_cpu(buf[0]); } else - tr->tclass = SECCLASS_PROCESS; + tr->tclass = p->process_class; ltr = tr; } return 0; @@ -3457,7 +3456,7 @@ static int range_read(policydb_t * p, struct policy_file *fp) goto err; rt->target_class = le32_to_cpu(buf[0]); } else - rt->target_class = SECCLASS_PROCESS; + rt->target_class = p->process_class; r = calloc(1, sizeof(*r)); if (!r) goto err; @@ -3586,7 +3585,7 @@ static int role_trans_rule_read(policydb_t *p, role_trans_rule_t ** r, if (ebitmap_read(&tr->classes, fp)) return -1; } else { - if (ebitmap_set_bit(&tr->classes, SECCLASS_PROCESS - 1, 1)) + if (ebitmap_set_bit(&tr->classes, p->process_class - 1, 1)) return -1; } @@ -3963,6 +3962,51 @@ static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) return -1; } +static sepol_security_class_t policydb_string_to_security_class( + struct policydb *policydb, + const char *class_name) +{ + class_datum_t *tclass_datum; + + tclass_datum = hashtab_search(policydb->p_classes.table, + (hashtab_key_t) class_name); + if (!tclass_datum) + return 0; + return tclass_datum->s.value; +} + +static sepol_access_vector_t policydb_string_to_av_perm( + struct policydb *policydb, + sepol_security_class_t tclass, + const char *perm_name) +{ + class_datum_t *tclass_datum; + perm_datum_t *perm_datum; + + if (!tclass || tclass > policydb->p_classes.nprim) + return 0; + tclass_datum = policydb->class_val_to_struct[tclass - 1]; + + perm_datum = (perm_datum_t *) + hashtab_search(tclass_datum->permissions.table, + (hashtab_key_t)perm_name); + if (perm_datum != NULL) + return 0x1U << (perm_datum->s.value - 1); + + if (tclass_datum->comdatum == NULL) + return 0; + + perm_datum = (perm_datum_t *) + hashtab_search(tclass_datum->comdatum->permissions.table, + (hashtab_key_t)perm_name); + + if (perm_datum != NULL) + return 0x1U << (perm_datum->s.value - 1); + + return 0; +} + + /* * Read the configuration data from a policy database binary * representation file into a policy database structure. @@ -4190,6 +4234,14 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) p->symtab[i].nprim = nprim; } + p->process_class = policydb_string_to_security_class(p, "process"); + if (!p->process_class) + goto bad; + + p->dir_class = policydb_string_to_security_class(p, "dir"); + if (!p->dir_class) + goto bad; + if (policy_type == POLICY_KERN) { if (avtab_read(&p->te_avtab, fp, r_policyvers)) goto bad; @@ -4233,6 +4285,16 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) if (policydb_index_classes(p)) goto bad; + p->process_trans = policydb_string_to_av_perm(p, p->process_class, + "transition"); + if (!p->process_trans) + goto bad; + p->process_trans_dyntrans = p->process_trans | + policydb_string_to_av_perm(p, p->process_class, + "dyntransition"); + if (!p->process_trans_dyntrans) + goto bad; + if (policydb_index_others(fp->handle, p, verbose)) goto bad; diff --git a/libsepol/src/services.c b/libsepol/src/services.c index 3758436f8e34..9dbba5673dfc 100644 --- a/libsepol/src/services.c +++ b/libsepol/src/services.c @@ -1,4 +1,3 @@ - /* * Author : Stephen Smalley, <sds@tycho.nsa.gov> */ @@ -59,7 +58,6 @@ #include <sepol/policydb/sidtab.h> #include <sepol/policydb/services.h> #include <sepol/policydb/conditional.h> -#include <sepol/policydb/flask.h> #include <sepol/policydb/util.h> #include "debug.h" @@ -68,6 +66,7 @@ #include "av_permissions.h" #include "dso.h" #include "mls.h" +#include "flask.h" #define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) #define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0) @@ -989,8 +988,8 @@ static int context_struct_compute_av(context_struct_t * scontext, * role is changing, then check the (current_role, new_role) * pair. */ - if (tclass == SECCLASS_PROCESS && - (avd->allowed & (PROCESS__TRANSITION | PROCESS__DYNTRANSITION)) && + if (tclass == policydb->process_class && + (avd->allowed & policydb->process_trans_dyntrans) && scontext->role != tcontext->role) { for (ra = policydb->role_allow; ra; ra = ra->next) { if (scontext->role == ra->role && @@ -998,8 +997,7 @@ static int context_struct_compute_av(context_struct_t * scontext, break; } if (!ra) - avd->allowed = (avd->allowed) & ~(PROCESS__TRANSITION | - PROCESS__DYNTRANSITION); + avd->allowed &= ~policydb->process_trans_dyntrans; } if (requested & ~avd->allowed) { @@ -1361,6 +1359,7 @@ static int sepol_compute_sid(sepol_security_id_t ssid, sepol_security_class_t tclass, uint32_t specified, sepol_security_id_t * out_sid) { + struct class_datum *cladatum = NULL; context_struct_t *scontext = 0, *tcontext = 0, newcontext; struct role_trans *roletr = 0; avtab_key_t avkey; @@ -1381,14 +1380,22 @@ static int sepol_compute_sid(sepol_security_id_t ssid, goto out; } + if (tclass && tclass <= policydb->p_classes.nprim) + cladatum = policydb->class_val_to_struct[tclass - 1]; + context_init(&newcontext); /* Set the user identity. */ switch (specified) { case AVTAB_TRANSITION: case AVTAB_CHANGE: - /* Use the process user identity. */ - newcontext.user = scontext->user; + if (cladatum && cladatum->default_user == DEFAULT_TARGET) { + newcontext.user = tcontext->user; + } else { + /* notice this gets both DEFAULT_SOURCE and unset */ + /* Use the process user identity. */ + newcontext.user = scontext->user; + } break; case AVTAB_MEMBER: /* Use the related object owner. */ @@ -1396,18 +1403,31 @@ static int sepol_compute_sid(sepol_security_id_t ssid, break; } - /* Set the role and type to default values. */ - switch (tclass) { - case SECCLASS_PROCESS: - /* Use the current role and type of process. */ + /* Set the role to default values. */ + if (cladatum && cladatum->default_role == DEFAULT_SOURCE) { newcontext.role = scontext->role; + } else if (cladatum && cladatum->default_role == DEFAULT_TARGET) { + newcontext.role = tcontext->role; + } else { + if (tclass == policydb->process_class) + newcontext.role = scontext->role; + else + newcontext.role = OBJECT_R_VAL; + } + + /* Set the type to default values. */ + if (cladatum && cladatum->default_type == DEFAULT_SOURCE) { newcontext.type = scontext->type; - break; - default: - /* Use the well-defined object role. */ - newcontext.role = OBJECT_R_VAL; - /* Use the type of the related object. */ + } else if (cladatum && cladatum->default_type == DEFAULT_TARGET) { newcontext.type = tcontext->type; + } else { + if (tclass == policydb->process_class) { + /* Use the type of process. */ + newcontext.type = scontext->type; + } else { + /* Use the type of the related object. */ + newcontext.type = tcontext->type; + } } /* Look for a type transition/member/change rule. */ @@ -1435,23 +1455,18 @@ static int sepol_compute_sid(sepol_security_id_t ssid, } /* Check for class-specific changes. */ - switch (tclass) { - case SECCLASS_PROCESS: - if (specified & AVTAB_TRANSITION) { - /* Look for a role transition rule. */ - for (roletr = policydb->role_tr; roletr; - roletr = roletr->next) { - if (roletr->role == scontext->role && - roletr->type == tcontext->type) { - /* Use the role transition rule. */ - newcontext.role = roletr->new_role; - break; - } + if (specified & AVTAB_TRANSITION) { + /* Look for a role transition rule. */ + for (roletr = policydb->role_tr; roletr; + roletr = roletr->next) { + if (roletr->role == scontext->role && + roletr->type == tcontext->type && + roletr->tclass == tclass) { + /* Use the role transition rule. */ + newcontext.role = roletr->new_role; + break; } } - break; - default: - break; } /* Set the MLS attributes. @@ -2203,10 +2218,10 @@ int hidden sepol_get_user_sids(sepol_security_id_t fromsid, continue; rc = context_struct_compute_av(fromcon, &usercon, - SECCLASS_PROCESS, - PROCESS__TRANSITION, + policydb->process_class, + policydb->process_trans, &avd, &reason, NULL, 0); - if (rc || !(avd.allowed & PROCESS__TRANSITION)) + if (rc || !(avd.allowed & policydb->process_trans)) continue; rc = sepol_sidtab_context_to_sid(sidtab, &usercon, &sid); @@ -2321,7 +2336,7 @@ int hidden sepol_fs_use(const char *fstype, } *sid = c->sid[0]; } else { - rc = sepol_genfs_sid(fstype, "/", SECCLASS_DIR, sid); + rc = sepol_genfs_sid(fstype, "/", policydb->dir_class, sid); if (rc) { *behavior = SECURITY_FS_USE_NONE; rc = 0; diff --git a/libsepol/src/sidtab.c b/libsepol/src/sidtab.c index 23b2e8f33630..e6bf57161e52 100644 --- a/libsepol/src/sidtab.c +++ b/libsepol/src/sidtab.c @@ -14,7 +14,7 @@ #include <sepol/policydb/sidtab.h> -#include <sepol/policydb/flask.h> +#include "flask.h" #define SIDTAB_HASH(sid) \ (sid & SIDTAB_HASH_MASK) diff --git a/libsepol/src/write.c b/libsepol/src/write.c index c6be2be2562e..ab5bc25889d4 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -40,7 +40,6 @@ #include <sepol/policydb/policydb.h> #include <sepol/policydb/conditional.h> #include <sepol/policydb/expand.h> -#include <sepol/policydb/flask.h> #include "debug.h" #include "private.h" @@ -514,7 +513,7 @@ static int role_trans_write(policydb_t *p, struct policy_file *fp) nel = 0; for (tr = r; tr; tr = tr->next) - if(new_roletr || tr->tclass == SECCLASS_PROCESS) + if(new_roletr || tr->tclass == p->process_class) nel++; buf[0] = cpu_to_le32(nel); @@ -522,7 +521,7 @@ static int role_trans_write(policydb_t *p, struct policy_file *fp) if (items != 1) return POLICYDB_ERROR; for (tr = r; tr; tr = tr->next) { - if (!new_roletr && tr->tclass != SECCLASS_PROCESS) { + if (!new_roletr && tr->tclass != p->process_class) { if (!warning_issued) WARN(fp->handle, "Discarding role_transition " "rules for security classes other than " @@ -1574,6 +1573,7 @@ struct rangetrans_write_args { size_t nel; int new_rangetr; struct policy_file *fp; + struct policydb *p; }; static int rangetrans_count(hashtab_key_t key, @@ -1582,11 +1582,12 @@ static int rangetrans_count(hashtab_key_t key, { struct range_trans *rt = (struct range_trans *)key; struct rangetrans_write_args *args = ptr; + struct policydb *p = args->p; /* all range_transitions are written for the new format, only process related range_transitions are written for the old format, so count accordingly */ - if (args->new_rangetr || rt->target_class == SECCLASS_PROCESS) + if (args->new_rangetr || rt->target_class == p->process_class) args->nel++; return 0; } @@ -1598,12 +1599,13 @@ static int range_write_helper(hashtab_key_t key, void *data, void *ptr) struct mls_range *r = data; struct rangetrans_write_args *args = ptr; struct policy_file *fp = args->fp; + struct policydb *p = args->p; int new_rangetr = args->new_rangetr; size_t items; static int warning_issued = 0; int rc; - if (!new_rangetr && rt->target_class != SECCLASS_PROCESS) { + if (!new_rangetr && rt->target_class != p->process_class) { if (!warning_issued) WARN(fp->handle, "Discarding range_transition " "rules for security classes other than " @@ -1642,6 +1644,7 @@ static int range_write(policydb_t * p, struct policy_file *fp) args.nel = 0; args.new_rangetr = new_rangetr; args.fp = fp; + args.p = p; rc = hashtab_map(p->range_tr, rangetrans_count, &args); if (rc) return rc; @@ -1766,13 +1769,15 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules, return POLICYDB_SUCCESS; } -static int only_process(ebitmap_t *in) +static int only_process(ebitmap_t *in, struct policydb *p) { - unsigned int i; + unsigned int i, value; ebitmap_node_t *node; + value = p->process_class - 1; + ebitmap_for_each_positive_bit(in, node, i) { - if (i != SECCLASS_PROCESS - 1) + if (i != value) return 0; } return 1; @@ -1789,7 +1794,7 @@ static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, int new_role = p->policyvers >= MOD_POLICYDB_VERSION_ROLETRANS; for (tr = t; tr; tr = tr->next) - if (new_role || only_process(&tr->classes)) + if (new_role || only_process(&tr->classes, p)) nel++; buf[0] = cpu_to_le32(nel); @@ -1797,7 +1802,7 @@ static int role_trans_rule_write(policydb_t *p, role_trans_rule_t * t, if (items != 1) return POLICYDB_ERROR; for (tr = t; tr; tr = tr->next) { - if (!new_role && !only_process(&tr->classes)) { + if (!new_role && !only_process(&tr->classes, p)) { if (!warned) WARN(fp->handle, "Discarding role_transition " "rules for security classes other than "
libsepol carried its own (outdated) copy of flask.h with the generated security class and initial SID values for use by the policy compiler and the forked copy of the security server code leveraged by tools such as audit2why. Convert libsepol and checkpolicy entirely to looking up class values from the policy, remove the SECCLASS_* definitions from its flask.h header, and move the header with its remaining initial SID definitions private to libsepol. While we are here, fix the sepol_compute_sid() logic to properly support features long since added to the policy and kernel, although there are no users of it other than checkpolicy -d (debug) and it is not exported to users of the shared library. There are still some residual differences between the kernel logic and libsepol. Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov> --- checkpolicy/checkmodule.c | 1 - checkpolicy/checkpolicy.c | 1 - checkpolicy/policy_define.c | 26 +++-- checkpolicy/policy_parse.y | 1 - checkpolicy/test/dismod.c | 1 - libsepol/cil/src/cil_binary.c | 1 - libsepol/include/sepol/policydb/flask.h | 94 ------------------- libsepol/include/sepol/policydb/flask_types.h | 4 +- libsepol/include/sepol/policydb/policydb.h | 5 + libsepol/src/flask.h | 38 ++++++++ libsepol/src/kernel_to_cil.c | 1 - libsepol/src/kernel_to_conf.c | 1 - libsepol/src/mls.c | 3 +- libsepol/src/policydb.c | 70 +++++++++++++- libsepol/src/services.c | 87 ++++++++++------- libsepol/src/sidtab.c | 2 +- libsepol/src/write.c | 25 +++-- 17 files changed, 196 insertions(+), 165 deletions(-) delete mode 100644 libsepol/include/sepol/policydb/flask.h create mode 100644 libsepol/src/flask.h