# Zoom out

This vulnerability in the Macintosh client for the Zoom audio/video conferencing system has gotten a lot of attention since it was published yesterday. In a nutshell:

1. Safari forces users to click a button to confirm they want an app launched.1 This would mean an extra click for Zoom users.
2. To get around this terrible imposition on their users, Zoom installed a webserver on their computers without telling them. A webserver that remains present and running, even when the Zoom app is not running. Even if you uninstall the Zoom app.
3. There is a set of commands you can run to kill the webserver and prevent its relaunch, even if you still want/need to use Zoom. The commands are near the end of the Medium post by Jonathan Leitschuh, who discovered all this. Ironically, the commands sometimes don’t appear in Safari on the Mac, apparently because of some incompatibility between the Safari and the GitHub embedding code used in the post.

I don’t pretend to follow all of Leitschuh’s explanation of the vulnerability, but I do understand the commands for the fix. I thought I’d talk about what they do. Also, there’s a cut-and-paste solution getting some traction on Twitter that I want to talk about.

First, here’s what Zoom says about the installation of the webserver:

Second, when Zoom is installed on a Mac device by the user, a limited-functionality web server that can only respond to requests from the local machine is also installed on the device. This is a workaround to a change introduced in Safari 12 that requires a user to confirm that they want to start the Zoom client prior to joining every meeting. The local web server enables users to avoid this extra click before joining every meeting. We feel that this is a legitimate solution to a poor user experience problem, enabling our users to have faster, one-click-to-join meetings. We are not alone among video conferencing providers in implementing this solution.

There’s no question that Mac users have a tendency to complain about changes Apple makes to the Mac’s OS and first-party software (I may have even done some complaining myself). But generally speaking, we think Apple’s focus on security is a good thing, and we certainly don’t want apps installing servers on our computers without telling us about it. Even if it means the “poor user experience” of (horrors!) an extra click when we want to use video. Note that Zoom doesn’t discuss the poor user experience of finding your computer’s camera turned on when you visit a malicious website.

Assuming you want to keep Zoom on your computer, the first step in Leitschuh’s fix is to make sure Zoom’s “Turn off my video when joining a meeting” setting is clicked on:

Let us bask for a moment in the warm glow of a user interface that asks you to turn something on in order to turn something off. And remember, Zoom is very concerned about poor user experiences.

With that bit of GUI work done, we have to move to the command line to rid ourselves of the unwanted webserver. These steps will be needed even if you deleted the Zoom app.

The unwanted webserver uses port 19421. We can find which process is using that port through the lsof command:

lsof -i :19421


lsof means “list open files,” and it’s using the expansive Unix definition of a file, which is basically anything that can read or write a stream of bytes. An internet address that’s listening for input, which our webserver uses, fits within that definition. The -i option to lsof allows us to specify as much of an internet address as necessary. We could, for example, give the protocol (TCP) and host (localhost) along with the port, but in this case only the port number (which has to come after a colon) is necessary.

The output is a table of processes that fit the specification

COMMAND     PID USER   FD   TYPE             DEVICE SIZE/OFF NODE NAME
ZoomOpene 59742 drang   7u  IPv4 0x31175d99fb28ad5b      0t0  TCP localhost:19421 (LISTEN)


The header line tells us what’s in the columns below. In this case, there’s only one entry. You can see from the COMMAND that it’s related to Zoom (the full name of the command is trucated to fit) and from the USER that it’s running as me. The key item is the PID, or process identification number. That’s the ID of the webserver we want to stop.

Stopping a process in Unix means using the kill command. Despite its name, kill normally just sends a signal to the given process to “please finish up what you’re doing and then stop, if you don’t mind.” But you can give it an option to be more forceful. The -9 option is aggressive; the process can’t ignore it and shuts down immediately. So our next command is

kill -9 <PID>


where <PID> is number we got from the lsof output.

This tweet from Mateusz Stawecki uses a Unix pipeline to get the PID from the lsof command and feed it to the kill command.

Given that the point of this exercise is to enhance the security of our computers, it’s hard to justify copying and pasting a command from Twitter. But Stawecki’s command does work. Let’s see why.

Ignoring for a moment everything that comes after the first semicolon, the pipeline is

lsof -i TCP:19421 | awk 'NR > 1 {print $2}' | xargs kill -9  As we’ve seen, the TCP part of the lsof command is an unnecessary but harmless addition. The output of lsof is fed to the awk command, which skips over the header line (NR > 1) and outputs the second field (print$2) of the next line. As we’ve seen, this second field is the PID of the process we want to kill. The xargs command takes the PID and turns it into an argument for the kill command.

There’s an easier way to do this, eliminating the awk command entirely. lsof has a “terse” option, -t, which reduces the output to just the PID(s) of the matching process(es). So we can cut Stawecki’s pipeline down to just two steps:

lsof -ti :19421 | xargs kill -9


And since there’s only one matching process, we could reduce the command even further:

kill -9 $(lsof -ti :19421)  The $(command) construct says “run this command and put its output here.” Because I like building up my commands step by step, I prefer the xargs solution, but either will work.

