Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams...

56
Are all BSDs created equally? A survey of BSD kernel vulnerabili9es. Ilja van Sprundel <[email protected]>

Transcript of Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams...

Page 1: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Are all BSDs created equally? A survey of BSD kernel vulnerabili9es.

IljavanSprundel<[email protected]>

Page 2: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Who Am I

•  IljavanSprundel•  [email protected]

•  DirectorofPenetra4onTes4ngatIOAc4ve•  Pentest•  Codereview•  BreakstuffforfunandprofitJ

Page 3: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Outline/Agenda

•  Intro•  Data!

•  vulnerabili4esovertheyears

•  Testbyaudit•  CommonaJacksurface•  SomewhatlesscommonaJacksurface

•  Someresults/conclusions

Page 4: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

What is this talk about?

•  BSDkernelvulnerabili4es•  Comparison•  BetweendifferentBSDflavors

•  Audience•  Lowlevelsecurityenthusiasts•  UNIX/BSDgeeks

•  IsuspectLinuxfolksmightenjoythistoo

•  CuriouspeoplethatliketopokearoundinOSinternals

•  Knowledge•  SomebasicknowledgeofUNIX/BSDinternals

Page 5: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Standing on the shoulders

of giants

•  Previousinteres4ngBSDkernelsecurityresearchby:•  Silvio•  thenoir•  EsaEtelavuori•  Patroklos(argp)Argyroudis•  ChristerOberg•  JoelErikkson•  ClementLecigne

Page 6: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

intro

Page 7: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Really? Got Data?

•  Somehowthatstatementhasalwaysbeenstuckinmyhead•  Isittrue?•  Canwelookatsomedata?

Page 8: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Source: hFps://www.cvedetails.com/product/47/Linux-Linux-Kernel.html

Page 9: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Data!

•  Goesfromcurrentbackto1999forLinuxkernelvulnerabili4es•  Cvedetails.comdoesn’tseemtoprovidedataforOBSD/NBSD/FBSD•  Manuallygrabitfrom

•  hJps://www.freebsd.org/security/advisories.html•  hJp://netbsd.org/support/security/advisory.html•  hJps://www.openbsd.org/errata*.html

Page 10: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

BSD kernel vulnerabili9es over the years

•  Lookingatthesenumbers,thatwasanastuteobserva4onbyTheo.•  20wasaverylowes4mate

• Butarethesenumbersonequalfoo4ng?

• Manyeyeballs?•  Yea,yea,Iknow….Butistheresometruthtoitinthiscase?

FreeBSD NetBSD OpenBSD

1999 3 8XXXTODO

2000 8 4XXXTODO

2001 6 7XXXTODO

2002 11 6XXXTODO

2003 7 3XXXTODO

2004 8 5XXXTODO

2005 11 8XXXTODO

2006 9 15XXXTODO

2007 1 4XXXTODO

2008 8 6XXXTODO

2009 5 1XXXTODO

2010 3 6XXXTODO

2011 1 2XXXTODO

2012 2 1XXXTODO

2013 8 8XXXTODO

2014 7 6XXXTODO

2015 7 2XXXTODO

2016 12 1XXXTODO

2017 1 3XXXTODO

Total 118 96XXXTODO

Page 11: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Test by audit!

•  SilvioCesaredidsomeinteres4ngworkin~2002thatgivessomeanswers

•  hJps://www.blackhat.com/presenta4ons/bh-usa-03/bh-us-03-cesare.pdf

•  Hisresultsseemtoindicatethereisn’treallythatmuchofaqualitydifference.However:•  thatwaswelloveradecadeago.

•  Havethingschanged?

•  TimespendontheBSDswasonlyacoupleofdayscomparedtoLinux•  Ifmore4mewould’vebeenspend,wouldmorebugshavebeenfound?

•  bugsaremostlyintoverflowsandinfoleaks•  Otherkindsofissuesthatcan‘easily’befound?

Page 12: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Test by Audit redux. •  SpendApril-May-Juneaudi4ngBSDsourcecode.•  Askedmyself,“wherewouldthebugsbe?”•  AJacksurface

•  Verycommon•  Syscalls•  TCP/IPstack

•  Somewhatlesscommon(inascendingorder,moreorless)•  Drivers(ioctlinterface)•  compatcode•  Traphandlers•  Filesystems•  Othernetworking(BT,wifi,IrDA)

