First of all, mysterious macros such as your CHECKERROR which hide away flow control are widely considered very bad practice. Don't do that - creating secret macro languages that no other C programmer understands is a much more serious quality concern than code repetition. Code repetition isn't good but it shouldn't be solved by creating a much worse problem. Assume that the reader knows C well, but don't assume that they know or want to know your secret macro language local to this project.
In idiomatic C there are two acceptable ways to write this code. Either with explicit return or with the "on error goto" pattern à la BASIC. I would generally recommend the return version since it saves you from having that old tiresome "goto considered harmful" debate yet again. But goto to a clean-up at the end of the function is acceptable too, as long as you only jump downwards.
(Your do-while(0) with break is just a goto in disguise. It isn't better or worse.)
The single point of return from functions is also debated, especially in the context of MISRA-C (see this). Multiple returns from a function is however fine as long as it doesn't make the code harder to read. In practice this means that you should avoid return (or goto) from inside deeply nested loops or statements. Generally keep the "cyclomatic complexity" (the number of possible execution paths in a function) as low as possible.
In case you need to free up resources, I personally prefer return over goto. For return you need to make a wrapper function, which also serves the purpose of separating resource allocation from the algorithm. I would have rewritten your code like this:
typedef enum // use an actual enum not sloppy int
{
OK, // keeping code 0 for no error is the most common practice
ERR_THIS,
ERR_THAT
} err_t;
static err_t the_actual_algorithm (handle_t res1, handle_t res2) // likely inlined
{
err_t errorcode;
errorcode = action1(res1, res2);
if(errorcode != OK) { return errorcode; }
errorcode = action2(res1, res2);
if(errorcode != OK) { return errorcode; }
return OK;
}
err_t somefunction (void) // note void, not empty parenthesis which is obsolete style
{
handle_t res1, res2;
err_t errorcode;
res1 = getResource();
res2 = getResource();
errorcode = the_actual_algorithm(res1, res2);
freeResource(res1);
freeResource(res2);
return errorcode;
}