Cookies op Tweakers

Tweakers maakt gebruik van cookies, onder andere om de website te analyseren, het gebruiksgemak te vergroten en advertenties te tonen. Door gebruik te maken van deze website, of door op 'Ga verder' te klikken, geef je toestemming voor het gebruik van cookies. Wil je meer informatie over cookies en hoe ze worden gebruikt, bekijk dan ons cookiebeleid.

Meer informatie

Door , , 107 reacties
Submitter: flux_w42

Google en Red Hat hebben een patch uitgebracht voor een kritiek lek in de veelgebruikte GNU C Library, oftewel glibc. Het lek maakte vanaf versie 2.9 een aanval mogelijk, waarbij door een stack-based buffer overflow willekeurige code op kwetsbare apparaten kon worden uitgevoerd.

Google laat in een blogpost weten dat een van zijn medewerkers de bug, bekend onder cve-2015-7547, vond toen hij probeerde een ssh-verbinding op te zetten met een bepaalde host. Na herhaaldelijk crashen van zijn ssh-client stuitte hij op een bug in de glibc-bibliotheek. Tot verbazing van Google was deze bug al sinds juli 2015 bekend bij de glibc-beheerders en waren twee Red Hat-medewerkers op hetzelfde moment als Google met een patch bezig.

De bug is aanwezig in de client side dns resolver van glibc, die verantwoordelijk is voor de vertaling van een domeinnaam naar een ip-adres. Wanneer de library function 'getaddrinfo' wordt gebruikt kan een aanvaller met een bepaalde domeinnaam of dns-server een udp- of tcp-antwoord van meer dan 2048 bytes versturen, waardoor het daarvoor gereserveerde geheugen wordt overschreden. Daardoor kan er uiteindelijk willekeurige code uitgevoerd worden op kwetsbare apparaten. Volgens Google is dit niet eenvoudig, omdat technieken als ASLR daartegen kunnen beschermen.

Het is nog niet duidelijk hoeveel applicaties glibc gebruiken, Google noemt slechts ssh, sudo en curl. Besturingssystemen als Windows en OS X zijn niet getroffen door het lek. Android is ook niet kwetsbaar, omdat het gebruikmaakt van de alternatieve 'Bionic'-bibliotheek. Omdat de kwetsbaarheid aanwezig is in apparaten met glibc 2.9 of hoger is het waarschijnlijk dat de bug wel een groot aantal apparaten, waaronder Linux-computers en routers, treft.

Ars Technica constateert dat de bug problematisch is, omdat de kwetsbare bibliotheek vaak aanwezig is op netwerkapparaten die geen regelmatige updates ontvangen en ook niet gebruikmaken van beschermingstechnieken als ASLR. Een volledige lijst met kwetsbare apparaten zal echter nog opgesteld moeten worden.

Versie 2.9 van glibc werd in 2008 gereleased. Er is inmiddels een patch beschikbaar en het wordt gebruikers dan ook aangeraden om de nodige updates uit te voeren.

Moderatie-faq Wijzig weergave

Reacties (107)

Een groot aantal routers is met deze library uitgerust. Blijf me toch verbazen dat buffer overflows nog steeds mogelijk zijn en dat er zo naïef wordt ontwikkeld. De fout bestaat al vrij lang, maar dan nog. Deze basisfunctie zou toch eigenlijk geen fout meer mogen hebben. Ook in 2008 al niet meer.
Gelukkig valt het juist voor routers wel mee. Veel (en in ieder geval OpenWRT, DD-WRT en Microtik) gebruiken uClib in plaats van glibc aangezien uClib gemaakt is voor embedded omgevingen waar weinig resources beschikbaar zijn. Van de stockfirmwares van veel fabrikanten weet ik het niet maar het ligt wel voor de hand dat ook die niet voor de relatief zware glibc hebben gekozen. Als je je toch zorgen maakt en je stockfirmware wil vervangen kan ik OpenWRT van harte aanbevelen: Het grote OpenWRT topic

Het grootste probleem is naar mijn idee alle apps waar glibc in mee gecompileerd is. Een OS update is betrekkelijk makkelijk uitgerold maar er achter komen of die specifieke applicatie die je draait misschien zelf een glibc implementatie draait is lastiger en reageert de maker van die applicatie bovendien misschien helemaal niet zo snel.

[Reactie gewijzigd door Maurits van Baerle op 17 februari 2016 11:18]

Daar zijn de meeste distro's met shared libraries niet zo vatbaar voor denk ik. Eerder dingen zoals Skype en andere precompiled binaries.
glibc is een problematische library, en dan druk ik me nog zacht uit. Het fundamentele probleem is dat de makers van glibc het onderscheid tussen OS en applicatie niet goed maken. Zo is "ld-linux.so" 1 van de 200 onderdelen van glibc. Dit is de shared-library loader, iets wat normaal gesproken een OS onderdeel is. Deze DNS resolving is op normale systemen ook onderdeel van het OS.

Het gevolg is dus dat je glibc niet zomaar mee kunt linken met je applicatie. Je blijft een dependency houden op OS-componenten. En als de glibc versie in het OS niet overeenkomt met de glibc versie die je statisch hebt meegelinkt, kun je heel vreemde bugs krijgen.

De achtergrond is dat zowel C als Unix ontstaan zijn binnen AT&T Bell Labs, en de twee waren historisch verstrengeld. Niemand stelt serieus voor om Java libraries als OS onderdeel te zien, maar C libraries zijn dat vaak wel.
De achtergrond is dat zowel C als Unix ontstaan zijn binnen AT&T Bell Labs, en de twee waren historisch verstrengeld. Niemand stelt serieus voor om Java libraries als OS onderdeel te zien, maar C libraries zijn dat vaak wel.
Zeg maar altijd, ik zo ook niet echt hoe het anders kan op een modern OS. Met een modern OS bedoel ik dan alles na MS-DOS. En OS is tegenwoordig meer dan alleen de kernel, er worden honderden applicaties en utillities meegeleverd. In het MS-DOS tijdperk konden dat nog stand-alone applicaties zijn die echt onafhankelijk van elkaar waren maar tegenwoordig is dat niet meer realistisch. Die systeemapplicaties maken, net als alle andere software, gebruik van libraries. Een OS zonder C library is dus eigenlijk niet mogelijk. In theorie kun je C en libc nog vervangen door een andere standaard taal & library (zoals java) maar je hebt iets nodig.
Het zal je misschien verbazen, maar onder Windows is de Visual C Runtime een applicatie-component. En als je de Borland C compiler gebruikt, dan is hun runtime evengoed een applicatie-component.

Windows zelf gebruikt een speciale build van de MSVC CRT, maar dat is een implementatie-detail van het OS. Applicaties gebruiken die CRT niet. Het gevolg is dat Microsoft die library gewoon kan renamen, zonder dat er iets breekt. Je moet onder Linux het niet wagen om glibc te renamen, dan kun je een reinstall doen.
Er zijn nog steeds applicaties (zoals die ontwikkeld met VS 6.0 en eerder en die ontwikkeld met MinGW GCC) die gelinkt worden aan msvcrt.dll. En daar is niets mis mee. Deze wordt ook geüpdatete en bijgewerkt met het OS, net zoals onder Linux het geval is, en in die zin is er bitter weinig verschil tussen glibc en msvcrt.dll.

Dat niet-steentijdperk-versies van VS linken met hun eigen runtime heeft meer te maken met de DLL hell en het feit dat msvcrt.dll soms heel slechte designkeuzes gemaakt heeft waarvan Microsoft wegens bovengenoemde redenen niet meer vanaf kan.

De nieuwe "Universal CRT" dat kan gebruikt worden vanaf VS 2015 zal ook geüpdatete worden met het OS, dus in die zin is de "Visual C Runtime" niet meer een applicatie component, maar net zoals onder Linux, een component beheerd door het OS.

Dat de loader onder Linux deel uitmaakt van glibc is inderdaad minder gewenst, maar over het algemeen werkt dit allemaal veel beter dan je laat uitschijnen. Dat Microsoft een library kan renamen vergelijken met een gebruiker die een library onder Linux renamed is nogal een scheef vergelijk. Ik ben ervan overtuigd dat als je glibc (en dus gcc/binutils) op de juiste manier aanpast (wat waarschijnlijk niet echt gemakkelijk is) dat je de libraries eender welke naam kan geven. Moet je enkel een symlink maken naar de oude naam of alles recompilen.
Microsoft heeft je al gewaarschuwd: "Windows is not a Microsoft Visual C/C++ Run-Time delivery channel". Ja, Windows 10 bevat nog steeds een "msvcrt.dll" maar dat is geen gewoon onderdeel van Windows. Dat is een onderdeel van de "Application Compatibility Toolkit". Microsoft doet veel moeite om ook incorrecte programma's te ondersteunen. Zo zit er ook een speciale hack in om een bug uit SimCity te negeren, waar vrijgegeven geheugen alsnog werd gebruikt.
Het gevolg is dat Microsoft die library gewoon kan renamen, zonder dat er iets breekt. Je moet onder Linux het niet wagen om glibc te renamen, dan kun je een reinstall doen.
Waarom zou je een library willen renamen, dat typisch een hacker actie.
Een hacker wil componenten van een rootkit op andere legitieme componenten laten lijken.
De praktische reden? Twee verschillende ld-linux.so versies op 1 systeem, om 2 glibc versies naast elkaar te hebben, omdat er geen glibc versie is die compatible is met alles.
De praktische reden? Twee verschillende ld-linux.so versies op 1 systeem, om 2 glibc versies naast elkaar te hebben, omdat er geen glibc versie is die compatible is met alles.
Waarom zou je dat willen?
Er is namelijk geen enkele reden voor. Dat is namelijk het voordeel van opensource en je wil als het niet strikt noodzakelijk is niet twee verschillende so versies op een systeem hebben. Dit is niet altijd de voorkomen, maar in het geval van glibc wel.

