<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<style type="text/css" style="display:none;"><!-- P {margin-top:0;margin-bottom:0;} --></style>
</head>
<body dir="ltr">
<div id="divtagdefaultwrapper" style="font-size:12pt;color:#000000;font-family:Calibri,Helvetica,sans-serif;" dir="ltr">
<p style="margin-top:0;margin-bottom:0">Thank you for the correction John.</p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">Despite changing the code to use strdup( ), the kernel still crashes. I have attached the modified file for reference. </p>
<p style="margin-top:0;margin-bottom:0"><br>
</p>
<p style="margin-top:0;margin-bottom:0">Is there anything else that might be causing the crash?</p>
</div>
<hr style="display:inline-block;width:98%" tabindex="-1">
<div id="divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" style="font-size:11pt" color="#000000"><b>From:</b> John Johansen <john.johansen@canonical.com><br>
<b>Sent:</b> 30 July 2019 04:10:00<br>
<b>To:</b> Abhishek Vijeev <abhishekvijeev@iisc.ac.in>; apparmor@lists.ubuntu.com <apparmor@lists.ubuntu.com><br>
<b>Cc:</b> Rakesh Rajan Beck <rakeshbeck@iisc.ac.in><br>
<b>Subject:</b> Re: [apparmor] Questions about AppArmor's Kernel Code</font>
<div> </div>
</div>
<div class="BodyFragment"><font size="2"><span style="font-size:11pt;">
<div class="PlainText">I haven't tested if this is the cause of your failure but it could very well be<br>
<br>
+ // Custom code begin<br>
+<br>
+ if (unpack_nameX(e, AA_STRUCT, "custom_label"))<br>
+ {<br>
+ profile->clabel = kzalloc (sizeof(struct custom_label), GFP_KERNEL);<br>
+ if (!profile->clabel)<br>
+ goto fail;<br>
<br>
this block of code<br>
+ if (!unpack_str(e, &name, NULL))<br>
+ goto fail;<br>
+ profile->clabel->label_name = kzalloc (strlen(name), GFP_KERNEL);<br>
+ if (!profile->clabel->label_name)<br>
+ goto fail;<br>
+ <br>
+ strcpy (profile->clabel->label_name, name);<br>
+<br>
you are allocation a string that is not long enough to include the null terminating \0 so when<br>
you use strcpy it is writing one byte beyond your allocated data.<br>
<br>
replace this with<br>
+ if (!unpack_strdup(e, &profile->clabel->label_name, NULL))<br>
+ goto fail;<br>
<br>
<br>
<br>
<br>
+ if (!unpack_u32(e, &(profile->clabel->allow_cnt), NULL))<br>
+ goto fail;<br>
+<br>
+ <br>
+ if (unpack_nameX(e, AA_STRUCT, "data_list")) <br>
+ {<br>
+ profile->clabel->allow_list = kzalloc(sizeof(struct data_list), GFP_KERNEL);<br>
+ if (!profile->clabel->allow_list)<br>
+ goto fail;<br>
+ INIT_LIST_HEAD(&(profile->clabel->allow_list->lh));<br>
+<br>
+ for (i = 0; i < profile->clabel->allow_cnt; i++)<br>
+ {<br>
+ if (!unpack_str(e, &name, NULL))<br>
+ goto fail;<br>
+ struct data_list *new_node = kzalloc(sizeof(struct data_list), GFP_KERNEL);<br>
+ if (!new_node)<br>
+ goto fail;<br>
<br>
<br>
same thing for this block of code<br>
+ new_node->data = kzalloc(strlen(name), GFP_KERNEL);<br>
+ if (!new_node->data)<br>
+ goto fail;<br>
+ strcpy(new_node->data, name);<br>
its writing 1 past the end of your allocation. You can either<br>
- increase allocation size by one to account for terminating \0<br>
- switch to unpack_strdup() like above and add a free on failure<br>
<br>
<br>
<br>
+ INIT_LIST_HEAD(&(new_node->lh));<br>
+ list_add(&(new_node->lh), &(profile->clabel->allow_list->lh));<br>
+ }<br>
+ if (!unpack_nameX(e, AA_STRUCTEND, NULL))<br>
+ goto fail;<br>
+ }<br>
+ if (!unpack_nameX(e, AA_STRUCTEND, NULL))<br>
+ goto fail; <br>
+ }<br>
+<br>
+ // Custom code end<br>
<br>
On 7/29/19 12:58 AM, Abhishek Vijeev wrote:<br>
> Thank you for the explanation John.<br>
> <br>
> I have attached the files we have modified. Every piece of code that we inserted is enclosed<br>
> within comment lines 'Custom code begin' and 'Custom code end' so that it's easy for you to find. Here<br>
> is a brief description of the changes made:<br>
> <br>
> AppArmor Parser (user-space) - We modified the grammar of AppArmor's parser to include additional <br>
> grammar rules. These rules store data in class Profile<br>
> <br>
> a) profile.h - 2 new structure definitions to store our custom data<br>
> - class Profile now contains a member 'clabel' <br>
> b) parser_interface.c - Added code to sd_serialize_profile( ) that serializes the additional custom<br>
> data we added to class Profile during the parsing phase<br>
> AppArmor LSM (kernel) : <br>
> <br>
> <br>
> a) include/policy.h - 2 new structure definitions<br>
> - struct aa_profile now contains a member 'clabel'<br>
> <br>
> b) policy_unpack.c- Added code to unpack_profile( ) that unpacks the serialized object sent from <br>
> user-space, and allocates kernel memory for the security structures added to <br>
> aa_profile - namely, a label string and a linked list containing allow permissions<br>
> c) policy.c - Added code to function aa_free_profile( ) that frees the allocated memory <br>
> <br>
> ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<br>
> *From:* John Johansen <john.johansen@canonical.com><br>
> *Sent:* 27 July 2019 00:10:14<br>
> *To:* Abhishek Vijeev <abhishekvijeev@iisc.ac.in>; apparmor@lists.ubuntu.com <apparmor@lists.ubuntu.com><br>
> *Cc:* Rakesh Rajan Beck <rakeshbeck@iisc.ac.in><br>
> *Subject:* Re: [apparmor] Questions about AppArmor's Kernel Code<br>
> <br>
> On 7/26/19 5:56 AM, Abhishek Vijeev wrote:<br>
>> Hi,<br>
>> <br>
>> <br>
>> I have a few questions about AppArmor's kernel code and would be grateful if you could kindly answer them. <br>
>> <br>
>> <br>
>> 1) Why does AppArmor maintain two separate security blobs in cred->security as well as task-security for processes? For a simple project that requires associating a security context with every task, would it suffice to use just one of these?<br>
>> <br>
> the task->security field is used to store task specific information, that is not used for general mediation. Currently the information stored their is for the change_hat and change_onexec apis and some info to track what the confinement was when no-newprivs
was applied to the task.<br>
> <br>
> cred->security is used to store the subjects label (type) for mediation.<br>
> <br>
> Before the task->security field was reintroduce all the information was stored off the cred in a intermediate structure. Doing so would cause use of the change_hat and change_onexec api to change the cred of the task even when the confinement had not changed.
The switch to using the task->security field was pre 4.18<br>
> <br>
>> <br>
>> 2) There has been a change in the way security blobs are accessed from kernel version 4.18 to 5.2. I see that in v5.2, the security blob's address is obtained by adding the size of the blob to the start address. Why has this change been made? (For reference: <a href="https://github.com/torvalds/linux/blob/master/security/apparmor/include/cred.h#L24">https://github.com/torvalds/linux/blob/master/security/apparmor/include/cred.h#L24</a>)<br>
>> <br>
> see Casey's answer<br>
> <br>
>> <br>
>> 3) I tried adding a custom field (pointer to a custom structure) to struct aa_profile, at exactly this point - <a href="https://github.com/torvalds/linux/blob/master/security/apparmor/include/policy.h#L144">https://github.com/torvalds/linux/blob/master/security/apparmor/include/policy.h#L144</a>.
I have taken care to allocate and free memory for the pointer at the appropriate places (allocation is performed here - <a href="https://github.com/torvalds/linux/blob/master/security/apparmor/policy_unpack.c#L671">https://github.com/torvalds/linux/blob/master/security/apparmor/policy_unpack.c#L671</a> and
freeing is performed here - <a href="https://github.com/torvalds/linux/blob/master/security/apparmor/policy.c#L205">https://github.com/torvalds/linux/blob/master/security/apparmor/policy.c#L205</a>). However, while booting the kernel, it crashes at the function
'security_prepare_creds( )', which I presume invokes 'apparmor_cred_prepare( )'. If I was, to assume for a moment that there are no bugs with my memory allocation code, is there any other reason why such a crash might have occurred? I have attached the kernel
crash log file with this email for your kind reference. <br>
>> <br>
> <br>
> I know the code points but to be able to comment beyond vague guesses I need to see your changes. I can give you the warning to not add your field after the current last field,<br>
> <br>
> struct aa_label label;<br>
> <br>
> as it has a variable length field. While that is always 2 entries when its embedded in the profile the compiler will end up treating it as zero length over lapping your new field with the start of the variable length array.<br>
> <br>
> I do have a patch to address this using a union but I haven't landed it yet.<br>
<br>
</div>
</span></font></div>
</body>
</html>