1 X Security it’s worse than it looks Ilja van Sprundel

Slides:



Advertisements
Similar presentations
JQuery MessageBoard. Lets use jQuery and AJAX in combination with a database to update and retrieve information without refreshing the page. Here we will.
Advertisements

CS 450 Module R1. R1 Introduction In Module R1, you will implement a user interface (command handler). There are a couple of options: ▫Command Line: interface.
Module R2 CS450. Next Week R1 is due next Friday ▫Bring manuals in a binder - make sure to have a cover page with group number, module, and date. You.
The Linux Kernel: Memory Management
Lecture 19 Page 1 CS 111 Online Protecting Operating Systems Resources How do we use these various tools to protect actual OS resources? Memory? Files?
C Programming - Lecture 5
SDN and Openflow.
Lecture 2 Page 1 CS 236, Spring 2008 Security Principles and Policies CS 236 On-Line MS Program Networks and Systems Security Peter Reiher Spring, 2008.
Chapter 3.5 Memory and I/O Systems. Memory Management 2 Only applies to languages with explicit memory management (C, C++) Memory problems are one of.
Chapter 3.7 Memory and I/O Systems. 2 Memory Management Only applies to languages with explicit memory management (C or C++) Memory problems are one of.
Netprog: Buffer Overflow1 Buffer Overflow Exploits Taken shamelessly from: netprog/overflow.ppt.
Silberschatz, Galvin and Gagne ©2009 Operating System Concepts – 8 th Edition Chapter 2: Operating-System Structures Modified from the text book.
Operating Systems Concepts 1. A Computer Model An operating system has to deal with the fact that a computer is made up of a CPU, random access memory.
Ch. 31 Q and A IS 333 Spring 2015 Victor Norman. SNMP, MIBs, and ASN.1 SNMP defines the protocol used to send requests and get responses. MIBs are like.
Java Security. Topics Intro to the Java Sandbox Language Level Security Run Time Security Evolution of Security Sandbox Models The Security Manager.
Lecture 18 Page 1 CS 111 Online Design Principles for Secure Systems Economy Complete mediation Open design Separation of privileges Least privilege Least.
Security Exploiting Overflows. Introduction r See the following link for more info: operating-systems-and-applications-in-
C Programming - Lecture 6 This lecture we will learn: –Error checking in C –What is a ‘wrappered function’? –What is a clean interface? –How to earn your.
1 Computing Software. Programming Style Programs that are not documented internally, while they may do what is requested, can be difficult to understand.
Files COP3275 – PROGRAMMING USING C DIEGO J. RIVERA-GUTIERREZ.
IT253: Computer Organization Lecture 4: Instruction Set Architecture Tonga Institute of Higher Education.
Chapter 2: Operating-System Structures. 2.2 Silberschatz, Galvin and Gagne ©2005 Operating System Concepts – 7 th Edition, Jan 14, 2005 Operating System.
Computer Security and Penetration Testing
Variables and Objects, pointers and addresses: Chapter 3, Slide 1 variables and data objects are data containers with names the value of the variable is.
Chapter 3.5 Memory and I/O Systems. 2 Memory Management Memory problems are one of the leading causes of bugs in programs (60-80%) MUCH worse in languages.
CS 11 java track: lecture 1 Administrivia need a CS cluster account cgi-bin/sysadmin/account_request.cgi need to know UNIX
IT253: Computer Organization Lecture 3: Memory and Bit Operations Tonga Institute of Higher Education.
Netprog: Java Intro1 Crash Course in Java. Netprog: Java Intro2 Why Java? Network Programming in Java is very different than in C/C++ –much more language.
Programming for Beginners Martin Nelson Elizabeth FitzGerald Lecture 5: Software Design & Testing; Revision Session.
CSE 451 – Operating Systems Section, Autumn 2003 TAs: Mike Swift Adrienne Noble
Games Development 2 Concurrent Programming CO3301 Week 9.
CE Operating Systems Lecture 3 Overview of OS functions and structure.
Viruses Hackers Backups Stuxnet Portfolio Computer viruses are small programs or scripts that can negatively affect the health of your computer. A.
Making Python Pretty!. How to Use This Presentation… Download a copy of this presentation to your ‘Computing’ folder. Follow the code examples, and put.
QA and Testing. QA Activity Processes monitoring Standards compliance monitoring Software testing Infrastructure testing Documentation testing Usability.
BMTRY 789 Lecture 11: Debugging Readings – Chapter 10 (3 rd Ed) from “The Little SAS Book” Lab Problems – None Homework Due – None Final Project Presentations.
Fall 2002CS 150: Intro. to Computing1 Streams and File I/O (That is, Input/Output) OR How you read data from files and write data to files.
Java Basics Opening Discussion zWhat did we talk about last class? zWhat are the basic constructs in the programming languages you are familiar.
A Tool for Pro-active Defense Against the Buffer Overrun Attack D. Bruschi, E. Rosti, R. Banfi Presented By: Warshavsky Alex.
Lecture 14 Page 1 CS 236 Online Variable Initialization Some languages let you declare variables without specifying their initial values And let you use.
Lesson 2: Reading a program. Remember: from yesterday We learned about… Precise language is needed to program Actors and Classes Methods – step by step.
SCSC 455 Computer Security Chapter 3 User Security.
CSCI 156: Lab 11 Paging. Our Simple Architecture Logical memory space for a process consists of 16 pages of 4k bytes each. Your program thinks it has.
A PC Wakes Up A STORY BY VICTOR NORMAN. Once upon a time…  a PC (we’ll call him “H”) is connected to a network and turned on. Aside: The network looks.
I/O Software CS 537 – Introduction to Operating Systems.
INF3110 Group 2 EXAM 2013 SOLUTIONS AND HINTS. But first, an example of compile-time and run-time type checking Imagine we have the following code. What.
Announcements Assignment 2 Out Today Quiz today - so I need to shut up at 4:25 1.
Lecture 4 Page 1 CS 111 Online Modularity and Memory Clearly, programs must have access to memory We need abstractions that give them the required access.
Ch. 31 Q and A IS 333 Spring 2016 Victor Norman. SNMP, MIBs, and ASN.1 SNMP defines the protocol used to send requests and get responses. MIBs are like.
This presentation deals with any kind of information you put online. It relates to e- mails, texts, social networking and the sharing of pictures and.
OPERATING SYSTEMS (OS) By the end of this lesson you will be able to explain: 1. What an OS is 2. The relationship between the OS & application programs.
Lecture 5 Page 1 CS 111 Summer 2013 Bounded Buffers A higher level abstraction than shared domains or simple messages But not quite as high level as RPC.
Lecture 1 Page 1 CS 111 Summer 2013 Important OS Properties For real operating systems built and used by real people Differs depending on who you are talking.
11 Making Decisions in a Program Session 2.3. Session Overview  Introduce the idea of an algorithm  Show how a program can make logical decisions based.
SE-1021 Software Engineering II
Protecting Memory What is there to protect in memory?
Protecting Memory What is there to protect in memory?
Module 30 (Unix/Linux Security Issues II)
Protecting Memory What is there to protect in memory?
C++ coding standard suggestion… Separate reasoning from action, in every block. Hi, this talk is to suggest a rule (or guideline) to simplify C++ code.
Modularity and Memory Clearly, programs must have access to memory
Processor Management Damian Gordon.
File I/O in C Lecture 7 Narrator: Lecture 7: File I/O in C.
CSC 495/583 Topics of Software Security Format String Bug (2) & Heap
CSCE 313 – Introduction to UNIx process
The Troubleshooting theory
C Programming - Lecture 5
Security Principles and Policies CS 236 On-Line MS Program Networks and Systems Security Peter Reiher.
Processor Management Damian Gordon.
Testing & Security Dr. X.
Presentation transcript:

