Re: [PATCH v5 3/5] refs: selectively set prefix in the seek functions

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jeff King <peff@xxxxxxxx> writes:

> On Tue, Jul 15, 2025 at 01:28:28PM +0200, Karthik Nayak wrote:
>
>> +static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator,
>> +				   const char *refname, unsigned int flags)
>> [...]
>> +		do {
>> +			int len, idx;
>> +			int cmp = 0;
>> +
>> +			sort_ref_dir(dir);
>> +
>> +			slash = strchr(slash, '/');
>> +			len = slash ? slash - refname : (int)strlen(refname);
>
> I was looking at this code due to a nearby thread and noticed this funny
> cast to int. I guess you added it to silence -Wsign-compare, but Why are
> we not using a size_t in the first place?
>

That's an oversight from my side.

> This kind of conversion can sometimes have security implications because
> a very large "refname" would cause "len" to become negative (i.e., if
> it's between 2GB and 4GB).
>

Indeed, I didn't think of that.

> In this particular case it ends up cast back to a size_t via strncmp:
>
>> +			for (idx = 0; idx < dir->nr; idx++) {
>> +				cmp = strncmp(refname, dir->entries[idx]->name, len);
>> +				if (cmp <= 0)
>> +					break;
>> +			}
>
> so we get the original value back. We'd still get truncation for a
> refname value over 4GB, which would presumably give us a slightly wrong
> answer. But I don't think we'd ever look outside the array.
>
> Such sizes are probably unlikely if we are feeding filesystem paths. But
> we probably should not set a bad example, and just do;
>

Agreed.

> diff --git a/refs/ref-cache.c b/refs/ref-cache.c
> index 1d95b56d40..3949d145e8 100644
> --- a/refs/ref-cache.c
> +++ b/refs/ref-cache.c
> @@ -498,13 +498,14 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator,
>  		 * indexing to each level as needed.
>  		 */
>  		do {
> -			int len, idx;
> +			size_t len;
> +			int idx;
>  			int cmp = 0;
>
>  			sort_ref_dir(dir);
>
>  			slash = strchr(slash, '/');
> -			len = slash ? slash - refname : (int)strlen(refname);
> +			len = slash ? slash - refname : strlen(refname);
>
>  			for (idx = 0; idx < dir->nr; idx++) {
>  				cmp = strncmp(refname, dir->entries[idx]->name, len);
>
> -Peff

Thanks, I think we have to typecast `slash - refname` to size_t, but
this is the right way to do it. Thanks for the review!

Karthik

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]

  Powered by Linux