Skip to content

Commit

Permalink
Merge pull request #63 from cscorley/pr-62
Browse files Browse the repository at this point in the history
  • Loading branch information
cscorley authored Nov 16, 2024
2 parents f274445 + 92c1bb6 commit 07b3e14
Show file tree
Hide file tree
Showing 8 changed files with 254 additions and 27 deletions.
9 changes: 8 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"]
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]

steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -56,6 +56,13 @@ jobs:
- name: Test
run: |
pytest --doctest-modules --doctest-glob='*.rst' --junitxml=junit/test-results-${{ matrix.python-version }}-${{ matrix.os }}.xml
if: ${{ matrix.os != 'macos-latest' }}

- name: Test macos-latest
run: |
export PATH="/opt/homebrew/opt/gpatch/libexec/gnubin:$PATH"
pytest --doctest-modules --doctest-glob='*.rst' --junitxml=junit/test-results-${{ matrix.python-version }}-${{ matrix.os }}.xml
if: ${{ matrix.os == 'macos-latest' }}

- name: Upload pytest test results
uses: actions/upload-artifact@v4
Expand Down
6 changes: 6 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

Nothing yet :)

# 1.0.7

- PR #62 fix: incorrect regular expression matching diffcmd (Thanks, @jingfelix)
- Support up to 3.13
- Drop support up to 3.8

# 1.0.6

- PR #60 Improve huge_patch test (Thanks, @arkamar)
Expand Down
38 changes: 19 additions & 19 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,29 +1,29 @@
[project]
name = "whatthepatch"
version = "1.0.6"
version = "1.0.7"
maintainers = [{ name = "Christopher S. Corley", email = "[email protected]" }]
requires-python = ">=3.8"
requires-python = ">=3.9"
readme = "README.rst"
description = "A patch parsing and application library."
keywords = ["patch", "diff", "parser"]
classifiers = [
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Version Control",
"Topic :: Software Development",
"Topic :: Text Processing",
"Development Status :: 5 - Production/Stable",
"Intended Audience :: Developers",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: MIT License",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3 :: Only",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: 3.13",
"Programming Language :: Python :: Implementation :: CPython",
"Topic :: Software Development :: Libraries :: Python Modules",
"Topic :: Software Development :: Version Control",
"Topic :: Software Development",
"Topic :: Text Processing",
]