1 X Security it’s worse than it looks Ilja van Sprundel

Who am I? IOActive Director of Penetration Testing Pentest Code review Break stuff for fun and profit 2

agenda Intro Client Server Solutions ? 3

What this talk is about Implementation of X.org parsers Client and server Identify some entrypoints Show some bugs and trends of bugs that show up often How bad is it really ? What is it not about ? Network operational side Yes, network X is bad (sniff, keylog, …) Should tunnel over ssh if you want that 4

Intro I started this about a year ago Looked at the client first, late last year (december) Took about a week Grepping for entrypoints was easy Reported ~80 bugs, all have been fixed (well, most) Been looking at the server on and off since may A lot more tedious Not finished (not by a long shot) Reported ~120 bugs so far 5

6 Client

Some observations X is a client/server protocol to be used for the gui in most unices It’s networked (can be tcp/ip, ipc, …) Binary protocol The client protocol parsers become interesting when suids use X You can make them connect to arbitrary X servers using the DISPLAY variable Who says these have to be well behaving X servers ? 7

X network architecture 8

Some observations The X client libraries (Xlib) are clear attack surface Spend about a week looking at the network parsing code in Xlib Have not looked at xcb yet. Things are were really really bad Binary protocol parsers in C. A lot of them written in the 80’s Server data appears to be trusted. Very little validation > 60 trivial bugs It’s clear that code was not written with trust boundaries in mind at all. 9

Typical bugs 10 Status XAllocColorCells( register Display *dpy, Colormap cmap, Bool contig, unsigned long *masks, /* LISTofCARD32 */ /* RETURN */ unsigned int nplanes, /* CARD16 */ unsigned long *pixels, /* LISTofCARD32 */ /* RETURN */ unsigned int ncolors) /* CARD16 */ {... xAllocColorCellsReply rep;... status = _XReply(dpy, (xReply *)&rep, 0, xFalse); if (status) { _XRead32 (dpy, (long *) pixels, 4L * (long) (rep.nPixels)); _XRead32 (dpy, (long *) masks, 4L * (long) (rep.nMasks)); }... }