Tevens ken ik geen enkele Linux computer die meer dan een ld-linux geïnstalleerd heeft buiten mogelijk de x86 en de 32 bits variant.
Er is geen enkele reden om 2 glibc versies naast elkaar te hebben op die manier.

Ofwel gebruik je een chroot ofwel link je met de oudste versie van glibc (gemakkelijkst van een chroot of virtual machine) en werkt je applicatie gewoon met elke nieuwere glibc (op vergelijkbare distro's, want die veranderen soms wat aan de basis).

De glibc versie die compatibel is met alles is dus de nieuwste, want glibc is by design backwards compatible. Zoek maar eens op glibc symbol versioning.
glibc is een problematische library, en dan druk ik me nog zacht uit. Het fundamentele probleem is dat de makers van glibc het onderscheid tussen OS en applicatie niet goed maken. Zo is "ld-linux.so" 1 van de 200 onderdelen van glibc. Dit is de shared-library loader, iets wat normaal gesproken een OS onderdeel is. Deze DNS resolving is op normale systemen ook onderdeel van het OS.
Volgens mij bedoel een deel van de kernel want "ld-linux.so" is een deel van het OS.
Als resolving een deel uitmaakt van de kernel ben je bij bugs nog verder van huis. Daarom is dit een betere keuze.
Het gevolg is dus dat je glibc niet zomaar mee kunt linken met je applicatie. Je blijft een dependency houden op OS-componenten. En als de glibc versie in het OS niet overeenkomt met de glibc versie die je statisch hebt meegelinkt, kun je heel vreemde bugs krijgen.
Je bedoel dynamisch, want met statisch zul je geen problemen krijgen. In dat geval wordt de code in de binary getrokken.
Bij dynamisch linken moet je rekening houden met de (so versie van libary aanwezig op het systeem).
De achtergrond is dat zowel C als Unix ontstaan zijn binnen AT&T Bell Labs, en de twee waren historisch verstrengeld. Niemand stelt serieus voor om Java libraries als OS onderdeel te zien, maar C libraries zijn dat vaak wel.
De Linux Kernel gebruikt geen enkele dynamische library. Op OS niveau worden wel dynamische libraries gebruikt net als Windows DLLs (Dynamic Link Libraries) gebruikt.
Dat is heel erg normaal.
Nee hoor, kijk maar op Debian waar ld-linux.so vandaan komt: "libc6" package, en dat is dus glibc - geen deel van het OS.

En het probleem met "statisch linken" is dat glibc zaken als "resolv.conf" door dynamisch laden oplost, zelfs als je kiest voor statisch linken.

[Reactie gewijzigd door MSalters op 17 februari 2016 15:28]

Nee hoor, kijk maar op Debian waar ld-linux.so vandaan komt: "libc6" package, en dat is dus glibc - geen deel van het OS.
Sorry dat ik het zeg, maar volgens mij heb je geen kaas van Linux gegeten.
Een Linux distro (OS) bestaat altijd uit packages. Zonder glibc werkt zo goed als niets. Het is een integraal deel van het OS. Zelfs de minimale installatie zal glibc installeren.
Alleen het kernel package doet niets.

Het Windows OS is ook meer dan alleen de kernel.

Als je me niet gelooft moet je eens een linux systeem installeren en dan glibc deinstalleren en kijken hoeveel dan nog werkt. Zelfs basis functies zullen niet meer werken. Het zal het niet meer (correct) booten.

Deinstallatie op openSUSE via "rpm -e glibc glibc-extra glibc-locale glibc-32bit glibc-locale-32bit --nodeps"
En het probleem met "statisch linken" is dat glibc zaken als "resolv.conf" door dynamisch laden oplost, zelfs als je kiest voor statisch linken.
Resolv.conf dynamisch linken? Dat is puur het inlezen van variabelen, heeft niets met dynamisch laden te maken.

Of laad Windows de variabelen uit de registry dynamisch?

[Reactie gewijzigd door worldcitizen op 17 februari 2016 19:17]

En dát is dus precies de design fout waar ik op wees. Het si niet "zomaar" glibc wat onderdeel is van het OS, het is glibc versie 2.13 (bijvoorbeeld, om een probleemgeval te noemen). Applicaties die met de huidige GCC (5.3.0) gecompileerd zijn werken niet met glibc versie 2.13 uit Debian 7.

resolv.conf bepaalt welke libnss_*.so dynamisch geladen wordt
En dát is dus precies de design fout waar ik op wees. Het si niet "zomaar" glibc wat onderdeel is van het OS, het is glibc versie 2.13 (bijvoorbeeld, om een probleemgeval te noemen). Applicaties die met de huidige GCC (5.3.0) gecompileerd zijn werken niet met glibc versie 2.13 uit Debian 7.
Ook daar ga je weer de fout in, het gaat helemaal niet om de compiler maar om de glibc so versie te maken, als het niet zou werken.

En zoals je ziet Debain 7 (Wheezy):
ii libc6:amd64 2.13-38+deb7u10 amd64 Embedded GNU C Library: Shared libraries

dpkg -L libc6 | grep libnss_dns
/lib/x86_64-linux-gnu/libnss_dns-2.13.so
/lib/x86_64-linux-gnu/libnss_dns.so.2

en Debian 8 (Jessie):
ii libc6:amd64 2.19-18+deb8u3 amd64 GNU C Library: Shared libraries

dpkg -L libc6 | grep libnss_dns
/lib/x86_64-linux-gnu/libnss_dns-2.19.so
/lib/x86_64-linux-gnu/libnss_dns.so.2

Hebben beide de zelfde so versie. Als het al niet zou werken zal het niet aan glibc liggen.
Op een opensource OS heeft het geen zin om versies van oudere distro versies te installeren. Maar dat betekend niet dat het niet zal werken.
resolv.conf bepaalt welke libnss_*.so dynamisch geladen wordt
in resolv.conf staan de nameservers.
nameserver ..

Volgens mij ben je in de war met de nsswitch.conf .

Zoals gezegd houd je bezig met zaken waar je verstand van hebt en probeer Linux niet onterecht zwart te maken.
Kijk, het is die arrogantie waarom ik denk dat Linux er zo slecht aan toe is. " Als het al niet zou werken zal het niet aan glibc liggen" - de foutmelding die wij regelmatig krijgen verwijst expliciet naar de glibc versie. Met hoofdletters zelfs.
Kijk, het is die arrogantie waarom ik denk dat Linux er zo slecht aan toe is. " Als het al niet zou werken zal het niet aan glibc liggen" - de foutmelding die wij regelmatig krijgen verwijst expliciet naar de glibc versie. Met hoofdletters zelfs.
Het heeft helemaal niets met arrogantie te maken. Het wordt door niemand geadviseerd om packages van een andere distro versie op de huidige versie te installeren.
Als je een specifieke oudere of nieuwere versie wil gebruiken, moet je deze of opnieuw bouwen op het huidige systeem, of uit backports halen etc.

Sorry dat ik het zeg maar packages van oudere of nieuwere distro versies gebruiken is IMO prutswerk.
Er is helemaal geen reden voor, om dit te doen.

Ik package zelf voor openSUSE ik zal nooit iemand adviseren on een rpm packet op een andere distro versie te installeren.

Ik package het package ook voor de andere distro, supported c.q. niet EOL, versies en vaak ook voor Redhat/Centos en SLES.
Vandaar is er ook geen reden voor.
In het geval dat er voor een versie die ik gebruik een specifiek packet niet bestaat of nog helemaal niet bestaat bouw ik at even snel op de opensuse buildserver.
Zo kan je in Windows ook niet statisch linken met OS libraries. De namen en interfaces verschillen enkel.
Nee, maar je kunt wél statisch linken tegen de C runtime (/MT in Visual C++). "Uiteraard" kun je niet statisch linken tegen Windows: dan zou je programma tegen Windows 8 linken, en niet werken op Windows 10.
Nee, maar je kunt wél statisch linken tegen de C runtime (/MT in Visual C++). "Uiteraard" kun je niet statisch linken tegen Windows: dan zou je programma tegen Windows 8 linken, en niet werken op Windows 10.
Volgens mij bedoel je tegen Windows 8 libraries (DDL) en Windows 10 libraries (DLL) linken. Je kunt niet tegen Windows <versie> linken.

Als je libraries hebt die compatibel zijn en samen met andere versie geïnstalleerd kunnen worden (so name in gcc libs). Zal het programma perfect werken als je de libraries mee kopieert.

[Reactie gewijzigd door worldcitizen op 17 februari 2016 17:16]

Op Windows is de C runtime niet zozeer een basisonderdeel van het OS (je kan applicaties schrijven die niet linken met een C runtime).

Onder Linux vormt de libc ook ineens de brug met de kernel (waar je op Windows bvb ntdll.dll hebt om een deel van dat werk te doen). Het is een andere manier van werken. Dat is omdat de basis-OS interface (POSIX) een uitbreiding van de C standard library is.
Het grootste probleem is naar mijn idee alle apps waar glibc in mee gecompileerd is. Een OS update is betrekkelijk makkelijk uitgerold maar er achter komen of die specifieke applicatie die je draait misschien zelf een glibc implementatie draait is lastiger en reageert de maker van die applicatie bovendien misschien helemaal niet zo snel.
Als de applicatie op de openSUSE buildserver gebouwd wordt, wordt deze automatisch opnieuw gebouwd zodra een bouw afhankelijkheid opnieuw gebouwd is.

In dit geval betreft het een dynamisch gelinkte library, dan hoeft er niets nieuw gebouwd te worden buiten glibc zelf.
Iemand die nog statisch linkt is niet meer van deze tijd. De meeste/veel distro's waaronder (open)SUSE staan dit niet toe.
Er is niks uit de tijd aan een statisch gelinkte binary. Dat hele gebeuren waar distributies over het algemeen graag alles opgesplitst hebben in hun eigen repositories heeft niet zo veel te maken met met wat een ander met een distro doet.
Pak Go, een zeer recente programmeertaal waar alles er van uit gaat dat je statisch linkt omdat het je leven over het algemeen makkelijker in plaats van moeilijker maakt.
Met een fatsoenlijke package manager, zoals op vrijwel elke Linux-distributie maakt dynamic linking het leven echt veel makkelijker. Bijvoorbeeld bij bugs als deze, alleen het hercompilen en updaten van glibc is voldoende, alle programma's die gebruik maken van glibc zijn dan automatisch bijgewerkt.

Met name in de closed source wereld is het gebruikelijker om statisch te linken zodat je alle dependencies van je applicatie meelevert en je niet hoeft toe te staan dat je applicatie tegen een andere library gelinked wordt dan je op je eigen systeem hebt geinstalleerd. Nog een groot nadeel is dat je binaries heel veel groter worden (alle code wordt gedupliceerd).

Dus ja, statisch linked is wmb wel echt achterhaald. Helaas is de hele wereld nog niet OSS.
Normaal als je statisch linkt worden alleen de functies/subroutines die je echt gebruikt mee gelinkt. Dus alle applicaties die niet die client side dns resolver gebruiken krijgen die coding ook niet mee. dus:

1. de binary wordt niet heel veel groter.
2 heel veel applicaties doen niet zelf aan DNS resolving, en dat de impact wel meevalt.
Niettegenstaande dat moet de bug wel opgelost worden in apps/os die er wel gebruik van maken.
Niet geheel waar. Het linken gebeurt op object-niveau, wat weer terug te koppelen is naar de bronbestanden. Alle functies die in 1 bestand staan zullen dus ofwel met z'n allen wel ofwel met z'n allen niet ingebed worden bij het linken. Ik weet niet precies hoe ze de broncode van glibc hebben ingericht, maar het is in ieder geval een reden om functies zo veel mogelijk in een eigen bestand te zetten, in ieder geval als ze ongerelateerd zijn.

En libs worden wel een stuk groter. Probeer maar eens een helloworld.c te maken en die statisch vs dynamisch te linken:

#include <stdio.h>

int main(int argc, char **argv)
{
printf("Hello world\n");
}

Nu dynamisch compileren:

gcc helloworld.c -s -o helloworld-dynamic

levert een binary op van 4.4KiB

Dan statisch:

gcc -static helloworld.c -s -o helloworld-static

levert een binary op van 730KiB. Een toename van 16500% noem jij niet 'heel veel groter'?
Nee ... dat is niet groot. We leven al lang niet meer in de tijd van floppy disks. We leven ook niet meer in de tijd dat je alles moet dynamische linken voor plaats te besparen ( met de gevolgen van dien als bepaalde programma updates bepaalde libraries moeten hebben ).

Veel mensen zullen graag een beetje meer harddisk plaats opofferen als het betekend dat ze de laatste versies van applicaties kunnen installeren zonder in de problemen te komen met de core libraries.

En je voorbeeld is ENORM overdreven. Bij een deftige applicatie zou de extra libraries ergens tussen 10 a 40% extra plaats innemen. Neem dezelfde voorbeeld, en voeg nu grafische elementen toe, geluid of andere zaken en ineens is die statische libraries niet meer de 16500%.

Je moet maar naar een beetje Windows programma's kijken en je ziet dat vaak de libraries niet de hoofdzaak zijn. Ja, de executable is altijd maar een fractie van het totaal packet, net zoals het is bij éénder welke deftige linux applicatie.

Vreemd genoeg is die extra grote voor de libraries geen probleem voor Windows gebruikers. Waarom is dat wel een issue ineens voor Linux gebruikers?

Ik kan ook gerust een Go applicatie schrijven waar men executable 20MB is voor iets simpel. Maar dat ding is dan wel instant upgradable naar nieuw versies. En ik moet me geen zorgen maken dat x distro niet compatible is of dat ze die libraries niet hebben. En ik moet dan ook niet via hun repo gaan, of eigen repo aanbieden.

Snap je waar het extra plaats argument gewoon misloopt? Want als je dat niet snapt, dan zit je zo danig in Linux, dat je jezelf niet kan inbeelden in de meer gewone gebruiker hun ervaringen met Linux.
Zoals ik in mijn andere post ook al aangaf is het formaat van de bestanden wel zeer relevant. Op Windows zijn executables van meerdere megabytes zeer gewoon, en dan vaak nog aangevuld met een bak DLL's van elk ook meerdere megabytes. Op Linux zijn de meeste binaries enkele honderden kilobytes.

Het verschil zie je duidelijk terug in het gebruik van je harde schijf bij Window en Linux. Op Windows kun je eigenlijk niet uit de voeten met een SSD van 40GB, op Linux is dat geen enkel probleem. Windows neemt daarvan al gauw 50% van in beslag. Op Linux kom je niet verder dan 10%.

Je ziet het bij consumentenlaptops ook nog steeds: veelal worden deze uitgerust met harde schijven, omdat deze goedkoper / groter zijn. Hierdoor is de gebruikerservaring significant minder. Moet je je nou eens voorstellen dat die allemaal door goedkope kleine SSD's vervangen zouden kunnen worden omdat Windows niet zo bizar groot is. De gebruikerservaring zou echt significant toenemen omdat er ten eerste uberhaupt minder data van de schijf ingeladen hoeft te worden en ten tweede omdat het van een SSD zo veel sneller gaat. Dat zou een ware revolutie teweeg brengen.

En Mijn Hello World is in dynamische vorm ook instante upgradable naar een nieuwere versie. Installeer je een nieuwe glibc dan gebruikt mijn Hello World die direct. Jouw Go-programma zul je dan opnieuw moeten linken. Wat is nu makkelijker?
Op Windows zijn executables van meerdere megabytes zeer gewoon, en dan vaak nog aangevuld met een bak DLL's van elk ook meerdere megabytes. Op Linux zijn de meeste binaries enkele honderden kilobytes.
Erh? Verreweg de meeste DLL's die ik vind in Windows\system32 zijn <100 KB?

Mijn ervaring is dat DLL's die groot zijn onder windows vrijwel altijd looiig zijn vanwege de embedded resources, zoals bijv. images, bitmaps, icoontjes, etc, etc. Het klopt inderdaad dat je die niet nodig hebt op je SSH bak. Onder Windows Core ook niet overigens.

Het blijft een beetje appels met peren vergelijken, omdat je met zo'n stelling embedded resources, programmeertaal (.NET en Native delen dezelfde extensie!) en de hoeveelheid code op een hoop gooit. Compilers kan je daarnaast ook nog instellen om op 'snelheid' of op 'code size' te optimaliseren - dat maakt ook nog een heel verschil.

Om fair te zijn, ik heb recent een aantal C++ projecten met weinig dependencies (specifiek: alleen de standard library) over meerdere platformen gecompileerd en zie daarbij wel grote verschillen in de executable sizes. MSVC++ doet het daarbij met afstand het beste (paar honderd KB), daarna GCC (enkele MB's), daarna Clang (enkele MB's) en daarna Intel compiler (tientallen MB's). Qua snelheid ligt het er een beetje aan wie wint... er is geen eenduidige winnaar.
Op Windows kun je eigenlijk niet uit de voeten met een SSD van 40GB, op Linux is dat geen enkel probleem. Windows neemt daarvan al gauw 50% van in beslag.
Kom, nog nooit gehoord van Windows Core en Windows for IoT?

Ik geef daarbij meteen toe dat het met een GUI best wel een issue is... that said, ik zou onder linux die 40 gb ook zo volkrijgen.
Niet met de OpenWatcom compiler die ik gebruik.
Dan is de excutable 700K kleiner. dan met jouw gcc compiler. (met 29696 bytes nog wel groter dan 4K, dat wil ik toegeven).

Je kunt zelf een file maken met allerlei eigen subroutines en die standaard compiler naar een object file en als je die linkt wordt alles mee genomen. Als in plaats daarvan een library object maakt zou de linker alleen die subroutines moeten halen uit de library die jij gebruikt hebt.
Tot nu toe werken alle compilers (Pr1me, Watcom, Microsoft, Sun) die ik de afgelopen 40 jaar heb gebruikt op die manier. En met dynamische libraries heb ik ook al vanaf 1985 ervaring.
Zie het als ipv de hele boekwinkel kopen, alleen de boeken meenemen die je nodig hebt.

Maar ik geef toe: het is een jaar of 8 geleden dat ik met GCC gewerkt heb.
"Het linken gebeurt op object-niveau, wat weer terug te koppelen is naar de bronbestanden. Alle functies die in 1 bestand staan zullen dus ofwel met z'n allen wel ofwel met z'n allen niet ingebed worden "

Dat is historisch gedrag, de moderne methode is --ffunction-sections. Hierbij is elke functie een los object. Iets meer werk voor de linker, maar computers zijn 10.000x zo snel geworden sinds C bedacht is.
kom kom,

Dat is al in al de ruim 40 jaren dat ik programmeerde zo.
Dat is waar libraries voor waren, naast de objects van je eigen set programmeren.
Voordat je aannames doet: de client side dns resolver in kwestie hier is "libnss_dns.so", en die wordt atlijd dynamisch gelinkt, zelfs als je probeert om alles statisch te linken.

En onder Linux doet elke applicatie "zelf" aan DNS resolving : DNS is uitbesteed is aan glibc, en glibc laadt een kopie van libnss.dns.so in elk proces wat DNS nodig heeft.
Voordat je aannames doet: de client side dns resolver in kwestie hier is "libnss_dns.so", en die wordt atlijd dynamisch gelinkt, zelfs als je probeert om alles statisch te linken.
Gek he, .so is een dynamsche library .a en .la files zijn statische libraries.
En onder Linux doet elke applicatie "zelf" aan DNS resolving : DNS is uitbesteed is aan glibc, en glibc laadt een kopie van libnss.dns.so in elk proces wat DNS nodig heeft.
Daar is niets mis mee. Je besteed niets uit aan glibc het programma gebruikt de glibc library. Dat daardoor een deel van het programma wordt.
Hoe is dit anders onder Windows dan? De OS componenten worden ook dynamisch gelinkt. Nogmaals: de namen van de functies verschillen, en de plaatsen waar deze worden opgehaald. En hoe de backwards/forwards compatibility wordt benaderd verschilt ook. Maar zoals ik zei, is glibc forward binary compatible, wat echt alles is dat je nodig hebt.

Vergeef me dat ik het punt van je hele betoog doorheen de comments niet echt begrijp.
Als er iets is dat in mijn ogen Linux meer kwaad dan goed doet, is de enorme afhankelijkheid van de programma's met de libraries.

Op je Windows PC kan je gewoon zonder al te veel rommelen, updates van programma's installeren. Je hebt Office x, en je wilt de nieuwe Office z. Geen probleem.

Wil je een applicatie updaten in bijvoorbeeld Linux, is het vaak vechten tegen de bierkaai. Want veel distro's hun package managers zijn gelinkt met vaak enorm verouderde libraries / software.

Een leuk voorbeeld is probeer die zelfde Go is te installeren. Debian ( 8 ): 1.3. Mint: 1.2, ... We zijn intussen al aan de 1.6 RC versies op dit moment van schrijven.

Eenmaal dat je het pad ingaat van upgrades van programma's dat buiten je repo vallen, dan ga je een wereld binnen van incompatibility en andere problemen. En dan begint de hell voor iedere niet Tech-begaafde gebruiker. Ik heb geen enkel probleem dat de OS bestanden dynamisch gelinkt zijn maar ik heb een hekel hoe heel wat applicaties voor enorme problemen kunnen zorgen wanneer de OS achterloopt met hun libraries.

Je mag zeggen wat je wilt over Windows en hun manier van werken. Maar het werk. Je kan een Windows 7 draaien en iedere programma updaten zonder zorgen over de libraries hell dat je bijvoorbeeld hebt onder Linux bij updates.

Dat is ook het punt dat mij het meeste stoort onder Linux. Geen enkel distro heeft een goede oplossing voor het probleem. Ofwel lopen ze tot één tot twee jaar achter met hun software ( Debian ), ofwel zijn ze bleeding edge ( Arch ) waar je nooit met een modale niet Tech gebruiker aan de slag mee kunt.

Zo lang ze dat probleem niet kunnen oplossen bij Linux distro's, zal je nooit de "gewone" gebruiker overtuigen. En ik kan je verzekeren, dat het me al vaak vloeken en tieren opgeleverd heeft wanneer ik bepaalde versies van software nodig heb ( wegens verbeteringen of features ), of soms zelf het totaal ontbreken van die software op die distro's hun platform. En het werk dat je moet verzetten om dat te installeren ( van source compileren, tot backports, tot ... ). Waartegen een Windows gebruiker gewoon download en dan "install" drukt. Voila ...

Ps: Ik draai Linux Mint als men OS. Voor het geval dat sommige denken denkt dat ik een Windows gebruik ben, dat Linux wilt bekritiseren. Het moet eens gezegd worden dat men moet durven afstappen van die oude gedachten goed in de Linux wereld.

Bekijk GoLang ... wat is juist door heel wat mensen aangezien als een main feature. Just, het feit dat ze statisch linken van de bestanden. Maakt het het bestand groter. Ja ... maakt het grotere bestand iets uit op éénder welke normale PC / Server: Geen klein beetje. Enkel op micro pc setups ( zoals de Pi, of routers enz ).

Je ziet juist meer & meer in die opkomende programmer talen dat de features omvatten: Het statisch linken van libraries. Het maakt het leven voor het distributie van je applicatie gewoon zo veel makkelijker wanneer je niet constant moet checken welke libraries zijn er op x distro.

Het nadeel is dat het de security updaten van de libraries/programma's verschuift naar de ontwikkelaar. Nu is er één core library een bug en je hebt miljoenen toestellen dat kwetsbaar zijn. Waartegen moesten applicaties hun eigen versie draaien ( zoals de pre 2.8 ), geen probleem. Een deftige sandboxed applicatie zou perfect oude informatie of mixed dll's mogen draaien.

Waarom zijn systemen zoals Docker / enz ook meer en meer populair. Omdat je gewoon de libraries hell verplaatst naar de containers, waardoor je gewoon zaken kan draaien zonder je zorgen te moeten maken dat die applicatie je systeem onstabiel maakt.

Sorry als ik het zeg, maar dynamische gelinkte bestanden zijn iets dat enkel tot de core OS zou mogen behoren en de rest zou in een sandboxed omgeving moeten draaien met hun eigen libraries! Dan pas kan je het gebruik gemak verhogen van de eind gebruiker.

Zal niet toevallig zijn dat je nu meer en meer nieuwe programmatie talen met statisch linken werken, en oplossingen zoals docker enz begint te zien. Dat men zelf bij de grote distro's zit te experimenteren met distro's dat puur met sandboxed applicaties werken a la docker. Juist omdat het heel wat zaken makkelijker maakt en toelaat om mensen voor de laatste versies van software te draaien zonder dat het gans je core OS onderuit kan halen.

Zoals ik zei, zo lang dat men dit niet verbeterd zal Linux voor de gewone eindgebruikers gewoon nooit de oplossingen worden ( Zelf met Steam ).

Ja, ik ga heel wat kritiek krijgen van die hard Linux gebruikers, van hoeveel oplossingen er wel zijn. Maar dat is niet het punt. Het punt is dat men gewoon achterloopt in de gewone gebruiker ervaring tegenover andere OS'en zoals Windows. En dat dit niet komt wegens technische onmogelijkheden maar eerder doordat men niet durft weg stappen van bepaalde gedachten ( zoals statisch linken = bad bad bad ). En zo lang een groot bedrijf niet doordruk zoals docker / sandbox voor graphic applicaties waardoor de druk wegvalt van het dynamisch linken...

Dat een technische persoon oplossingen kan vinden en hup even de command line opzoekt is geen oplossing.
Tsja, dat is echt je eigen keuze. Debian is wat conservatiever. Ubuntu Wily (oktober 2015) heeft Golang 1.5, Ubuntu Xenial (april 2016) zal met Golang 1.6 komen. Krijg je nog meer gebruikersvriendelijkheid op de koop toe, vanuit een Windows-perspectief in ieder geval.

Met Debian kies je vooor stabiliteit ten koste van bleeding-edge software. Wil je wel nieuwere golang (in dit geval dan), dan zul je testing of unstable moeten gebruiken. In Debian is daar idd wat command-line-activiteit voor nodig, maar ja, welke 'gewone gebruiker' draait dan ook Debian? Onder Windows-converts draait het grootste gedeelte toch Ubuntu.

Het is helemaal niet zo slecht gesteld met hoe 'ouderwets' packages zijn, je moet alleen wel een distributie nemen die bij je verwachtingspatroon past.

En die enorme toename van de bestandsgrootte van binaries merk je wel. Ik ben blij dat mijn Linux-distributie af kan met 4 GB voor het besturingssysteem. Had ik Windows 7, 8 of 10 gedraaid dan zit je al gauw aan 10 tot 30 GB voor alleen het besturingssysteem. Op een SSD van 120GB is dat wel een significant verschil.

Overigens zie je juist op Windows een toename van shared libraries met dank aan .net. Doordat het een managed systeem is heb je een VM nodig die de code kan draaien, het .net framework. Deze gebruikt dezelfde libraries voor alle software die .net gebruikt. Hetzelde geldt natuurlijk voor Java, maar dat raakt juist meer en meer uit de mode op desktops.

[Reactie gewijzigd door MadEgg op 17 februari 2016 15:33]

Debian is maar een voorbeeld. Er zijn genoeg andere distro's dat niet Debian gebaseerd zijn en dat ook enorm achterlopen met hun software.

De testing of unstable... Please ... laat een gewone eind gebruiker deze draaien en we zullen zien hoe lang het duurt eer men Linux afzweert. Het is te makkelijk voorkomend dat een gans systeem onderuit gaat als je testing of unstable ( 100% kans ) draait.

Het probleem is dat je niet veel keuze hebt met je distro keuze. Je hebt stabiel ( = vaak software van 1 of 2 jaar oud want men update niet snel ). Of onstabiel ( libraries dat in conflict komen met verschillende applicaties ). Of custom ( Arch ).

Dan zit je ook dat bepaalde applicaties nooit voor komen in die distro's of enorm verouderd zijn.

In het verleden heb ik Windows 7 zitten draaien voor jaren als Server / Workstation 24/7. Upgrades van programma's zijn simpel en nooit een issue. Linux daartegen zoals ik zei hierboven.

Je ontwijkt eerlijk gezegd de vraag / probleem stelling door te zeggen "je moet alleen wel een distributie nemen die bij je verwachtingspatroon past". Iedere distro heeft dit probleem, zelf Ubuntu. Want men kan niet alle applicaties in het oog houden, testen en releasen.

De vrouw hier thuis draait Windows 7 op een 120GB SSD en ze heeft nog altijd 55GB vrij ( en dat is inclusive een massieve swap / hyb files ).

Men zou enorm veel werk uitsparen indien een hoop distro's niet met hun eigen package community moesten werken. Indien de applicatie ontwikkelaar gewoon zijn updates doet en het is statisch gelinkt / sandboxed, dan is er geen nood aan het testen van die applicaties. Mensen kunnen direct draaien en voila.

Nu ja, wie ben ik ...
Ik ontwijk niet de vraag. Ik stel dat als je Ubuntu Wily draait je wel een recente Go hebt. En dat geldt voor nagenoeg alle libraries. In de zeer uitzonderlijke situaties waar dat niet zo is (en je dus als 'gewone gebruiker' ook niet tegenaan loopt), heb je PPA's. Ik zal direct toegeven dat het gebruiken van PPA's niet geschikt is voor de gewone gebruiker, maar ja, de gewone gebruiker zal ook geen Go willen installeren.

Wat heeft je vrouw thuis verder op de laptop, en welke van die software levert problemen op met libraries op, bijvoorbeeld, Ubuntu Wily?

Overigens is er niets wat je tegenhoudt om statisch gelinkte software te gebruiken op Linux, en je ziet het bij niet-opensource software ook vaak gebeuren. Ofwel wel dynamisch gelinkt maar zelf de 'juiste' versie van de libraries meeleveren (LD_LIBRARY_PATH=./ my_proprietary_binary doet wonderen), ofwel statisch gelinkt. Werkt prima. Is alleen niet handig en gebeurt dus ook niet zo veel.
Het idee dat je per se Testing moet draaien om de nieuwste Golang te kunnen gebruiken is natuurlijk idioot.

Verder zie je bij .Net Core juist dat iedere applicatie zijn eigen libraries en framework mee distribueert. Om de simpele reden dat systeembeheerders altijd conservatief zijn met updates en developers daardoor niet de nieuwste .Net features konden gebruiken.

Bij .Net Core is dat verleden tijd.. Juist omdat je alles mee stuurt per applicatie.
Het idee dat je per se Testing moet draaien om de nieuwste Golang te kunnen gebruiken is natuurlijk idioot.
Waarom? In Debian is het idee dat software zich eerst bewezen moet hebben voordat het in de stable repositories opgenomen wordt. Golang 1.5 is in augustus 2015 uitgekomen, die heeft zich dus niet kunnen bewijzen voor een distributie uit april 2015. En de policy is om geen nieuwe major of minor releases op te nemen binnen een release van Debian, alleen point releases. Security patches worden eventueel gebackport. Waarom? Om de stabiliteit te garanderen. Wil je dat niet? Dan moet je geen Debian draaien, maar bijvoorbeeld Ubuntu.

[Reactie gewijzigd door MadEgg op 17 februari 2016 16:21]

Als ik op Windows of OS X de nieuwste Golang wil uitproberen hoef ik ook niet ineens de stabiliteit van de rest van het systeem in gevaar te brengen.

Zeker als software developer wil je vaak de nieuwste tools en api's testen, maar dat betekent niet dat je graag een instabiel systeem wil.

Je wil het er gewoon naast zetten zonder gevolgen.

Overigens geloof ik ook niet dat het niet kan :P Waarschijnlijk zal je wat dingen zelf moeten compileren op Debian in aparte mappen en even je gopath aanpassen en gaan.

Het idee dat het niet zou kunnen, zou ik iig erg vervelend vinden.
Het kan inderdaad prima maar vereist wat handwerk. Als genoeg mensen het interessant vinden of de auteur, dan zijn er makkelijker wegen. De nieuwste versie van PostgreSQL is altijd in een Debian-repository van PostgreSQL te vinden, al enkele dagen na de release.

En je zou alles statisch kunnen linken als je graag wilt dat je software zonder dependencies kunt draaien. Er is technisch niets dat je tegenhoudt. Dat het in de praktijk vrijwel niet gebeurt duidt er sterk op dat er geen animo voor is. Op deze manier is het marginaal meer werk voor de developers: packages bouwen voor alle platformen die je wilt ondersteunen, maar het gevolg is een veel betere gebruikerservaring.

Als Golang graag zou willen dat mensen op Debian Jessie zonder issues de nieuwste Golang kunnen draaien kunnen ze prima Golang linken tegen de gangbare libraries in Debian Jessie en een .deb bestand ter download aanbieden wat je vanuit de GUI kunt installeren door er simpelweg op te klikken. Dynamisch gelinkt nog wel. Wederom: technisch staat niets het in de weg. Dat het er niets is is niets anders dan een gebrek aan animo.
Windows maakt voor elke user installed software aparte kopies aan van DLL's die het gebruikt en plaatst die in een aparte folder behorend bij die installed software.

Voordeel is dat het blijft werken. Nadeel is dat je, zij het via een omweg, toch weer min of meer een vorm van statisch linken introduceert. Met als gevolg een grote SxS-folder.
Dat is inderdaad geen oplossing. Het wordt niet opgeschoond. Als al die libraries nou eens niet in windows/sxs stonden maar in Program Files, dan zouden ze in ieder geval verdwijnen als het programma verdwijnt. Nu is SxS een immer uitdijend gedrocht wat zonder specialistische tools niet in toom te houden is. Maar ja, het ontbreekt sowieso nagenoeg volledig aan enige vorm van package management op Windows, dus verbazend is het niet.
Ik vind de security vulnerability die met "application packages" zoals die van Go, en eender welke app-store, net een heel groot probleem. Wordt de app niet meer geüpdatete? Dan zit je met een verouderd, en afhankelijk van het hoe en het wat, een kwetsbaar systeem.

Ik kijk heel argwanend tegenover het hele app gebeuren. Ik vind dit geen goede evolutie op het vlak van transparente updates. Developers kappen ermee, oude applicaties blijven in gebruik, en je krijgt overal mini-stagefright, windows XP, en andere gelijksoortige gevallen van onherroepelijke kwetsbare toepassingen.
Pak Go, een zeer recente programmeertaal waar alles er van uit gaat dat je statisch linkt omdat het je leven over het algemeen makkelijker in plaats van moeilijker maakt.
Dat ligt er maar aan wie je het vraagt.
Statisch linken is makkelijk voor de programmeur maar vervelend voor de systeembeheerder. Een programmeur denkt alleen aan de belangen van zijn eigen applicatie, de systeembeheerder moet honderden applicaties beheren.
Een bug in een statische binary is voor de programmeur met 1 handeling op te lossen, de systeembeheerder zal het voor iedere (statische) applicatie apart moeten doen.

Deze bug illustreert dit uitstekend. Linux-beheerders moeten één systeembrede patch installeren. Beheerders van systemen die met statische binaries werken zullen al hun applicaties moeten patchen. Omdat statische binaries meestal van een leverancier komen (en de gebruiker dus geen sources heeft) kan er pas gepatchd worden als de de leverancier de oplossing aanlevert, dat kan lang duren.
Dat gaat ook alleen maar op wanneer applicaties allemaal dezelfde versie van die dynamische lib gebruiken.
Zodra ze dat niet doen mag die systeembeheerder voor elke applicatie gaan uitzoeken welke versie lib er gebruikt wordt en zonodig patchen.

Ik ben van de statische school; applicaties moeten zo weinig mogelijk afhankelijkheden hebben, dus ook net in dynamische libs. Dan kan je ze makkelijker sandboxen en de/re/installeren, heb je midnder afhankelijkheden in je ontwikkelpad en is het voor de gebruiker ook makkelijker te begrijpen.

Ruimtegebruik is geen argument. Diskruimte stijgt harder dan lib size. Wil je dan toch minder dan pas je maar een filesysteem met deduplicatie toe.
Er is niets mis met dynamische libraries, en deduplicatie is alleen fatsoenlijk mogelijk met dynamische libraries. Het probleem zijn shared dynamische libraries, waar de update van 1 applicatie de andere applicaties beïnvloedt.

SxS (Side by Side) van Microsoft is in theorie de correcte oplosisng, net zoals "libFoo.so.<versienummer>" op Linux. Alleen is SxS een onhandelbaar, onoverzichtelijk gedrocht en gebruikt vrijwel geen enkele library onder Linux dat versienummer daadwerkelijk. Zo is de glibc waar het hier over gaat bekend als glibc versie 2.9, maar is het versienummer op disk libc.so.6
Er is niets mis met dynamische libraries, en deduplicatie is alleen fatsoenlijk mogelijk met dynamische libraries. Het probleem zijn shared dynamische libraries, waar de update van 1 applicatie de andere applicaties beïnvloedt.
Bij Windows ja, omdat daar vaal ook de libraries in een installable meegeleverd worden. Bij Linux is dat uit den boze.
SxS (Side by Side) van Microsoft is in theorie de correcte oplosisng, net zoals "libFoo.so.<versienummer>" op Linux. Alleen is SxS een onhandelbaar, onoverzichtelijk gedrocht en gebruikt vrijwel geen enkele library onder Linux dat versienummer daadwerkelijk. Zo is de glibc waar het hier over gaat bekend als glibc versie 2.9, maar is het versienummer op disk libc.so.6
De so versie betekend dat deze versie compatibel is met de alle andere met de zelfde so versie.

En:
ls -l /lib64/libresolv.so.2
lrwxrwxrwx 1 root root 17 Jan 18 00:37 /lib64/libresolv.so.2 -> libresolv-2.22.so
of
file /lib64/libresolv.so.2
/lib64/libresolv.so.2: symbolic link to libresolv-2.22.so

Je ziet direct dat het uit glibc 2.22 gebouwd is en de so versie 2 is.

Tevens zie je:
rpm -q glibc
glibc-2.22-6.2.x86_64
en
rpm -qf /lib64/libm.so.6
glibc-2.22-6.2.x86_64

Praat a.u.b. niet zoveel over zaken waar je geen kaas van gegeten hebt.
Dat gaat ook alleen maar op wanneer applicaties allemaal dezelfde versie van die dynamische lib gebruiken.
Zodra ze dat niet doen mag die systeembeheerder voor elke applicatie gaan uitzoeken welke versie lib er gebruikt wordt en zonodig patchen.
Je kan best een paar versies van een libje op je systeem hebben. Je package-manager weet precies welke en waar ze staan.
Ik ben van de statische school; applicaties moeten zo weinig mogelijk afhankelijkheden hebben, dus ook net in dynamische libs. Dan kan je ze makkelijker sandboxen en de/re/installeren, heb je midnder afhankelijkheden in je ontwikkelpad en is het voor de gebruiker ook makkelijker te begrijpen.
Maar hoe patch je ze dan. Zo'n bug als waar we het hier nu over hebben, hoe doe je dat? Ga je al je applicaties één voor één controleren en patchen? Heb je een lijstje met welke versie van welke lib door welke applicatie wordt gebruikt? Moet je al die applicaties nu recompilen?
Ruimtegebruik is geen argument.
Daar ben ik het helemaal mee eens. Was dat een reactie op iets wat ik schreef? Dan hebben we denk ik een communicatiefoutje.
Maar hoe patch je ze dan. Zo'n bug als waar we het hier nu over hebben, hoe doe je dat? Ga je al je applicaties één voor één controleren en patchen? Heb je een lijstje met welke versie van welke lib door welke applicatie wordt gebruikt? Moet je al die applicaties nu recompilen?
Tja, het probleem dat je iets moet doen hou je. En een update mechanisme blijft handig. In dit geval moeten dan alle applicaties geupdate worden; er moeten dus nieuwe versies beschikbaar komen en dus ben je afhankelijk van de ontwikkelaars van die apps.
Maar je hebt geen last van incompatibiliteitsproblemen. Het blijft kiezen tussen twee kwaden.
Daar ben ik het helemaal mee eens. Was dat een reactie op iets wat ik schreef? Dan hebben we denk ik een communicatiefoutje.
Nee, meer op wat ik verder terug las ;)
Er is niks uit de tijd aan een statisch gelinkte binary. Dat hele gebeuren waar distributies over het algemeen graag alles opgesplitst hebben in hun eigen repositories heeft niet zo veel te maken met met wat een ander met een distro doet.
Pak Go, een zeer recente programmeertaal waar alles er van uit gaat dat je statisch linkt omdat het je leven over het algemeen makkelijker in plaats van moeilijker maakt.
Volgens mij bedoel je Go/golang ?
Zoek eens op "Pak Go". :+

De reden dat go dit doet is dat je dan in een keer de binary op een systeem kan gooien en deze werkt. Wat onnodig veel plaats gebruikt en IMO zinloos is voor opensource systemen.
En in dit geval een probleem hebt bij bugs in een library die moet je dan zelf identificeren. Bij een commerciële binary heb je dan pech, als de leverancier die niet nieuw wil bouwen. Wat geen probleem is bij dynamisch gelinkte programma's .
Even context:

- Deze vulnerability is remote exploitable door glibc een DNS resolve te laten doen naar een malicious, speciaal gecrafte URL.
- Er zijn allerlei manieren om dit te doen. Bijvoorbeeld door een image op een website / social media te zetten en deze de URL te laten resolven. Of door bij een torrent een hostname toe te voegen aan de lijst. Of door een URL te verspreiden via e-mail. Of ...
Een groot aantal routers is met deze library uitgerust.
Mijn gedachte was dit ook, dus heb ik het even nagevraagd bij een expert. Het idee is als volgt:

- Non-linux PC achter de router doet een DNS resolve;
- Router handled de DNS resolve en doet zelf een DNS resolve;
- Boem.

Gelukkig draaien de meeste routers (c.f. expert) dnsmasq hiervoor, welke zijn eigen DNS library gebruikt. (En zie reactie Maurits over uClib). Routers lijken dus niet vulnerable te zijn.
Blijf me toch verbazen dat buffer overflows nog steeds mogelijk zijn [snip]
Ik denk dat je het als volgt moet zien: C/C++ moet je niet zien als "high level programmeertaal" maar als een soort "high level assembler". Dat maakt dat het potentieel heel hard gaat, maar ook dat ongelukjes heel zwaar worden bestraft. Daar krijg je de vrijheid voor terug om te doen wat je maar wilt op de machine. "Echte" high-level programmeertalen die ook memory management en resource management voor je doen, hebben hier geen last van. De prijs die je daarvoor betaald is bovengenoemde vrijheden en performance.

Vrijwel alle low-level libraries op deze wereld zijn in C geschreven (incl. de low-level componenten van .NET, Java, etc) omdat ze deze vrijheden nodig hebben om hun werk te kunnen doen. Er zijn wel verschillende opvattingen in hoever je daarin moet gaan. In .NET gebeurt bijv. DNS nog via de C libraries, maar alles daarboven via de .NET socket code; je zou natuurlijk ook DNS in de .NET libraries kunnen doen.

Waarom dat relevant is, is omdat dingen als buffer overflows voortkomen uit de manier waarop de stack en pointers werken. Dat zijn hele low-level constructs die je in C hebt, maar niet in bovengenoemde high-level talen. In managed .NET code zal je dus nooit een buffer overflow krijgen.

PS: in iOS worden data en code strict van elkaar gescheiden. Data kan niet worden geschreven in code-space en code kan niet geexecuteerd worden in data-space. Dat is natuurlijk ook een oplossing... maar ook die heeft nadelen, zoals het niet kunnen JIT'ten van .NET code (daarom heeft mono/xamarin een AOT compiler)
Zou de kans op dit soort fouten nou kleiner zijn als het in een taal als Rust (schijnt ook redelijk te zijn qua performance) of Ada zou zijn gemaakt? Wat zouden de nadelen zijn?
Ik denk dat je hierop het antwoord al weet, aangezien die talen daar specifiek op ontworpen zijn. Je zou ook Java kunnen noemen. Of C#. Of een van de andere honderd alternatieven.

Specifiek wel noemenswaardig vind ik C++, omdat het goede performance heeft (dus niet "redelijk"), de mogelijkheid geeft tot heel mooi programmeren, maar tegelijkertijd ook de mogelijkheid tot hacken tot op het laagste niveau. Een goede programmeur kan in C++ om vrijwel alle mogelijke buffer overflows heenwerken. Leuk detail: als ik me niet vergis doen o.a. Microsoft en Google zo ongeveer alle low-level dingen in C++. In C kan dat theoretisch gezien ook, maar is je gereedschapskist een stuk beperkter.

Vwb. de nadelen, ik denk dat het gewoon niet eens is overwogen: toen glibc begon in de geschiedenis, deden we dat lekker in C, want het was immers een C library. Vervolgens zijn we allemaal applicaties gaan maken die gebruik maakten van glibc, want handig. Dat creeert een lock-in situatie.

Ik vermoed dat Rust en Ada gewoon gebruik maken van glibc, net als zoveel andere dingen. De vraag is dus ergens ook een beetje een kip-ei verhaal.

Dan heb je ook nog het feit dat er een stuk meer programmeurs te vinden zijn die C snappen dan die Rust en Ada snappen. Dat is ook wel zo praktisch.

En tot slot (maar m.i. niet relevant voor DNS resolving) moet je niet vergissen in wat "redelijke" performance vs "goede" performance betekent. Ik schrijf af en toe stukjes code in C++ die werken op L1 cache speed. C# wordt ook JIT of AOT gecompileerd en staat bekend om de "redelijke" performance -- maar ik kan je vertellen dat wat je ook probeert - het echt niet zo hard gaat als een goed geoptimaliseerd C++ programma; het verschil is al snel een factor 10 of meer (jaja ik weet het, dat geldt niet voor willekeurige programma's en er is nog iets met hotspots enzo). Anyhow, voor bedrijven als Google is dat gewoon onacceptabel: dat betekent gewoon 10 keer meer servers kopen.
Kleine correctie op het gebruik van DNSmasq: default laat DNSmasq responses toe van max. 4096 bytes, dus ben je volgens mij nog steeds vatbaar. Je moet de volgende config setting opnemen in /etc/dnsmasq.conf:
edns-packet-max=2048 (of edns-packet-max=1024). Dan worden de eventuele replies die problemen op kunnen leveren netjes afgekapt voordat ze glibc bereiken.
Ik heb dit zojuist op mijn router (asus RT-AC68U) gedaan, zodat alles achter mijn router in ieder geval veilig is tot er een update beschikbaar komt.
het zal je verbazen, maar mensen maken fouten (!)
Misschien was in die tijd een maximaal antwoord van 512 bytes heel gewoon en een antwoord van 2048 bytes onvoorstelbaar (dus veilg genoeg)? Punt is, je weet niet wat er destijds speelde, dus vind ik jouw "naïef " nogal ...naïef.
Ben ik niet met je eens. Buffer overflows zijn (of in ieder geval waren) de meest gebruikte manier om in een systeem binnen te dringen. Dat was in 2008 ook al zo.

Er zijn gewoon manieren van defensief programmeren die buffer overflows uitsluit en er is geen excuus om die methodes niet te gebruiken.
Inderdaad!
Als ontwikkelaar dien je alle input te wantrouwen. Controleer alles wat je binnenkrijgt op validiteit alvorens daadwerkelijk te gebruiken.
Dat is niets nieuws; Het is altijd al goed gebruik geweest. Ook vóór 2000 in ieder geval toen ik nog veel C code schreef. Jammer dat er nog steeds laks geprogrammeerd wordt.
Uit performance overwegingen worden validaties vaak niet herhaald, maar bij wijzigingen in niet directe gerelateerde code kan de waarheid van assumpties soms toch veranderen.

Wie zonder zonde is, werpe de eerste exceptie :+
Buffer overflows waren een erkend risico in 1988, toen het eerste Internet virus (de "Morris worm") opdook wat daar misbruik van maakte. Dat 20 jaar later diezelfde fouten in glibc worden geïntroduceerd is dan ook verontrustend.

Aan de andere kant is het ook niet zo verbazingwekkend. glibc is een C library, en intern ook in C geïmplementeerd. Dat is nu eenmaal vragen om ongelukken.
C is niet vragen om ongelukken. C is een afweging tussen overhead/performance en abstractieniveaus. C vraagt wel om een ervaren programmeur met verstand van zaken.

Of is een chirurg met een scalpel ook per definitie vragen om ongelukken?
C heeft bijna de performance van C++ (de strengere aliasing rules van C++ zorgen ervoor dat de optimizer makkelijker aan kan tonen dat twee variabelen elkaar niet beïnvloeden), maar C++ heeft een véél hoger abstractienivo. C++ std::string weet wél hoe groot een string is, char* weet dat niet. Kortom, als je performance tegen abstractie afweegt, dan kom je niet op een taal uit die op beiden inferieur is.
Wat bedoel je te zeggen? De C++ std::string is veel abstracter, en heeft veel lagere performance. Ga je code maar eens herschrijven van het gebruik van iostreams naar cstdio (std::cout -> printf, std::string -> char *) en de performance wordt significant hoger, koste van wat usability en wat safety checks. Ook is de compile-time veel lager (door het overslaan van de enorme C++ STL), en de resulterende binary wordt ook kleiner.

Voor desktop-applicaties maakt dat geen fluit uit (en dan kan je net zo goed Python gebruiken om maar eens wat te noemen), maar voor low-level systemen als kernels en systeembibliotheken maakt dat een enorm verschil.
Haha, maar nee. De performance van std::string is juist hoger (Small String Optimalisatie (SSO) voor cache lines). Ik weet niet waarom je iostreams erbij betrekt, en bovendien is de performance daarvan vrijwel hetzelfde mits je het exclusief gebruikt (dus met .sync_with_stdio(false) ).

Kan het nog sneller? Ja, mijn record performance optimalisatie staat op 2500% sneller (>24 uur naar <1 uur) bij het herschrijven van een C programma naar C++ waarbij ik een dedicated string klasse introduceerde die een nóg betere SSO had. Locality of reference maakt veel uit.
Interessant, je hebt er duidelijk veel ervaring mee. Die SSO kende ik nog niet, leuke optimalisatie.

Neemt natuurlijk niet weg dat je SSO ook prima kunt toepassen in C, er is daar niets C++-specifieks aan.
C vraagt wel om een ervaren programmeur met verstand van zaken.
Alleen lijken die bij bijvoorbeeld glibc en OpenSSL niet aanwezig te zijn.
Buffer overflows waren een erkend risico in 1988, toen het eerste Internet virus (de "Morris worm") opdook wat daar misbruik van maakte. Dat 20 jaar later diezelfde fouten in glibc worden geïntroduceerd is dan ook verontrustend.
Die "fouten" worden nog in ieder stuk software geïntroduceerd. Dat is geen uniek glibc probleem.
Aan de andere kant is het ook niet zo verbazingwekkend. glibc is een C library, en intern ook in C geïmplementeerd. Dat is nu eenmaal vragen om ongelukken.
Het is duidelijk dat C niet je voorkeur programmeertaal is.

C is de juiste tool voor de mensen met de juiste kennis. Kinderen laat je ook niet met een cirkelzaag spelen of in een auto rijden.
Of is een auto en een cirkelzaag alleen maar vragen om ongelukken?
Ik moet je deels gelijk geven. Ik denk niet dat iemand destijds had kunnen voorzien dat er zoveel data in DNS gestopt zou worden. Niet alleen krijg je nu vaak zowel een IPv4 als een IPv6 adres terug, er zit vaak ook nog DNSSEC keys, anti-spam keys, en allerlei andere security features en certificates in DNS verkeer.

Uiteraard had er gecheckt moeten worden op de input, dat is de fout, maar dat 512 bytes een redelijk te verwachten maximum was kon je ze toen niet kwalijk nemen.

[Reactie gewijzigd door Maurits van Baerle op 17 februari 2016 11:24]

Ik denk niet dat iemand destijds had kunnen voorzien dat er zoveel data in DNS gestopt zou worden.
Ehm, excuse me? Zo moeilijk is het niet om de packet lengte uit te lezen en daarvoor speciaal een buffer op de heap aan te maken, e.v.t. met een upper-bound om te voorkomen dat je out of memory gaat als bijv. iemand pretendeert een 8GB packet te verzenden. Dit valt gewoon in de categorie slordig.
Dat zeg ik toch, er had gewoon op input gecheckt moeten worden.

Mijn punt was dat tien jaar geleden niemand had kunnen denken dat we DNS records voor zoveel andere dingen zouden gaan gebruiken.
Verkeerde veronderstelling.

Het probleem is niet dat een te klein aantal bytes is gekozen, het probleem is dat een te groot antwoord wordt geaccepteerd terwijl de verwerking er niet mee over weg kan.

https://en.wikipedia.org/wiki/Buffer_overflow

Zeg dat jij op je fiets een koerier dienst begint met een maximaal pakket gewicht van 10 kilo. En jij komt bij een klant en die geeft jouw 10 ton en jij pakt het aan en wordt erdoor verpletterd.

Is dan de fout dat jij een fiets heb gekozen? Nee. De fout is dat jij niet heb gecontroleerd dat het binnen komende pakketje wel binnen jou limieten past.

Altijd input controleren, niet alleen op inhoud maar vooral en eerst op formaat.
Veel routers draaien op een BSD kernel welke dit probleem niet heeft omdat (Free)BSD een eigen libc implementatie heeft. Zelfde geld dus voor alle *BSD distributies, iets dat het artikel wel had mogen vermelden.
Veel grote routers draaien een BSD kernel die inderdaad geen glibc draait. Veel huis-tuin-en-keuken routers draaien daarentegen een Linux kernel waar dit probleem theoretisch wel speelt. Maar, als je consumentenrouter uClib gebruikt in plaats van glibc heb je er ook geen last van. Maurits van Baerle in 'nieuws: Google en Red Hat patchen kritiek Linux-lek in glibc-bibliotheek'
Veel routers draaien op een BSD kernel
Puur uit nieuwsgierigheid welke eigenlijk ?
Juniper OS is volgens mij op een BSD gebaseerd.
FreeBSD, de preciese versie is afhankelijk van welke hardware je hebt en natuurlijk of je updates installeert.
Ik zou eerder denken NetBSD. Dat heb ik al zien draaien op Ricoh Copiers.
Maar ik viste eigenlijk naar welke routerproducten en dus welke producenten (cisco, juniper, netgear) een BSD draaien.
Oeps, ik had m'n antwoord beter aan de post van Bantoo kunnen hangen.

Al die grote leveranciers hebben meerdere systemen in huis en dus ook meerdere OS'en, onderstaande is dus niet compleet, maar:

NXOS van Cisco is gebaseerd op (een variant van) Linux.
Netgear baseert z'n OS op WRT en dat gebruikt Linux.
Juniper OS is dus gebaseerd op FreeBSD.
RouterOS van Mikrotik is op Linux gebaseerd.
ArubaOS van Aruba is Linux.
Ik weet niet wat HP doet met ProCurve maar op grond van een beetje googelen denk ik dat er ook Linux achter zit maar dat kan ik niet hard maken.
Vanmorgen 39 updates voor CentOS 7.2 geïnstalleerd, waaronder deze fix(2.17-106.el7_2.4). Is een reboot voldoende of moet ik bijvoorbeeld curl nog rebuilden?
Glibc is normaal gesproken dynamisch gelinkt. Een update van glibc is dus voldoende.
De library in kwestie (libnss_dns.so) is zelfs niet eens statisch te linken. curl krijgt de update dus vanzelf mee.
Alleen als curl statisch linkt. Nieuwe instances van dynamisch linkende software zou automatisch de update moeten oppikken, maar programmas die al draaien zullen herstart (zoals open ssh verbindingen en waarschijnlijk nog vele anderen) moeten worden. Een reboot lost dat sowieso op.
39 ? Dat puppetize je toch gewoon, versie aanpassen en weer koffie halen ;)
Vanmorgen 39 updates voor CentOS 7.2 geïnstalleerd, waaronder deze fix(2.17-106.el7_2.4). Is een reboot voldoende of moet ik bijvoorbeeld curl nog rebuilden?
Een reboot of herstart van de processen die glibc gebruiken zou normaal gesproken voldoende moeten zijn.
Tenzij je applicaties gebruikt die glibc statisch gelinkt hebben, als dat mogelijk is..
Best wel. Meeste applicaties hebben de oude versie nog in hun address space steken. En libc wordt werkelijk door alles gebruikt.
Ik begreep ook dat DNS en DNSSEC erg kwetsbaar zijn. Wat de impact vrij groot maakt.
Ik begreep ook dat DNS en DNSSEC erg kwetsbaar zijn. Wat de impact vrij groot maakt.
Staat in de Tweakers post "getaddrinfo". Is DNS resolving, dus ook DNS en DNSSEC, mits ze DNS queries sturen.
Als de glibc update geïnstalleerd is en de processen opnieuw gestart zijn, bestaat dit probleem niet meer. Aangezien de patch beschikbaar is.
Ik heb vanochtend mijn Raspberry Pi al geupdate, die leek wel kwetsbaar te zijn. Vergeet die dus niet als je ergens in een hoekje een Raspberry Pi hebt draaien. Even een sudo apt-get update gevolgd door sudo apt-get upgrade en je bent klaar.
ja, alleen gebruiken nu al je services nog de oude libs..