Now we’ve killed the web server, but we need to do more to prevent it from coming back. Zoom put a folder named .zoomus in your home directory, and inside that folder is an app called ZoomOpener. This is the app that launches the web server.

We get rid of the app and its enclosing folder through

rm -r ~/.zoomus


Leitschuh’s article and Stawecki’s pipeline both use rm -rf, but the force (-f) option is unnecessary. The Unix rm command is powerful and a little scary, especially when combined with the recursive (-r) option. You may prefer to use the Finder to throw the .zoomus folder into the Trash and empty it. If so, you’ll have make the folder visible (files and folders that start with a period are invisible by default). This is done by pressing ⇧⌘. (that’s Command-Shift-Period). Press it again to go back to the usual Finder view.

With the ZoomOpener app deleted, we must be finished, right? Wrong. The Zoom app will recreate the folder and the ZoomOpener app the next time you launch it unless you do this:

touch ~/.zoomus


The touch command is meant to update an existing file’s access and modification dates without changing its contents, but if the file you give it as an argument doesn’t exist, it will create it. For reasons I don’t quite understand, putting a file named .zoomus in your home directory prevents the Zoom app from creating a .zoomus folder and installing ZoomOpener in it.

If you go back to Stawecki’s tweet, you’ll see that he has the rm and touch commands in there after the pipeline. Again, I don’t blame you for being leery of using his commands, but they do work and won’t ruin your system.

Of course, the real question is why should you trust me? Or anyone? You may want to read Ken Thompson’sReflections on Trusting Trust.”

1. Thanks to Jeff Johnson for clearing up my initial confusion about the confirmation. Jeff makes StopTheNews, an app that handles Apple News URLs and is the sort of app that gets launched from a URL and requires a confirmation. Pretty sure Jeff hasn’t added a web server to get around that.

When in the course of human events it becomes necessary for a person to dissolve the computational bands which have connected him with an app and to assume among the powers of the earth, the separate and equal station to which the Laws of Mathematics and of Polynomials entitle him, a decent respect to the opinions of other users of the app requires that he should declare the causes which impel him to the separation.

A few months ago, I explained why I wrote my own combinations function for PCalc. Today I declare my independence from its quadratic formula function.

We all know the quadratic formula. It works on equations that look like this,

and provides the two solutions:

It’s the ± that gives us two solutions. One of the solutions uses the minus and the other uses the plus.

PCalc comes with a quadratic solver function. You can find it in the Special section of functions, and it has a very long and explicit name.

What the name is telling you is to put the a term in the X register, the b term in the Y register, and the c term in the memory (or the M0 memory if you have multiple memories turned on). Then the two solutions, $x_1$ and $x_2$, will come out in the X and Y registers.

This solution has the advantage of being usable to every PCalc user. It works whether you have multiple memories on or not. More important, it works whether you’re in algebraic or RPN mode. It’s also presented in a form that should be familiar to anyone who knows what the quadratic formula is. PCalc’s developer, James Thomson, was careful to set it up with universal applicability.

But I don’t care about universal applicability. I care about what seems natural to me, and the placement of the a, b, and c terms has never seemed right to me. So I wrote my own quadratic solver function that fits with the way I think.

First, there’s no need for three inputs. Any quadratic can be put in the form

without any loss of generality by dividing through by the leading coefficient. This means the inputs to the function can fit in the X and Y registers—no need to use one of PCalc’s memory registers.1

Second, I prefer to enter the b term in the Y register and the c term in the X register. In RPN mode, I enter them onto the stack in what I consider their natural order: b first and then c. Even if I were in algebraic mode—which I never am—it would seem more natural to me to enter b first, press the key to put it in the Y register, and then enter the c term.

So with that design of the inputs, the PCalc function for the quadratic formula looks like this (the long screenshot was stitched together with PicSew):

If you don’t want to enter the steps yourself, you can download it.

Note that if the equation has complex roots, my function will throw an error. This is consistent with PCalc’s built-in quadratic function and with how it handles the square roots of negative numbers. PCalc is a real calculator.

To solve a quadratic, I just enter b and c in that order and call the function. Here’s the input and output for the equation

I hold that for the kinds of work I do with quadratic equations, the superiority of my quadratic solver function is self-evident.

1. You may think that dividing through by the leading coefficient is extra work. Not really. Most of the quadratics I deal with already have a leading coefficient of one, so I seldom need to divide. And even when I do, the two divisions can be done quickly with RPN stack manipulation. It’s harder for me to remember which term goes into memory than it is to do two divisions.

# PDF overlays

Today I needed to combine two PDFs into one. Not by concatenating the pages; that would be easy using any number of apps, of which Preview is probably the most obvious. No, I had two single-page PDFs, each of which was meant to be printed on Avery 5161 label stock.

One of the PDFs had printing for the first three row of labels and the other had printing for the fourth and fifth rows. I could, of course, have printed the first page and then taken the sheet and fed it back through the printer for the second page, but I didn’t want to do it that way because

1. Every time you pass label stock through a laser printer, it picks up a bit of toner on all the labels, making the remaining (unprinted upon) labels dingier.
2. Where’s the fun in taking the easy way out?

