RE: A few questions about module compile/link source code

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Joshua,
 
Many thanks for your response! Hope you had an enjoyable vacation :-)
 
Well, for the init_parser() problem, so far I am new to lex & yacc, I am most puzzled that some rules are handled when pass == 1 and the id queue is purged when pass == 2, whereas some other rules are handled when pass == 2 and the id queue got cleaned up when pass == 1.
 
Who decides when a particular rule should be processed and when the id queue should be cleaned ? and does it and how does it relate with the syntax of a certain rule ?
 
Thanks again!
 
Best regards,
Harry
 
> Date: Thu, 19 May 2011 21:13:53 -0400
> From: method@xxxxxxxxxxxxxxx
> To: harrytaurus2002@xxxxxxxxxxx
> CC: selinux@xxxxxxxxxxxxx
> Subject: Re: A few questions about module compile/link source code
>
> HarryCiao wrote:
> > Hi Joshua,
> >
> > When I am studying the source code about SELinux module
> > compile/link/expansion, so far I run into below 6 questions and would
> > like to ask you about. I believe most of them are silly and I really
> > appreciate you taking time to have a look at them. Or you could point me
> > at some relevant email threads or articles or anything and I could start
> > from there myself. Thanks !!
>
> Sorry for the late response, you caught me on vacation. I'll try to
> answer the questions but it has been 6 years since I looked at some of
> this code (particularly checkpolicy). I'm glad someone new is f! inally
> looking at this stuff.
>
> >
> >
> > 1, In is_id_in_scope(), if no scope_datum_t is found in the current
> > module, then return 1 as success:
> >
> > int is_id_in_scope(uint32_t symbol_type, hashtab_key_t id)
> > {
> > scope_datum_t *scope =
> > (scope_datum_t *) hashtab_search(policydbp->scope[symbol_type].
> > table, id);
> > if (scope == NULL) {
> > return 1; /* id is not known, so return success */
> > }
> > return is_scope_in_stack(scope, stack_top);
> > }
> >
> > Any module, either to define an identifier, or declare it as an outside
> > dependency. Both declare_symbol() and require_symbol() would invoke
> > symtab_insert() to register the identifier's (key, scope_datum_t) pair
> > into the relevant scope[] hashtab, so no scope_datum_t is found would
>! ; > mean that the identifier is neither defined nor declared ever b efore,
> > then why to return 1 as success ?
> >
>
> I've been staring at this for a while and really can't recall. It is
> possible that some symbols use to never make it into the scope tables
> (eg., object_t) but I can't seem to trigger it now.
>
> >
> > 2, In define_type(), we get the attribute from the p_types hashtab for
> > the current module:
> >
> > attr = hashtab_search(policydbp->p_types.table, id);
> > if (!attr) {
> > /* treat it as a fatal error */
> > yyerror2("attribute %s is not declared", id);
> > return -1;
> > }
> >
> > if (attr->flavor != TYPE_ATTRIB) {
> > yyerror2("%s is a type, not an attribute", id);
> >
> > if ((attr = get_local_type(id, attr->s.value, 1)) == NULL) {
> > yyerror("Out of memory!");
> > return -1;
> > }
>! >
> > But in get_local_type(), if the current block/decl is not
> > global/unconditional block, then the attribute's type_datum_t would be
> > duplicated to the current block/decl's symtab[SYM_TYPES], resulting that
> > the current type identifier would be recorded into type_datum_t.types in
> > the current block/decl's symtab[SYM_TYPES], rather than the one in the
> > p_types hashtab.
> >
> > Why would we need to get the local attribute from current block/decl's
> > symtab then set its ebitmap, rather than setting the ebitmap for the one
> > in p_types ?
> >
>
> The types are set in the local decl block so that when the optional
> decl's have been disabled those types won't end up in the final
> attribute bitmap.
>
> >
> > 3, Who decides the value for the "pass" argument to all those parser
> > functio! ns? how and when the value for pass is determined?
> >
&g t; > Say in define_attrib(), when pass == 1, the token in id_queue is parsed
> > but when pass == 2, the id_queue is purged:
> >
> <snip>
> >
> > By whom/when/how is "pass" set to be 1 or 2 ?
> >
>
> Look at init_parser() and the calls to it.
>
> >
> > 4, In define_te_avtab_helper(), if the current permission is not defined
> > for a class, then "continue" to the next loop to handle the next class
> > (to get the current permission's policy value defined in the class,
> > record it in the class_perm_node_t.data for that class) :
> >
> > while ((id = queue_remove(id_queue))) {
> > cur_perms = perms;
> > ebitmap_for_each_bit(&tclasses, node, i) {
> > if (!ebitmap_node_get_bit(node, i))
> > continue;
> > cladatum = policydbp->class_val_to_struct[i];
> >
> > .! .....
> >
> > if (!perdatum) {
> > if (!suppress)
> > yyerror2("permission %s is not defined for class %s", id,
> > policydbp->p_class_val_to_name[i]);
> > continue;
> > } else if (!is_perm_in_scope(id, policydbp->p_class_val_to_name[i])) {
> > if (!suppress) {
> > yyerror2("permission %s of class %s is not within scope", id,
> > policydbp->p_class_val_to_name[i]);
> > }
> > continue;
> > } else {
> > cur_perms->data |= 1U << (perdatum->s.value - 1);
> > }
> >
> > next:
> > cur_perms = cur_perms->next;
> > }
> >
> > free(id);
> >
> > }
> >
> > If the current permission is not defined for the class, then we should
> > not simply continue the next loop, but do "goto next", since we need to
> > move up to th! e next element in the cur_perms accordingly (the Nth
> > non -zero bit and the Nth element of class_perm_node_t are all about the
> > same class), perhaps this is a bug, am I right ?
> >
>
> This is very historical and could possibly be removed, suppress doesn't
> seem to ever be set anymore. This code use to exist circa 2004:
>
> if (policyvers < POLICYDB_VERSION_NLCLASS &&
> (cladatum->value >= SECCLASS_NETLINK_ROUTE_SOCKET &&
> cladatum->value <= SECCLASS_NETLINK_DNRT_SOCKET)) {
> sprintf(errormsg, "remapping class %s to netlink_socket "
> "for policy version %d", id, policyvers);
> yywarn(errormsg);
> classvalue = SECCLASS_NETLINK_SOCKET;
> suppress = 1;
>
>
>
>
> >
> > 5, I have two questions in following snippet of link_modules():
> >
> > /* copy all types, declared and required */
> > for (i = 0; i < len; i++) {
> > sta! te.cur = modules[i];
> > state.cur_mod_name = modules[i]->policy->name;
> > ret =
> > hashtab_map(modules[i]->policy->p_types.table,
> > type_copy_callback, &state);
> > if (ret) {
> > retval = ret;
> > goto cleanup;
> > }
> > }
> >
> > /* then copy everything else, including aliases, and fixup attributes */
> > for (i = 0; i < len; i++) {
> > state.cur = modules[i];
> > state.cur_mod_name = modules[i]->policy->name;
> > ret =
> > copy_identifiers(&state, modules[i]->policy->symtab, NULL);
> > if (ret) {
> > retval = ret;
> > goto cleanup;
> > }
> > }
> >
> >
> > if (policydb_index_others(state.handle, state.base, 0)) {
> > ERR(state.handle, "Error while indexing others");
> > goto cleanup;
> > }> >
> > /* copy and remap the module's data over to base */
> > for (i = 0; i < len; i++) {
> > state.cur = modules[i];
> > ret = copy_module(&state, modules[i]);
> > if (ret) {
> > retval = ret;
> > goto cleanup;
> > }
> > }
> >
> > 1) since copy_identifers() could cover the invoke of type_copy_callback,
> > then why we need to call it explicitly before calling copy_identifiers()?
> >
>
> There are some serious ordering issues in this code. Symbols must be
> copied in a precise order. copy_identifiers is also used elsewhere in
> the code when it is not appropriate to copy types.
>
> > 2) copy_identifers() has been invoked before calling copy_module(), but
> > copy_module() could invoke copy_identifers() again. Since
> > copy_identifers() only gets called by link_modules(), could we stop
> > copy_module() from invoking copy_identifers() onc! e again ?
> >
>
> Interesting. It is possible that we are calling it excessively, though I
> have not tried removing it to see what happens. I'm not completely
> certain what happened here, though it wasn't like that in the historical
> linker, it may have happened during a refactor.
>
>
> --
> This message was distributed to subscribers of the selinux mailing list.
> If you no longer wish to subscribe, send mail to majordomo@xxxxxxxxxxxxx with
> the words "unsubscribe selinux" without quotes as the message.

[Index of Archives]     [Selinux Refpolicy]     [Linux SGX]     [Fedora Users]     [Fedora Desktop]     [Yosemite Photos]     [Yosemite Camping]     [Yosemite Campsites]     [KDE Users]     [Gnome Users]

  Powered by Linux