All of lore.kernel.org
 help / color / mirror / Atom feed
* A few questions about module compile/link source code
@ 2011-05-12  9:58 HarryCiao
  2011-05-20  1:13 ` Joshua Brindle
  0 siblings, 1 reply; 4+ messages in thread
From: HarryCiao @ 2011-05-12  9:58 UTC (permalink / raw)
  To: method, selinux-mailing-list

[-- Attachment #1: Type: text/plain, Size: 6896 bytes --]


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 !!


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 before, then why to return 1 as success ?


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 ?


3, Who decides the value for the "pass" argument to all those parser functions? how and when the value for pass is determined?

Say in define_attrib(), when pass == 1, the token in id_queue is parsed but when pass == 2, the id_queue is purged:

int define_attrib(void)
{
    if (pass == 2) {
        free(queue_remove(id_queue));
        return 0;
    }

    if (declare_type(TRUE, TRUE) == NULL) {
        return -1;
    }
    return 0;
}

But in define_te_avtab(), the id_queue is purged when pass == 1:

int define_te_avtab(int which) 
{ 
        char *id; 
        avrule_t *avrule; 
        int i; 

        if (pass == 1) { 
                for (i = 0; i < 4; i++) { 
                        while ((id = queue_remove(id_queue))) 
                                free(id); 
                } 
                return 0; 
        } 


By whom/when/how is "pass" set to be 1 or 2 ?


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 the 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 ?


5, I have two questions in following snippet of link_modules():

    /* copy all types, declared and required */
    for (i = 0; i < len; i++) {
        state.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()?

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() once again ?

Many thanks for all your help!

Best regards,
Harry 		 	   		  

[-- Attachment #2: Type: text/html, Size: 13891 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: A few questions about module compile/link source code
  2011-05-12  9:58 A few questions about module compile/link source code HarryCiao
@ 2011-05-20  1:13 ` Joshua Brindle
  2011-05-23 13:15   ` HarryCiao
  0 siblings, 1 reply; 4+ messages in thread
From: Joshua Brindle @ 2011-05-20  1:13 UTC (permalink / raw)
  To: HarryCiao; +Cc: selinux-mailing-list

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 finally
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 before, 
> 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 
> functions? how and when the value for pass is determined?
> 
> 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 the 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++) {
> state.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() once 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@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: A few questions about module compile/link source code
  2011-05-20  1:13 ` Joshua Brindle
@ 2011-05-23 13:15   ` HarryCiao
  2011-05-23 13:46     ` Stephen Smalley
  0 siblings, 1 reply; 4+ messages in thread
From: HarryCiao @ 2011-05-23 13:15 UTC (permalink / raw)
  To: method; +Cc: selinux-mailing-list

[-- Attachment #1: Type: text/plain, Size: 8371 bytes --]


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@manicmethod.com
> To: harrytaurus2002@hotmail.com
> CC: selinux@tycho.nsa.gov
> 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 finally
> 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 before, 
> > 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 
> > functions? how and when the value for pass is determined?
> > 
> > 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 the 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++) {
> > state.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() once 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@tycho.nsa.gov with
> the words "unsubscribe selinux" without quotes as the message.
 		 	   		  

[-- Attachment #2: Type: text/html, Size: 10687 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* RE: A few questions about module compile/link source code
  2011-05-23 13:15   ` HarryCiao
@ 2011-05-23 13:46     ` Stephen Smalley
  0 siblings, 0 replies; 4+ messages in thread
From: Stephen Smalley @ 2011-05-23 13:46 UTC (permalink / raw)
  To: HarryCiao; +Cc: method, selinux-mailing-list

On Mon, 2011-05-23 at 13:15 +0000, HarryCiao wrote:
> 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 ?

Hi Harry,

The 2nd pass in checkpolicy was introduced long ago (the original CVS
tree shows it as happening 2000.09.19) in order to relax some of the
ordering requirements in the policy configuration.  It allows
checkpolicy to collect up some definitions in the first pass before it
performs any rule expansion, e.g. so that all type attributes are known
before any allow rules are expanded.  More traditionally this would be
done by generating an AST and then just walking the AST for subsequent
passes rather than re-parsing the original source on each pass.

-- 
Stephen Smalley
National Security Agency


--
This message was distributed to subscribers of the selinux mailing list.
If you no longer wish to subscribe, send mail to majordomo@tycho.nsa.gov with
the words "unsubscribe selinux" without quotes as the message.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2011-05-23 13:46 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-12  9:58 A few questions about module compile/link source code HarryCiao
2011-05-20  1:13 ` Joshua Brindle
2011-05-23 13:15   ` HarryCiao
2011-05-23 13:46     ` Stephen Smalley

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.