Commit Graph

24 Commits

Author SHA1 Message Date
FRIGN
d23cc72490 Simplify return & fshut() logic
Get rid of the !!()-constructs and use ret where available (or introduce it).

In some cases, there would be an "abort" on the first fshut-error, but we want
to close all files and report all warnings and then quit, not just the warning
for the first file.
2015-05-26 16:41:43 +01:00
FRIGN
9a074144c9 Remove handrolled strcmp()'s
Favor readability over bare-metal.
2015-05-21 15:43:38 +01:00
FRIGN
0545d32ce9 Handle '-' consistently
In general, POSIX does not define /dev/std{in, out, err} because it
does not want to depend on the dev-filesystem.
For utilities, it thus introduced the '-'-keyword to denote standard
input (and output in some cases) and the programs have to deal with
it accordingly.

Sadly, the design of many tools doesn't allow strict shell-redirections
and many scripts don't even use this feature when possible.

Thus, we made the decision to implement it consistently across all
tools where it makes sense (namely those which read files).

Along the way, I spotted some behavioural bugs in libutil/crypt.c and
others where it was forgotten to fshut the files after use.
2015-05-16 13:34:00 +01:00
Hiltjo Posthuma
e2edbdcb87 sed: use reallocarray (non-issue) 2015-04-17 19:01:02 +01:00
sin
ea819714c2 Don't close stdin early in sed(1)
Fix by emg.
2015-04-09 15:33:57 +01:00
Hiltjo Posthuma
dd395693d4 sed: remove unused strnacpy() 2015-04-08 15:32:56 +01:00
FRIGN
11e2d472bf Add *fshut() functions to properly flush file streams
This has been a known issue for a long time. Example:

printf "word" > /dev/full

wouldn't report there's not enough space on the device.
This is due to the fact that every libc has internal buffers
for stdout which store fragments of written data until they reach
a certain size or on some callback to flush them all at once to the
kernel.
You can force the libc to flush them with fflush(). In case flushing
fails, you can check the return value of fflush() and report an error.

However, previously, sbase didn't have such checks and without fflush(),
the libc silently flushes the buffers on exit without checking the errors.
No offense, but there's no way for the libc to report errors in the exit-
condition.

GNU coreutils solve this by having onexit-callbacks to handle the flushing
and report issues, but they have obvious deficiencies.
After long discussions on IRC, we came to the conclusion that checking the
return value of every io-function would be a bit too much, and having a
general-purpose fclose-wrapper would be the best way to go.

It turned out that fclose() alone is not enough to detect errors. The right
way to do it is to fflush() + check ferror on the fp and then to a fclose().
This is what fshut does and that's how it's done before each return.
The return value is obviously affected, reporting an error in case a flush
or close failed, but also when reading failed for some reason, the error-
state is caught.

the !!( ... + ...) construction is used to call all functions inside the
brackets and not "terminating" on the first.
We want errors to be reported, but there's no reason to stop flushing buffers
when one other file buffer has issues.
Obviously, functionales come before the flush and ret-logic comes after to
prevent early exits as well without reporting warnings if there are any.

One more advantage of fshut() is that it is even able to report errors
on obscure NFS-setups which the other coreutils are unable to detect,
because they only check the return-value of fflush() and fclose(),
not ferror() as well.
2015-04-05 09:13:56 +01:00
Hiltjo Posthuma
06b663234f sed: declare functions and global vars static (some still missing) 2015-03-27 16:20:50 +01:00
Hiltjo Posthuma
244539e473 sed: style improvements
- declare variables at the top of a function.
- free(NULL) is valid.
- avoid VLA.
2015-03-27 16:01:55 +01:00
Hiltjo Posthuma
0547e72441 sed: show specific error strings (strerror) and minor style fixes 2015-03-27 15:59:09 +01:00
FRIGN
9144d51594 Check getline()-return-values properly
It's not useful when 0 is returned anyway, so be sure that we have a
string with length > 0, this also solves some indexing-gotchas like
"len - 1" and so on.
Also, add checked getline()'s whenever it has been forgotten and
clean up the error-messages.
2015-03-27 14:49:48 +01:00
Evan Gates
b7886f3e67 change estrlcat back to strlcat
strlcat is used to here to purposely truncate the string
2015-03-24 22:50:26 +00:00
FRIGN
93fd817536 Add estrlcat() and estrlcpy()
It has become a common idiom in sbase to check strlcat() and strlcpy()
using