Typical bugs 11 XTimeCoord *XGetMotionEvents(register Display *dpy, Window w, Time start, Time stop, int *nEvents) /* RETURN */ { xGetMotionEventsReply rep;... if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) { … }... if (! (tc = (XTimeCoord *) Xmalloc( (unsigned) (nbytes = (long) rep.nEvents * sizeof(XTimeCoord))))) {... }... for (i = rep.nEvents, tcptr = tc; i > 0; i--, tcptr++) { _XRead (dpy, (char *) &xtc, nbytes); tcptr->time = xtc.time; … }...}

Typical bugs 12 _XkbReadGetDeviceInfoReply(Display *dpy, xkbGetDeviceInfoReply *rep, XkbDeviceInfoPtrdevi) {... if (rep->nBtnsWanted>0) { act= &devi->btn_acts[rep->firstBtnWanted]; bzero((char *)act,(rep->nBtnsWanted*sizeof(XkbAction))); }... int size; act= &devi->btn_acts[rep->firstBtnRtrn]; size= rep->nBtnsRtrn*SIZEOF(xkbActionWireDesc); if (!_XkbCopyFromReadBuffer(&buf,(char *)act,size)) goto BAILOUT;... }

Typical bugs 13 Private Bool _XimXGetReadData( Xim im, char *buf, int buf_len, int *ret_len, XEvent *event) {... return_code = XGetWindowProperty(im->core.display, spec->lib_connect_wid, prop, 0L, (long)((length + 3)/ 4), True, AnyPropertyType, &type_ret, &format_ret, &nitems, &bytes_after_ret, &prop_ret);... if (buf_len >= length) { (void)memcpy(buf, prop_ret, (int)nitems);... }... }

Typical bugs 14 static char * ReadInFile(_Xconst char *filename) { register int fd, size;... if ( (fd = _XOpenFile (filename, O_RDONLY)) == -1 ) return (char *)NULL;... if ( (fstat(fd, &status_buffer)) == -1 ) { close (fd); return (char *)NULL; } else size = status_buffer.st_size; } if (!(filebuf = Xmalloc(size + 1))) { /* leave room for '\0' */ close(fd); return (char *)NULL; } size = read (fd, filebuf, size);... }

