Whenever a bug or vulnerability is detected in the Linux kernel, the kernel developers will endeavour to fix it by introducing a patch into the mainline version of the Linux kernel source tree. However, many users run older “stable” versions of Linux, meaning that the patch should also be “backported” to one or more of these older kernel versions. This process is error-prone and there is usually a long delay in publishing the backported patch. Based on an empirical study, we show that around 8% of all commits submitted to Linux mainline are backported to older versions, but often more than one month elapses before the backport is available. Hence, we propose a patch backporting technique that can automatically transfer patches from the mainline version of Linux into older stable versions. Our approach first synthesizes a partial transformation rule based on a Linux mainline patch. This rule can then be generalized by analysing the alignment between the mainline and target versions. The generalized rule is then applied to the target version to produce a backported patch. We have implemented our transformation technique in a tool called FixMorph and evaluated it on 350 Linux mainline patches. FixMorph correctly backports 75.1% of them. Compared to existing techniques, FixMorph improves both the precision and recall in backporting patches. Apart from automation of software maintenance tasks, patch backporting helps in reducing the exposure to known security vulnerabilities which have not been fixed.
Given a pair of reference/donor program versions Pa and Pb and a target/host program Pc to apply the transformation, FixMorph first extracts the syntactic edits between Pa and Pb to learn a transformation that generalizes the change in the code. Second, using evolution history (i.e. version control history) and/or clone detection FixMorph localize the correct location to apply the transformation from Pa to Pc. Next, analysing the abstract syntax trees of Pa and Pc, FixMorph generates an alignment between the two versions to adapt the learnt transformation. Based on the alignment the transformation will be customized with namespace adaptations, code evolution (i.e. importing missing dependencies). Finally, the transformation will be enforced to source-level changes using LLVM/Clang front-end infrastructure. Finally, the changes will be verified for syntactic correctness using static-analysers.
Patch Type | Patch Count | FixMorph | patch - No Context | patch - Context | SYDIT | Accuracy | Precision | Recall | Accuracy | Precision | Recall | Accuracy | Precision | Recall | Accuracy | Precision | Recall |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Type-I | 1 | 100% | 100% | 100% | 100% | 100% | 100% | 100% | 100% | 100% | 0% | 0% | 0% |
Type-II | 235 | 87% | 95% | 91% | 53% | 77% | 63% | 77% | 99% | 78% | 38% | 46% | 69% |
Type-III | 9 | 78% | 100% | 78% | 0% | 0% | 0% | 0% | 0% | 0% | 22% | 29% | 50% |
Type-IV | 30 | 63% | 86% | 70% | 0% | 0% | 0% | 0% | 0% | 0% | 20% | 38% | 30% |
Type-V | 75 | 43% | 78% | 48% | 0% | 0% | 0% | 0% | 0% | 0% | 0% | 0% | 0% |
Total | 350 | 75% | 92% | 80% | 36% | 71% | 42% | 52% | 82% | 59% | 28% | 44% | 43% |
docker pull rshariffdeen/fixmorph:issta21
You can also download the source to build the image on your own using the source from Github, and the following command: docker build -t rshariffdeen/fixmorph .
Original Patch (Reference) Mainline Commit: 19454462 |
drivers/usb/class/cdc-acm.c
|
|
Ported Patch (Manual) Stable Commit: 291625aa |
drivers/usb/class/cdc-acm.c
|
|
Generated Patch (FixMorph) |
drivers/usb/class/cdc-acm.c
|
Original Patch (Reference) Mainline Commit: 61894b02 |
drivers/dma-buf/sw_sync.c
|
|
Ported Patch (Manual) Stable Commit: fc839ecb |
drivers/dma-buf/sw_sync.c
|
|
Generated Patch (FixMorph) |
drivers/dma-buf/sw_sync.c
|
Original Patch (Reference) Mainline Commit: 0b1d250a |
drivers/usb/serial/io_ti.c
|
|
Ported Patch (Manual) Stable Commit: 23b94d65 |
drivers/usb/serial/io_ti.c
|
|
Generated Patch (FixMorph) |
drivers/dma-buf/sw_sync.c
|