What I wanted was to create a third PDF with all five rows on a single page, an overlay of the second PDF onto the first. There are ways to do this in PDFpenPro and PDF Expert, but a command-line solution seemed more efficient in the long run.1

For me, the Swiss Army knife of PDF manipulation is the so-called server version of PDFtk, so I checked its man page to see if it had an overlay command. It has two:

• background, which puts one PDF behind the other.
• stamp, which puts one PDF in front of the other.

You might think these are redundant operations, but because of scaling, rotation, and transparency differences, you might find that one of these commands can do what you want and the other can’t. For the PDFs I was working with, either would do.

The command that did what I wanted was

pdftk first.pdf stamp second.pdf output labels.pdf


I then printed labels.pdf and got all the labels in a single pass through the printer. To cut down on the amount of typing I’d need to do in the future, I made a simple script,2 called overlay:

#bash
#!/bin/bash

pdftk "$1" stamp "$2" output -


Now I can use this command with a syntax similar to cat:

overlay first.pdf second.pdf > labels.pdf


To make it really like cat, I’d have to generalize overlay to handle any number of inputs, not just two. I’ll leave that, as the math textbooks like to say, as an exercise for the reader.

1. And there is a long run. I’ve had this situation come up before where I either did the two-passes-through-the-printer thing or used a GUI app to make the combined PDF. It was time to create an automated solution.

2. Thanks to Vitor Galvão for reminding me to wrap the argument placeholders in double quotes. I always forget that.

# Cheesegraters and crystals

Earlier this week, Stephen Hackett wrote a nice article on the design of the new Mac Pro’s grill and how it’s related to older and simpler Apple grill designs. It led me to Apple’s page on the design of the Pro and this language:

The lattice pattern on Mac Pro is based on a naturally occurring phenomenon in molecular crystal structures. A network of three-dimensional interlocking hemispheres, it increases the surface area, optimizing airflow and structural rigidity.

… The result is a lightweight lattice pattern that maximizes airflow while creating an extremely rigid structure.

This isn’t just marketing blather. The hole are a negative-space representation of a common atomic arrangement in metallic crystals, something that most engineers learn about in their introductory materials science class.

Atoms are hard to see, but crystal structures bear a geometric relationship to the packing of spheres, which are easy to see. We start with a layer of spheres and then set another layer on top of it, with the balls of the second layer fitting into valleys formed by the first layer.

• First, when discussing sphere packing, the balls in each layer are normally shown touching each other because that gives the densest arrangement. I’ve shown them slightly separated for reasons that will become apparent later when we return to the Mac Pro grill.
• Second, each layer can be thought of as extending out infinitely in each direction. The sphere arrangement isn’t limited to the balls shown in the drawings.

We can now set a third layer on top of the second, but there are two ways to do it. In one (on the left), the balls of the third layer are directly above those of the first. In the other (right), the balls of the third layer are set in the openings that run through the first two layers.

The left method is called the “hexagonal close packed” (hcp) structure, and the right is called “face-centered cubic” (fcc).

The hcp structure is fairly easy to visualize. Image a layer of seven balls arranged in a hexagon, then a layer of three, then a layer of seven again.

In materials science books, the hcp crystal structure, in which atoms arrange themselves like the spheres we’ve been looking at, is usually shown in an oblique view, like in the drawing at the lower right. That shows you the three layers and all the atom locations in a single image.

The fcc structure isn’t as obvious because it’s harder to visualize cubic arrangements in our layers of balls. I find it easiest to imagine four layers: three layers like those shown above and another that’s just like the green layer but placed below the blue layer.

The trick is to recognize that the faces of the cube aren’t aligned with the layers of balls. We’re looking down the diagonal of a cube, with the green balls at the farthest and nearest corners.

The drawing on the right is the fcc crystal structure as it would commonly be shown in a materials science book.

Now we can see how the cheesegrater grill of the Mac Pro is related to crystal structures. Here’s Apple’s animation of the machining process, which gives a good 3D view of the holes.

A frame capture from the video shows how the hemispherical holes machined into the aluminum plate are arranged like the blue and red layers in our sphere-packing drawings.. The holes on the near side are like the layer of red spheres, and the holes on the far side are like the layer of blue spheres.

Now you can see why I drew the spheres of each layer slightly separated from one another. It was to match the separation of the holes on the two sides of the plate. The holes need to be separated to keep the grill from falling apart.

The other difference between the holes in the Mac Pro grill and the packing of spheres is that the holes from the two sides don’t simply touch, they intersect. Otherwise, there’d be no airflow.

So, the lattice pattern on Mac Pro really is “based on a naturally occurring phenomenon in molecular crystal structures.” I have no idea how this “maximizes airflow”—I suspect maximum airflow would come if the holes from one side were drilled straight through. But if the holes were drilled straight through it wouldn’t look as cool. Also, Stephen and I would have had nothing to write about.

One last thing, which I’m sure delights the metallurgists at Apple. Aluminum has an fcc structure, so the geometry of the grill mimics—in part, at least—the atomic arrangement of the material from which it’s made.