installeer debian-goodies en voor het commando :
checkrestart -v uit.
dan zie je wat er herstart moet worden.
Mijn advies is om je hele systeem te herstarten. Checkrestart is niet perfect en deze bug zit op enorm veel plekken in je systeem. Als het even kan is rebooten de verstandige oplossing.
Ook dat klopt.. debian goodies 0.63 heeft paar leuke bugjes. 0.64 is stuk beter.
Maar dan nog, ook ik heb gewoon even de server herstart hoor, maar ik vind het wel een handige om te weten wat er even herstart zou moeten worden.
lsof /lib{,64}/libc.so.6
Ja, soms zakt je broek af dat dergelijke zaken in de kast blijven liggen, als het 5 over 12 is wordt het aanmodderen.

[Reactie gewijzigd door pgm5700 op 17 februari 2016 13:05]

Ubuntu Touch is ook getroffen door deze bug. In OTO-9.1 zal dit opgelost worden. OTA-9.1 zal binnenkort verschijnen. Misschien nog deze week...
De oplossing is simpel, maar moet wel gebeuren :
yum clean all
yum update glibc

voor SystemD systemen :
systemctl daemon-reexec

voor niet SystemD systemen :
reboot -h now
of alle netwerk services herstarten.
Simpel omdat ze het al gefixt hebben in een release. :Y)

