bugThe GNU Bourne-Again SHell - Bugs: bug #67586, Fix CHERI out-of-bounds access by...

 
 

bug #67586: Fix CHERI out-of-bounds access by updating 'input_string' after rellaoc

Submitter:  Florian Schmaus <flow>
Submitted:  Mon 06 Oct 2025 05:27:32 PM UTC
   
 
Category:  None Severity:  3 - Normal
Priority:  5 - Normal Item Group:  None
Status:  Fixed Privacy:  Public
Assigned to:  None Open/Closed:  Open
* Mandatory Fields

Post a Comment

Add a New Comment Rich Markup
   

Discussion

Jump to the original submission

Tue 21 Oct 2025 03:08:04 PM UTC, comment #7: 

On 10/21/25 2:17 AM, Florian Schmaus wrote:

> Follow-up Comment #6, bug #67586 (group bash):
>
>
>> OK. Can you give me a non-CHERI example where this fails?
>
> In
>
> void *m1 = malloc(1);
> void *m2 = realloc(m1, 2);
>
> using m1 after realloc() iff m2 != NULL is undefined behavior (UB) because the
> lifetime of m1 ended.


I understand the theory. I have more pragmatic concerns.

> If this UB translates to observable behavior depends on the compiler and the
> used compiler options. Sam provided a link to a post which gave a nice example
> of this when using -D_FORTIFY_SOURCE=3. Maybe using -D_FORTIFY_SOURCE=3 and a
> crafted test case that triggers the xrealloc() code path is enough to observer
> the behavior described in the blog post.

Sam also said he hadn't been able to create a scenario where bash crashes.
I'm trying to find a system where that xrealloc (it's easy to create a
scenario that takes that code path) actually causes problems. lldb/ubsan
doesn't flag it, and the Linux/gcc systems I have ready access to don't
deal with _FORTIFY_SOURCE > 2 (which doesn't trigger it, either). Once I
find a system that exhibits the issue, I can gauge its urgency.

Chet Ramey <chet>
Group administrator
Tue 21 Oct 2025 06:17:00 AM UTC, comment #6: 


> OK. Can you give me a non-CHERI example where this fails?


In

void *m1 = malloc(1);
void *m2 = realloc(m1, 2);

using m1 after realloc() iff m2 != NULL is undefined behavior (UB) because the lifetime of m1 ended.

If this UB translates to observable behavior depends on the compiler and the used compiler options. Sam provided a link to a post which gave a nice example of this when using -D_FORTIFY_SOURCE=3. Maybe using -D_FORTIFY_SOURCE=3 and a crafted test case that triggers the xrealloc() code path is enough to observer the behavior described in the blog post.

But in the end, and in case it matters, I agree with Sam that the correct fix is to run the code unconditionally.

Florian Schmaus <flow>
Mon 20 Oct 2025 08:38:42 PM UTC, comment #5: 

I just want to be able to reproduce this behavior in different failure scenarios.

Chet Ramey <chet>
Group administrator
Mon 20 Oct 2025 08:28:54 PM UTC, comment #4: 

I haven't had Bash fail yet. I've had other applications fail with -D_FORTIFY_SOURCE=3 (which various distros now use) with this problem.

If you don't want to change Bash, while I'd disagree with it, it's your decision -- I partly wanted to note it so Florian has this in mind if he submits similar fixes elsewhere too.

Sam James <thesamesam>
Mon 20 Oct 2025 03:49:57 PM UTC, comment #3: 

OK. Can you give me a non-CHERI example where this fails?

Chet Ramey <chet>
Group administrator
Thu 16 Oct 2025 11:57:46 AM UTC, comment #2: 

I don't think the suggested fix is quite right. See https://gotplt.or ... freed-object.html.

It should be done unconditionally.

Sam James <thesamesam>
Mon 06 Oct 2025 08:02:16 PM UTC, comment #1: 

Thanks for the report. Fixed.

Chet Ramey <chet>
Group administrator
Mon 06 Oct 2025 05:27:32 PM UTC, original submission:  

On CHERI systems with architectural capabilities, the (capability) pointer returned by xrealloc() may have the same address part but it will have updated bounds. Not using the returned pointer with the updated bounds results in CHERI out-of-bounds faults. Therefore, it is important always use the pointer returned by xrealloc() even if its address part is equal.

Bash currently does not update the 'input_string' pointer in read.def:


char *x;
x = (char *)xrealloc (input_string, size += 128);

/* Only need to change unwind-protect if input_string changes */
if (x != input_string)
{
      input_string = x;
      remove_unwind_protect ();
      add_unwind_protect (xfree, input_string);
}


Attached patch fixes this.

Florian Schmaus <flow>

 

Attached Files

Attached Files

(Note: upload size limit is set to 4.0MiB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

 

Dependencies

This item does not depend on any other items.

No items depend on this one.

 

Mail Notification Carbon-Copy List

Carbon-Copy List
  • -email is unavailable- added by thesamesam (Posted a comment)
  • -email is unavailable- added by chet (Posted a comment)
  • -email is unavailable- added by flow (Submitted the item)
  •  

    Votes

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

    History

    Follow 2 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2025-10-06 chet StatusNone Fixed
    2025-10-06 flow Attached File- Added read-always-update-input_string-pointer-on-CHERI.patch, #57701

    Back to the top

    Powered by Savane 3.16-598c.
    Corresponding source code