Typical bugs 15 static char* TransFileName(Xim im, char *name) { char *home = NULL, *lcCompose = NULL; char dir[XLC_BUFSIZE]; char *i = name, *ret, *j; int l = 0; while (*i) { if (*i == '%') { i++; switch (*i) { case 'H': home = getenv("HOME"); if (home) l += strlen(home);  possible int overflow (long HOME and loads of %H's) break; case 'L': if (lcCompose == NULL) lcCompose = _XlcFileName(im->core.lcd, COMPOSE_FILE); if (lcCompose) l += strlen(lcCompose);  possible integer overflow (long lcCompose and loads of %L's) break; case 'S': xlocaledir(dir, XLC_BUFSIZE); l += strlen(dir);  possible integer overflow (long dir and loads of %S's) break; }

Typical bugs 16 j = ret = Xmalloc(l+1);  integer overflow, alloc too short if any of the int overflows occured... i = name; while (*i) { if (*i == '%') { i++; switch (*i) { case '%': *j++ = '%'; break; case 'H': if (home) { strcpy(j, home);  buffer overflow if integer overflow occured j += strlen(home); } break; case 'L': if (lcCompose) { strcpy(j, lcCompose);  buffer overflow if integer overflow occured j += strlen(lcCompose); } break; case 'S': strcpy(j, dir);  buffer overflow if integer overflow occured j += strlen(dir); break; }...

Typical bugs 17 XFixesCursorImage *XFixesGetCursorImage (Display *dpy) {... xXFixesGetCursorImageAndNameReplyrep; intnpixels;... if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {... }... npixels = rep.width * rep.height;  ushort * ushort... rlength = (sizeof (XFixesCursorImage) + npixels * sizeof (unsigned long) + nbytes_name + 1);... image = (XFixesCursorImage *) Xmalloc (rlength);... image->x = rep.x;... }

Typical bugs 18 Bool DMXGetScreenAttributes(Display *dpy, int physical_screen, DMXScreenAttributes *attr) {... xDMXGetScreenAttributesReply rep;... if (!_XReply(dpy, (xReply *)&rep, (SIZEOF(xDMXGetScreenAttributesReply) - 32) >> 2, xFalse)) { UnlockDisplay(dpy); SyncHandle(); return False; } attr->displayName = Xmalloc(rep.displayNameLength /* for pad */); _XReadPad(dpy, attr->displayName, rep.displayNameLength); attr->displayName[rep.displayNameLength] = '\0';... }

Typical bugs 19 int XGetDeviceButtonMapping( register Display*dpy, XDevice*device, unsigned char map[], unsigned int nmap) { int status = 0; unsigned char mapping[256];/* known fixed size */... xGetDeviceButtonMappingReply rep;... status = _XReply(dpy, (xReply *) & rep, 0, xFalse); if (status == 1) { nbytes = (long)rep.length << 2; _XRead(dpy, (char *)mapping, nbytes);... }... }

Typical bugs 20 XEventClass * XGetDeviceDontPropagateList( register Display*dpy, Window window, int*count) {... xGetDeviceDontPropagateListReply rep;... if (!_XReply(dpy, (xReply *) & rep, 0, xFalse)) {... }... list = (XEventClass *) Xmalloc(rep.length * sizeof(XEventClass)); if (list) {... for (i = 0; i < rep.length; i++) { _XRead(dpy, (char *)(&ec), sizeof(CARD32)); list[i] = (XEventClass) ec; }... }

Typical bugs 21 static int _XIPassiveGrabDevice(Display* dpy, int deviceid, int grabtype, int detail, Window grab_window, Cursor cursor, int grab_mode, int paired_device_mode, Bool owner_events, XIEventMask *mask, int num_modifiers, XIGrabModifiers *modifiers_inout) {... if (!_XReply(dpy, (xReply *)&reply, 0, xFalse)) {... } failed_mods = calloc(reply.num_modifiers, sizeof(xXIGrabModifierInfo));... _XRead(dpy, (char*)failed_mods, reply.num_modifiers * sizeof(xXIGrabModifierInfo)); for (i = 0; i < reply.num_modifiers; i++) { modifiers_inout[i].status = failed_mods[i].status; … }... }

Typical bugs 22 XineramaScreenInfo * XineramaQueryScreens( Display *dpy, int *number ) { XExtDisplayInfo*info = find_display (dpy); xXineramaQueryScreensReplyrep;.... if((scrnInfo = Xmalloc(sizeof(XineramaScreenInfo) * rep.number))) {... for(i = 0; i < rep.number; i++) { _XRead(dpy, (char*)(&scratch), sz_XineramaScreenInfo); scrnInfo[i].screen_number = i; scrnInfo[i].x_org = scratch.x_org; scrnInfo[i].y_org = scratch.y_org; scrnInfo[i].width = scratch.width; scrnInfo[i].height = scratch.height; }... }... }

Typical bugs 23 XvImageFormatValues * XvListImageFormats ( Display *dpy, XvPortID port, int *num ){... xvListImageFormatsReply rep;... if (_XReply(dpy, (xReply *)&rep, 0, xFalse) == 0) {... }... int size = (rep.num_formats * sizeof(XvImageFormatValues));... if((ret = Xmalloc(size))) {... for(i = 0; i < rep.num_formats; i++) {... }... }

Typical bugs 24 Bool XF86VidModeGetGammaRamp ( Display *dpy, int screen, int size, unsigned short *red, unsigned short *green, unsigned short *blue ) {... xXF86VidModeGetGammaRampReply rep;... if (!_XReply (dpy, (xReply *) &rep, 0, xFalse)) {... } if(rep.size) { _XRead(dpy, (char*)red, rep.size << 1); _XRead(dpy, (char*)green, rep.size << 1); _XRead(dpy, (char*)blue, rep.size << 1); }... }

Typical bugs 25 Bool uniDRIOpenConnection(dpy, screen, hSAREA, busIdString) Display *dpy; int screen; drm_handle_t *hSAREA; char **busIdString; {... xXF86DRIOpenConnectionReply rep;... if (!(*busIdString = (char *)Xcalloc(rep.busIdStringLength + 1, 1))) {... } _XReadPad(dpy, *busIdString, rep.busIdStringLength);... }

Typical bugs 26 static XcursorFileHeader * _XcursorReadFileHeader (XcursorFile *file) {... if (!_XcursorReadUInt (file, &head.ntoc))  unsigned 32bit ntoc var read from file return NULL;... fileHeader = _XcursorFileHeaderCreate (head.ntoc);  passed on to allocate buffer... for (n = 0; n ntoc; n++) { if (!_XcursorReadUInt (file, &fileHeader->tocs[n].type)) break; if (!_XcursorReadUInt (file, &fileHeader->tocs[n].subtype)) break; if (!_XcursorReadUInt (file, &fileHeader->tocs[n].position)) break; }... }

Typical bugs 27 static XcursorFileHeader * _XcursorFileHeaderCreate (int ntoc) { XcursorFileHeader*fileHeader; if (ntoc > 0x10000) return NULL; fileHeader = malloc (sizeof (XcursorFileHeader) + ntoc * sizeof (XcursorFileToc)); if (!fileHeader) return NULL; fileHeader->magic = XCURSOR_MAGIC; fileHeader->header = XCURSOR_FILE_HEADER_LEN; fileHeader->version = XCURSOR_FILE_VERSION; fileHeader->ntoc = ntoc; fileHeader->tocs = (XcursorFileToc *) (fileHeader + 1); return fileHeader; }

Typical bugs 28 static void ReqCleanup( Widget widget, XtPointer closure, XEvent *ev, Boolean *cont) {... char *value;... (void) XGetWindowProperty(event->display, XtWindow(widget), event->atom, 0L, , True, AnyPropertyType, &target, &format, &length, &bytesafter, (unsigned char **) &value);  should check return value. XFree(value);... }

More observations The X client libraries (Xlib) All discovered X bugs are being fixed The developer involved is actually quite good Amazing Alan Coopersmith Very deep understanding of X and the bugs involved No pushback, no handholding Worked tirelessly 104 patches, with reviews and some tests in < 3 months And had some interesting comments 29

30 “I don't know how many setuid X clients still exist these days (is xterm still setuid on any platforms, or did they all get grantpt() or similar calls to avoid needing root?), but since we know there's more X clients than we can keep track of (especially once you get to home grown apps in various companies they've been using for decades), we have to assume there still may be some. It would be good to put a reminder in the security advisory that best practice is to separate out the parts of an application that require elevated privileges from the GUI to avoid such issues - GTK requires this, but not all toolkits do.” More observations

31 “Shoot me now. And then shoot daniels for not freeing us from XKB yet. And then shoot anyone who volunteers to try to fix XKB, before it's too late for them too.” “Here's my initial analysis of the first part of the Xlib set, until I got so tired my head started spinning trying to figure them out” “Really, if your window shape is anywhere near 2^32 rectangles, what are you doing?” “Yes, these [bugs] all seem possible, and far more feasible now than when this code was written, back when disk sizes were still measured in megabytes.”

More observations Comment on LWN from one of the people that introduced some of these bugs in the ‘80’s 32

More observations Debian turn around on these bugs was ridiculously fast! 104 patches to merge in 2 week embargo Full releases and advisory on day embargo expired No one else managed to do this I think Moritz Mühlenhoff deserves most of the credit for that one 33

More observations However, Raw X is rarely used nowadays There’s stuff build on top And they use raw X gtk+ KDE (which uses QT which uses raw X) Rare direct calls to Xlib code other 34

More observations KDE / QT Crappyness is about on par with Xlib Trivial bugs! 35

More observations Several instances of this 36 Qkeymapper_x11.cpp void QKeyMapperPrivate::clearMappings() {... uchar *data = 0; if (XGetWindowProperty(X11->display, RootWindow(X11->display, 0), ATOM(_XKB_RULES_NAMES), 0, 1024, false, XA_STRING, &type, &format, &nitems, &bytesAfter, &data) == Success && type == XA_STRING && format == 8 && nitems > 2) {... char *names[5] = { 0, 0, 0, 0, 0 }; char *p = reinterpret_cast (data), *end = p + nitems; int i = 0; do { names[i++] = p; p += qstrlen(p) + 1; } while (p < end);... }

More observations In QT init code (affects all QT applications) 37 Qapplication_x11.cpp void qt_init(QApplicationPrivate *priv, int, Display *display, Qt::HANDLE visual, Qt::HANDLE colormap) {... } else if (arg == "-name") { if (++i < argc) appName = argv[i];  if it was previously new'ed, it isn't anymore. }... } void qt_cleanup() {... if (X11->foreignDisplay) { delete [] (char *)appName;  could delete [] a pointer that isn't new'ed and possibly corrupt memory appName = 0; }... }

More observations So I reported these bugs They didn’t seem to think it was a security issue Quote from X developer (previous slide) is dead on Suid remark QT does not seem to agree with this 38

More observations "KDE has precisely one setuid application, kcheckpass, for this reason. I suspect that someone running an suid Qt application would fall into a huge number of problems, the most obvious one being a malicious style that would allow them to trivially execute arbitrary code“ Wait, did we just get a free Code exec bug from the QT security team ? 39

More observations I respond back, saying there are more KDE suid binaries, and specifically mention kppp, and question him on the styles thing 40

More observations 41 “> I am aware of this, regardless, this is library code, as such, chances are, there are suid applications out there that will use it. That would be a security hole in those applications rather than in Qt, there are many ways that people can abuse a library to create unsafe applications. > Do styles contain executable code ? Yes.”

42 “> also, does kppp no longer run suid ? kppp should not be installed setuid. Here's a quote from its FAQ: "There is no need for the setuid bit, if you know a bit of UNIX® systems administration. Simply create a modem group, add all users that you want to give access to the modem to that group and make the modem device read/writable for that group." I doubt any modern distro would install it suid, in fact most are extremely careful about what they allow to be suid and are actively working to minimise what is.” More observations

That kppp FAQ quote in incomplete, it goes on to say: 43 “… The KPPP team has lately done a lot of work to make KPPP setuid-safe. But it's up to you to decide if you install and how you install it.”

More observations In fact, distros do still have it suid. E.g. Ubuntu This is library code! They should not set policy for the apps that use them. They’re sitting on the fence, because it’s easy you don’t actually have to do anything Either defend it, and shut up Or do a suid check and exit() 44

More observations None of those bugs are fixed Got the ok from QT security team to disclose: 45 “> Ok, since you guys don't consider this a security issue, you're ok with me talking about this publicly? Yes, that's fine”

More observations So loaders have LD_PRELOAD And has been made setuid safe years ago KDE/QT QT_PLUGIN_PATH Gnome GTK_MODULES Neither are setuid safe ! 46

More observations The GTK+ people seem to be doing somewhat better. They do not allow suid GTK+ applications. And clearly explain why on their webpage 47

More observations ( Talking Radios born from taco trucks 48

More observations This is beautiful, well though out and sane! “Security of GTK+ requires the security of Xlib. The GTK+ team is not prepared to make that guarantee” Or is it ? 49

More observations 50 Gtkmain.c /* This checks to see if the process is running suid or sgid * at the current time. If so, we don't allow GTK+ to be initialized. * This is meant to be a mild check - we only error out if we * can prove the programmer is doing something wrong, not if * they could be doing something wrong. For this reason, we * don't use issetugid() on BSD or prctl (PR_GET_DUMPABLE). */ static gboolean check_setugid (void)

More observations What does that mean ? Suid binaries can use GTK+, BUT … … they must acquire the privileged resources they want first And then drop privileges After that it’s ok to use GTK+ Want to have their cake and eat it too Check should be stronger! 51

More observations games are a great example They are suid Share a highscore database Once aquired, privs are dropped Only thing an attacker would have access to is that db assuming a bug was found and exploited That db is considered trusted. Any security bug in db parsing allows for further escalation Any user now playing any of those games gets pwned 52

More observations By far the most common bug when using Xlib Check return values ! XLib defense in depth fixes. Now guarantees NULL init of arguments on failure. 53 void fn() {... SomeFormat *sf;... (void) XGetWindowProperty(dpy, w, property, 0L, , False, SomePropertyType, &type, &format, &length, &bytesafter, (unsigned char **) &sf);... XFree((char*)sf);... }

More observations Developers using Xlib don’t seem to realize that most of the api’s they use parse potentially untrusted network data _XReply _XRead32 _XRead _XGetAsyncReply XGetWindowProperty XNextEvent XPeekEventXIfEvent XCheckIfEvent XPeekIfEvent XCheckTypedWindowEvent XSetErrorHandler XQueryFont 54

More observations derived from XGetWindowProperty: XFetchName XGetIconName XGetSizeHints XGetWMHints XGetWMSizeHints XGetIconSizes XGetTransientForHint XGetClassHint XGetRGBColormaps XGetTextProperty XGetWMName XGetWMIconName XGetWMClientMachine XGetCommand XGetWMColormapWindows XGetWMProtocols 55 XScreenResourceString XFetchBuffer XFetchBytes XkbRF_GetNamesProp

More observations Conceptually there’s a couple of X suid apps around that you’ll see: Config tools (e.g. kppp) Games (e.g. swell foop) Screen locking utils (e.g. Xlock, Xlockmore, Xscreensaver, …) Virtually all of these apps do drop privileges Still holding on to privileged resources in most cases 56

Client summary Xlib in suids is a bad idea GTK+ kinda sorta still allowed in suids Very common sloppy misuse of Xlib api’s 57

58 Server

server Reviewing the X server code has been ongoing work since may-june Not finished a LOT of code I’m lazy GLX is a horrible demotivator! 59

Server architecture Remember the X architecture layout ? 60

X network architecture 61

server This is a lie! X hasn’t looked like this in a very long time Should watch Daniel Stone’s “The real story behind wayland and X” talk ( ) X hasn’t been network transparant in a long time Shared memory DRI / DRM Direct rendering MMIO Kernel drivers / ioctl’s 62

63

Server: core protocol Let’s start with the beginning X server parses core X protocol All straight c code This is 30 years old If it was written in the early 90’s iso 80’s, it would’ve probably been written in C++. This code is actually pretty cool (from a security perspective) You can actually see where the bugs got patched over time (e.g. integer overflow checks) 64

Server: core protocol Dix/dispatch.c (dispatch()) This is where all connections for the X server come in client calls initial connection (e.g. set up byte order) proc Establish connection (e.g. authorization) proc Client now gets to send core X protocol requests to server Requests are limited to ~64k (~16mb with big requests enabled) 65

Server: core protocol Content of requests depends on the request (TLV) All of them begin with a: CARD8 type; CARD8 data; CARD16 length; Anything < 4 bytes won’t make it through. Type 0-127, core protocol Type , extensions Extensions get to pick and choose how they want their (sub)type delivered Will usually take data for (sub)type 66

Server: core protocol Procedures clients can call Dix/tables.c ProcVector SwappedProcVector (different byteorder) Create/destroy/query Windows Atoms Properties Image Text … 67

Server: Extensions This is how people have worked around X11s old age and brokenness (while leaving the core protocol in tact) Extensions for Input Output Shared memory OpenGL DRI … 68

Server: Extensions Extensions get registered by calling AddExtension() Will add MainProc to ProcVector (>128) Will add SwappedMainProc to SwappedProcVector MinorOpcodeProc decides how extension wants it’s type delivered 69

Server: Extensions Extensions can also add new resources Types of handles basically Done by calling CreateNewResourceType() Takes two arguments Delete function Name Delete logic can get very complicated Possible source of bugs 70

Server: Extensions Rought list of Extensions Core protocol ProcListExtensions proc XListExtensions() xlib api Shows list of loaded extension 71 $ grep AddExtension * -r | awk 'BEGIN{FS=":";} {print $1;}' | grep ".*\.c" | sort | uniq composite/compext.c damageext/damageext.c dbe/dbe.c dix/extension.c glx/glxext.c hw/dmx/dmx.c hw/dmx/glxProxy/glxext.c hw/kdrive/ephyr/ephyrdriext.c hw/xfree86/dixmods/extmod/xf86dga2.c hw/xfree86/dixmods/extmod/xf86vmode.c hw/xfree86/dri/xf86dri.c hw/xfree86/dri2/dri2ext.c hw/xquartz/applewm.c hw/xquartz/pseudoramiX.c hw/xquartz/xpr/appledri.c hw/xwin/winwindowswm.c randr/randr.c randr/rrxinerama.c record/record.c render/render.c Xext/bigreq.c Xext/dpms.c Xext/geext.c Xext/panoramiX.c Xext/saver.c Xext/security.c Xext/shape.c Xext/shm.c Xext/sync.c Xext/xcmisc.c Xext/xf86bigfont.c Xext/xres.c Xext/xselinux_ext.c Xext/xtest.c Xext/xvmain.c Xext/xvmc.c xfixes/xfixes.c Xi/exevents.c Xi/extinit.c Xi/selectev.c xkb/xkb.c int main() { Display *dpy = XOpenDisplay(NULL); int nextensions, i = 0; char **p, **extensionList = XListExtensions(dpy, &nextensions); for(p = extensionList; nextensions; nextensions--, p++){i++; printf("extension %d: %s\n", i, *p); }

Server: Extensions Prime attack surface Have reviewed most of these Some are small, some are huge Some select few were HUMONGOUS Varying level of quality Some good, some bad GLX was sheer terror 72

Server: Request procedure So what does a general request Proc look like ? xTestReq is a structure describing the request REQUEST() is a macro that defines a structure of type xTestReq called stuff (and points it to the request buffer) 73 int ProcTest(ClientPtr client) { REQUEST(xTestReq); REQUEST_SIZE_MATCH(xTest Req); useRequestData(stuff); return Success; }

Server: Request procedure REQUEST_SIZE_MATCH(type) Indicates that the request has to be exactly as big as the structure REQUEST_AT_LEAST_SIZE(type) Indicates that the request has to be at least as big as the structure REQUEST_FIXED_SIZE(type, len) Indicates that the request has to be exactly as big as the structure + len Has implicit integer overflow! Use of these macro’s prevent out of bound read/write 74

Server: Type of bugs There’s some typical bugs that keep showing up when looking at a bunch of these request Proc’s 75

Server: Type of bugs Memory allocation Forgetting to check return values In OOM cases, can return NULL Would crash on NULL deref 76

Server: Type of bugs Integer overflows when parsing large files > 4gig files Read it all in one large buffer Buffer either dynamically grows (int overflow) Loop over file to calculate size (int overflow) When parsing protocol data out of bound reads (bypassing length checks) Memory corruption (when doing buffer length calculations) Malloc wrappers Implicit in REQUEST_FIXED_SIZE 77

Server: Type of bugs Cute realloc bugs realloc() with size of 0 becomes free Leads to use after free and double free bugs 78

Server: Type of bugs Unvalidated length fields / index (as part of the protocol) Leads to out of bound reads and writes 79

Server: Type of bugs Out of bound reads No validation for this whatsoever when accessing data in the request 80

Server: Type of bugs Byte order bugs when byte order swapping is Basically need to create a swap wrapper before the actual proc This one needs to do proper calls to REQUEST_SIZE_MATCH REQUEST_AT_LEAST_SIZE REQUEST_FIXED_SIZE Often not written as careful as the actual proc Dev forgot to use size macro’s Or used them too late 81

Server: Type of bugs Byte order bugs Memory corruption If size macro’s are missing (or too late) Since in place byte swap happens 82

Server: Type of bugs Pretty standard memory leaks Do alloc Forgot to free in error corner cases 83

Server:… This is about as far as I’ve come I had hoped to gotten further but There’s a ton of code really GLX No seriously, GLX is horrible The rest of the slides will just be general entry points 84

Server: Drivers There’s a whole range of drivers that can be used in one way or the other font drivers drawable drivers gc rivers Server display driver opengl drivers DRI drivers 85

Server: Server display Drivers Wanted to look at these Haven’t gotten to it yet 86

Server: Font Drivers These get registered with RegisterFPEFunctions Have actually looked at the one that contains the font client code This was horribly outdated code Riddled with trivial bugs Noone really uses font servers anymore 87

Server: OpenGL Drivers I was getting to these GLX talks to OpenGL drivers Figuring out the amount of control over data being send back and forth is probably tedious work Need to look at hundres of Proc functions Drivers would call _glapi_set_dispatch 88

Server: Library dependancies pixman mesa SDL DRMLib FreeType Gallium3d 89

Server: DRI Direct Rendering infrastructure framework: allows for direct hardware access by clients Much more efficient Requires DRI extensions in X server Requires DRM drivers in kernel DRM: Direct Rendering Manager Can talk to DRM and DRM drivers through IOCTL’s 90

Server: DRI 91

Server: DRM Looked at linux implementation of DRM And DRM drivers Drivers/gpu/drm/drm_drv.c Exposes an ioctl interface The drm itself has a number of ioctls The drm drivers can expose a number of ioctls Standard linux ioctl’s are just a number BSD ioctl’s encode stuff in the ioctl number (in, out, len) DRM ioctl’s are like BSD ioctls 92

Server: DRM Also adds a bit more than just BSD ioctls DRM Drivers expose their ioctls as follows 3 rd argument are flags 93 struct drm_ioctl_desc radeon_ioctls[] = { DRM_IOCTL_DEF_DRV(RADEON_CP_INIT, radeon_cp_init, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_START, radeon_cp_start, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_STOP, radeon_cp_stop, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_RESET, radeon_cp_reset, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), DRM_IOCTL_DEF_DRV(RADEON_CP_IDLE, radeon_cp_idle, DRM_AUTH), DRM_IOCTL_DEF_DRV(RADEON_CP_RESUME, radeon_cp_resume, DRM_AUTH), DRM_IOCTL_DEF_DRV(RADEON_RESET, radeon_engine_reset, DRM_AUTH), DRM_IOCTL_DEF_DRV(RADEON_FULLSCREEN, radeon_fullscreen, DRM_AUTH), DRM_IOCTL_DEF_DRV(RADEON_SWAP, radeon_cp_swap, DRM_AUTH), … };

Server: DRM Flag meaning / validation: 94 } else if (((ioctl->flags & DRM_ROOT_ONLY) && !capable(CAP_SYS_ADMIN)) || ((ioctl->flags & DRM_AUTH) && !drm_is_render_client(file_priv) && !file_priv->authenticated) || ((ioctl->flags & DRM_MASTER) && !file_priv->is_master) || (!(ioctl->flags & DRM_CONTROL_ALLOW) && (file_priv->minor->type == DRM_MINOR_CONTROL)) || (!(ioctl->flags & DRM_RENDER_ALLOW) && drm_is_render_client(file_priv))) {

Server: SHM X allows for sharing of images between client and server over shared memory Much faster than ipc/tcp X Extension Procs Version Attach Detach Putimg Get img Create pixmap 95

Server: SHM Fonts can use shared memory too (xf86bigfont) Number of other places 96

Server: SHM Would find typical shared memory bugs ?? Incorrect permissions (e.g. world read/write) Race conditions ? 97

Server: Security The whole X server runs as root There has been some talk of implementing priv sep / priv drop Afaik noone has done this for xorg OpenBSD did it! Xorg guys should steal that code! X Access Control Extension (XaceHooks) Influenced by LSM Allows drivers to implement a security model E.g. which actions is allowed for which connection Does anyone really use this ? Comes from the NSA … 98

How bad is it? Can we do better? Trivial bugs in clientside fixed by now Yay! Plenty of bugs left in the server / extensions / drivers Maybe the load of bugs reported will scare people into adopting wayland faster ? Even with Wayland, Xorg is going to be around for a long time These bugs need to get fixed If clientside fix rate is any indication, this will happen fast. Need driving force to go audit for more bugs Long and tedious work Should really implement priv sep / priv drop 99

Questions ? 100