Re: [PATCH 24/30] merge-recursive: Add computation of collisions due to dir rename & merging

2018-06-14 Thread Junio C Hamano
René Scharfe  writes:

> The value of PATH_MAX is platform-dependent, so it's easy to exceed when
> doing cross-platform development.  It's also not a hard limit on most
> operating systems, not even on Windows.  Further reading:
>
>https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
>
> So using a fixed buffer is not a good idea, and writing to it without
> checking is dangerous.  Here's a fix:
>
> -- >8 --
> Subject: [PATCH] merge-recursive: use xstrdup() instead of fixed buffer
>
> Paths can be longer than PATH_MAX.  Avoid a buffer overrun in
> check_dir_renamed() by using xstrdup() to make a private copy safely.
>
> Signed-off-by: Rene Scharfe 
> ---

Thanks.  Makes sense.

>  merge-recursive.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/merge-recursive.c b/merge-recursive.c
> index ac27abbd4c..db708176c5 100644
> --- a/merge-recursive.c
> +++ b/merge-recursive.c
> @@ -2211,18 +2211,18 @@ static struct hashmap *get_directory_renames(struct 
> diff_queue_struct *pairs,
>  static struct dir_rename_entry *check_dir_renamed(const char *path,
> struct hashmap *dir_renames)
>  {
> - char temp[PATH_MAX];
> + char *temp = xstrdup(path);
>   char *end;
> - struct dir_rename_entry *entry;
> + struct dir_rename_entry *entry = NULL;;
>  
> - strcpy(temp, path);
>   while ((end = strrchr(temp, '/'))) {
>   *end = '\0';
>   entry = dir_rename_find_entry(dir_renames, temp);
>   if (entry)
> - return entry;
> + break;
>   }
> - return NULL;
> + free(temp);
> + return entry;
>  }
>  
>  static void compute_collisions(struct hashmap *collisions,


Re: [PATCH 24/30] merge-recursive: Add computation of collisions due to dir rename & merging

2018-06-11 Thread Elijah Newren
On Sun, Jun 10, 2018 at 3:56 AM, René Scharfe  wrote:
> Am 10.11.2017 um 20:05 schrieb Elijah Newren:
>> +static struct dir_rename_entry *check_dir_renamed(const char *path,
>> +   struct hashmap *dir_renames) 
>> {
>> + char temp[PATH_MAX];
>> + char *end;
>> + struct dir_rename_entry *entry;
>> +
>> + strcpy(temp, path);
>> + while ((end = strrchr(temp, '/'))) {
>> + *end = '\0';
>> + entry = dir_rename_find_entry(dir_renames, temp);
>> + if (entry)
>> + return entry;
>> + }
>> + return NULL;
>> +}
>
> The value of PATH_MAX is platform-dependent, so it's easy to exceed when
> doing cross-platform development.  It's also not a hard limit on most
> operating systems, not even on Windows.  Further reading:
>
>https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
>
> So using a fixed buffer is not a good idea, and writing to it without
> checking is dangerous.  Here's a fix:

Thanks for the pointers, and for providing a fix.

> -- >8 --
> Subject: [PATCH] merge-recursive: use xstrdup() instead of fixed buffer
>
> Paths can be longer than PATH_MAX.  Avoid a buffer overrun in
> check_dir_renamed() by using xstrdup() to make a private copy safely.
>
> Signed-off-by: Rene Scharfe 
> ---
>  merge-recursive.c | 10 +-
>  1 file changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/merge-recursive.c b/merge-recursive.c
> index ac27abbd4c..db708176c5 100644
> --- a/merge-recursive.c
> +++ b/merge-recursive.c
> @@ -2211,18 +2211,18 @@ static struct hashmap *get_directory_renames(struct 
> diff_queue_struct *pairs,
>  static struct dir_rename_entry *check_dir_renamed(const char *path,
>   struct hashmap *dir_renames)
>  {
> -   char temp[PATH_MAX];
> +   char *temp = xstrdup(path);
> char *end;
> -   struct dir_rename_entry *entry;
> +   struct dir_rename_entry *entry = NULL;;
>
> -   strcpy(temp, path);
> while ((end = strrchr(temp, '/'))) {
> *end = '\0';
> entry = dir_rename_find_entry(dir_renames, temp);
> if (entry)
> -   return entry;
> +   break;
> }
> -   return NULL;
> +   free(temp);
> +   return entry;
>  }
>
>  static void compute_collisions(struct hashmap *collisions,
> --
> 2.17.1

Reviewed-by: Elijah Newren 


Re: [PATCH 24/30] merge-recursive: Add computation of collisions due to dir rename & merging

2018-06-10 Thread Jeff King
On Sun, Jun 10, 2018 at 12:56:31PM +0200, René Scharfe wrote:

> The value of PATH_MAX is platform-dependent, so it's easy to exceed when
> doing cross-platform development.  It's also not a hard limit on most
> operating systems, not even on Windows.  Further reading:
> 
>https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
> 
> So using a fixed buffer is not a good idea, and writing to it without
> checking is dangerous.  Here's a fix:

Even on platforms where it _is_ a hard-limit, we are quite often dealing
with paths that come from tree objects (so even if the OS would
eventually complain about our path, it is small consolation when we
smash the stack before we get there).

Your patch looks good to me, and we definitely should address this
before v2.18-final.

> - char temp[PATH_MAX];
> + char *temp = xstrdup(path);
>   char *end;
> - struct dir_rename_entry *entry;
> + struct dir_rename_entry *entry = NULL;;
>  
> - strcpy(temp, path);

I'm sad that this strcpy() wasn't caught in review. IMHO we should avoid
that function altogether, even when we _think_ it can't trigger an
overflow. That's easier to reason about (and makes auditing easier).

It looks like another one has crept in recently, too.

-- >8 --
Subject: [PATCH] blame: prefer xsnprintf to strcpy for colors

Our color buffers are all COLOR_MAXLEN, which fits the
largest possible color. So we can never overflow the buffer
by copying an existing color. However, using strcpy() makes
it harder to audit the code-base for calls that _are_
problems. We should use something like xsnprintf(), which
shows the reader that we expect this never to fail (and
provides a run-time assertion if it does, just in case).

Signed-off-by: Jeff King 
---
Another option would just be color_parse(repeated_meta_color, "cyan").
The run-time cost is slightly higher, but it probably doesn't matter
here, and perhaps it's more readable.

This one is less critical for v2.18.

 builtin/blame.c | 4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/builtin/blame.c b/builtin/blame.c
index 4202584f97..45770c5a8c 100644
--- a/builtin/blame.c
+++ b/builtin/blame.c
@@ -1068,7 +1068,9 @@ int cmd_blame(int argc, const char **argv, const char 
*prefix)
find_alignment(&sb, &output_option);
if (!*repeated_meta_color &&
(output_option & OUTPUT_COLOR_LINE))
-   strcpy(repeated_meta_color, GIT_COLOR_CYAN);
+   xsnprintf(repeated_meta_color,
+ sizeof(repeated_meta_color),
+ "%s", GIT_COLOR_CYAN);
}
if (output_option & OUTPUT_ANNOTATE_COMPAT)
output_option &= ~(OUTPUT_COLOR_LINE | 
OUTPUT_SHOW_AGE_WITH_COLOR);
-- 
2.18.0.rc1.446.g4486251e51



Re: [PATCH 24/30] merge-recursive: Add computation of collisions due to dir rename & merging

2018-06-10 Thread René Scharfe
Am 10.06.2018 um 12:56 schrieb René Scharfe:
> Am 10.11.2017 um 20:05 schrieb Elijah Newren:
>> +static struct dir_rename_entry *check_dir_renamed(const char *path,
>> +  struct hashmap *dir_renames) {
>> +char temp[PATH_MAX];
>> +char *end;
>> +struct dir_rename_entry *entry;
>> +
>> +strcpy(temp, path);
>> +while ((end = strrchr(temp, '/'))) {
>> +*end = '\0';
>> +entry = dir_rename_find_entry(dir_renames, temp);
>> +if (entry)
>> +return entry;
>> +}
>> +return NULL;
>> +}
> 
> The value of PATH_MAX is platform-dependent, so it's easy to exceed when
> doing cross-platform development.  It's also not a hard limit on most
> operating systems, not even on Windows.  Further reading:
> 
> https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html
> 
> So using a fixed buffer is not a good idea, and writing to it without
> checking is dangerous.  Here's a fix:

Argh, I meant to reply to v10 of that patch, i.e. this:

   https://public-inbox.org/git/20180419175823.7946-21-new...@gmail.com/

The cited code wasn't changed and is in current master, though, so both
that part and my patch are still relevant.

René


Re: [PATCH 24/30] merge-recursive: Add computation of collisions due to dir rename & merging

2018-06-10 Thread René Scharfe
Am 10.11.2017 um 20:05 schrieb Elijah Newren:
> +static struct dir_rename_entry *check_dir_renamed(const char *path,
> +   struct hashmap *dir_renames) {
> + char temp[PATH_MAX];
> + char *end;
> + struct dir_rename_entry *entry;
> +
> + strcpy(temp, path);
> + while ((end = strrchr(temp, '/'))) {
> + *end = '\0';
> + entry = dir_rename_find_entry(dir_renames, temp);
> + if (entry)
> + return entry;
> + }
> + return NULL;
> +}

The value of PATH_MAX is platform-dependent, so it's easy to exceed when
doing cross-platform development.  It's also not a hard limit on most
operating systems, not even on Windows.  Further reading:

   https://insanecoding.blogspot.com/2007/11/pathmax-simply-isnt.html

So using a fixed buffer is not a good idea, and writing to it without
checking is dangerous.  Here's a fix:

-- >8 --
Subject: [PATCH] merge-recursive: use xstrdup() instead of fixed buffer

Paths can be longer than PATH_MAX.  Avoid a buffer overrun in
check_dir_renamed() by using xstrdup() to make a private copy safely.

Signed-off-by: Rene Scharfe 
---
 merge-recursive.c | 10 +-
 1 file changed, 5 insertions(+), 5 deletions(-)

diff --git a/merge-recursive.c b/merge-recursive.c
index ac27abbd4c..db708176c5 100644
--- a/merge-recursive.c
+++ b/merge-recursive.c
@@ -2211,18 +2211,18 @@ static struct hashmap *get_directory_renames(struct 
diff_queue_struct *pairs,
 static struct dir_rename_entry *check_dir_renamed(const char *path,
  struct hashmap *dir_renames)
 {
-   char temp[PATH_MAX];
+   char *temp = xstrdup(path);
char *end;
-   struct dir_rename_entry *entry;
+   struct dir_rename_entry *entry = NULL;;
 
-   strcpy(temp, path);
while ((end = strrchr(temp, '/'))) {
*end = '\0';
entry = dir_rename_find_entry(dir_renames, temp);
if (entry)
-   return entry;
+   break;
}
-   return NULL;
+   free(temp);
+   return entry;
 }
 
 static void compute_collisions(struct hashmap *collisions,
-- 
2.17.1