if (strl{cat, cpy}(dst, src, siz) >= siz)
        eprintf("path too long\n");

However, this was not carried out consistently and to this very day,
some tools employed unchecked calls to these functions, effectively
allowing silent truncations to happen, which in turn may lead to
security issues.
To finally put an end to this, the e*-functions detect truncation
automatically and the caller can lean back and enjoy coding without
trouble. :)
2015-03-17 11:24:49 +01:00
Evan Gates
ad6da18ca6 increment pointer by runelen(delim) not 1 2015-03-13 13:42:03 +00:00
FRIGN
833c2aebb4 Remove mallocarray(...) and use reallocarray(NULL, ...)
After a short correspondence with Otto Moerbeek it turned out
mallocarray() is only in the OpenBSD-Kernel, because the kernel-
malloc doesn't have realloc.
Userspace applications should rather use reallocarray with an
explicit NULL-pointer.

Assuming reallocarray() will become available in c-stdlibs in the
next few years, we nip mallocarray() in the bud to allow an easy
transition to a system-provided version when the day comes.
2015-03-11 10:50:18 +01:00
FRIGN
3c33abc520 Implement mallocarray()
A function used only in the OpenBSD-Kernel as of now, but it surely
provides a helpful interface when you just don't want to make sure
the incoming pointer to erealloc() is really NULL so it behaves
like malloc, making it a bit more safer.

Talking about *allocarray(): It's definitely a major step in code-
hardening. Especially as a system administrator, you should be
able to trust your core tools without having to worry about segfaults
like this, which can easily lead to privilege escalation.

How do the GNU coreutils handle this?
$ strings -n 4611686018427387903
strings: invalid minimum string length -1
$ strings -n 4611686018427387904
strings: invalid minimum string length 0

They silently overflow...

In comparison, sbase:

$ strings -n 4611686018427387903
mallocarray: out of memory
$ strings -n 4611686018427387904
mallocarray: out of memory

The first out of memory is actually a true OOM returned by malloc,
whereas the second one is a detected overflow, which is not marked
in a special way.
Now tell me which diagnostic error-messages are easier to understand.
2015-03-10 22:19:19 +01:00
FRIGN
3b825735d8 Implement reallocarray()
Stateless and I stumbled upon this issue while discussing the
semantics of read, accepting a size_t but only being able to return
ssize_t, effectively lacking the ability to report successful
reads > SSIZE_MAX.
The discussion went along and we came to the topic of input-based
memory allocations. Basically, it was possible for the argument
to a memory-allocation-function to overflow, leading to a segfault
later.
The OpenBSD-guys came up with the ingenious reallocarray-function,
and I implemented it as ereallocarray, which automatically returns
on error.
Read more about it here[0].

A simple testcase is this (courtesy to stateless):
$ sbase-strings -n (2^(32|64) / 4)

This will segfault before this patch and properly return an OOM-
situation afterwards (thanks to the overflow-check in reallocarray).

[0]: http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man3/calloc.3
2015-03-10 21:23:36 +01:00
sin
804b62f7a2 Fix broken sbase-box due to multiple definitions of usage 2015-02-28 18:33:33 +00:00
Hiltjo Posthuma
31f0624f3d code-style: minor cleanup and nitpicking 2015-02-20 13:29:38 +01:00
FRIGN
767e36e410 sed(1): Add back line numbers to compiler error messages 2015-02-18 11:43:34 +01:00
FRIGN
4391984115 Use e-functions in sed(1)
and take off the tin-foil-head by removing checks for printf-return-
values.
2015-02-18 11:21:56 +01:00
FRIGN
a98405d277 Refactor sed(1) a bit
Well, isspacerune() has been fixed and some other FIXME's were also easy
to do.
There are some places where maybe some util-functions could be helpful.
In some cases, like for instance in regard to escape-sequences, I'm all
for consistency rather than adhering to the POSIX-standard too much.
Relying on centralized util-functions also makes it possible to keep
this consistency across the board.
2015-02-18 10:51:39 +01:00
FRIGN
31572c8b0e Clean up #includes 2015-02-14 21:12:23 +01:00
Evan Gates
bc07f1b9b5 Add initial implementation of sed(1)
No manpage yet.
2015-02-10 10:35:22 +00:00