Page 13: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Syscalls

Page 14: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint

•  TheobviousaJacksurface•  Syscallsarehowuserlandgetsanythingdonefromkernel•  Hundredsofthem

•  FreeBSD:~550•  OpenBSD:~330•  NetBSD:~480

•  Assump4on:giventhatthey’reobvious,andwelltested,lesslikelytocontainsecuritybugs

Page 15: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

intsys_sendsyslog(structproc*p,void*v,register_t*retval){

structsys_sendsyslog_args/*{ syscallarg(constvoid*)buf; syscallarg(size_t)nbyte; syscallarg(int)flags;}*/*uap=v;interror;sta4cintdropped_count,orig_error;

...error=dosendsyslog(p,SCARG(uap,buf),

SCARG(uap,nbyte),SCARG(uap,flags),UIO_USERSPACE);

...return(error);

}

intdosendsyslog(structproc*p,constchar*buf,size_tnbyte,intflags,enumuio_segsflg){...

structiovecaiov;structuioauio;size_ti,len;

...aiov.iov_base=(char*)buf;aiov.iov_len=nbyte;ßusercontrolledsize_t.nevercappedanywhere

...auio.uio_resid=aiov.iov_len;

...len=auio.uio_resid;ßusercontrolledsize_tif(fp){

...}elseif(consJy||cn_devvp){

...}else{

... kbuf=malloc(len,M_TEMP,M_WAITOK);

...}

...}

Page 16: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug

•  sendsyslogsystemcall•  OpenBSD6.1

•  BeentheresinceOpenBSD6.0•  Unboundlengthpassedtomalloc()fromuserland• Willtriggerakernelpanic

•  Previousassump4onisnot[en4rely]true:bugsinsyscallsdooccurwithsomefrequency•  Especiallynewlyaddedsyscalls

Page 17: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

TCP/IP stack

Page 18: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint

•  TCP/IPstack•  Ipv4/6•  Udp/tcp/icmp•  Ipsec•  …

•  ObviousandwellknownaJacksurface•  Hasbeenaroundforever•  Assump4on:welltestedandlesslikelytofindbugsthere

Page 19: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

structsecpolicy*key_msg2sp(

structsadb_x_policy*xpl0, size_tlen, int*error)

