lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <Z30t5diuUrCNY55Z@ryzen>
Date: Tue, 7 Jan 2025 14:36:37 +0100
From: Niklas Cassel <cassel@...nel.org>
Cc: manivannan.sadhasivam@...aro.org, kw@...ux.com, kishon@...nel.org,
	arnd@...db.de, gregkh@...uxfoundation.org,
	linux-pci@...r.kernel.org, linux-kernel@...r.kernel.org,
	rockswang7@...il.com
Subject: Re: [v8] misc: pci_endpoint_test: Fix overflow of bar_size

On Tue, Jan 07, 2025 at 08:09:48PM +0800, Hans Zhang wrote:
> Hi Niklas,
> 
> The robot has been compiled with CONFIG_PHYS_ADDR_T_64BIT=y, so
> resource_size_t=u64
> 
> 
> include/linux/types.h
> 
> #ifdef CONFIG_PHYS_ADDR_T_64BIT
> typedef u64 phys_addr_t;
> #else
> typedef u32 phys_addr_t;
> #endif
> 
> typedef phys_addr_t resource_size_t;
> 
> 
> Is my understanding wrong? Could you correct me, please? Thank you very
> much.

I see. That is correct.


> 
> config: i386-randconfig-003-20250101 (https://download.01.org/0day-ci/archive/20250101/202501011917.ugP1ywJV-lkp@intel.com/config)
> 
> 
> I compiled it as a KO module for an experiment.
> __umoddi3 and __udivdi3 is similar to __udivmoddi4.
> 
> u64 bar_size;
> 
> iters = bar_size / buf_size;
> remain = bar_size % buf_size;

I think that I am an idiot (I'm the one who wrote this code).

A BAR size is always a power of two.

So I don't see how there can ever be a remainer...

buf_size = min(SZ_1M, bar_size);

If the BAR size is <= 1MB, there will be 1 iteration, no remainder.

If the BAR size is > 1MB, there will be more than one iteration,
but the size will always be evenly divisible by 1MB, so no remainder.

This should probably be two patches:
patch 1/2:
@@ -316,12 +317,6 @@ static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
                                                 write_buf, read_buf, buf_size))
                        return false;
 
-       remain = bar_size % buf_size;
-       if (remain)
-               if (pci_endpoint_test_bar_memcmp(test, barno, buf_size * iters,
-                                                write_buf, read_buf, remain))
-                       return false;
-
        return true;
 }


patch 2/2:
@@ -283,10 +283,11 @@ static int pci_endpoint_test_bar_memcmp(struct pci_endpoint_test *test,
 static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
                                  enum pci_barno barno)
 {
-       int j, bar_size, buf_size, iters, remain;
+       int j, buf_size, iters;
        void *write_buf __free(kfree) = NULL;
        void *read_buf __free(kfree) = NULL;
        struct pci_dev *pdev = test->pdev;
+       resource_size_t bar_size;
 
        if (!test->bar[barno])
                return false;



The error:
drivers/misc/pci_endpoint_test.c:315: undefined reference to `__udivmoddi4'
sounds like the compiler is using a specialized instruction to do both div
and mod in one. By removing the mod in patch 1/2, I expect that patch 2/2
will no longer get this error.


Kind regards,
Niklas

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