Hi, there is a hard to reach but possible buffer overflow when using patch with a very large (modified) input file. I doubt you will ever see this with a 64 bit system, but it's possible with 32 bit:
$ echo hello > file1 $ echo world > file2 $ diff -Nau file1 file2 > file.diff Nothing fancy so far. Adjust file1 so it contains at least one line that is 2 GB in size. Larger is fine too, but stay below 4 GB. $ tr '\0' c < /dev/zero | dd bs=1K count=2097152 of=file1 Now try to patch it. $ patch -Np0 -i file.diff Segmentation fault The issue is in patch's "plan b" strategy (If your system would still want to use "plan a", force patch to use "plan b" through debug flag). Plan b writes lines into a temporary file, with equally long lines, so it can use a buffer mechanism to access them in a kind of randomly fassion. In order to do that, it retrieves the longest line. In this example, it will encounter the 2 GB line and stores that as the longest one. Afterwards it will adjust the tibufsize variable to be large enough: for (tibufsize = TIBUFSIZE_MINIMUM; tibufsize < maxlen; tibufsize <<= 1) /* do nothing */ ; Due to maxlen's size (2 GB), tibufsize will be SIZE_T_MAX, i.e. 4 GB. A few lines later it allocates space for the tibuf buffers: tibuf[0] = xmalloc (2 * tibufsize); tibuf[1] = tibuf[0] + tibufsize; This will allocate 0 bytes because tibufsize overflowed. The next time patch writes into the buffer, a segmentation fault will occur... Depends on your system how long it takes until that happens. ;) The fix is simple: Bail out on lines that are too long. Patch already does that for files that have too many lines. Tobias --- patch-2.7.1.4-2f40-dirty/src/inp.c~ 2012-09-19 03:07:31.000000000 +0200 +++ patch-2.7.1.4-2f40-dirty/src/inp.c 2014-10-26 13:13:13.240167836 +0100 @@ -45,6 +45,7 @@ static bool plan_a (char const *); /* yield false if memory runs out */ static void plan_b (char const *); static void report_revision (bool); +static void too_long_lines (char const *) __attribute__((noreturn)); static void too_many_lines (char const *) __attribute__((noreturn)); /* New patch--prepare to edit another file. */ @@ -123,6 +124,12 @@ static void +too_long_lines (char const *filename) +{ + fatal ("File %s has too long lines", quotearg (filename)); +} + +static void too_many_lines (char const *filename) { fatal ("File %s has too many lines", quotearg (filename)); @@ -367,7 +374,8 @@ while ((c = getc (ifp)) != EOF) { - len++; + if (++len > ((size_t)-1) / 2) + too_long_lines (filename); if (c == '\n') {