{...

switch(xpl0->sadb_x_policy_type){...

caseIPSEC_POLICY_IPSEC: {

... tlen=PFKEY_EXTLEN(xpl0)-sizeof(*xpl0); xisr=(structsadb_x_ipsecrequest*)(xpl0+1); while(tlen>0){

/*lengthcheck*/if(xisr->sadb_x_ipsecrequest_len<sizeof(*xisr)){

ipseclog((LOG_DEBUG,"key_msg2sp:""invalidipsecrequestlength.\n"));key_freesp(newsp,KEY_SADB_UNLOCKED);*error=EINVAL;returnNULL;

}

lengthcheckisincomplete.sadb_x_ipsecrequest_lencanbeinvalid

if(xisr->sadb_x_ipsecrequest_len>sizeof(*xisr)){structsockaddr*paddr; paddr=(structsockaddr*)(xisr+1); /*validitycheck*/if(paddr->sa_len >sizeof((*p_isr)->saidx.src)){ ipseclog((LOG_DEBUG,"key_msg2sp:invalidrequest" "addresslength.\n")); key_freesp(newsp,KEY_SADB_UNLOCKED); *error=EINVAL; returnNULL; }

lengthcheckisincomplete.sadb_x_ipsecrequest_lencanbeinvalid

lengthcheckisincomplete.paddr->sa_lencanbeinvalid

bcopy(paddr,&(*p_isr)->saidx.src,paddr->sa_len);

thiscopycanoutofboundreadonpaddr.AssumemalicioususerthatcontrolsheapchunkaÇerpaddr.couldmakeitsopaddr->sa_lenislargeandcausesmemorycorrup4on

Page 20: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug

•  IPSECsetsockopt()•  Outofboundread•  Canendupcorrup4ngmemory•  Affects:

•  FreeBSD11•  NetBSD7.1

•  Previousassump4onisnot[en4rely]true:bugsinTCP/IPstackdooccurwithsomefrequency•  newercode•  mbufhandlingiscomplicatedanderrorprone

Page 21: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Drivers

Page 22: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint

•  Lotsandlotsofdrivers•  Forallsortsofthings•  UNIX:everythingisafile

•  Mostexposeentrypointsin/dev•  Fileopera4ons

•  Open•  Ioctl•  Read•  Write•  Close•  …

•  IoctliswheremostoftheaJacksurfaceis!

Page 23: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

intcryptof_ioctl(structfile*fp,u_longcmd,void*data){...

switch(cmd){...

mutex_enter(&crypto_mtx); fcr->m4me=fcr->a4me; mutex_exit(&crypto_mtx); mkop=(structcrypt_mkop*)data; knop=kmem_alloc((mkop->count*sizeof(structcrypt_n_kop)), KM_SLEEP); error=copyin(mkop->reqs,knop, (mkop->count*sizeof(structcrypt_n_kop))); if(!error){ error=cryptodev_mkey(fcr,knop,mkop->count); if(!error) error=copyout(knop,mkop->reqs, (mkop->count*sizeof(structcrypt_n_kop))); } kmem_free(knop,(mkop->count*sizeof(structcrypt_n_kop))); break;

...}

Integeroverflow

Memorycorrup4onduetointoverflow

Page 24: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug

•  CryptodeviceCIOCNFKEYMioctl•  NetBSD7.1

•  BeentheresinceNetBSD4.0.1?ThuApr1022:48:422008•  Classicintegeroverflowàmemorycorrup4on

Page 25: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

sta4cintksyms_open(structcdev*dev,intflags,intfmt__unused,structthread*td){...

structksyms_soÇc*sc; ...

sc=(structksyms_soÇc*)malloc(sizeof(*sc),M_KSYMS,M_NOWAIT|M_ZERO);

...sc->sc_proc=td->td_proc;sc->sc_pmap=&td->td_proc->p_vmspace->vm_pmap;ßwillbeusedind_mmapcallback.

...error=devfs_set_cdevpriv(sc,ksyms_cdevpriv_dtr);

…}

sta4cintksyms_mmap(structcdev*dev,vm_ooffset_toffset,vm_paddr_t*paddr,

intprot__unused,vm_memaJr_t*memaJr__unused){ structksyms_soÇc*sc;

interror;

error=devfs_get_cdevpriv((void**)&sc);if(error) return(error);

/**XXXmmap()willactuallymapthesymboltableintotheprocess*addressspaceagain.*/if(offset>round_page(sc->sc_usize)||(*paddr=pmap_extract(sc->sc_pmap,ßcanbeexpiredpointer!(vm_offset_t)sc->sc_uaddr+offset))==0) return(-1);

return(0);

}

Page 26: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug 2

•  Ksymsdevice•  FreeBSD11

•  BeentheresinceFreeBSD8.0TueMay2621:39:092009•  Expiredpointer•  open()callbacksavespointertopmaptoprivatefd/devicestorage•  mmap()callbackusessavedpointerinprivatefd/devicestorage•  Sohowisthisaproblem?

• Whatifwehandfdofftoanotherprocess(e.g.sendoversocketorfork/execve)•  Andthenweexit•  Ifotherprocessnowdoesmmap,itwillbeusinganexpiredpmap!

Page 27: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Compat code

Page 28: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint

•  TheBSDshavebinarycompa4bility[compat]supportforsomebinaries:•  OlderversionsoftheOS•  32bitversionsofaprogram(ona64bitversionoftheOS)•  Otheropera4ngsystem(e.g.Linux)

•  Hastoemulateabunchofstuff(e.g.syscalls)

“The people who rely on the compat layers don't care enough to maintain it. The people who work on the mainline system don't care about the compat layers because they don't use them. The cultures aren't aligned in the same direction. Compat layers rot very quickly.” – Theo De Raadt

Page 29: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

sta4cint4_bind(file_t*fp,intfd,structsvr4_strioctl*ioc,structlwp*l){...

structsvr4_strmcmdbnd;...

if(ioc->len>sizeof(bnd)) returnEINVAL;

if((error=copyin(NETBSD32PTR(ioc->buf),&bnd,ioc->len))!=0) returnerror;

...switch(st->s_family){caseAF_INET:

... netaddr_to_sockaddr_in(&sain,&bnd);

...}

...}

#defineSVR4_C_ADDROF(sc)(constvoid*)(((constchar*)(sc))+(sc)->offs)...sta4cvoidnetaddr_to_sockaddr_in

(structsockaddr_in*sain,conststructsvr4_strmcmd*sc){

conststructsvr4_netaddr_in*na;

na=SVR4_C_ADDROF(sc);ßcouldpointtoanywhereinmemorymemset(sain,0,sizeof(*sain));sain->sin_len=sizeof(*sain);sain->sin_family=na->family;ßcrashorinfoleaksain->sin_port=na->port;ßcrashorinfoleaksain->sin_addr.s_addr=na->addr;ßcrashorinfoleak

…} /*

*Pretendthatwehavestreams...*Yes,thisisgross....*/

Page 30: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug

•  SVR4streamscompatcode•  NetBSD7.1

•  BeentheresinceNetBSD1.2ThuApr1112:49:131996•  Usesoffsetthatcomesfromuserland

•  Withoutanyvalida4on

•  Canreadarbitrary(-ish)kernelmemory•  Panic•  Infoleak

Page 31: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Trap handlers

Page 32: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint

•  Traphandlershandlesomekindofexcep4onorfault•  Divbyzero•  Syscall•  Breakpoint•  Invalidmemoryaccess•  …

•  Somecanbetriggeredbyuserland,andthekernelhastohandlethemcorrectly

•  duetotheirnature,theyareuglyandhighlyarchitecturespecific

Page 33: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Fuzz it!

•  whatwouldhappenifyousimplyexecutedabunchofrandombytesasinstruc4ons?•  Surelyabunchoftrapswillgetgenerated,andthekernelwouldhavetohandlethem

intrfd;voidexecute_code(unsignedchar*p){int(*fn)();fn=p;fn();return;}voidfuzz(){unsignedchar*code=mmap(NULL,lenbuf,PROT_EXEC|PROT_READ|PROT_WRITE,MAP_PRIVATE|MAP_ANONYMOUS,-1,0);while(1){ read(rfd,code,lenbuf); intpid=fork(); if(pid==-1){ exit(0); }elseif(pid==0){ execute_code(code); }else{ intstatus; pid_tr; r=waitpid(pid,&status,0); if(r==-1){ kill(pid,9); sleep(1); waitpid(pid,&status,WNOHANG); } }}}intmain(void){rfd=open("/dev/urandom",O_RDONLY);fuzz();}

Page 34: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

demo!

Page 35: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Hit xen trap

•  NULLderef

Page 36: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

File systems

Page 37: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint

•  FilesystemaJacksurfaceseemseasyenough.•  Maliciousfsimagethatgetsmounted

•  Alsodofileopera4onsonthemoncemounted•  IscertainlyaJacksurface

•  However,thereismore!•  Inrecentyearsall3BSDssupportfuse•  VFSlayernowhastodealwithmaliciousdatathatcomesfromuserland

•  Beforeitalwayscamefromatrustedfilesystemdriver

Page 38: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

AFack surface entrypoint [fuse] •  FBSD/OBSD/NBSDallhavedifferentfuseimplementa4ons(nosharedcodewhatsoever)

•  NBSD:mostcomplete(allowsforthemostfileopera4ons)•  FBSD:mostcontrolledargumentspassedbackandforth(getaJr,readdir)lessopportunityforconsumerstomakemistakes,butmoreparsing/processinginfusefsitself,morepoten4alforbugsinfusecodeitself

•  OBSD:minimalfunc4onalimplementa4on(comparedtotheprevioustwo)

•  noneimplementioctl

•  alldo:•  read•  write•  readdir•  getaJr•  setaJr•  ...

Page 39: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

intvfs_getcwd_scandir(structvnode**lvpp,structvnode**uvpp,char**bpp,char*bufp,structproc*p){

inteofflag,tries,dirbuflen,len,reclen,error=0;...

structvaJrva;...

error=VOP_GETATTR(lvp,&va,p->p_ucred,p);ßdatacancomefromfusefs...

dirbuflen=DIRBLKSIZ;

if(dirbuflen<va.va_blocksize) dirbuflen=va.va_blocksize;ßfusefscanmakethisreallybig

dirbuf=malloc(dirbuflen,M_TEMP,M_WAITOK);ßmalloc()willpaniconverylargevalues

...

error=VOP_READDIR(uvp,&uio,p->p_ucred,&eofflag);ßfusefscanprovidearbitrarycontent...cpos=dirbuf;...for(len=(dirbuflen-uio.uio_resid);len>0;len-=reclen){

dp=(structdirent*)cpos;reclen=dp->d_reclen;

/*Checkformalformeddirectory*/if(reclen<DIRENT_RECSIZE(1)){ error=EINVAL; gotoout;}

if(dp->d_fileno==fileno){ char*bp=*bpp; bp-=dp->d_namlen;ßfusefscanlieaboutd_namlen

if(bp<=bufp){ error=ERANGE; gotoout; }

memmove(bp,dp->d_name,dp->d_namlen);ßoutofboundread.

Page 40: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug

•  Unboundmallocandoutofboundread(couldpanicorinfoleak)•  OpenBSD6.1

•  BeentheresinceOpenBSD4.0FriApr2808:34:312006•  getcwdsyscallwhentakingdatafromfuse/userland

Page 41: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

sta4cdaddr_text2_nodealloccg(structinode*ip,intcg,daddr_tipref,intmode){...

error=bread(ip->i_devvp,fsbtodb(fs,fs->e2fs_gd[cg].ext2bgd_i_bitmap),(int)fs->e2fs_bsize,NOCRED,&bp);ßreadfromfilesystem

...ibp=(char*)bp->b_data;

...len=howmany(fs->e2fs->e2fs_ipg-ipref,NBBY);loc=memcchr(&ibp[start],0xff,len);if(loc==NULL){ len=start+1; start=0; loc=memcchr(&ibp[start],0xff,len);ßlogicdrivenbyfsdata if(loc==NULL){ prinÜ("cg=%d,ipref=%lld,fs=%s\n", cg,(longlong)ipref,fs->e2fs_fsmnt); panic("ext2fs_nodealloccg:mapcorrupted");ßpanicdrivenbyfsdata /*NOTREACHED*/ }}

...}

Page 42: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Sample bug 2

•  panic()drivenbyfilesystemdata•  FreeBSD11

•  BeentheresinceFreeBSD8.1ThuJan1414:30:542010•  Ext2filesystemcode

Page 43: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Networking (bt, wifi, irda)

Page 44: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Wifi AFack surface entrypoint

•  Stackitself•  802.11networkdata•  Parsing•  Infoleaks

• Wifidrivers•  Datasendbydevicetohost

Page 45: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

802.11 stack

•  One802.11stackforallwifidrivers•  Mucheasiertomaintain

•  Needtofixinonly1placeifbugsarefound•  ieee80211_input()ismainparsinginput

•  Calledfromallwifidrivers

Page 46: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

ieee80211_eapol_key_input(structieee80211com*ic,structmbuf*m,structieee80211_node*ni){

structifnet*ifp=&ic->ic_if;structether_header*eh;structieee80211_eapol_key*key;

...eh=mtod(m,structether_header*);

...if(m->m_len<sizeof(*key)&&(m=m_pullup(m,sizeof(*key)))==NULL){ßguaranteesthattherearesizeof(structieee80211_eapol_key)con4nuousbytesinthembuf

..}

...key=mtod(m,structieee80211_eapol_key*);

...if(m->m_pkthdr.len<4+BE_READ_2(key->len))ßassumekey->lenislargerthankey->payload gotodone;

/*checkkeydatalength*/totlen=sizeof(*key)+BE_READ_2(key->paylen);ßassumekey->lenislargerthankey->payloadif(m->m_pkthdr.len<totlen||totlen>MCLBYTES) gotodone;

.../*makesurethekeydatafieldiscon4guous*/if(m->m_len<totlen&&(m=m_pullup(m,totlen))==NULL){ßnotenoughdatapulledupifkey->lenislargerthankey->payload!

…}key=mtod(m,structieee80211_eapol_key*);

... ieee80211_recv_4way_msg3(ic,key,ni);ßcancrashinhereifnotenoughdataispulledup.

...}

Page 47: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

802.11 Stack sample bug

•  mbufmishandling,leadingtocrash•  Doesn’tguaranteeitpullsupenoughmbufdata

•  OpenBSD6.1•  Bughasbeenthereforalmost9years

•  ParsingEAPOLframes

Page 48: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

802.11 Drivers

•  WifidriversareeitherPCIorUSB

•  Doyoutrusttheradio?•  Whatifitdoesgetcompromised?

•  AssumePCIcardscausetotalcompromise(theycandoDMA)•  Well,actually,withIOMMUthat’snolongerthecase…

•  USBispacketbasedprotocol•  HostUSBparsersshouldbeabletoparsesafely

•  CurrentlyBSDwifidriversdonotdothis!•  Leadstotrivialheapsmashes

Page 49: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

voidrun_rx_frame(structrun_soÇc*sc,uint8_t*buf,intdmalen){...

structrt2860_rxwi*rxwi;...

uint16_tlen;...

rxwi=(structrt2860_rxwi*)buf;...

len=letoh16(rxwi->len)&0xfff;ßcanbeatmost4095...

/*couldusem_devgetbutnet80211wantscon4gmgmtframes*/MGETHDR(m,M_DONTWAIT,MT_DATA);if(__predict_false(m==NULL)){ ifp->if_ierrors++; return;}if(len>MHLEN){<--iflenis4095,comehere MCLGET(m,M_DONTWAIT);ßallocatesacluster,whichis2048byteslong if(__predict_false(!(m->m_flags&M_EXT))){ ifp->if_ierrors++; m_freem(m); return; }}

.../*finalizembuf*/memcpy(mtod(m,caddr_t),wh,len);ßmemorycorrup4on!m->m_pkthdr.len=m->m_len=len;

...}

/**Aframehasbeenuploaded:passtheresul4ngmbufchainupto*thehigherlevelprotocols.*/voidatu_rxeof(structusbd_xfer*xfer,void*priv,usbd_statusstatus){...

h=(structatu_rx_hdr*)c->atu_buf;len=UGETW(h->length)-4;/*XXXmagicnumber*/ßintegerunderflow

m=c->atu_mbuf;memcpy(mtod(m,char*),c->atu_buf+ATU_RX_HDRLEN,len);ßneedtovalidatelenbeforecopy.cancausememorycorrup4on

...usbd_setup_xfer(c->atu_xfer,sc->atu_ep[ATU_ENDPT_RX],c,c->atu_buf,ATU_RX_BUFSZ,USBD_SHORT_XFER_OK|USBD_NO_COPY,USBD_NO_TIMEOUT, atu_rxeof);usbd_transfer(c->atu_xfer);

}

voidotus_sub_rxeof(structotus_soÇc*sc,uint8_t*buf,intlen)ßlencomesfromusb.canbe~8k{...

uint8_t*plcp;...

plcp=buf;...

mlen=len-AR_PLCP_HDR_LEN-sizeof(*tail);...

mlen-=IEEE80211_CRC_LEN;/*strip802.11FCS*/

wh=(structieee80211_frame*)(plcp+AR_PLCP_HDR_LEN);...

MGETHDR(m,M_DONTWAIT,MT_DATA);if(__predict_false(m==NULL)){ ifp->if_ierrors++; return;}if(align+mlen>MHLEN){ MCLGET(m,M_DONTWAIT);ßallocatesacluster,whichis2048byteslong if(__predict_false(!(m->m_flags&M_EXT))){ ifp->if_ierrors++; m_freem(m); return; }}/*Finalizembuf.*/m->m_data+=align;memcpy(mtod(m,caddr_t),wh,mlen);ßmlencanbe~8k.cancausememorycorrup4on.

...}

voidrsu_event_survey(structrsu_soÇc*sc,uint8_t*buf,intlen){...

structndis_wlan_bssid_ex*bss;structmbuf*m;intpktlen;

...bss=(structndis_wlan_bssid_ex*)buf;

...if(__predict_false(len<sizeof(*bss)+letoh32(bss->ieslen)))ßcouldintoverflow return;

.../*Buildafakebeaconframetoletnet80211doalltheparsing.*/pktlen=sizeof(*wh)+letoh32(bss->ieslen);ßcouldintoverflowif(__predict_false(pktlen>MCLBYTES))ßsignednessissue return;MGETHDR(m,M_DONTWAIT,MT_DATA);if(__predict_false(m==NULL)) return;if(pktlen>MHLEN){ MCLGET(m,M_DONTWAIT); if(!(m->m_flags&M_EXT)){ m_free(m); return; }}wh=mtod(m,structieee80211_frame*);

...memcpy(&wh[1],(uint8_t*)&bss[1],letoh32(bss->ieslen));ßmemorycorrup4on

...}

Page 50: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

802.11 drivers sample bug

• WideopenaJacksurface•  AtmelAT76C50xIEEE802.11bwirelessnetworkdevice[atu(4)]•  AtherosUSBIEEE802.11a/b/g/nwirelessnetworkdevice[otus(4)]•  RealtekRTL8188SU/RTL8192SUUSBIEEE802.11b/g/nwirelessnetworkdevice[rsu(4)]•  RalinkTechnology/MediaTekUSBIEEE802.11a/b/g/nwirelessnetworkdevice[run(4)]•  AtherosUSBIEEE802.11a/b/gwirelessnetworkdevice[uath(4)]

•  AcrossallBSDs

•  Theydidn’tthinkabouttheaJacksurfaceonthisone

Page 51: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Results •  results:

•  About~115kernelbugssofar•  FBSD:~30•  OBSD:25•  NBSD:~60

•  typesofbugsseen:•  Straightheap/stacksmash•  racecondi4ons•  expiredpointers•  Doublefrees•  recursionissues•  integerissues

•  Underflows,overflows,signedness•  infoleaks•  outofboundread•  NULLderef•  Divisionbyzero•  kernelpanicsdrivenbyuserland•  Memoryleaks

Page 52: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Conclusions •  Bugswerefoundinall3oftheexaminedBSDs

•  AmongalloftheaJacksurfacesmen4onedabove

•  Winner/loser•  OBSDclearwinner(theyhavemassivelyreducedtheiraJacksurfaceovertheyears):

•  AJacksurfacereduc4on•  noloadablemodules•  rela4velyfewdevices•  Virtuallynocompatcode(theyremovedLinuxacoupleofyearsago)•  removeden4reBluetoothstack•  Significantlylesssyscalls(e.g.200+syscallslessthanFBSD)•  Cutsupportforsomeolderarchitectures

•  CodeQuality•  intoverflows/signednessbugs,asgoodasgoneinmostplaces•  Fewinfoleaks

•  NBSDclearloser•  Tonsoflegacyandcompatcode(whothehells4llneedstheISOprotocols???Really?)•  seemstobelessconsistentwithsecuritycodequality

•  Toomanysignednessbugs.

•  FBSDissomewhereinbetween

Page 53: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

More conclusions

•  Bugsares4lleasytofindinthosekernels.EvenOpenBSD.

•  Varyinglevelofqualitydependingonageandwhowroteit•  MostconsistentqualitywasobservedwithOpenBSD

•  ThemaintainersofvariousBSDsshouldtalkmoreamongeachother•  Severalbugsinonewerefixedintheother

•  OpenBSDexpiredprocpointerinmidiioctl()fixedinNetBSD•  NetBSDsignednessbuginac97_query_devinfo()fixedinOpenBSD

Page 54: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

More conclusions

•  Codebasesize•  OpenBSD:2863505loc•  NetBSD:7330629loc•  FreeBSD:8997603loc

•  Obviouslythisplaysapart

•  Can’thaveabugincodeyoudon’thave•  Accidentalvs.planned

•  Haven’tgoJentoimplemen4ngsomethingyetor…•  Choicemadeonpurposetodeletecode

•  AJacksurfacereduc4on

Page 55: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

More conclusions

•  Manyeyeballs…

•  Gutfeeling,Isuspectthisisafactor.

•  Basedonmyresult,codequalityalonecan’taccountforthediscrepancybetweenthebugnumbers(BSDvs.Linux).

•  SaywhatyouwillaboutthepeoplereviewingtheLinuxkernelcode,therearesimplyordersofmagnitudemoreofthem.Anditshowsinthenumbers.

Page 56: Are all BSDs created equally? - DEF CON CON 25/DEF CON 25... · 2020-05-16 · • SVR 4 streams compat code • NetBSD 7.1 • Been there since NetBSD 1.2 Thu Apr 11 12:49:13 1996

Ques9ons ?