RHEL Engineering is moving the tracking of its product development work on RHEL 6 through RHEL 9 to Red Hat Jira (issues.redhat.com). If you're a Red Hat customer, please continue to file support cases via the Red Hat customer portal. If you're not, please head to the "RHEL project" in Red Hat Jira and file new tickets here. Individual Bugzilla bugs in the statuses "NEW", "ASSIGNED", and "POST" are being migrated throughout September 2023. Bugs of Red Hat partners with an assigned Engineering Partner Manager (EPM) are migrated in late September as per pre-agreed dates. Bugs against components "kernel", "kernel-rt", and "kpatch" are only migrated if still in "NEW" or "ASSIGNED". If you cannot log in to RH Jira, please consult article #7032570. That failing, please send an e-mail to the RH Jira admins at rh-issues@redhat.com to troubleshoot your issue as a user management inquiry. The email creates a ServiceNow ticket with Red Hat. Individual Bugzilla bugs that are migrated will be moved to status "CLOSED", resolution "MIGRATED", and set with "MigratedToJIRA" in "Keywords". The link to the successor Jira issue will be found under "Links", have a little "two-footprint" icon next to it, and direct you to the "RHEL project" in Red Hat Jira (issue links are of type "https://issues.redhat.com/browse/RHEL-XXXX", where "X" is a digit). This same link will be available in a blue banner at the top of the page informing you that that bug has been migrated.
Bug 1845161 - ipmitool dies in read_fru_area() repeatedly due to buffer overflow
Summary: ipmitool dies in read_fru_area() repeatedly due to buffer overflow
Keywords:
Status: CLOSED WORKSFORME
Alias: None
Product: Red Hat Enterprise Linux 8
Classification: Red Hat
Component: ipmitool
Version: 8.2
Hardware: All
OS: Linux
high
high
Target Milestone: rc
: 8.0
Assignee: Pavel Cahyna
QA Contact: Rachel Sibley
URL:
Whiteboard:
Depends On:
Blocks: 1894575
TreeView+ depends on / blocked
 
Reported: 2020-06-08 14:52 UTC by Renaud Métrich
Modified: 2021-02-03 22:55 UTC (History)
4 users (show)

Fixed In Version:
Doc Type: No Doc Update
Doc Text:
Clone Of:
Environment:
Last Closed: 2021-02-03 22:54:58 UTC
Type: Bug
Target Upstream Version:
Embargoed:


Attachments (Terms of Use)


Links
System ID Private Priority Status Summary Last Updated
Github ipmitool ipmitool pull 191 0 None open read_fru_area: fix memset() parameters 2021-02-10 11:19:31 UTC

Description Renaud Métrich 2020-06-08 14:52:12 UTC
This bug was initially created as a copy of Bug #1845158

I am copying this bug because: 

From source code, should also happen on RHEL8 and Upstream

Description of problem:

A customer reports the ipmitool is repeatedly dying with Segmentation fault.
The coredump analysis shows that this is due to a buffer overflow while initializing memory to 0.

Backtrace:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
Core was generated by `                           '.
#0  __memset_sse2 () at ../sysdeps/x86_64/memset.S:908
908		movntdq %xmm0,(%rdi)
(gdb) bt
#0  __memset_sse2 () at ../sysdeps/x86_64/memset.S:908
#1  0x000000000041ff78 in read_fru_area (intf=0x6c12e0, fru=0x7ffe544fa1f0, id=16 '\020', offset=256, 
    length=2, frubuf=0x7ffe544fa200 "\001\t") at /usr/include/bits/string3.h:85
#2  0x0000000000425f72 in fru_area_print_product (intf=0x6c12e0, id=16 '\020') at ipmi_fru.c:1139
#3  __ipmi_fru_print (intf=0x6c12e0, id=16 '\020') at ipmi_fru.c:2983
#4  0x00000000004269ce in ipmi_fru_print (intf=0x6c12e0, fru=0x19952c0) at ipmi_fru.c:3057
#5  0x0000000000426c9b in ipmi_fru_print_all (intf=0x6c12e0) at ipmi_fru.c:3187
#6  0x0000000000426e68 in ipmi_fru_main (intf=0x6c12e0, argc=1, argv=0x7ffe544fa628) at ipmi_fru.c:4424
#7  0x0000000000000000 in ?? ()

(gdb) up
#1  0x000000000041ff78 in read_fru_area (intf=0x6c12e0, fru=0x7ffe544fa1f0, id=16 '\020', offset=256, 
    length=2, frubuf=0x7ffe544fa200 "\001\t") at /usr/include/bits/string3.h:85
85	/usr/include/bits/string3.h: No such file or directory.
	in /usr/include/bits/string3.h
(gdb) p fru->size
$1 = 256
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

The crash happened in read_fru_area() while setting memory to 0. The buffer overflow resulted in corrupting the stack (hence the question marks "??" and the invalid command detected as "null string" in "Core was generated by" line above).
On frame 1, we see that:
- offset=256
- length=2
- frubuf is a buffer defined in fru_area_print_product() on line 1134 in the stack (see below)
- fru->size=256

Related source code:
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
 597 int
 598 read_fru_area(struct ipmi_intf * intf, struct fru_info *fru, uint8_t id,
 599                         uint32_t offset, uint32_t length, uint8_t *frubuf)
 600 {
 :
 614 
 615         finish = offset + length;
 616         if (finish > fru->size) {
 617                 memset(frubuf + fru->size, 0, length - fru->size);
 618                 finish = fru->size;
 619                 lprintf(LOG_NOTICE, "Read FRU Area length %d too large, "
 620                         "Adjusting to %d",
 621                         offset + length, finish - offset);
 622                 length = finish - offset;
 623         }
 :

1127 static void
1128 fru_area_print_product(struct ipmi_intf * intf, struct fru_info * fru,
1129                                 uint8_t id, uint32_t offset)
1130 {
1131         char * fru_area;
1132         uint8_t * fru_data;
1133         uint32_t fru_len, i;
1134         uint8_t tmp[2];
1135 
1136         fru_len = 0;
1137 
1138         /* read enough to check length field */
1139         if (read_fru_area(intf, fru, id, offset, 2, tmp) == 0) {
1140                 fru_len = 8 * tmp[1];
1141         }
 :
-------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

The interesting code is line 617. Here we have an initialization of the memory to 0.
I can see 2 code errors here:
- frubuf + fru->size (256) is memory outside frubuf "allocated area" (which is 2 bytes, as shown on line 1134)
- the computation "length - fru->size" equals -254 which is negative value, which is not something possible, from memset(3) manpage ("size_t" is an unsigned number):

  memset(3) excerpt:
  -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------
  void *memset(void *s, int c, size_t n);

  The  memset() function fills the first n bytes of the memory area pointed to by s with the constant byte c.
  -------- 8< ---------------- 8< ---------------- 8< ---------------- 8< --------

All this looks non-sense to me.
Browsing the Web, I could find the following "bug report" again Upstream code, which looks pretty similar:

  https://www.bountysource.com/issues/75164615-buffer-overflow-in-fru_area_print_product


Version-Release number of selected component (if applicable):


How reproducible:


Steps to Reproduce:
1.
2.
3.

Actual results:


Expected results:


Additional info:

Comment 1 Vaclav Dolezal 2020-06-23 12:15:54 UTC
Thanks for extensive report.

It looks that the intent of this line is just to zero unused part of `frubuf`.
This is probably unnecessary as all functions passes buffers which are zeroed.

I found related pull request upstream (added to links).


Note You need to log in before you can comment on or make changes to this bug.