UNIX Socket FAQ

A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

  • Index
  • » C
  • » C multi-line macro: do/while(0) and checking its return value

#1 2017-02-16 09:12 PM

eax
Member
Registered: 2017-01-20
Posts: 4

C multi-line macro: do/while(0) and checking its return value

Hello,

I'm interested in the security aspect of macro like this:

#define SET_GUID() do \
 { \
    setgid(real_gid); \
    setuid(real_uid); \
    eff_uid = real_uid; \
    eff_gid = real_gid; \
  } while (0)

...

SET_GUID();

What are the benefits (if any) of writing the code in that way? This program should run with root privilege and in some cases we change uid.
The return value from the call of setgid/setuid is not checked. If an error occurs in run time of these functions, the following code may execute with unexpected privileges.
Is there any reason to believe that this will always works fine?

I think programmer should always check return values after every function call.

Thank you,
Alex


p.s. I found this thread, but there is nothing about security or general C problems, regarding return values.
http://stackoverflow.com/questions/1067 … cope-block

Last edited by eax (2017-02-16 09:16 PM)

Offline

#2 2017-02-17 01:23 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: C multi-line macro: do/while(0) and checking its return value

You're right that it's always a good idea to check return values, especially for something important like setuid(), where its failure will leave you running with an unexpected UID...  In practice, if you start off as root, the setuid() is likely going to always work anyway, but it sure can't hurt to make sure!  Since it's a macro, it's easy enough to add the checking right there and all callers will automatically get the checking without needing to change them all...  You presumably just want to die with a fatal error if the setuid()/setgid() fails...

(In actual practice, no one checks the return value from EVERYTHING, though...  Eg: nearly everyone ignores the return value from printf() and friends, as well as from close()...  If you can't figure out what you should do in the case something fails, there's not much point in checking for failure...  Seriously, what are you going to do if close() fails?  Keep retrying forever?  Die with a fatal error?  That's hardly an improvement over just silently carrying on with a possibly unclosed file descriptor...  Maybe logging it and carrying on is best, but in practice how much real good is that logging going to do?)

Offline

#3 2017-02-17 09:58 PM

eax
Member
Registered: 2017-01-20
Posts: 4

Re: C multi-line macro: do/while(0) and checking its return value

RobSeace wrote:

Since it's a macro, it's easy enough to add the checking right there and all callers will automatically get the checking without needing to change them all...

What do you mean "to add the checking right there"? Can you show code please?
I can check every function, but in my view it make more sense to put all function in new function and don't use macro. Which benefits gives me macro like this in this case?

Offline

#4 2017-02-18 03:42 PM

RobSeace
Administrator
From: Boston, MA
Registered: 2002-06-12
Posts: 3,829
Website

Re: C multi-line macro: do/while(0) and checking its return value

Well, the benefit of a macro over inline code is the same benefit of using a function in place of inline code: code reduction and cleaner codebase...  Anything that's done multiple times throughout your codebase and which takes multiple lines of code to do each time is a good candidate for breaking out into a separate function or macro...  That way you can be sure all places are using the same exact code, and if you should ever need to change it, you only need change the one location (function definition or macro definition) and all callers get the changes automatically...

As for what I mean, I mean just add the return value checking to the existing macro definition...  Eg:

#define SET_GUID() do \
 { \
    if (setgid(real_gid)) die ("setgid(): %s", strerror (errno)); \
    if (setuid(real_uid)) die ("setuid(): %s", strerror (errno)); \
    eff_uid = real_uid; \
    eff_gid = real_gid; \
  } while (0)

Where die() is some function that logs an error message and exits...

Offline

  • Index
  • » C
  • » C multi-line macro: do/while(0) and checking its return value

Board footer

Powered by FluxBB