Bug 58646

Summary: Risky variable declaration inside a macros may cause segmentation fault
Product: [Retired] Red Hat Linux Reporter: Denis <denis.ermoshin>
Component: mmAssignee: Nalin Dahyabhai <nalin>
Status: CLOSED WONTFIX QA Contact:
Severity: medium Docs Contact:
Priority: medium    
Version: 7.2   
Target Milestone: ---   
Target Release: ---   
Hardware: i386   
OS: Linux   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2002-01-22 09:06:14 UTC Type: ---
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:

Description Denis 2002-01-22 09:06:09 UTC
From Bugzilla Helper:
User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows NT 5.0)

Description of problem:
The package mm contains the header file mm.h. There is a bug in mm.h. By the 
way, this header file is installed into the directory /usr/include where 
standard header files are. 
mm.h contains macro versions of the standard functions memset and memcpy, and 
may declare these macros instead of the real functions in some conditions. See 
the lines 119-130 of mm.h:

#if !defined(HAVE_MEMCPY)
#if defined(HAVE_BCOPY)
#define memcpy(to,from,len) bcopy(from,to,len)
#else
#define memcpy(to,from,len) \
        { int i; for (i = 0; i < (len); i++) *(((char *)(to))+i) = *(((char *)
(from))+i); }
#endif
#endif
#if !defined(HAVE_MEMSET)
#define memset(to,ch,len) \
        { int i; for (i = 0; i < (len); i++) *(((char *)(to))+i) = (ch); }
#endif

You can see that the variable "i" is declared inside the macros. It is risky. 
For example, this causes a real problem if trying to build the package mm not 
by the standard GNU C/C++ compiler (gcc) but the Intel C/C++ compiler (icc). 
For gcc, the script "configure" makes HAVE_MEMCPY and HAVE_MEMSET defined so 
that the macros are not declared. For icc, they are declared. (In future 
versions of icc, this may change.) Then mm_test.c is built, run and then 
crashes emitting the message "Segmentation fault". The problem is that 
mm_test.c calls memset in the following way (line 225):
memset(cp[i], 0xF5, (i+1)*(i+1));
You can see that this macro call will be preprocessed into the following 
erroneous code:
{ int i; for (i = 0; i < ((i+1)*(i+1)); i++) *(((char *)(cp[i]))+i) = (0xF5); };


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


How reproducible:
Always

Steps to Reproduce:
If you don't have Intel compiler (icc) you are unable to reproduce the problem. 
This compiler is not free. If you really need it to fix the problem, let me 
know and I'll try to help you. If you have the compiler, the steps to reproduce 
the problem will be the following:
1. Make sure that all environment necessary for icc is set.
2. Make sure that icc will be called instead of gcc, g++, cc, cpp and c++. I 
recommend you make links to icc with these names, put them into some directory 
and add this directory to the beginning of the PATH variable.
3. Install the package mentioned above from the .src.rpm file (-i option of 
rpm). Make sure you have enough permissions to do that.
4. Try to build the .spec file (-bc option of rpm).


Actual Results:  The package won't build. In the output (somewhere near the 
end), you may see the message "Segmentation fault". 


Expected Results:  The package should build Ok and print the following in the 
end:
OK - ALL TESTS SUCCESSFULLY PASSED.


Additional info:

I would recommend you to substitute "__i" for "i" in the macro definitions. As 
far as I know, the prefix "__" is reserved for standard headers and user is not 
expected to start his/her variable names with "__".

Comment 1 Nalin Dahyabhai 2002-07-24 19:07:06 UTC
These macros appear to be defined in the private section of the header, and
shouldn't be processed at all unless MM_PRIVATE has been defined at
compile-time.  I'm inclined to close this bug and tag it "won't fix" because I
don't see how this could happen if the header were used properly.