Commit 83ef225
fix(extensions): keep-config restore must not follow symlinks; split mode/time restore
Two hardening fixes to the reinstall keep-config restore loop:
1. Never write *through* a non-regular file at the config path. If dest_cfg
is a symlink (copied with symlinks=True, or swapped in by a racing process
between copytree and the restore), write_bytes() would follow it and
clobber an arbitrary target outside the extension dir. Drop any symlink
(unlink, never follow) or stray directory (rmtree) first, so write_bytes()
always creates a fresh regular file — and skip the entry if the path can't
be made safe rather than clobber.
2. Restore mode and mtime independently. The single try/except meant a chmod
failure skipped os.utime (and vice versa); either can succeed on its own,
so each gets its own guard.
Tests: a symlink-at-path case (proves the write doesn't follow the link to an
external victim; skipped where symlinks need privilege, runs on CI) and a
directory-at-path case (cross-platform: fails/crashes before the guard, passes
after). Behavior for the normal regular-file case is unchanged.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>1 parent 4a885d7 commit 83ef225
2 files changed
Lines changed: 110 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1441 | 1441 | | |
1442 | 1442 | | |
1443 | 1443 | | |
| 1444 | + | |
| 1445 | + | |
| 1446 | + | |
| 1447 | + | |
| 1448 | + | |
| 1449 | + | |
| 1450 | + | |
| 1451 | + | |
| 1452 | + | |
| 1453 | + | |
| 1454 | + | |
| 1455 | + | |
| 1456 | + | |
1444 | 1457 | | |
| 1458 | + | |
| 1459 | + | |
1445 | 1460 | | |
1446 | 1461 | | |
| 1462 | + | |
| 1463 | + | |
| 1464 | + | |
1447 | 1465 | | |
1448 | 1466 | | |
1449 | 1467 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1591 | 1591 | | |
1592 | 1592 | | |
1593 | 1593 | | |
| 1594 | + | |
| 1595 | + | |
| 1596 | + | |
| 1597 | + | |
| 1598 | + | |
| 1599 | + | |
| 1600 | + | |
| 1601 | + | |
| 1602 | + | |
| 1603 | + | |
| 1604 | + | |
| 1605 | + | |
| 1606 | + | |
| 1607 | + | |
| 1608 | + | |
| 1609 | + | |
| 1610 | + | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
| 1615 | + | |
| 1616 | + | |
| 1617 | + | |
| 1618 | + | |
| 1619 | + | |
| 1620 | + | |
| 1621 | + | |
| 1622 | + | |
| 1623 | + | |
| 1624 | + | |
| 1625 | + | |
| 1626 | + | |
| 1627 | + | |
| 1628 | + | |
| 1629 | + | |
| 1630 | + | |
| 1631 | + | |
| 1632 | + | |
| 1633 | + | |
| 1634 | + | |
| 1635 | + | |
| 1636 | + | |
| 1637 | + | |
| 1638 | + | |
| 1639 | + | |
| 1640 | + | |
| 1641 | + | |
| 1642 | + | |
| 1643 | + | |
| 1644 | + | |
| 1645 | + | |
| 1646 | + | |
| 1647 | + | |
| 1648 | + | |
| 1649 | + | |
| 1650 | + | |
| 1651 | + | |
| 1652 | + | |
| 1653 | + | |
| 1654 | + | |
| 1655 | + | |
| 1656 | + | |
| 1657 | + | |
| 1658 | + | |
| 1659 | + | |
| 1660 | + | |
| 1661 | + | |
| 1662 | + | |
| 1663 | + | |
| 1664 | + | |
| 1665 | + | |
| 1666 | + | |
| 1667 | + | |
| 1668 | + | |
| 1669 | + | |
| 1670 | + | |
| 1671 | + | |
| 1672 | + | |
| 1673 | + | |
| 1674 | + | |
| 1675 | + | |
| 1676 | + | |
| 1677 | + | |
| 1678 | + | |
| 1679 | + | |
| 1680 | + | |
| 1681 | + | |
| 1682 | + | |
| 1683 | + | |
| 1684 | + | |
| 1685 | + | |
1594 | 1686 | | |
1595 | 1687 | | |
1596 | 1688 | | |
| |||
0 commit comments