LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   strcpy differences under HP-UX and Linux (https://www.linuxquestions.org/questions/programming-9/strcpy-differences-under-hp-ux-and-linux-832988/)

amarg 09-18-2010 03:10 AM

strcpy differences under HP-UX and Linux
 
Hi All,

Following code works perfect under HP-UX.

#include <string.h>

int main() {
char a[10];
char *b = NULL;

strcpy(a, b);
}

But same code crash under linux (Red Hat). It’s crashing with obvious reasons.
Best solution will be put the check before each strcpy and throw the error in case of 2nd arg pointing to NULL.

Currently we are doing the HP-UX to Linux migration, and it will be very hard to do these changes in all the places.

Any suggestions?

Regards,
Amar

rupertwh 09-18-2010 03:24 AM

Quote:

Originally Posted by amarg (Post 4101461)
Following code works perfect under HP-UX.

There is no way a strcpy from a null pointer can work perfect(ly) in C.

Quote:

Originally Posted by amarg (Post 4101461)
Any suggestions?

  • your code is broken
  • fix it

Regards

Rupert

Aquarius_Girl 09-18-2010 03:33 AM

Quote:

Originally Posted by amarg (Post 4101461)
and it will be very hard to do these changes in all the places.

Any suggestions?

Use the mighty debugger : http://www.gnu.org/software/gdb/documentation/

When your code will gift you the "segmentation fault" ,the debugger will lead your way and point you to the buggy code. That way you'll spend less time hunting for bugs in the large code.

and use code tags for posting code in the forum:
http://www.linuxquestions.org/questi...do=bbcode#code

amarg 09-18-2010 04:15 AM

Yes Code is broken agreed. But it's a fact it's working fine under HP-UX. May be because of smart compiler of HP-UX.
I agree, code is not written good. And this problem will not be only with strcpy, it’s going to be with all string operation.

HP-UX given the flexibility to do this mistake, and guys are doing it since last 10-15 years without any problem.

Now we are migrating to the Linux (just because of cost cutting).

Fix for this problem is very easy, but it’s 20-30 thousand files, I don’t remember how many string operations are there.
Fix one by one all the string operation will take years, so looking for some other smart solution like re-writing the string function again to handle NULL pointer.

eg.

strcpy(char *a, char *b) {
if(a == NULL) throw error;
if(b == NULL) throw error;
original.strcpy(a,b);
}

Just looking for some good suggestion.

amarg 09-18-2010 04:16 AM

Addition to above comment, strcpy(a, b) is working fine in case of b is NULL, but crashing (I hope should crash everywhere) where a is NULL.

Aquarius_Girl 09-18-2010 04:17 AM

Quote:

Originally Posted by amarg (Post 4101498)
But it's a fact it's working fine under HP-UX. May be because of smart compiler of HP-UX.

A compiler which ignores broken code is DUMB not smart ;)

amarg 09-18-2010 04:29 AM

Yes, you are right. But it's actually not ignoring.
It's just putting a[0] = '\0';
which is exactly our implemetation is looking for.

I think because of this no one notice this problem even exist.
Now only because of Linux we started to get this problem.
Code is nearly about 10-15 year old.

mallikarjun_chougule 05-23-2023 11:16 AM

Hi @amarg, I'm here in 2023 with same issue. Porting legacy C code from HP-UX to RHEL and foudn that, HP-UX complier can derefrence NULL pointer inside string operation methods like strcpy, strlen. However, RHEL GCC complier SegFaluts.

What solution applied you back then to resolve this issue with derefrencing NULL pointer for RHEL GCC complier.
Any wrapper method for legacy strcpy()? Thanks for your suggestions.

NevemTeve 05-23-2023 11:59 AM

Aix is another example for a platform, where address zero is readable (the kernel starts at address zero).

There is no universal solution, the bugs have to be found one by one. The good news is that you can use valgrind on Linux: it will find many other problems as well (e.g. uninitalized variables).