[project.urls]
Expand Down
4 changes: 2 additions & 2 deletions release.nix
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
{ lib, python3Packages, setuptools }:
with python3Packages;
buildPythonPackage rec {
buildPythonPackage {
pname = "whatthepatch";
version = "1.0.6";
version = "1.0.7";
format = "pyproject";
src = ./.;

Expand Down
4 changes: 2 additions & 2 deletions src/whatthepatch/patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
# .+? was previously [^:\t\n\r\f\v]+

# general diff regex
diffcmd_header = re.compile("^diff.* (.+) (.+)$")
diffcmd_header = re.compile("^diff(?: .+)? (.+) (.+)$")
unified_header_index = re.compile("^Index: (.+)$")
unified_header_old_line = re.compile(r"^--- " + file_timestamp_str + "$")
unified_header_new_line = re.compile(r"^\+\+\+ " + file_timestamp_str + "$")
Expand Down Expand Up @@ -68,7 +68,7 @@
cvs_header_rcs = re.compile(r"^RCS file: (.+)(?:,\w{1}$|$)")
cvs_header_timestamp = re.compile(r"(.+)\t([\d.]+)")
cvs_header_timestamp_colon = re.compile(r":([\d.]+)\t(.+)")
old_cvs_diffcmd_header = re.compile("^diff.* (.+):(.*) (.+):(.*)$")
old_cvs_diffcmd_header = re.compile("^diff(?: .+)? (.+):(.*) (.+):(.*)$")


def parse_patch(text):
Expand Down
31 changes: 31 additions & 0 deletions tests/casefiles/eclipse-attachment-1701.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
? cvsdiff
? model/org/eclipse/jdt/internal/debug/core/BreakMouseGrab.java
Index: model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java
===================================================================
RCS file: /home/eclipse/org.eclipse.jdt.debug/model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java,v
retrieving revision 1.34
diff -u -p -r1.34 JDIDebugPlugin.java
--- model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java 6 Jun 2002 20:33:46 -0000 1.34
+++ model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java 16 Jul 2002 20:37:56 -0000
@@ -61,6 +61,13 @@ public class JDIDebugPlugin extends Plug
private boolean fTrace = false;

/**
+ * On SWT/GTK applications, we need to drop
+ * any mouse grabs when a breakpoint is hit
+ * or the mouse is not usable.
+ */
+ private BreakMouseGrab breakMouseGrab;
+
+ /**
* Returns whether the debug UI plug-in is in trace
* mode.
*
@@ -117,6 +124,7 @@ public class JDIDebugPlugin extends Plug
fBreakpointListeners = new ListenerList(5);
getPluginPreferences().setDefault(JDIDebugModel.PREF_REQUEST_TIMEOUT, JDIDebugModel.DEF_REQUEST_TIMEOUT);
getPluginPreferences().addPropertyChangeListener(this);
+ breakMouseGrab = new BreakMouseGrab();
}

/**
140 changes: 140 additions & 0 deletions tests/casefiles/linux-29e1dfcd5150097f32f34891c85a50d9ead19df3.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
From 29e1dfcd5150097f32f34891c85a50d9ead19df3 Mon Sep 17 00:00:00 2001
From: Lihong Kou <[email protected]>
Date: Tue, 23 Jun 2020 20:28:41 +0800
Subject: Bluetooth: add a mutex lock to avoid UAF in do_enale_set

[ Upstream commit f9c70bdc279b191da8d60777c627702c06e4a37d ]

In the case we set or free the global value listen_chan in
different threads, we can encounter the UAF problems because
the method is not protected by any lock, add one to avoid
this bug.

BUG: KASAN: use-after-free in l2cap_chan_close+0x48/0x990
net/bluetooth/l2cap_core.c:730
Read of size 8 at addr ffff888096950000 by task kworker/1:102/2868

CPU: 1 PID: 2868 Comm: kworker/1:102 Not tainted 5.5.0-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine,
BIOS Google 01/01/2011
Workqueue: events do_enable_set
Call Trace:
__dump_stack lib/dump_stack.c:77 [inline]
dump_stack+0x1fb/0x318 lib/dump_stack.c:118
print_address_description+0x74/0x5c0 mm/kasan/report.c:374
__kasan_report+0x149/0x1c0 mm/kasan/report.c:506
kasan_report+0x26/0x50 mm/kasan/common.c:641
__asan_report_load8_noabort+0x14/0x20 mm/kasan/generic_report.c:135
l2cap_chan_close+0x48/0x990 net/bluetooth/l2cap_core.c:730
do_enable_set+0x660/0x900 net/bluetooth/6lowpan.c:1074
process_one_work+0x7f5/0x10f0 kernel/workqueue.c:2264
worker_thread+0xbbc/0x1630 kernel/workqueue.c:2410
kthread+0x332/0x350 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

Allocated by task 2870:
save_stack mm/kasan/common.c:72 [inline]
set_track mm/kasan/common.c:80 [inline]
__kasan_kmalloc+0x118/0x1c0 mm/kasan/common.c:515
kasan_kmalloc+0x9/0x10 mm/kasan/common.c:529
kmem_cache_alloc_trace+0x221/0x2f0 mm/slab.c:3551
kmalloc include/linux/slab.h:555 [inline]
kzalloc include/linux/slab.h:669 [inline]
l2cap_chan_create+0x50/0x320 net/bluetooth/l2cap_core.c:446
chan_create net/bluetooth/6lowpan.c:640 [inline]
bt_6lowpan_listen net/bluetooth/6lowpan.c:959 [inline]
do_enable_set+0x6a4/0x900 net/bluetooth/6lowpan.c:1078
process_one_work+0x7f5/0x10f0 kernel/workqueue.c:2264
worker_thread+0xbbc/0x1630 kernel/workqueue.c:2410
kthread+0x332/0x350 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

Freed by task 2870:
save_stack mm/kasan/common.c:72 [inline]
set_track mm/kasan/common.c:80 [inline]
kasan_set_free_info mm/kasan/common.c:337 [inline]
__kasan_slab_free+0x12e/0x1e0 mm/kasan/common.c:476
kasan_slab_free+0xe/0x10 mm/kasan/common.c:485
__cache_free mm/slab.c:3426 [inline]
kfree+0x10d/0x220 mm/slab.c:3757
l2cap_chan_destroy net/bluetooth/l2cap_core.c:484 [inline]
kref_put include/linux/kref.h:65 [inline]
l2cap_chan_put+0x170/0x190 net/bluetooth/l2cap_core.c:498
do_enable_set+0x66c/0x900 net/bluetooth/6lowpan.c:1075
process_one_work+0x7f5/0x10f0 kernel/workqueue.c:2264
worker_thread+0xbbc/0x1630 kernel/workqueue.c:2410
kthread+0x332/0x350 kernel/kthread.c:255
ret_from_fork+0x24/0x30 arch/x86/entry/entry_64.S:352

The buggy address belongs to the object at ffff888096950000
which belongs to the cache kmalloc-2k of size 2048
The buggy address is located 0 bytes inside of
2048-byte region [ffff888096950000, ffff888096950800)
The buggy address belongs to the page:
page:ffffea00025a5400 refcount:1 mapcount:0 mapping:ffff8880aa400e00 index:0x0
flags: 0xfffe0000000200(slab)
raw: 00fffe0000000200 ffffea00027d1548 ffffea0002397808 ffff8880aa400e00
raw: 0000000000000000 ffff888096950000 0000000100000001 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
ffff88809694ff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
ffff88809694ff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
>ffff888096950000: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
^
ffff888096950080: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
ffff888096950100: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
==================================================================

Reported-by: [email protected]
Signed-off-by: Lihong Kou <[email protected]>
Signed-off-by: Marcel Holtmann <[email protected]>
Signed-off-by: Sasha Levin <[email protected]>
---
net/bluetooth/6lowpan.c | 5 +++++
1 file changed, 5 insertions(+)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 357475cceec61b..9a75f9b00b5129 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -57,6 +57,7 @@ static bool enable_6lowpan;
/* We are listening incoming connections via this channel
*/
static struct l2cap_chan *listen_chan;
+static DEFINE_MUTEX(set_lock);

struct lowpan_peer {
struct list_head list;
@@ -1082,12 +1083,14 @@ static void do_enable_set(struct work_struct *work)

enable_6lowpan = set_enable->flag;

+ mutex_lock(&set_lock);
if (listen_chan) {
l2cap_chan_close(listen_chan, 0);
l2cap_chan_put(listen_chan);
}

listen_chan = bt_6lowpan_listen();
+ mutex_unlock(&set_lock);

kfree(set_enable);
}
@@ -1139,11 +1142,13 @@ static ssize_t lowpan_control_write(struct file *fp,
if (ret == -EINVAL)
return ret;

+ mutex_lock(&set_lock);
if (listen_chan) {
l2cap_chan_close(listen_chan, 0);
l2cap_chan_put(listen_chan);
listen_chan = NULL;
}
+ mutex_unlock(&set_lock);

if (conn) {
struct lowpan_peer *peer;
--
cgit 1.2.3-korg

49 changes: 46 additions & 3 deletions tests/test_patch.py
Original file line number Diff line number Diff line change
Expand Up @@ -1390,6 +1390,7 @@ def test_apache_attachment_2241(self):
self.assert_diffs_equal(results, expected)

def test_space_in_path_header(self):
# From https://bugzillaattachments.eclipsecontent.org/bugs/attachment.cgi?id=126343
with open("tests/casefiles/eclipse-attachment-126343.header") as f:
text = f.read()

Expand Down Expand Up @@ -1426,7 +1427,8 @@ def test_svn_mixed_line_ends(self):
self.assertEqual(results[0].header, expected_header)

def test_huge_patch(self):
text_parts = ["""diff --git a/huge.file b/huge.file
text_parts = [
"""diff --git a/huge.file b/huge.file
index 0000000..1111111 100644
--- a/huge.file
+++ a/huge.file
Expand All @@ -1438,9 +1440,10 @@ def test_huge_patch(self):
-44444444
+55555555
+66666666
"""]
"""
]
text_parts.extend("+" + hex(n) + "\n" for n in range(0, 1000000))
text = ''.join(text_parts)
text = "".join(text_parts)
start_time = time.time()
result = list(wtp.patch.parse_patch(text))
self.assertEqual(1, len(result))
Expand Down Expand Up @@ -1508,6 +1511,46 @@ def test_git_bin_patch_minline(self):
== "b07b94142cfce2094b5be04e9d30b653a7c63917"
)

def test_linux_29e1dfc(self):
with open(
"tests/casefiles/linux-29e1dfcd5150097f32f34891c85a50d9ead19df3.patch"
) as f:
text = f.read()

# testing we get to the diff
path = "net/bluetooth/6lowpan.c"
expected = headerobj(
index_path=None,
old_path=path,
old_version="357475cceec61b",
new_path=path,
new_version="9a75f9b00b5129",
)

results = list(wtp.patch.parse_patch(text))
self.assertEqual(len(results), 1)
self.assertEqual(results[0].header, expected)

def test_eclipse_cvsdiff(self):
# From https://bugzillaattachments.eclipsecontent.org/bugs/attachment.cgi?id=1701
with open("tests/casefiles/eclipse-attachment-1701.patch") as f:
text = f.read()

expected = headerobj(
index_path=(
"model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java"
),
old_path="model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java",
old_version="1.34",
new_path="model/org/eclipse/jdt/internal/debug/core/JDIDebugPlugin.java",
new_version="16 Jul 2002 20:37:56 -0000",
)

results = list(wtp.patch.parse_patch(text))
self.assertEqual(len(results), 1)
self.assertEqual(results[0].header, expected)
self.assertEqual(len(results[0].changes), 20)


if __name__ == "__main__":
unittest.main()

0 comments on commit 07b3e14

Please sign in to comment.