Linux and Glibc API Changes
man7.org
man7.org
As a longtime subscriber of LWN, the man is a treasure to the Linux community (and industry!).
I do hope there's a new edition eventually, but as he says the core is still the same.
if so that would be glibc and kernel abi additions only?
APIs are occasionally broken too, although that would be a bug.
At least one API is known buggy and hasn't been fixed: fts_open. It only works properly if used on 32 bit architectures. [Edit: I just noticed that glibc got around to fixing this - yay!]
glibc+Linux is not entirely conforming to POSIX - threads being a good example where it differs in some significant respects from what POSIX requires.
Sometimes POSIX itself isn't well defined. Until very recently it was not properly specified if a file descriptor is closed if close(2) returns an error. Some POSIX systems closed it, some didn't, some closed it on some errors but not on others; and most programs wouldn't retry the close on error so would leak the fd. It has since been changed so that the fd is always closed even in the error case.
As for what C version one is required to use alongside libc, UNIX is C's platform, on other OSes libc is part of the compiler not OS.
Also a post C11 compliant compiler is not required to still provide gets() in their libc for the case you use C89/C99 language mode.
Memory map a read/write page and after that memory map a no-permissions guard page. Now you can safely use gets() to read a page size string without allowing a buffer overflow.
I think the only safe way to use gets() is with trusted input.
Edit: I guess you're considering "used safely" to include reading a truncated string, in which case writing in order would allow the program to be written such that it recovers from the fault and reads the valid page-worth of string.
If there are other threads accessing data that happens to be placed after the guard page, bad things could happen, but this seems rather unlikely to be a real problem.
Actually, it is possible to use gets() safely, under a sufficiently contrived set of circumstances. Since it reads from stdin, you just have to make sure that stdin reads from a pipe which has its write end under the control of the same process, and be careful to only ever write a limited amount of data to that pipe, smaller than the buffer of any gets() call in the process.
Notable quote from that: If there's a bug that people rely on, it's not a bug, it's a feature.
Otherwise, both the kernel and glibc regularly break things accidentally. You rarely hear about it, though, because its the nature of software development that the areas most likely to be broken are those where people rarely lurk. glibc makes at least as much effort as Linux in terms of supporting backward compatibility, but glibc's job is in some ways much more difficult, and they have far fewer contributors to help out. There's no shortage of bugs in glibc, and I have plenty of my own gripes, but by the standards of the industry (particularly of FOSS), they do an outstanding job of maintaining ABI compatibility.
Once upon a time people would claim that glibc's efforts were feeble as compared to proprietary OSs like Solaris, AIX, or Windows. But these days those backward compat stories are far more complex and less pristine, and glibc has well over a decade (or two decades?) of using ELF symbol versioning to maintain compat.
Honestly, I'd say that is on them. It has been discouraged to use it since basically forever (it has been noted in all-caps in the manpage since at least 2001), the kernel started complaining about its usage since Linux 2.6.24 which was released in January 2008, and it finally disappeared in Linux 5.5, released in January 2020. That's a two-decade deprecation period.
Also, the removal of sysctl by distros took away a facility, descriptor-less kernel entropy consumption via sysctl+RANDOM_UUID, that wouldn't be restored until getrandom was added many years later. Until then jail'd processes (or other code that couldn't make too many assumptions about its environment) had no easy way to seed their RNGs. Indeed, it likely created many unknown security issues that have [hopefully] been accidentally fixed with the adoption of getrandom by various libraries.
To this day Linux is still resolving issues and dilemmas caused by the removal of sysctl. There are many scenarios where /proc can't and shouldn't be accessible. (In most of those scenarios sysctl shouldn't be accessible, either, but especially since the addition of seccomp BPF it's easier to filter scalar syscall arguments than /proc opens.)
[1] Though, I don't remember any man page warning prior to 2008. (Or after, for that matter. I just remember the dmesg warnings, which because of the aforementioned dilemma regarding /proc put you between a rock and a hard place, waiting for the sword to fall, presuming you even caught it in time. Embedded developers might revisit a particular codebase only every couple of years.) Perhaps you're referring to notes that it wasn't portable? But there are countless interfaces that glibc documents as non-portable but infinitely less likely to disappear than even a Linux syscall. Do you have a link to a 2001 manual page?
For sure, I agree that Linux's record isn't perfectly clean. Just wanted to point out that if you were hit by that removal, part of the blame is on you.
> Do you have a link to a 2001 manual page?
I got it from the oldest manpages package from archive.debian.org. The git history on kernel.org doesn't go as far back.
The note I was referring to was the following:
BUGS
The object names vary between kernel versions. THIS MAKES THIS SYSTEM CALL WORTHLESS FOR APPLICATIONS. Use the /proc/sys interface instead.
Which in 2007 got replaced with the following (partly bolded): NOTES
Glibc does not provide a wrapper for this system call; call it using syscall(2).
Or rather... don't call it: use of this system call has long been discouraged, and it is so unloved that it is likely to disappear in a future kernel version.
Remove it from your programs now; use the /proc/sys interface instead.glibc does deprecate and remove things, but it uses very careful symbol versioning, such that code compiled against previous versions of glibc continues to run but new code can't use those interfaces. It's a rare example of being ABI-compatible but not API-compatible.
The only way I can think of this working is if the symbols are exported in the lib file but not exposed in a header. Is that what you mean?
I would be afraid to use all these new additions in an application; you couldn't use that with a docker container on an older system (docker uses the same kernel/glibc as the host)
Docker containers usesthe same kernel as the host, but the libc comes from the container.
Not really. The kernel obviously is compatible with older versions of libc, but glibc is also compatible with older kernel versions (down to 3.2 for the latest version), and it even attempts to emulate some system calls if your kernel doesn't support them. You've quite some freedom to mix versions.
TIL that this this glibc mirror is kept in sync with the real one https://github.com/bminor/glibc