PS: if your old platform is big endian, then expect some problems on little endian platform x86 (or amd64).

PPS: Current gcc/clang compilers give you many useful warnings, I suggest you fix them all.

pan64 05-23-2023 12:51 PM

Quote:

Originally Posted by mallikarjun_chougule (Post 6432482)
Any wrapper method for legacy strcpy()? Thanks for your suggestions.

There is no wrapper. It is just incorrect (strcpy to/from NULL).
That code is just broken and useless (not strcpy, but where is it called from). So you need to inspect that one by one (line by line) and find out what was the original intention.
There is only one general way to avoid segfault:
define (overwrite) strcpy to check first a and b and do nothing if any of them is NULL. But I don't think your code will work that way.

dugan 05-23-2023 05:53 PM

I think I know what the code does. Replace it with:

Code:

#include <string.h>

int main() {
char a[10];
memset(a, '\0', sizeof(char) * 10);
}

And if it's modern C++, replace it with:

Code:

int main() {
char a[10]{};
}

Of course, this works too:

Quote:

Originally Posted by amarg (Post 4101508)
Yes, you are right. But it's actually not ignoring.
It's just putting a[0] = '\0';
which is exactly our implemetation is looking for.

If you need the process of finding these errors to go faster, use clang-tidy:

Code:

❯ cat init.c
#include <stdio.h>
#include <string.h>

int main()
{

    char a[10];
    char *b = NULL;

    strcpy(a, b);

    printf("%s\n", a);
}

~/Documents/init via C v13.1.1-gcc
❯ bear -- gcc init.c

~/Documents/init via C v13.1.1-gcc
❯ clang-tidy init.c
2 warnings generated.
init.c:10:5: warning: Null pointer passed to 2nd parameter expecting 'nonnull' [clang-analyzer-core.NonNullParamChecker]
    strcpy(a, b);
    ^        ~
init.c:8:5: note: 'b' initialized to a null pointer value
    char *b = NULL;
    ^~~~~~~
init.c:10:5: note: Null pointer passed to 2nd parameter expecting 'nonnull'
    strcpy(a, b);
    ^        ~
init.c:10:5: warning: Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119 [clang-analyzer-security.insecureAPI.strcpy]
    strcpy(a, b);
    ^~~~~~
init.c:10:5: note: Call to function 'strcpy' is insecure as it does not provide bounding of the memory buffer. Replace unbounded copy functions with analogous functions that support length arguments such as 'strlcpy'. CWE-119
    strcpy(a, b);
    ^~~~~~

There are no shortcuts beyond this. If fixing the technical debt in this legacy code is going to take years, then, well, that's your estimate.

jmccue 05-25-2023 07:30 AM

Quote:

Originally Posted by amarg (Post 4101461)
Currently we are doing the HP-UX to Linux migration, and it will be very hard to do these changes in all the places.
Any suggestions?

I can see that happening if HPUX did something with its version of strcpy().

Maybe use sed to do something like this:

Code:

sed 's/strcpy(a, b);/strcpy(a, (b == NULL ? "" : b));/'
Or better option is create a wrap-around to strcpy() and add that function to all your programs, use sed to change strcpy to hpstrcpy:

Code:

char *hpstrcpy(char *a, char *b)
{
if (b == NULL)
  *a=NULL;
else
  strcpy(a,b);

return(a);
}

good luck

ntubski 05-25-2023 07:43 AM

Quote:

Originally Posted by jmccue (Post 6432809)
Maybe use sed to do something like this:

Code:

sed 's/strcpy(a, b);/strcpy(a, (b == NULL ? "" : b));/'

You might consider looking into more specialized tools than sed. For example, I've seen the Linux kernel project reference https://coccinelle.lip6.fr/

Quote:

Coccinelle is a program matching and transformation engine which provides the language SmPL (Semantic Patch Language) for specifying desired matches and transformations in C code.


All times are GMT -5. The time now is 09:17 PM.