NB. ik doe gewoon een yum install glibc is dat niet genoeg?
Nee, de in-memory library's blijven actief zolang het process actief blijft en gezien de meeste red-hat (en varianten) wel enkele jaren uptime kunnen hebben, wil je niet gehackt worden over enkele jaren ;)
Ja ok ik heb wel een reboot om die reden, maar ik bedoelde dus de install ipv clean+upgrade.
Oh, op die manier, normaal wel ja, maar soms zit een cache in de weg die nog even op zich laat wachten ;)
Tja en die cache was dus de reden dat ik me afvroeg in welke glibc versie het dan gefixt is.. zie mijn andere comment hier Barryke in 'nieuws: Google en Red Hat patchen kritiek Linux-lek in glibc-bibliotheek'
Mocht er nog geen update beschikbaar zijn en achter een router zitten waarbij je zelf DNSmasq kan aanpassen:
De volgende config setting opnemen in /etc/dnsmasq.conf:
edns-packet-max=2048 (of edns-packet-max=1024). Dan worden de eventuele replies die problemen op kunnen leveren netjes afgekapt voordat ze glibc bereiken.
Ik heb dit zojuist op mijn router (asus RT-AC68U) gedaan, zodat alles achter mijn router in ieder geval veilig is tot er een update beschikbaar komt.
Weet iemand welke glibc versie dit dan gefixt is? Ik geloof .. glibc v1.23 (bron)

Op dit item kan niet meer gereageerd worden.



Apple iOS 10 Google Pixel Apple iPhone 7 Sony PlayStation VR AMD Radeon RX 480 4GB Battlefield 1 Google Android Nougat Watch Dogs 2

© 1998 - 2016 de Persgroep Online Services B.V. Tweakers vormt samen met o.a. Autotrack en Carsom.nl de Persgroep Online Services B.V. Hosting door True