Re: [PATCH v6 10/18] x86/power/64: Remove VLA usage

2018-07-25 Thread Kees Cook
On Wed, Jul 25, 2018 at 4:32 AM, Rafael J. Wysocki  wrote:
> On Tue, Jul 24, 2018 at 6:49 PM, Kees Cook  wrote:
>> In the quest to remove all stack VLA usage from the kernel[1], this
>> removes the discouraged use of AHASH_REQUEST_ON_STACK by switching to
>> shash directly and allocating the descriptor in heap memory (which should
>> be fine: the tfm has already been allocated there too).
>>
>> [1] 
>> https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qpxydaacu1rq...@mail.gmail.com
>>
>> Signed-off-by: Kees Cook 
>> Acked-by: Pavel Machek 
>
> I think I can queue this up if there are no objections from others.
>
> Do you want me to do that?

Sure thing. It looks like the other stand-alone patches like this one
are getting taken into the non-crypto trees, so that's fine.

Thanks!

-Kees

-- 
Kees Cook
Pixel Security


[PATCH] wireless/lib80211: Convert from ahash to shash

2018-07-15 Thread Kees Cook
In preparing to remove all stack VLA usage from the kernel[1], this
removes the discouraged use of AHASH_REQUEST_ON_STACK in favor of
the smaller SHASH_DESC_ON_STACK by converting from ahash-wrapped-shash
to direct shash. The stack allocation will be made a fixed size in a
later patch to the crypto subsystem.

[1] 
https://lkml.kernel.org/r/CA+55aFzCG-zNmZwX4A2FQpadafLfEzK6CC=qpxydaacu1rq...@mail.gmail.com

Signed-off-by: Kees Cook 
---
 net/wireless/lib80211_crypt_tkip.c | 55 --
 1 file changed, 30 insertions(+), 25 deletions(-)

diff --git a/net/wireless/lib80211_crypt_tkip.c 
b/net/wireless/lib80211_crypt_tkip.c
index ba0a1f398ce5..e6bce1f130c9 100644
--- a/net/wireless/lib80211_crypt_tkip.c
+++ b/net/wireless/lib80211_crypt_tkip.c
@@ -65,9 +65,9 @@ struct lib80211_tkip_data {
int key_idx;
 
struct crypto_skcipher *rx_tfm_arc4;
-   struct crypto_ahash *rx_tfm_michael;
+   struct crypto_shash *rx_tfm_michael;
struct crypto_skcipher *tx_tfm_arc4;
-   struct crypto_ahash *tx_tfm_michael;
+   struct crypto_shash *tx_tfm_michael;
 
/* scratch buffers for virt_to_page() (crypto API) */
u8 rx_hdr[16], tx_hdr[16];
@@ -106,8 +106,7 @@ static void *lib80211_tkip_init(int key_idx)
goto fail;
}
 
-   priv->tx_tfm_michael = crypto_alloc_ahash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
+   priv->tx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
if (IS_ERR(priv->tx_tfm_michael)) {
priv->tx_tfm_michael = NULL;
goto fail;
@@ -120,8 +119,7 @@ static void *lib80211_tkip_init(int key_idx)
goto fail;
}
 
-   priv->rx_tfm_michael = crypto_alloc_ahash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
+   priv->rx_tfm_michael = crypto_alloc_shash("michael_mic", 0, 0);
if (IS_ERR(priv->rx_tfm_michael)) {
priv->rx_tfm_michael = NULL;
goto fail;
@@ -131,9 +129,9 @@ static void *lib80211_tkip_init(int key_idx)
 
   fail:
if (priv) {
-   crypto_free_ahash(priv->tx_tfm_michael);
+   crypto_free_shash(priv->tx_tfm_michael);
crypto_free_skcipher(priv->tx_tfm_arc4);
-   crypto_free_ahash(priv->rx_tfm_michael);
+   crypto_free_shash(priv->rx_tfm_michael);
crypto_free_skcipher(priv->rx_tfm_arc4);
kfree(priv);
}
@@ -145,9 +143,9 @@ static void lib80211_tkip_deinit(void *priv)
 {
struct lib80211_tkip_data *_priv = priv;
if (_priv) {
-   crypto_free_ahash(_priv->tx_tfm_michael);
+   crypto_free_shash(_priv->tx_tfm_michael);
crypto_free_skcipher(_priv->tx_tfm_arc4);
-   crypto_free_ahash(_priv->rx_tfm_michael);
+   crypto_free_shash(_priv->rx_tfm_michael);
crypto_free_skcipher(_priv->rx_tfm_arc4);
}
kfree(priv);
@@ -510,29 +508,36 @@ static int lib80211_tkip_decrypt(struct sk_buff *skb, int 
hdr_len, void *priv)
return keyidx;
 }
 
-static int michael_mic(struct crypto_ahash *tfm_michael, u8 * key, u8 * hdr,
-  u8 * data, size_t data_len, u8 * mic)
+static int michael_mic(struct crypto_shash *tfm_michael, u8 *key, u8 *hdr,
+  u8 *data, size_t data_len, u8 *mic)
 {
-   AHASH_REQUEST_ON_STACK(req, tfm_michael);
-   struct scatterlist sg[2];
+   SHASH_DESC_ON_STACK(desc, tfm_michael);
int err;
 
if (tfm_michael == NULL) {
pr_warn("%s(): tfm_michael == NULL\n", __func__);
return -1;
}
-   sg_init_table(sg, 2);
-   sg_set_buf([0], hdr, 16);
-   sg_set_buf([1], data, data_len);
 
-   if (crypto_ahash_setkey(tfm_michael, key, 8))
+   desc->tfm = tfm_michael;
+   desc->flags = 0;
+
+   if (crypto_shash_setkey(tfm_michael, key, 8))
return -1;
 
-   ahash_request_set_tfm(req, tfm_michael);
-   ahash_request_set_callback(req, 0, NULL, NULL);
-   ahash_request_set_crypt(req, sg, mic, data_len + 16);
-   err = crypto_ahash_digest(req);
-   ahash_request_zero(req);
+   err = crypto_shash_init(desc);
+   if (err)
+   goto out;
+   err = crypto_shash_update(desc, hdr, 16);
+   if (err)
+   goto out;
+   err = crypto_shash_update(desc, data, data_len);
+   if (err)
+   goto out;
+   err = crypto_shash_final(desc, mic);
+
+out:
+   shash_desc_zero(desc);
return err;
 }
 
@@ -654,9 +659,9 @@ static int lib80211_tkip_set_key(void *key, int len, u8 * 
seq, void *priv)
 {
struct lib80211_tkip_data *tkey = priv;
int keyidx;
-   stru

Re: [PATCH v6 05/13] firmware_loader: enhance Kconfig documentation over FW_LOADER

2018-05-09 Thread Kees Cook
On Wed, May 9, 2018 at 1:55 PM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> On Tue, May 08, 2018 at 03:42:33PM -0700, Kees Cook wrote:
>> On Tue, May 8, 2018 at 11:12 AM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
>> > + This used to be the default firmware loading facility, and udev 
>> > used
>> > + to listen for uvents to load firmware for the kernel. The 
>> > firmware
>> > + loading facility functionality in udev has been removed, as such 
>> > it
>> > + can no longer be relied upon as a fallback mechanism. Linux no 
>> > longer
>> > + relies on or uses a fallback mechanism in userspace. If you need 
>> > to
>> > + rely on one refer to the permissively licensed firmwared:
>>
>> Typo: firmware
>
> Thanks fixed all typos except this one, this one is meant to be firmwared as
> that is the name of the project, the url is below.
>
>>
>> > +
>> > + https://github.com/teg/firmwared

Oh! Yes, hah. :) Thanks!

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v6 00/13] firmware_loader changes for v4.18

2018-05-08 Thread Kees Cook
On Tue, May 8, 2018 at 11:12 AM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> Greg,
>
> Here is what I have queued up for the firmware_loader for v4.18. It
> includes a slew of cleanup work, and the new firmware_request_nowarn()
> which is quiet but enables the sysfs fallback mechanism. I've gone ahead
> and also queued up a few minor fixes for the firmware loader documentation
> which have come up recently. These changes are available on my git tree
> both based on linux-next [0] and Linus' latest tree [1]. Folks working
> on new developments for the firmware loader can use my linux-next
> branch 20180508-firmware_loader_for-v4.18-try2 for now.
>
> 0-day sends its blessings.
>
> The patches from Mimi's series still require a bit more discussion and
> review. The discussion over the EFI firmware fallback mechanism is still
> ongoing.
>
> As for the rename that you wanted, perhaps we can do this late in the
> merge window considering we're at rc4 now. I can prep something up for
> that later.
>
> Question, and specially rants are warmly welcomed.

I sent some typo catches, but with those fixed, please consider the
whole series:

Reviewed-by: Kees Cook <keesc...@chromium.org>

Thanks!

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v6 05/13] firmware_loader: enhance Kconfig documentation over FW_LOADER

2018-05-08 Thread Kees Cook
this feature enabled is to support a
> + driver which explicitly relies on this fallback mechanism. Only two
> + drivers need this today:
> +
> +   o CONFIG_LEDS_LP55XX_COMMON
> +   o CONFIG_DELL_RBU
> +
> + Outside of supporting the above drivers, another reason for needing
> + this may be that your firmware resides outside of the paths the 
> kernel
> + looks for and cannot possibily be specified using the firmware_class
> + path module parameter or kernel firmware_class path boot parameter
> + if firmware_class is built-in.
> +
> + A modern use case may be to temporarily mount a custom partition
> + during provisioning which is only accessible to userspace, and then
> + to use it to look for and fetch the required firmware. Such type of
> + driver functionality may not even ever be desirable upstream by
> + vendors, and as such is only required to be supported as an 
> interface
> + for provisioning. Since udev's firmware loading facility has been
> + removed you can use firmwared or a fork of it to customize how you
> + want to load firmware based on uevents issued.
> +
> + Enabling this option will increase your kernel image size by about
> + 13436 bytes.
> +
> + If you are unsure about this, say N here, unless you are Linux
> + distribution and need to support the above two drivers, or you are
> + certain you need to support some really custom firmware loading
> + facility in userspace.
>
>  config FW_LOADER_USER_HELPER_FALLBACK
> -   bool "Fallback user-helper invocation for firmware loading"
> -   depends on FW_LOADER
> -   select FW_LOADER_USER_HELPER
> +   bool "Force the firmware sysfs fallback mechanism when possible"
> +   depends on FW_LOADER_USER_HELPER
> help
> - This option enables / disables the invocation of user-helper
> - (e.g. udev) for loading firmware files as a fallback after the
> - direct file loading in kernel fails.  The user-mode helper is
> - no longer required unless you have a special firmware file that
> - resides in a non-standard path. Moreover, the udev support has
> - been deprecated upstream.
> + Enabling this option forces a sysfs userspace fallback mechanism
> + to be used for all firmware requests which explicitly do not 
> disable a
> + a fallback mechanism. Firmware calls which do prohibit a fallback
> + mechanism is request_firmware_direct(). This option is kept for
> +  backward compatibility purposes given this precise mechanism can 
> also
> + be enabled by setting the proc sysctl value to true:
> +
> +  /proc/sys/kernel/firmware_config/force_sysfs_fallback
>
>   If you are unsure about this, say N here.
>
> +endif # FW_LOADER
> +endmenu
> +
>  config WANT_DEV_COREDUMP
> bool
> help
> --
> 2.17.0
>


-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v3] ath9k: dfs: Remove VLA usage

2018-04-25 Thread Kees Cook
On Wed, Apr 25, 2018 at 12:26 AM, Kalle Valo <kv...@codeaurora.org> wrote:
> I have already applied an almost identical patch:
>
> ath9k: dfs: remove accidental use of stack VLA
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=ath-next=9c27489a34548913baaaf3b2776e05d4a9389e3e

Ah! Cool, no worries. I didn't see that in linux-next yet. :)

Thanks!

-Kees

-- 
Kees Cook
Pixel Security


[PATCH v3] ath9k: dfs: Remove VLA usage

2018-04-24 Thread Kees Cook
In the quest to remove all stack VLA usage from the kernel[1], this
redefines FFT_NUM_SAMPLES as a #define instead of const int, which still
triggers gcc's VLA checking pass.

[1] https://lkml.org/lkml/2018/3/7/621

Co-developed-by: Andreas Christoforou <andreaschrist...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
v3: replace FFT_NUM_SAMPLES as a #define (Joe)
---
 drivers/net/wireless/ath/ath9k/dfs.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ath/ath9k/dfs.c 
b/drivers/net/wireless/ath/ath9k/dfs.c
index 6fee9a464cce..e6e56a925121 100644
--- a/drivers/net/wireless/ath/ath9k/dfs.c
+++ b/drivers/net/wireless/ath/ath9k/dfs.c
@@ -40,8 +40,8 @@ static const int BIN_DELTA_MIN= 1;
 static const int BIN_DELTA_MAX = 10;
 
 /* we need at least 3 deltas / 4 samples for a reliable chirp detection */
-#define NUM_DIFFS 3
-static const int FFT_NUM_SAMPLES   = (NUM_DIFFS + 1);
+#define NUM_DIFFS  3
+#define FFT_NUM_SAMPLES(NUM_DIFFS + 1)
 
 /* Threshold for difference of delta peaks */
 static const int MAX_DIFF  = 2;
-- 
2.7.4


-- 
Kees Cook
Pixel Security


Re: [RESEND] rsi: Remove stack VLA usage

2018-03-13 Thread Kees Cook
On Tue, Mar 13, 2018 at 7:11 PM, Tobin C. Harding <m...@tobin.cc> wrote:
> On Tue, Mar 13, 2018 at 11:00:47PM +0200, Andy Shevchenko wrote:
>> On Tue, Mar 13, 2018 at 10:17 PM, tcharding <m...@tobin.cc> wrote:
>> > On Mon, Mar 12, 2018 at 09:46:06AM +, Kalle Valo wrote:
>> >> tcharding <m...@tobin.cc> wrote:
>>
>> I'm pretty much sure it depends on the original email headers, like
>> above ^^^ — no name.
>> Perhaps git config on your side should be done.
>
> Thanks for the suggestion Andy but the 'tcharding' as the name was
> munged by either Kalle or patchwork.  I'm guessing patchwork.

Something you're sending from is using "tcharding" (see the email Andy
quotes). I see the headers as:

Date: Wed, 14 Mar 2018 07:17:57 +1100
From: tcharding <m...@tobin.cc>
...
Message-ID: <20180313201757.GK8631@eros>
X-Mailer: Mutt 1.5.24 (2015-08-30)
User-Agent: Mutt/1.5.24 (2015-08-30)

Your most recently email shows "Tobin C. Harding" though, and also
sent with Mutt...

Do you have multiple Mutt configurations? Is something lacking a
"From" header insertion and your MTA is filling it in for you from
your username?

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH] drivers: net: wireless: ath: ath9: dfs: remove VLA usage

2018-03-10 Thread Kees Cook
On Sat, Mar 10, 2018 at 3:06 PM, Arend van Spriel
<arend.vanspr...@broadcom.com> wrote:
> On 3/9/2018 1:30 PM, Andreas Christoforou wrote:
>>
>> The kernel would like to have all stack VLA usage removed.
>
>
> I think there was a remark made earlier to give more explanation here. It
> should explain why we want "VLA on stack" removed.
>
>> Signed-off-by: Andreas Christoforou <andreaschrist...@gmail.com>
>> ---
>>   drivers/net/wireless/ath/ath9k/dfs.c | 3 +--
>>   1 file changed, 1 insertion(+), 2 deletions(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/dfs.c
>> b/drivers/net/wireless/ath/ath9k/dfs.c
>> index 6fee9a4..cfb0f84 100644
>> --- a/drivers/net/wireless/ath/ath9k/dfs.c
>> +++ b/drivers/net/wireless/ath/ath9k/dfs.c
>> @@ -41,7 +41,6 @@ static const int BIN_DELTA_MAX= 10;
>>
>>   /* we need at least 3 deltas / 4 samples for a reliable chirp detection
>> */
>>   #define NUM_DIFFS 3
>> -static const int FFT_NUM_SAMPLES   = (NUM_DIFFS + 1);
>>
>>   /* Threshold for difference of delta peaks */
>>   static const int MAX_DIFF = 2;
>> @@ -101,7 +100,7 @@ static bool ath9k_check_chirping(struct ath_softc *sc,
>> u8 *data,
>>  int datalen, bool is_ctl, bool is_ext)
>>   {
>> int i;
>> -   int max_bin[FFT_NUM_SAMPLES];
>> +   int max_bin[NUM_DIFFS + 1];
>
>
> Just wondering. Is this actually a VLA. FFT_NUM_SAMPLES was static const so
> not really going to show a lot of variation. This array will always have the
> same size on the stack.

The problem is that it's not a "constant expression", so the compiler
frontend still yells about it under -Wvla. I would characterize this
mainly as a fix for "accidental VLA" or "misdetected VLA" or something
like that. AIUI, there really isn't a functional change here.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH v3 00/20] firmware: development for v4.17

2018-03-10 Thread Kees Cook
On Sat, Mar 10, 2018 at 6:14 AM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> Greg,
>
> Here's a respin of what I have queued up for v4.17 for the firmware API. It
> combines the cleanup I've been working on and the addition of the new API call
> request_firmware_cache() for fixing a corner case suspend issue on some type 
> of
> cards with an optimization in place where the firmware is *not* needed on
> reboot.
>
> The cleanup work allows us to test the firmware API with one kernel
> configuration. I've addressed Kees' feedback on this respin and
> combined the code into drivers/base/firmware_class/.
>
> I've made one new test_firmware change in consideration for one firmware
> change, the patch "firmware: ensure the firmware cache is not used on
> incompatible calls" requires us to modify our tests scripts to use
> the APIs sanely as well.
>
> I've put up these changes on my git tree, refer to the branch
> "20180307-firmware-dev-for-v4.17" based on linux-next [0] and
> the same name based on Linus' tree [1].
>
> Questions, feedback, and specially rants are always welcomed.

This all looks good to me! Thanks for respinning. :)

-Kees

>
> [0] 
> https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux-next.git/log/?h=20180307-firmware-dev-for-v4.17
> [1] 
> https://git.kernel.org/pub/scm/linux/kernel/git/mcgrof/linux.git/log/?h=20180307-firmware-dev-for-v4.17
>
> Luis R. Rodriguez (20):
>   test_firmware: add simple firmware firmware test library
>   test_firmware: enable custom fallback testing on limited kernel
> configs
>   test_firmware: replace syfs fallback check with kconfig_has helper
>   firmware: enable to split firmware_class into separate target files
>   firmware: simplify CONFIG_FW_LOADER_USER_HELPER_FALLBACK further
>   firmware: use helpers for setting up a temporary cache timeout
>   firmware: move loading timeout under struct firmware_fallback_config
>   firmware: split firmware fallback functionality into its own file
>   firmware: move firmware loader into its own directory
>   firmware: enable run time change of forcing fallback loader
>   firmware: enable to force disable the fallback mechanism at run time
>   test_firmware: expand on library with shared helpers
>   test_firmware: test three firmware kernel configs using a proc knob
>   rename: _request_firmware_load() fw_load_sysfs_fallback()
>   firmware: fix checking for return values for fw_add_devm_name()
>   firmware: add helper to check to see if fw cache is setup
>   test_firmware: modify custom fallback tests to use unique files
>   firmware: ensure the firmware cache is not used on incompatible calls
>   firmware: add request_firmware_cache() to help with cache on reboot
>   mt7601u: use request_firmware_cache() to address cache on reboot
>
>  .../driver-api/firmware/fallback-mechanisms.rst|   2 +-
>  .../driver-api/firmware/request_firmware.rst   |  14 +
>  MAINTAINERS|   2 +-
>  drivers/base/Makefile  |   2 +-
>  drivers/base/firmware_loader/Makefile  |   7 +
>  drivers/base/firmware_loader/fallback.c| 674 +
>  drivers/base/firmware_loader/fallback.h|  67 ++
>  drivers/base/firmware_loader/fallback_table.c  |  55 ++
>  drivers/base/firmware_loader/firmware.h| 115 +++
>  .../{firmware_class.c => firmware_loader/main.c}   | 833 
> ++---
>  drivers/net/wireless/mediatek/mt7601u/mcu.c|   2 +-
>  include/linux/firmware.h   |   3 +
>  kernel/sysctl.c|  11 +
>  tools/testing/selftests/firmware/Makefile  |   2 +-
>  tools/testing/selftests/firmware/config|   4 +
>  tools/testing/selftests/firmware/fw_fallback.sh|  65 +-
>  tools/testing/selftests/firmware/fw_filesystem.sh  |  72 +-
>  tools/testing/selftests/firmware/fw_lib.sh | 194 +
>  tools/testing/selftests/firmware/fw_run_tests.sh   |  70 ++
>  19 files changed, 1332 insertions(+), 862 deletions(-)
>  create mode 100644 drivers/base/firmware_loader/Makefile
>  create mode 100644 drivers/base/firmware_loader/fallback.c
>  create mode 100644 drivers/base/firmware_loader/fallback.h
>  create mode 100644 drivers/base/firmware_loader/fallback_table.c
>  create mode 100644 drivers/base/firmware_loader/firmware.h
>  rename drivers/base/{firmware_class.c => firmware_loader/main.c} (60%)
>  create mode 100755 tools/testing/selftests/firmware/fw_lib.sh
>  create mode 100755 tools/testing/selftests/firmware/fw_run_tests.sh
>
> --
> 2.16.2
>



-- 
Kees Cook
Pixel Security


Re: [RFT 3/7] firmware: make fw_add_devm_name() return 0 if cache present

2018-02-27 Thread Kees Cook
On Tue, Feb 27, 2018 at 3:20 PM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> Currently fw_add_devm_name() returns 1 if the firmware cache
> was already set. This makes it complicated for us to check for
> correctness. It is actually non-fatal if the firmware cache
> is already setup, so just return 0, and simplify the checkers.
>
> Signed-off-by: Luis R. Rodriguez <mcg...@kernel.org>

That'll teach me to read all the patches first. ;)

Honestly, I'd just fold this into the prior patch: there's only one
caller and it's exactly about checking the return value.

-Kees

> ---
>  drivers/base/firmware_loader.c | 4 ++--
>  1 file changed, 2 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/firmware_loader.c b/drivers/base/firmware_loader.c
> index 48932581c70c..a385622bf3e1 100644
> --- a/drivers/base/firmware_loader.c
> +++ b/drivers/base/firmware_loader.c
> @@ -403,7 +403,7 @@ static int fw_add_devm_name(struct device *dev, const 
> char *name)
>
> fwn = fw_find_devm_name(dev, name);
> if (fwn)
> -   return 1;
> +   return 0;
>
> fwn = devres_alloc(fw_name_devm_release, sizeof(struct fw_name_devm),
>GFP_KERNEL);
> @@ -450,7 +450,7 @@ int assign_fw(struct firmware *fw, struct device *device,
> if (device && (opt_flags & FW_OPT_UEVENT) &&
> !(opt_flags & FW_OPT_NOCACHE)) {
> ret = fw_add_devm_name(device, fw_priv->fw_name);
> -   if (ret && ret != 1) {
> +   if (ret) {
> mutex_unlock(_lock);
> return ret;
> }
> --
> 2.16.2
>



-- 
Kees Cook
Pixel Security


Re: [RFT 2/7] firmware: fix checking for return values for fw_add_devm_name()

2018-02-27 Thread Kees Cook
On Tue, Feb 27, 2018 at 3:20 PM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> fw_add_devm_name() adds device's name onto the devres for the
> device so that prior to suspend we cache the firmware onto memory,
> so that on resume the firmware is reliably available. We never
> were checking for success for this call though, meaning in some
> really rare cases we my have never setup the firmware cache for
> a device, which could in turn make resume fail.
>
> This is all theoretical, no known issues have been reported.
> This small issue has been present way since the addition of the
> devres firmware cache names on v3.7.
>
> Fixes: f531f05ae9437 ("firmware loader: store firmware name into devres list")
> Signed-off-by: Luis R. Rodriguez <mcg...@kernel.org>
> ---
>  drivers/base/firmware_loader.c | 10 --
>  1 file changed, 8 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/base/firmware_loader.c b/drivers/base/firmware_loader.c
> index 21dd31ef08ae..48932581c70c 100644
> --- a/drivers/base/firmware_loader.c
> +++ b/drivers/base/firmware_loader.c
> @@ -431,6 +431,7 @@ int assign_fw(struct firmware *fw, struct device *device,
>   unsigned int opt_flags)
>  {
> struct fw_priv *fw_priv = fw->priv;
> +   int ret;
>
> mutex_lock(_lock);
> if (!fw_priv->size || fw_state_is_aborted(fw_priv)) {
> @@ -447,8 +448,13 @@ int assign_fw(struct firmware *fw, struct device *device,
>  */
> /* don't cache firmware handled without uevent */
> if (device && (opt_flags & FW_OPT_UEVENT) &&
> -   !(opt_flags & FW_OPT_NOCACHE))
> -   fw_add_devm_name(device, fw_priv->fw_name);
> +   !(opt_flags & FW_OPT_NOCACHE)) {
> +   ret = fw_add_devm_name(device, fw_priv->fw_name);
> +   if (ret && ret != 1) {

Why not if (ret < 0) ?

-Kees

> +   mutex_unlock(_lock);
> +   return ret;
> +   }
> +   }
>
> /*
>  * After caching firmware image is started, let it piggyback
> --
> 2.16.2
>



-- 
Kees Cook
Pixel Security


Re: [RFT 1/7] rename: _request_firmware_load() fw_load_sysfs_fallback()

2018-02-27 Thread Kees Cook
On Tue, Feb 27, 2018 at 3:20 PM, Luis R. Rodriguez <mcg...@kernel.org> wrote:
> This reflects much clearer what is being done.
>
> Signed-off-by: Luis R. Rodriguez <mcg...@kernel.org>
> ---
>  Documentation/driver-api/firmware/fallback-mechanisms.rst | 2 +-
>  drivers/base/firmware_fallback.c  | 4 ++--
>  2 files changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/Documentation/driver-api/firmware/fallback-mechanisms.rst 
> b/Documentation/driver-api/firmware/fallback-mechanisms.rst
> index 4055ac76b288..f353783ae0be 100644
> --- a/Documentation/driver-api/firmware/fallback-mechanisms.rst
> +++ b/Documentation/driver-api/firmware/fallback-mechanisms.rst
> @@ -112,7 +112,7 @@ Since a device is created for the sysfs interface to help 
> load firmware as a
>  fallback mechanism userspace can be informed of the addition of the device by
>  relying on kobject uevents. The addition of the device into the device
>  hierarchy means the fallback mechanism for firmware loading has been 
> initiated.
> -For details of implementation refer to _request_firmware_load(), in 
> particular
> +For details of implementation refer to fw_load_sysfs_fallback(), in 
> particular
>  on the use of dev_set_uevent_suppress() and kobject_uevent().
>
>  The kernel's kobject uevent mechanism is implemented in lib/kobject_uevent.c,
> diff --git a/drivers/base/firmware_fallback.c 
> b/drivers/base/firmware_fallback.c
> index 13fa5ff2b46c..ce7ccfe82c69 100644
> --- a/drivers/base/firmware_fallback.c
> +++ b/drivers/base/firmware_fallback.c
> @@ -536,7 +536,7 @@ fw_create_instance(struct firmware *firmware, const char 
> *fw_name,
>  }
>
>  /* load a firmware via user helper */

As long as this is being renamed, maybe add full kern-doc for this function?

-Kees

> -static int _request_firmware_load(struct fw_sysfs *fw_sysfs,
> +static int fw_load_sysfs_fallback(struct fw_sysfs *fw_sysfs,
>   unsigned int opt_flags, long timeout)
>  {
> int retval = 0;
> @@ -621,7 +621,7 @@ static int fw_load_from_user_helper(struct firmware 
> *firmware,
> }
>
> fw_sysfs->fw_priv = firmware->priv;
> -   ret = _request_firmware_load(fw_sysfs, opt_flags, timeout);
> +   ret = fw_load_sysfs_fallback(fw_sysfs, opt_flags, timeout);
>
> if (!ret)
> ret = assign_fw(firmware, device, opt_flags);
> --
> 2.16.2
>



-- 
Kees Cook
Pixel Security


[PATCH] NFC: llcp: Limit size of SDP URI

2018-02-09 Thread Kees Cook
The tlv_len is u8, so we need to limit the size of the SDP URI. Enforce
this both in the NLA policy and in the code that performs the allocation
and copy.

Fixes: d9b8d8e19b073 ("NFC: llcp: Service Name Lookup netlink interface")
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
Alternatively, tlv_len switch to size_t, but we'd still have to do the "-4"
calculation.
---
 net/nfc/llcp_commands.c | 4 
 net/nfc/netlink.c   | 3 ++-
 2 files changed, 6 insertions(+), 1 deletion(-)

diff --git a/net/nfc/llcp_commands.c b/net/nfc/llcp_commands.c
index 367d8c027101..2ceefa183cee 100644
--- a/net/nfc/llcp_commands.c
+++ b/net/nfc/llcp_commands.c
@@ -149,6 +149,10 @@ struct nfc_llcp_sdp_tlv *nfc_llcp_build_sdreq_tlv(u8 tid, 
char *uri,
 
pr_debug("uri: %s, len: %zu\n", uri, uri_len);
 
+   /* sdreq->tlv_len is u8, takes uri_len, + 3 for header, + 1 for NULL */
+   if (WARN_ON_ONCE(uri_len > U8_MAX - 4))
+   return NULL;
+
sdreq = kzalloc(sizeof(struct nfc_llcp_sdp_tlv), GFP_KERNEL);
if (sdreq == NULL)
return NULL;
diff --git a/net/nfc/netlink.c b/net/nfc/netlink.c
index c0b83dc9d993..f018eafc2a0d 100644
--- a/net/nfc/netlink.c
+++ b/net/nfc/netlink.c
@@ -61,7 +61,8 @@ static const struct nla_policy nfc_genl_policy[NFC_ATTR_MAX + 
1] = {
 };
 
 static const struct nla_policy nfc_sdp_genl_policy[NFC_SDP_ATTR_MAX + 1] = {
-   [NFC_SDP_ATTR_URI] = { .type = NLA_STRING },
+   [NFC_SDP_ATTR_URI] = { .type = NLA_STRING,
+  .len = U8_MAX - 4 },
[NFC_SDP_ATTR_SAP] = { .type = NLA_U8 },
 };
 
-- 
2.7.4


-- 
Kees Cook
Pixel Security


Re: [PATCH 13/17] iwlwifi: mvm: Convert timers to use timer_setup()

2017-11-06 Thread Kees Cook
On Mon, Nov 6, 2017 at 11:48 AM, Luca Coelho <l...@coelho.fi> wrote:
> On Mon, 2017-11-06 at 11:45 -0800, Kees Cook wrote:
>> On Sun, Oct 29, 2017 at 5:28 AM, Luca Coelho <l...@coelho.fi> wrote:
>> > From: Kees Cook <keesc...@chromium.org>
>> >
>> > In preparation for unconditionally passing the struct timer_list
>> > pointer to
>> > all timer callbacks, switch to using the new timer_setup() and
>> > from_timer()
>> > to pass the timer pointer explicitly.
>> >
>> > The RCU lifetime on baid_data is unclear, so this adds a direct
>> > copy of the
>> > rcu_ptr passed to the original callback. It may be possible to
>> > improve this
>> > to just use baid_data->mvm->baid_map[baid_data->baid] instead.
>> >
>> > Cc: Johannes Berg <johannes.b...@intel.com>
>> > Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
>> > Cc: Luca Coelho <luciano.coe...@intel.com>
>> > Cc: Intel Linux Wireless <linuxw...@intel.com>
>> > Cc: Kalle Valo <kv...@codeaurora.org>
>> > Cc: Sara Sharon <sara.sha...@intel.com>
>> > Cc: linux-wireless@vger.kernel.org
>> > Cc: net...@vger.kernel.org
>> > Signed-off-by: Kees Cook <keesc...@chromium.org>
>> > Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
>> > ---
>> >  drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  3 ++-
>> >  drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |  4 ++--
>> >  drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 18 +
>> > -
>> >  3 files changed, 13 insertions(+), 12 deletions(-)
>>
>> Hi,
>>
>> Thanks for taking this! I had a question on timing: is this expected
>> to land for 4.15? If not, I would like to take this via the timers
>> tree, since it is one of the few remaining conversions.
>
> Hi Kees,
>
> Yes, this should land for 4.15.  Kalle just pulled my pull-request
> (which includes this) to wireless-drivers-next.  He told me he'll send
> a pull-request for 4.15 during this week and hopefully Dave will pull
> from him too.
>
> I'll let you know if something doesn't go as planned.

Awesome, thanks very much!

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH 13/17] iwlwifi: mvm: Convert timers to use timer_setup()

2017-11-06 Thread Kees Cook
On Sun, Oct 29, 2017 at 5:28 AM, Luca Coelho <l...@coelho.fi> wrote:
> From: Kees Cook <keesc...@chromium.org>
>
> In preparation for unconditionally passing the struct timer_list pointer to
> all timer callbacks, switch to using the new timer_setup() and from_timer()
> to pass the timer pointer explicitly.
>
> The RCU lifetime on baid_data is unclear, so this adds a direct copy of the
> rcu_ptr passed to the original callback. It may be possible to improve this
> to just use baid_data->mvm->baid_map[baid_data->baid] instead.
>
> Cc: Johannes Berg <johannes.b...@intel.com>
> Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
> Cc: Luca Coelho <luciano.coe...@intel.com>
> Cc: Intel Linux Wireless <linuxw...@intel.com>
> Cc: Kalle Valo <kv...@codeaurora.org>
> Cc: Sara Sharon <sara.sha...@intel.com>
> Cc: linux-wireless@vger.kernel.org
> Cc: net...@vger.kernel.org
> Signed-off-by: Kees Cook <keesc...@chromium.org>
> Signed-off-by: Luca Coelho <luciano.coe...@intel.com>
> ---
>  drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  3 ++-
>  drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |  4 ++--
>  drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 18 +-
>  3 files changed, 13 insertions(+), 12 deletions(-)

Hi,

Thanks for taking this! I had a question on timing: is this expected
to land for 4.15? If not, I would like to take this via the timers
tree, since it is one of the few remaining conversions.

Thanks!

-Kees

-- 
Kees Cook
Pixel Security


Re: drivers/wireless: ath: Convert timers to use timer_setup()

2017-10-27 Thread Kees Cook
On Fri, Oct 27, 2017 at 11:18 AM, Kalle Valo <kv...@qca.qualcomm.com> wrote:
> Kees Cook <keesc...@chromium.org> wrote:
>
>> In preparation for unconditionally passing the struct timer_list pointer to
>> all timer callbacks, switch to using the new timer_setup() and from_timer()
>> to pass the timer pointer explicitly.
>>
>> Cc: Kalle Valo <kv...@qca.qualcomm.com>
>> Cc: linux-wireless@vger.kernel.org
>> Cc: net...@vger.kernel.org
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>> Signed-off-by: Kalle Valo <kv...@qca.qualcomm.com>
>
> There were some conflicts but luckily 3-way merge was able to automatically
> solve them. But please do check the patch from my pending branch:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/kvalo/ath.git/commit/?h=master-pending=dd08329d31a4c150f8aab8274033901baaf3e923

This looks correct to me, thanks for merging!

-Kees

-- 
Kees Cook
Pixel Security


[PATCH] drivers/wireless: qtnfmac: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Igor Mitsyanko <imitsya...@quantenna.com>
Cc: Avinash Patil <avina...@quantenna.com>
Cc: Sergey Matyukevich <smatyukev...@quantenna.com>
Cc: Kamlesh Rath <kr...@quantenna.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 7 +++
 drivers/net/wireless/quantenna/qtnfmac/core.c | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c 
b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 32bf72c0399f..ac1b9bd5ed90 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -581,9 +581,9 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device 
*dev,
return ret;
 }
 
-static void qtnf_scan_timeout(unsigned long data)
+static void qtnf_scan_timeout(struct timer_list *t)
 {
-   struct qtnf_wmac *mac = (struct qtnf_wmac *)data;
+   struct qtnf_wmac *mac = from_timer(mac, t, scan_timeout);
 
pr_warn("mac%d scan timed out\n", mac->macid);
qtnf_scan_done(mac, true);
@@ -602,8 +602,7 @@ qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request 
*request)
return -EFAULT;
}
 
-   mac->scan_timeout.data = (unsigned long)mac;
-   mac->scan_timeout.function = qtnf_scan_timeout;
+   mac->scan_timeout.function = (TIMER_FUNC_TYPE)qtnf_scan_timeout;
mod_timer(>scan_timeout,
  jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ);
 
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c 
b/drivers/net/wireless/quantenna/qtnfmac/core.c
index 5e60180482d1..aa7f146278a7 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -289,7 +289,7 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct 
qtnf_bus *bus,
mac->iflist[i].vifid = i;
qtnf_sta_list_init(>iflist[i].sta_list);
mutex_init(>mac_lock);
-   init_timer(>scan_timeout);
+   setup_timer(>scan_timeout, NULL, 0);
    }
 
qtnf_mac_init_primary_intf(mac);
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] drivers/wireless: cw1200: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Solomon Peachy <pi...@shaftnet.org>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/st/cw1200/main.c  | 3 +--
 drivers/net/wireless/st/cw1200/queue.c | 6 +++---
 drivers/net/wireless/st/cw1200/sta.c   | 5 ++---
 drivers/net/wireless/st/cw1200/sta.h   | 2 +-
 4 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/main.c 
b/drivers/net/wireless/st/cw1200/main.c
index dc478cedbde0..a186d1df1f29 100644
--- a/drivers/net/wireless/st/cw1200/main.c
+++ b/drivers/net/wireless/st/cw1200/main.c
@@ -373,8 +373,7 @@ static struct ieee80211_hw *cw1200_init_common(const u8 
*macaddr,
INIT_WORK(>update_filtering_work, cw1200_update_filtering_work);
INIT_WORK(>set_beacon_wakeup_period_work,
  cw1200_set_beacon_wakeup_period_work);
-   setup_timer(>mcast_timeout, cw1200_mcast_timeout,
-   (unsigned long)priv);
+   timer_setup(>mcast_timeout, cw1200_mcast_timeout, 0);
 
if (cw1200_queue_stats_init(>tx_queue_stats,
CW1200_LINK_ID_MAX,
diff --git a/drivers/net/wireless/st/cw1200/queue.c 
b/drivers/net/wireless/st/cw1200/queue.c
index 0ba5ef9b3e7b..5153d2cfd991 100644
--- a/drivers/net/wireless/st/cw1200/queue.c
+++ b/drivers/net/wireless/st/cw1200/queue.c
@@ -130,11 +130,11 @@ static void __cw1200_queue_gc(struct cw1200_queue *queue,
}
 }
 
-static void cw1200_queue_gc(unsigned long arg)
+static void cw1200_queue_gc(struct timer_list *t)
 {
LIST_HEAD(list);
struct cw1200_queue *queue =
-   (struct cw1200_queue *)arg;
+   from_timer(queue, t, gc);
 
spin_lock_bh(>lock);
__cw1200_queue_gc(queue, , true);
@@ -179,7 +179,7 @@ int cw1200_queue_init(struct cw1200_queue *queue,
INIT_LIST_HEAD(>pending);
INIT_LIST_HEAD(>free_pool);
spin_lock_init(>lock);
-   setup_timer(>gc, cw1200_queue_gc, (unsigned long)queue);
+   timer_setup(>gc, cw1200_queue_gc, 0);
 
queue->pool = kzalloc(sizeof(struct cw1200_queue_item) * capacity,
GFP_KERNEL);
diff --git a/drivers/net/wireless/st/cw1200/sta.c 
b/drivers/net/wireless/st/cw1200/sta.c
index a52224836a2b..03687a80d6e9 100644
--- a/drivers/net/wireless/st/cw1200/sta.c
+++ b/drivers/net/wireless/st/cw1200/sta.c
@@ -2112,10 +2112,9 @@ void cw1200_multicast_stop_work(struct work_struct *work)
}
 }
 
-void cw1200_mcast_timeout(unsigned long arg)
+void cw1200_mcast_timeout(struct timer_list *t)
 {
-   struct cw1200_common *priv =
-   (struct cw1200_common *)arg;
+   struct cw1200_common *priv = from_timer(priv, t, mcast_timeout);
 
wiphy_warn(priv->hw->wiphy,
   "Multicast delivery timeout.\n");
diff --git a/drivers/net/wireless/st/cw1200/sta.h 
b/drivers/net/wireless/st/cw1200/sta.h
index a0bacaa39b31..719de34dcbfe 100644
--- a/drivers/net/wireless/st/cw1200/sta.h
+++ b/drivers/net/wireless/st/cw1200/sta.h
@@ -117,6 +117,6 @@ void cw1200_set_tim_work(struct work_struct *work);
 void cw1200_set_cts_work(struct work_struct *work);
 void cw1200_multicast_start_work(struct work_struct *work);
 void cw1200_multicast_stop_work(struct work_struct *work);
-void cw1200_mcast_timeout(unsigned long arg);
+void cw1200_mcast_timeout(struct timer_list *t);
 
 #endif
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] drivers/wireless: iwlegacy: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Stanislaw Gruszka <sgrus...@redhat.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/intel/iwlegacy/3945-mac.c |  2 +-
 drivers/net/wireless/intel/iwlegacy/3945-rs.c  | 10 +++---
 drivers/net/wireless/intel/iwlegacy/4965-mac.c |  9 -
 drivers/net/wireless/intel/iwlegacy/common.c   |  4 ++--
 drivers/net/wireless/intel/iwlegacy/common.h   |  2 +-
 5 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c 
b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index 329f3a63dadd..4b53ebf00c7f 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -3429,7 +3429,7 @@ il3945_setup_deferred_work(struct il_priv *il)
 
il3945_hw_setup_deferred_work(il);
 
-   setup_timer(>watchdog, il_bg_watchdog, (unsigned long)il);
+   timer_setup(>watchdog, il_bg_watchdog, 0);
 
tasklet_init(>irq_tasklet,
 (void (*)(unsigned long))il3945_irq_tasklet,
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-rs.c 
b/drivers/net/wireless/intel/iwlegacy/3945-rs.c
index b2f35dfbc01b..e8983c6a2b7b 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-rs.c
@@ -181,9 +181,9 @@ il3945_rate_scale_flush_wins(struct il3945_rs_sta *rs_sta)
 #define IL_AVERAGE_PACKETS 1500
 
 static void
-il3945_bg_rate_scale_flush(unsigned long data)
+il3945_bg_rate_scale_flush(struct timer_list *t)
 {
-   struct il3945_rs_sta *rs_sta = (void *)data;
+   struct il3945_rs_sta *rs_sta = from_timer(rs_sta, t, rate_scale_flush);
struct il_priv *il __maybe_unused = rs_sta->il;
int unflushed = 0;
unsigned long flags;
@@ -360,9 +360,6 @@ il3945_rs_rate_init(struct il_priv *il, struct 
ieee80211_sta *sta, u8 sta_id)
rs_sta->flush_time = RATE_FLUSH;
rs_sta->last_tx_packets = 0;
 
-   rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
-   rs_sta->rate_scale_flush.function = il3945_bg_rate_scale_flush;
-
for (i = 0; i < RATE_COUNT_3945; i++)
il3945_clear_win(_sta->win[i]);
 
@@ -415,8 +412,7 @@ il3945_rs_alloc_sta(void *il_priv, struct ieee80211_sta 
*sta, gfp_t gfp)
rs_sta = >rs_sta;
 
spin_lock_init(_sta->lock);
-   init_timer(_sta->rate_scale_flush);
-
+   timer_setup(_sta->rate_scale_flush, il3945_bg_rate_scale_flush, 0);
D_RATE("leave\n");
 
return rs_sta;
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c 
b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index 65eba2c24292..de63f2518f23 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -4074,9 +4074,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf 
*rxb)
  * used for calibrating the TXPOWER.
  */
 static void
-il4965_bg_stats_periodic(unsigned long data)
+il4965_bg_stats_periodic(struct timer_list *t)
 {
-   struct il_priv *il = (struct il_priv *)data;
+   struct il_priv *il = from_timer(il, t, stats_periodic);
 
if (test_bit(S_EXIT_PENDING, >status))
return;
@@ -6258,10 +6258,9 @@ il4965_setup_deferred_work(struct il_priv *il)
 
INIT_WORK(>txpower_work, il4965_bg_txpower_work);
 
-   setup_timer(>stats_periodic, il4965_bg_stats_periodic,
-   (unsigned long)il);
+   timer_setup(>stats_periodic, il4965_bg_stats_periodic, 0);
 
-   setup_timer(>watchdog, il_bg_watchdog, (unsigned long)il);
+   timer_setup(>watchdog, il_bg_watchdog, 0);
 
tasklet_init(>irq_tasklet,
 (void (*)(unsigned long))il4965_irq_tasklet,
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c 
b/drivers/net/wireless/intel/iwlegacy/common.c
index 8d5acda92a9b..558bb16bfd46 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -4844,9 +4844,9 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
  * we reset the firmware. If everything is fine just rearm the timer.
  */
 void
-il_bg_watchdog(unsigned long data)
+il_bg_watchdog(struct timer_list *t)
 {
-   struct il_priv *il = (struct il_priv *)data;
+   struct il_priv *il = from_timer(il, t, watchdog);
int cnt;
unsigned long timeout;
 
diff --git a/drivers/net/wireless/intel/iwlegacy/common.h 
b/drivers/net/wireless/intel/iwlegacy/common.h
index 18c60c92e3a3..dc6a74a05983 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.h
+++ b/drivers/net/wireless/intel/iwlegacy/comm

[PATCH] drivers/wireless: atmel: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Simon Kelley <si...@thekelleys.org.uk>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/atmel/atmel.c | 10 --
 1 file changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/net/wireless/atmel/atmel.c 
b/drivers/net/wireless/atmel/atmel.c
index e816d53c2c05..c9dd5e44c9c6 100644
--- a/drivers/net/wireless/atmel/atmel.c
+++ b/drivers/net/wireless/atmel/atmel.c
@@ -586,7 +586,7 @@ static int atmel_validate_channel(struct atmel_private 
*priv, int channel);
 static void atmel_management_frame(struct atmel_private *priv,
   struct ieee80211_hdr *header,
   u16 frame_len, u8 rssi);
-static void atmel_management_timer(u_long a);
+static void atmel_management_timer(struct timer_list *t);
 static void atmel_send_command(struct atmel_private *priv, int command,
   void *cmd, int cmd_size);
 static int atmel_send_command_wait(struct atmel_private *priv, int command,
@@ -1579,8 +1579,7 @@ struct net_device *init_atmel_card(unsigned short irq, 
unsigned long port,
priv->default_beacon_period = priv->beacon_period = 100;
priv->listen_interval = 1;
 
-   setup_timer(>management_timer, atmel_management_timer,
-   (unsigned long)dev);
+   timer_setup(>management_timer, atmel_management_timer, 0);
spin_lock_init(>irqlock);
spin_lock_init(>timerlock);
 
@@ -3434,10 +3433,9 @@ static void atmel_management_frame(struct atmel_private 
*priv,
 }
 
 /* run when timer expires */
-static void atmel_management_timer(u_long a)
+static void atmel_management_timer(struct timer_list *t)
 {
-   struct net_device *dev = (struct net_device *) a;
-   struct atmel_private *priv = netdev_priv(dev);
+   struct atmel_private *priv = from_timer(priv, t, management_timer);
unsigned long flags;
 
/* Check if the card has been yanked. */
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] drivers/wireless: rsi: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Amitkumar Karwar <amit.kar...@redpinesignals.com>
Cc: Prameela Rani Garnepudi <prameela.j0...@gmail.com>
Cc: Pavani Muthyala <pavani.muthy...@redpinesignals.com>
Cc: Karun Eagalapati <karun...@gmail.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/rsi/rsi_91x_hal.c  | 7 +++
 drivers/net/wireless/rsi/rsi_91x_mac80211.c | 4 ++--
 drivers/net/wireless/rsi/rsi_91x_main.c | 4 +---
 drivers/net/wireless/rsi/rsi_common.h   | 2 +-
 4 files changed, 7 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wireless/rsi/rsi_91x_hal.c 
b/drivers/net/wireless/rsi/rsi_91x_hal.c
index 689527d7007a..1176de646942 100644
--- a/drivers/net/wireless/rsi/rsi_91x_hal.c
+++ b/drivers/net/wireless/rsi/rsi_91x_hal.c
@@ -418,9 +418,9 @@ int rsi_prepare_beacon(struct rsi_common *common, struct 
sk_buff *skb)
return 0;
 }
 
-static void bl_cmd_timeout(unsigned long priv)
+static void bl_cmd_timeout(struct timer_list *t)
 {
-   struct rsi_hw *adapter = (struct rsi_hw *)priv;
+   struct rsi_hw *adapter = from_timer(adapter, t, bl_cmd_timer);
 
adapter->blcmd_timer_expired = true;
del_timer(>bl_cmd_timer);
@@ -428,8 +428,7 @@ static void bl_cmd_timeout(unsigned long priv)
 
 static int bl_start_cmd_timer(struct rsi_hw *adapter, u32 timeout)
 {
-   setup_timer(>bl_cmd_timer, (void *)_cmd_timeout,
-   (unsigned long)adapter);
+   timer_setup(>bl_cmd_timer, bl_cmd_timeout, 0);
adapter->bl_cmd_timer.expires = (msecs_to_jiffies(timeout) + jiffies);
 
adapter->blcmd_timer_expired = false;
diff --git a/drivers/net/wireless/rsi/rsi_91x_mac80211.c 
b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
index b1f5dbbde3cb..9427c9d7c9c7 100644
--- a/drivers/net/wireless/rsi/rsi_91x_mac80211.c
+++ b/drivers/net/wireless/rsi/rsi_91x_mac80211.c
@@ -1663,9 +1663,9 @@ static void rsi_resume_conn_channel(struct rsi_common 
*common)
}
 }
 
-void rsi_roc_timeout(unsigned long data)
+void rsi_roc_timeout(struct timer_list *t)
 {
-   struct rsi_common *common = (struct rsi_common *)data;
+   struct rsi_common *common = from_timer(common, t, roc_timer);
 
rsi_dbg(INFO_ZONE, "Remain on channel expired\n");
 
diff --git a/drivers/net/wireless/rsi/rsi_91x_main.c 
b/drivers/net/wireless/rsi/rsi_91x_main.c
index 71b8cfb8252e..2a1fbb7db6c4 100644
--- a/drivers/net/wireless/rsi/rsi_91x_main.c
+++ b/drivers/net/wireless/rsi/rsi_91x_main.c
@@ -262,9 +262,7 @@ struct rsi_hw *rsi_91x_init(void)
 
rsi_default_ps_params(adapter);
spin_lock_init(>ps_lock);
-   common->roc_timer.data = (unsigned long)common;
-   common->roc_timer.function = (void *)_roc_timeout;
-   init_timer(>roc_timer);
+   timer_setup(>roc_timer, rsi_roc_timeout, 0);
common->init_done = true;
return adapter;
 
diff --git a/drivers/net/wireless/rsi/rsi_common.h 
b/drivers/net/wireless/rsi/rsi_common.h
index 272e18d750ff..29acaea3636d 100644
--- a/drivers/net/wireless/rsi/rsi_common.h
+++ b/drivers/net/wireless/rsi/rsi_common.h
@@ -85,5 +85,5 @@ void rsi_91x_deinit(struct rsi_hw *adapter);
 int rsi_read_pkt(struct rsi_common *common, s32 rcv_pkt_len);
 struct rsi_sta *rsi_find_sta(struct rsi_common *common, u8 *mac_addr);
 struct ieee80211_vif *rsi_get_vif(struct rsi_hw *adapter, u8 *mac);
-void rsi_roc_timeout(unsigned long data);
+void rsi_roc_timeout(struct timer_list *t);
 #endif
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] drivers/wireless: ath: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@qca.qualcomm.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/ath/ar5523/ar5523.c  |  7 +++
 drivers/net/wireless/ath/ath10k/htt_rx.c  |  6 +++---
 drivers/net/wireless/ath/ath10k/pci.c | 17 -
 drivers/net/wireless/ath/ath10k/pci.h |  2 +-
 drivers/net/wireless/ath/ath6kl/cfg80211.c|  6 ++
 drivers/net/wireless/ath/ath6kl/core.h|  2 +-
 drivers/net/wireless/ath/ath6kl/main.c|  5 ++---
 drivers/net/wireless/ath/ath6kl/txrx.c|  6 +++---
 drivers/net/wireless/ath/ath6kl/wmi.c |  4 ++--
 drivers/net/wireless/ath/ath6kl/wmi.h |  2 +-
 drivers/net/wireless/ath/ath9k/ath9k.h|  4 ++--
 drivers/net/wireless/ath/ath9k/channel.c  | 14 ++
 drivers/net/wireless/ath/ath9k/gpio.c | 14 ++
 drivers/net/wireless/ath/ath9k/htc.h  |  2 +-
 drivers/net/wireless/ath/ath9k/htc_drv_init.c |  3 +--
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |  4 ++--
 drivers/net/wireless/ath/ath9k/init.c |  4 ++--
 drivers/net/wireless/ath/ath9k/link.c |  6 +++---
 drivers/net/wireless/ath/ath9k/main.c |  4 ++--
 drivers/net/wireless/ath/wil6210/main.c   | 15 +++
 drivers/net/wireless/ath/wil6210/p2p.c|  4 ++--
 drivers/net/wireless/ath/wil6210/wil6210.h|  2 +-
 22 files changed, 61 insertions(+), 72 deletions(-)

diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c 
b/drivers/net/wireless/ath/ar5523/ar5523.c
index 68f0463ed8df..b94759daeacc 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -889,9 +889,9 @@ static void ar5523_tx_work(struct work_struct *work)
mutex_unlock(>mutex);
 }
 
-static void ar5523_tx_wd_timer(unsigned long arg)
+static void ar5523_tx_wd_timer(struct timer_list *t)
 {
-   struct ar5523 *ar = (struct ar5523 *) arg;
+   struct ar5523 *ar = from_timer(ar, t, tx_wd_timer);
 
ar5523_dbg(ar, "TX watchdog timer triggered\n");
ieee80211_queue_work(ar->hw, >tx_wd_work);
@@ -1599,8 +1599,7 @@ static int ar5523_probe(struct usb_interface *intf,
mutex_init(>mutex);
 
INIT_DELAYED_WORK(>stat_work, ar5523_stat_work);
-   init_timer(>tx_wd_timer);
-   setup_timer(>tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar);
+   timer_setup(>tx_wd_timer, ar5523_tx_wd_timer, 0);
INIT_WORK(>tx_wd_work, ar5523_tx_wd_work);
INIT_WORK(>tx_work, ar5523_tx_work);
INIT_LIST_HEAD(>tx_queue_pending);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a3f5dc78353f..f068376ec565 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -200,9 +200,9 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct 
ath10k_htt *htt)
spin_unlock_bh(>rx_ring.lock);
 }
 
-static void ath10k_htt_rx_ring_refill_retry(unsigned long arg)
+static void ath10k_htt_rx_ring_refill_retry(struct timer_list *t)
 {
-   struct ath10k_htt *htt = (struct ath10k_htt *)arg;
+   struct ath10k_htt *htt = from_timer(htt, t, rx_ring.refill_retry_timer);
 
ath10k_htt_rx_msdu_buff_replenish(htt);
 }
@@ -507,7 +507,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
*htt->rx_ring.alloc_idx.vaddr = 0;
 
/* Initialize the Rx refill retry timer */
-   setup_timer(timer, ath10k_htt_rx_ring_refill_retry, (unsigned long)htt);
+   timer_setup(timer, ath10k_htt_rx_ring_refill_retry, 0);
 
spin_lock_init(>rx_ring.lock);
 
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 195dafb98131..2b975bb3f67e 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -585,10 +585,10 @@ static void ath10k_pci_sleep(struct ath10k *ar)
spin_unlock_irqrestore(_pci->ps_lock, flags);
 }
 
-static void ath10k_pci_ps_timer(unsigned long ptr)
+static void ath10k_pci_ps_timer(struct timer_list *t)
 {
-   struct ath10k *ar = (void *)ptr;
-   struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+   struct ath10k_pci *ar_pci = from_timer(ar_pci, t, ps_timer);
+   struct ath10k *ar = ar_pci->ar;
unsigned long flags;
 
spin_lock_irqsave(_pci->ps_lock, flags);
@@ -838,9 +838,10 @@ void ath10k_pci_rx_post(struct ath10k *ar)
ath10k_pci_rx_post_pipe(_pci->pipe_info[i]);
 }
 
-void ath10k_pci_rx_replenish_retry(unsigned long ptr)
+void ath10k_pci_rx_replenish_retry(struct timer_list *t)
 {
-   struct ath10k *ar = (void *)

[PATCH] drivers/wireless: iwlwifi/mvm: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

The RCU lifetime on baid_data is unclear, so this adds a direct copy of the
rcu_ptr passed to the original callback. It may be possible to improve this
to just use baid_data->mvm->baid_map[baid_data->baid] instead.

Cc: Johannes Berg <johannes.b...@intel.com>
Cc: Emmanuel Grumbach <emmanuel.grumb...@intel.com>
Cc: Luca Coelho <luciano.coe...@intel.com>
Cc: Intel Linux Wireless <linuxw...@intel.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Sara Sharon <sara.sha...@intel.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/intel/iwlwifi/mvm/mvm.h  |  3 ++-
 drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c |  4 ++--
 drivers/net/wireless/intel/iwlwifi/mvm/sta.c  | 18 +-
 3 files changed, 13 insertions(+), 12 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h 
b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
index bf25c3ce7c95..a22c0ecff324 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/mvm.h
@@ -636,6 +636,7 @@ struct iwl_mvm_baid_data {
u16 timeout;
unsigned long last_rx;
struct timer_list session_timer;
+   struct iwl_mvm_baid_data __rcu **rcu_ptr;
struct iwl_mvm *mvm;
struct iwl_mvm_reorder_buffer reorder_buf[];
 };
@@ -1829,7 +1830,7 @@ void iwl_mvm_tdls_ch_switch_work(struct work_struct 
*work);
 void iwl_mvm_sync_rx_queues_internal(struct iwl_mvm *mvm,
 struct iwl_mvm_internal_rxq_notif *notif,
 u32 size);
-void iwl_mvm_reorder_timer_expired(unsigned long data);
+void iwl_mvm_reorder_timer_expired(struct timer_list *t);
 struct ieee80211_vif *iwl_mvm_get_bss_vif(struct iwl_mvm *mvm);
 bool iwl_mvm_is_vif_assoc(struct iwl_mvm *mvm);
 
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
index 5e679859f948..53485dc096b3 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/rxmq.c
@@ -456,9 +456,9 @@ static void iwl_mvm_release_frames(struct iwl_mvm *mvm,
}
 }
 
-void iwl_mvm_reorder_timer_expired(unsigned long data)
+void iwl_mvm_reorder_timer_expired(struct timer_list *t)
 {
-   struct iwl_mvm_reorder_buffer *buf = (void *)data;
+   struct iwl_mvm_reorder_buffer *buf = from_timer(buf, t, reorder_timer);
int i;
u16 sn = 0, index = 0;
bool expired = false;
diff --git a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c 
b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
index 282424f40c43..b95b24a03959 100644
--- a/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
+++ b/drivers/net/wireless/intel/iwlwifi/mvm/sta.c
@@ -252,9 +252,11 @@ int iwl_mvm_sta_send_to_fw(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
return ret;
 }
 
-static void iwl_mvm_rx_agg_session_expired(unsigned long data)
+static void iwl_mvm_rx_agg_session_expired(struct timer_list *t)
 {
-   struct iwl_mvm_baid_data __rcu **rcu_ptr = (void *)data;
+   struct iwl_mvm_baid_data *data =
+   from_timer(data, t, session_timer);
+   struct iwl_mvm_baid_data __rcu **rcu_ptr = data->rcu_ptr;
struct iwl_mvm_baid_data *ba_data;
struct ieee80211_sta *sta;
struct iwl_mvm_sta *mvm_sta;
@@ -2150,10 +2152,8 @@ static void iwl_mvm_init_reorder_buffer(struct iwl_mvm 
*mvm,
reorder_buf->head_sn = ssn;
reorder_buf->buf_size = buf_size;
/* rx reorder timer */
-   reorder_buf->reorder_timer.function =
-   iwl_mvm_reorder_timer_expired;
-   reorder_buf->reorder_timer.data = (unsigned long)reorder_buf;
-   init_timer(_buf->reorder_timer);
+   timer_setup(_buf->reorder_timer,
+   iwl_mvm_reorder_timer_expired, 0);
spin_lock_init(_buf->lock);
reorder_buf->mvm = mvm;
reorder_buf->queue = i;
@@ -2250,9 +2250,9 @@ int iwl_mvm_sta_rx_agg(struct iwl_mvm *mvm, struct 
ieee80211_sta *sta,
baid_data->baid = baid;
baid_data->timeout = timeout;
baid_data->last_rx = jiffies;
-   setup_timer(_data->session_timer,
-   iwl_mvm_rx_agg_session_expired,
-   (unsigned long)>baid_map[baid]);
+   baid_data->rcu_ptr = >baid_map[baid];
+   timer_setup(_data->session_timer,
+   iwl_mvm_rx_agg_session_expired, 0);
baid_data->mvm = mvm;
    baid_data->tid = tid;
baid_data->sta_id = mvm_sta->sta_id;
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] drivers/wireless: marvell/libertas: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Arvind Yadav <arvind.yadav...@gmail.com>
Cc: Ingo Molnar <mi...@kernel.org>
Cc: Johannes Berg <johannes.b...@intel.com>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: Andrew Zaborowski <andrew.zaborow...@intel.com>
Cc: libertas-...@lists.infradead.org
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/marvell/libertas/if_usb.c|  6 +++---
 drivers/net/wireless/marvell/libertas/main.c  | 21 +
 drivers/net/wireless/marvell/libertas_tf/if_usb.c |  6 +++---
 drivers/net/wireless/marvell/libertas_tf/main.c   |  7 +++
 4 files changed, 18 insertions(+), 22 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/if_usb.c 
b/drivers/net/wireless/marvell/libertas/if_usb.c
index 16e54c757dd0..ffea610f67e2 100644
--- a/drivers/net/wireless/marvell/libertas/if_usb.c
+++ b/drivers/net/wireless/marvell/libertas/if_usb.c
@@ -161,9 +161,9 @@ static void if_usb_setup_firmware(struct lbs_private *priv)
}
 }
 
-static void if_usb_fw_timeo(unsigned long priv)
+static void if_usb_fw_timeo(struct timer_list *t)
 {
-   struct if_usb_card *cardp = (void *)priv;
+   struct if_usb_card *cardp = from_timer(cardp, t, fw_timeout);
 
if (cardp->fwdnldover) {
lbs_deb_usb("Download complete, no event. Assuming success\n");
@@ -205,7 +205,7 @@ static int if_usb_probe(struct usb_interface *intf,
if (!cardp)
goto error;
 
-   setup_timer(>fw_timeout, if_usb_fw_timeo, (unsigned long)cardp);
+   timer_setup(>fw_timeout, if_usb_fw_timeo, 0);
init_waitqueue_head(>fw_wq);
 
cardp->udev = udev;
diff --git a/drivers/net/wireless/marvell/libertas/main.c 
b/drivers/net/wireless/marvell/libertas/main.c
index aefa88f4f29c..f22e1c220cba 100644
--- a/drivers/net/wireless/marvell/libertas/main.c
+++ b/drivers/net/wireless/marvell/libertas/main.c
@@ -722,9 +722,9 @@ EXPORT_SYMBOL_GPL(lbs_resume);
  *
  * @data:  lbs_private pointer
  */
-static void lbs_cmd_timeout_handler(unsigned long data)
+static void lbs_cmd_timeout_handler(struct timer_list *t)
 {
-   struct lbs_private *priv = (struct lbs_private *)data;
+   struct lbs_private *priv = from_timer(priv, t, command_timer);
unsigned long flags;
 
spin_lock_irqsave(>driver_lock, flags);
@@ -756,9 +756,9 @@ static void lbs_cmd_timeout_handler(unsigned long data)
  *
  * @data:  lbs_private pointer
  */
-static void lbs_tx_lockup_handler(unsigned long data)
+static void lbs_tx_lockup_handler(struct timer_list *t)
 {
-   struct lbs_private *priv = (struct lbs_private *)data;
+   struct lbs_private *priv = from_timer(priv, t, tx_lockup_timer);
unsigned long flags;
 
spin_lock_irqsave(>driver_lock, flags);
@@ -779,9 +779,9 @@ static void lbs_tx_lockup_handler(unsigned long data)
  * @data:   lbs_private pointer
  * returns:N/A
  */
-static void auto_deepsleep_timer_fn(unsigned long data)
+static void auto_deepsleep_timer_fn(struct timer_list *t)
 {
-   struct lbs_private *priv = (struct lbs_private *)data;
+   struct lbs_private *priv = from_timer(priv, t, auto_deepsleep_timer);
 
if (priv->is_activity_detected) {
priv->is_activity_detected = 0;
@@ -847,12 +847,9 @@ static int lbs_init_adapter(struct lbs_private *priv)
init_waitqueue_head(>fw_waitq);
mutex_init(>lock);
 
-   setup_timer(>command_timer, lbs_cmd_timeout_handler,
-   (unsigned long)priv);
-   setup_timer(>tx_lockup_timer, lbs_tx_lockup_handler,
-   (unsigned long)priv);
-   setup_timer(>auto_deepsleep_timer, auto_deepsleep_timer_fn,
-   (unsigned long)priv);
+   timer_setup(>command_timer, lbs_cmd_timeout_handler, 0);
+   timer_setup(>tx_lockup_timer, lbs_tx_lockup_handler, 0);
+   timer_setup(>auto_deepsleep_timer, auto_deepsleep_timer_fn, 0);
 
INIT_LIST_HEAD(>cmdfreeq);
INIT_LIST_HEAD(>cmdpendingq);
diff --git a/drivers/net/wireless/marvell/libertas_tf/if_usb.c 
b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
index e9104eca327b..5153922e7ce1 100644
--- a/drivers/net/wireless/marvell/libertas_tf/if_usb.c
+++ b/drivers/net/wireless/marvell/libertas_tf/if_usb.c
@@ -115,9 +115,9 @@ static void if_usb_setup_firmware(struct lbtf_private *priv)
lbtf_deb_leave(LBTF_DEB_USB);
 }
 
-static void if_usb_fw_timeo(unsigned long priv)
+static void if_usb_fw_timeo(struct timer_list *t)
 {
-   struct if_usb_card *cardp = (void *)priv;
+   struct if_usb_card *cardp = from_timer(cardp, t

[PATCH] drivers/wireless: rtlwifi: Convert timers to use timer_setup()

2017-10-24 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Larry Finger <larry.fin...@lwfinger.net>
Cc: Chaoming Li <chaoming...@realsil.com.cn>
Cc: Ping-Ke Shih <pks...@realtek.com>
Cc: Arvind Yadav <arvind.yadav...@gmail.com>
Cc: Souptick Joarder <jrdr.li...@gmail.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/realtek/rtlwifi/base.c | 20 ++--
 drivers/net/wireless/realtek/rtlwifi/base.h |  4 ++--
 drivers/net/wireless/realtek/rtlwifi/core.c |  2 +-
 drivers/net/wireless/realtek/rtlwifi/ps.c   |  2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c |  6 --
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h |  2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c |  7 +--
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h |  2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 12 
 9 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c 
b/drivers/net/wireless/realtek/rtlwifi/base.c
index ea18aa7afecb..03482deb1558 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -461,10 +461,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw 
*hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
 
/* <1> timer */
-   setup_timer(>works.watchdog_timer,
-   rtl_watch_dog_timer_callback, (unsigned long)hw);
-   setup_timer(>works.dualmac_easyconcurrent_retrytimer,
-   rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw);
+   timer_setup(>works.watchdog_timer,
+   rtl_watch_dog_timer_callback, 0);
+   timer_setup(>works.dualmac_easyconcurrent_retrytimer,
+   rtl_easy_concurrent_retrytimer_callback, 0);
/* <2> work queue */
rtlpriv->works.hw = hw;
rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
@@ -1975,10 +1975,9 @@ void rtl_watchdog_wq_callback(void *data)
rtl_scan_list_expire(hw);
 }
 
-void rtl_watch_dog_timer_callback(unsigned long data)
+void rtl_watch_dog_timer_callback(struct timer_list *t)
 {
-   struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
-   struct rtl_priv *rtlpriv = rtl_priv(hw);
+   struct rtl_priv *rtlpriv = from_timer(rtlpriv, t, works.watchdog_timer);
 
queue_delayed_work(rtlpriv->works.rtl_wq,
   >works.watchdog_wq, 0);
@@ -2084,10 +2083,11 @@ void rtl_c2hcmd_wq_callback(void *data)
rtl_c2hcmd_launcher(hw, 1);
 }
 
-void rtl_easy_concurrent_retrytimer_callback(unsigned long data)
+void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t)
 {
-   struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
-   struct rtl_priv *rtlpriv = rtl_priv(hw);
+   struct rtl_priv *rtlpriv =
+   from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer);
+   struct ieee80211_hw *hw = rtlpriv->hw;
struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
 
if (buddy_priv == NULL)
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h 
b/drivers/net/wireless/realtek/rtlwifi/base.h
index b56d1b7f5567..23f1564811b8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.h
+++ b/drivers/net/wireless/realtek/rtlwifi/base.h
@@ -120,7 +120,7 @@ void rtl_init_rx_config(struct ieee80211_hw *hw);
 void rtl_init_rfkill(struct ieee80211_hw *hw);
 void rtl_deinit_rfkill(struct ieee80211_hw *hw);
 
-void rtl_watch_dog_timer_callback(unsigned long data);
+void rtl_watch_dog_timer_callback(struct timer_list *t);
 void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
 
 bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
@@ -169,7 +169,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
 u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
 void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
 u8 rtl_tid_to_ac(u8 tid);
-void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
+void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t);
 extern struct rtl_global_var rtl_global_var;
 void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c 
b/drivers/net/wireless/realtek/rtlwifi/core.c
index 294a6b43d1bc..e025cb06443d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -160,7 +160,7 @@ static int rtl_op_start(struct ieee80211_hw *hw)
mutex_lock(>locks.conf_mutex);
err = rtlpriv->int

Re: [PATCH] mac80211: aggregation: Convert timers to use timer_setup()

2017-10-18 Thread Kees Cook
On Wed, Oct 18, 2017 at 1:50 PM, Johannes Berg
<johan...@sipsolutions.net> wrote:
> On Wed, 2017-10-18 at 07:19 -0700, Kees Cook wrote:
>> On Wed, Oct 18, 2017 at 3:29 AM, Johannes Berg
>> <johan...@sipsolutions.net> wrote:
>> > > This has been the least trivial timer conversion yet. Given the use of
>> > > RCU and other things I may not even know about, I'd love to get a close
>> > > look at this. I *think* this is correct, as it will re-lookup the tid
>> > > entries when firing the timer.
>> >
>> > I'm not really sure why you're doing the lookup again? That seems
>> > pointless, since you already have the right structure, and already rely
>> > on it being valid. You can't really get a new struct assigned to the
>> > same TID without the old one being destroyed.
>>
>> I couldn't tell what the lifetime expectation was, so I left the
>> re-lookup. I assumed it was possible to have a timer fire after the
>> structure had been removed from the station structure.
>
> Oh, right, I guess that would've been possible in theory. It's not
> actually possible though since the aggregation sessions can't live on
> without a station, so I've already made a follow-up patch to remove the
> indirection.

Okay, cool, thanks.

It seems like I have a similar case in the iwlwifi driver too, but
it's different enough that I'm not sure about that one either. I'll
send that when I've got it ready.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH 00/58] networking: Convert timers to use timer_setup()

2017-10-18 Thread Kees Cook
On Tue, Oct 17, 2017 at 10:44 PM, Kalle Valo <kv...@codeaurora.org> wrote:
> Kees Cook <keesc...@chromium.org> writes:
>> Which split is preferred? I had been trying to separate wireless from
>> the rest of net (but missed some cases).
>
> So what we try to follow is that I apply all patches for
> drivers/net/wireless to my wireless-drivers trees, with exception of
> Johannes taking mac80211_hwsim.c patches to his mac80211 trees. And
> Johannes of course takes all patches for net/wireless and net/mac80211.
>
> So in general I prefer that I take all drivers/net/wireless patches and
> make it obvious for Dave that he can ignore those patches (not mix
> wireless-drivers and net patches into same set etc). But like I said,
> it's ok to push API changes like these via Dave's net trees as well if
> you want (and if Dave is ok with that). The chances of conflicts is low,
> and if there are be any those would be easy to fix either by me or Dave.

Okay, great. That'll help. I'll wait for the dust to settle and rebase
against -next, and then I'll see what's outstanding and double-check
where they need to be sent (and I'll queue new conversions up
accordingly too).

>>> For now I'll just drop all your timer_setup() related patches from my
>>> queue and I'll assume Dave will take those. Ok?
>>>
>>> [1] https://patchwork.kernel.org/project/linux-wireless/list/
>>
>> I guess I'll wait to see what Dave says.
>
> Ok, I don't drop the patches from my queue quite yet then.

Alright, thanks very much!

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH] mac80211: aggregation: Convert timers to use timer_setup()

2017-10-18 Thread Kees Cook
On Wed, Oct 18, 2017 at 3:29 AM, Johannes Berg
<johan...@sipsolutions.net> wrote:
>> This has been the least trivial timer conversion yet. Given the use of
>> RCU and other things I may not even know about, I'd love to get a close
>> look at this. I *think* this is correct, as it will re-lookup the tid
>> entries when firing the timer.
>
> I'm not really sure why you're doing the lookup again? That seems
> pointless, since you already have the right structure, and already rely
> on it being valid. You can't really get a new struct assigned to the
> same TID without the old one being destroyed.

I couldn't tell what the lifetime expectation was, so I left the
re-lookup. I assumed it was possible to have a timer fire after the
structure had been removed from the station structure.

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH] mac80211: aggregation: Convert timers to use timer_setup()

2017-10-18 Thread Kees Cook
On Wed, Oct 18, 2017 at 4:37 AM, Johannes Berg
<johan...@sipsolutions.net> wrote:
> On Wed, 2017-10-18 at 13:31 +0200, Johannes Berg wrote:
>> On Wed, 2017-10-18 at 12:29 +0200, Johannes Berg wrote:
>>
>> > Anyway, the change here looks correct to me, so I'll apply it and then
>> > perhaps clean up more. I've only changed "u16 tid" to "u8 tid" since
>> > the valid range is 0-15 (in theory, in practice 0-7).

I started with u8 tid, but I saw it cast to u16 and in a few other
places it was u16, so I went with that ultimately.

>> Well, I guess I'm clearly wrong - it's crashing our test suite left and
>> right.
>>
>> I'll dig a little bit, but I don't have much time today, and will be
>> out for a few days starting tomorrow.
>
> Ok, it's pretty obvious - you never initialize the new fields in tid_tx
> (sta and tid), only in tid_rx. Let's see if it passes with that fixed.

Argh, whoops, thanks for working on this.

-Kees

-- 
Kees Cook
Pixel Security


[PATCH] mac80211: aggregation: Convert timers to use timer_setup()

2017-10-17 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

This removes the tid mapping array and expands the tid structures to
add a pointer back to the station, along with the tid index itself.

Cc: Johannes Berg <johan...@sipsolutions.net>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
Resend, with linux-wireless in Cc (no idea how it got missed before)
---
 net/mac80211/agg-rx.c   | 41 +
 net/mac80211/agg-tx.c   | 42 --
 net/mac80211/sta_info.c |  8 
 net/mac80211/sta_info.h | 12 ++--
 4 files changed, 43 insertions(+), 60 deletions(-)

diff --git a/net/mac80211/agg-rx.c b/net/mac80211/agg-rx.c
index 88cc1ae935ea..63aba6dbc92a 100644
--- a/net/mac80211/agg-rx.c
+++ b/net/mac80211/agg-rx.c
@@ -151,21 +151,17 @@ EXPORT_SYMBOL(ieee80211_stop_rx_ba_session);
  * After accepting the AddBA Request we activated a timer,
  * resetting it after each frame that arrives from the originator.
  */
-static void sta_rx_agg_session_timer_expired(unsigned long data)
+static void sta_rx_agg_session_timer_expired(struct timer_list *t)
 {
-   /* not an elegant detour, but there is no choice as the timer passes
-* only one argument, and various sta_info are needed here, so init
-* flow in sta_info_create gives the TID as data, while the timer_to_id
-* array gives the sta through container_of */
-   u8 *ptid = (u8 *)data;
-   u8 *timer_to_id = ptid - *ptid;
-   struct sta_info *sta = container_of(timer_to_id, struct sta_info,
-timer_to_tid[0]);
+   struct tid_ampdu_rx *tid_rx_timer =
+   from_timer(tid_rx_timer, t, session_timer);
+   struct sta_info *sta = tid_rx_timer->sta;
+   u16 tid = tid_rx_timer->tid;
struct tid_ampdu_rx *tid_rx;
unsigned long timeout;
 
rcu_read_lock();
-   tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[*ptid]);
+   tid_rx = rcu_dereference(sta->ampdu_mlme.tid_rx[tid]);
if (!tid_rx) {
rcu_read_unlock();
return;
@@ -180,21 +176,18 @@ static void sta_rx_agg_session_timer_expired(unsigned 
long data)
rcu_read_unlock();
 
ht_dbg(sta->sdata, "RX session timer expired on %pM tid %d\n",
-  sta->sta.addr, (u16)*ptid);
+  sta->sta.addr, tid);
 
-   set_bit(*ptid, sta->ampdu_mlme.tid_rx_timer_expired);
+   set_bit(tid, sta->ampdu_mlme.tid_rx_timer_expired);
ieee80211_queue_work(>local->hw, >ampdu_mlme.work);
 }
 
-static void sta_rx_agg_reorder_timer_expired(unsigned long data)
+static void sta_rx_agg_reorder_timer_expired(struct timer_list *t)
 {
-   u8 *ptid = (u8 *)data;
-   u8 *timer_to_id = ptid - *ptid;
-   struct sta_info *sta = container_of(timer_to_id, struct sta_info,
-   timer_to_tid[0]);
+   struct tid_ampdu_rx *tid_rx = from_timer(tid_rx, t, reorder_timer);
 
rcu_read_lock();
-   ieee80211_release_reorder_timeout(sta, *ptid);
+   ieee80211_release_reorder_timeout(tid_rx->sta, tid_rx->tid);
rcu_read_unlock();
 }
 
@@ -356,14 +349,12 @@ void ___ieee80211_start_rx_ba_session(struct sta_info 
*sta,
spin_lock_init(_agg_rx->reorder_lock);
 
/* rx timer */
-   setup_deferrable_timer(_agg_rx->session_timer,
-  sta_rx_agg_session_timer_expired,
-  (unsigned long)>timer_to_tid[tid]);
+   timer_setup(_agg_rx->session_timer,
+   sta_rx_agg_session_timer_expired, TIMER_DEFERRABLE);
 
/* rx reorder timer */
-   setup_timer(_agg_rx->reorder_timer,
-   sta_rx_agg_reorder_timer_expired,
-   (unsigned long)>timer_to_tid[tid]);
+   timer_setup(_agg_rx->reorder_timer,
+   sta_rx_agg_reorder_timer_expired, 0);
 
/* prepare reordering buffer */
tid_agg_rx->reorder_buf =
@@ -399,6 +390,8 @@ void ___ieee80211_start_rx_ba_session(struct sta_info *sta,
tid_agg_rx->auto_seq = auto_seq;
tid_agg_rx->started = false;
tid_agg_rx->reorder_buf_filtered = 0;
+   tid_agg_rx->tid = tid;
+   tid_agg_rx->sta = sta;
status = WLAN_STATUS_SUCCESS;
 
/* activate it for RX */
diff --git a/net/mac80211/agg-tx.c b/net/mac80211/agg-tx.c
index bef516ec47f9..dedbb1fb10e7 100644
--- a/net/mac80211/agg-tx.c
+++ b/net/mac80211/agg-tx.c
@@ -422,15 +422,12 @@ int ___ieee80211_stop_tx_ba_session(struct sta_info *sta, 
u16 tid,
  * add Block Ack response will arrive from the recipient.

Re: [PATCH 00/58] networking: Convert timers to use timer_setup()

2017-10-17 Thread Kees Cook
On Tue, Oct 17, 2017 at 7:18 AM, Kalle Valo <kv...@codeaurora.org> wrote:
> + linux-wireless
>
> Hi Kees,
>
> Kees Cook <keesc...@chromium.org> writes:
>
>> This is the current set of outstanding networking patches to perform
>> conversions to the new timer interface (rebased to -next). This is not
>> all expected conversions, but it contains everything needed in networking
>> to eliminate init_timer(), and all the non-standard setup_*_timer() uses.
>
> So this also includes patches which I had queued for
> wireless-drivers-next:
>
> https://patchwork.kernel.org/patch/9986253/
> https://patchwork.kernel.org/patch/9986245/
>
> And looking at patchwork[1] I have even more timer_setup() related
> patches from you. It would be really helpful if you could clearly
> document to which tree you want the patches to be applied. I don't care

Hi! Sorry about that. It's been a bit tricky to juggle everything.

> if it's net-next or wireless-drivers-next as long as it's not the both
> (meaning that both Dave and me apply the same patch, which would be
> bad). The thing is that I really do not have time to figure out for
> every patch via which tree it's supposed to go.

Which split is preferred? I had been trying to separate wireless from
the rest of net (but missed some cases).

> For now I'll just drop all your timer_setup() related patches from my
> queue and I'll assume Dave will take those. Ok?
>
> [1] https://patchwork.kernel.org/project/linux-wireless/list/

I guess I'll wait to see what Dave says.

Thanks!

-Kees

-- 
Kees Cook
Pixel Security


[PATCH 17/58] net/cw1200: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Solomon Peachy <pi...@shaftnet.org>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/st/cw1200/pm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/pm.c 
b/drivers/net/wireless/st/cw1200/pm.c
index d2202ae92bdd..ded23df1ac1d 100644
--- a/drivers/net/wireless/st/cw1200/pm.c
+++ b/drivers/net/wireless/st/cw1200/pm.c
@@ -91,7 +91,7 @@ struct cw1200_suspend_state {
u8 prev_ps_mode;
 };
 
-static void cw1200_pm_stay_awake_tmo(unsigned long arg)
+static void cw1200_pm_stay_awake_tmo(struct timer_list *unused)
 {
/* XXX what's the point of this ? */
 }
@@ -101,8 +101,7 @@ int cw1200_pm_init(struct cw1200_pm_state *pm,
 {
spin_lock_init(>lock);
 
-   setup_timer(>stay_awake, cw1200_pm_stay_awake_tmo,
-   (unsigned long)pm);
+   timer_setup(>stay_awake, cw1200_pm_stay_awake_tmo, 0);
 
return 0;
 }
-- 
2.7.4



[PATCH 08/58] net/wireless/ray_cs: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/ray_cs.c | 53 ---
 1 file changed, 24 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 170cd504e8ff..d8afcdfca1ed 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,7 +92,7 @@ static const struct iw_handler_def ray_handler_def;
 /* Prototypes for raylink functions **/
 static void authenticate(ray_dev_t *local);
 static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
-static void authenticate_timeout(u_long);
+static void authenticate_timeout(struct timer_list *t);
 static int get_free_ccs(ray_dev_t *local);
 static int get_free_tx_ccs(ray_dev_t *local);
 static void init_startup_params(ray_dev_t *local);
@@ -102,7 +102,7 @@ static int ray_init(struct net_device *dev);
 static int interrupt_ecf(ray_dev_t *local, int ccs);
 static void ray_reset(struct net_device *dev);
 static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, 
int len);
-static void verify_dl_startup(u_long);
+static void verify_dl_startup(struct timer_list *t);
 
 /* Prototypes for interrpt time functions **/
 static irqreturn_t ray_interrupt(int reg, void *dev_id);
@@ -120,9 +120,8 @@ static void associate(ray_dev_t *local);
 
 /* Card command functions */
 static int dl_startup_params(struct net_device *dev);
-static void join_net(u_long local);
-static void start_net(u_long local);
-/* void start_net(ray_dev_t *local); */
+static void join_net(struct timer_list *t);
+static void start_net(struct timer_list *t);
 
 /*===*/
 /* Parameters that can be set with 'insmod' */
@@ -323,7 +322,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
dev_dbg(_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
netif_stop_queue(dev);
 
-   init_timer(>timer);
+   timer_setup(>timer, NULL, 0);
 
this_device = p_dev;
return ray_config(p_dev);
@@ -570,8 +569,7 @@ static int dl_startup_params(struct net_device *dev)
local->card_status = CARD_DL_PARAM;
/* Start kernel timer to wait for dl startup to complete. */
local->timer.expires = jiffies + HZ / 2;
-   local->timer.data = (long)local;
-   local->timer.function = verify_dl_startup;
+   local->timer.function = (TIMER_FUNC_TYPE)verify_dl_startup;
add_timer(>timer);
dev_dbg(>dev,
  "ray_cs dl_startup_params started timer for verify_dl_startup\n");
@@ -641,9 +639,9 @@ static void init_startup_params(ray_dev_t *local)
 } /* init_startup_params */
 
 /*===*/
-static void verify_dl_startup(u_long data)
+static void verify_dl_startup(struct timer_list *t)
 {
-   ray_dev_t *local = (ray_dev_t *) data;
+   ray_dev_t *local = from_timer(local, t, timer);
struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
UCHAR status;
struct pcmcia_device *link = local->finder;
@@ -676,16 +674,16 @@ static void verify_dl_startup(u_long data)
return;
}
if (local->sparm.b4.a_network_type == ADHOC)
-   start_net((u_long) local);
+   start_net(>timer);
else
-   join_net((u_long) local);
+   join_net(>timer);
 } /* end verify_dl_startup */
 
 /*===*/
 /* Command card to start a network */
-static void start_net(u_long data)
+static void start_net(struct timer_list *t)
 {
-   ray_dev_t *local = (ray_dev_t *) data;
+   ray_dev_t *local = from_timer(local, t, timer);
struct ccs __iomem *pccs;
int ccsindex;
struct pcmcia_device *link = local->finder;
@@ -710,9 +708,9 @@ static void start_net(u_long data)
 
 /*===*/
 /* Command card to join a network */
-static void join_net(u_long data)
+static void join_net(struct timer_list *t)
 {
-   ray_dev_t *local = (ray_dev_t *) data;
+   ray_dev_t *local = from_timer(local, t, timer);
 
struct ccs __iomem *pccs;
int ccsindex;
@@ -1639,13 +1637,13 @@ static int get_free_ccs(ray_dev_t *local)
 } /* get_free_ccs */
 
 /*===*/
-static void authenti

[PATCH] wireless: ath: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@qca.qualcomm.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/ath/ar5523/ar5523.c  |  7 +++
 drivers/net/wireless/ath/ath10k/htt_rx.c  |  6 +++---
 drivers/net/wireless/ath/ath10k/pci.c | 17 -
 drivers/net/wireless/ath/ath10k/pci.h |  2 +-
 drivers/net/wireless/ath/ath6kl/cfg80211.c|  6 ++
 drivers/net/wireless/ath/ath6kl/core.h|  2 +-
 drivers/net/wireless/ath/ath6kl/main.c|  5 ++---
 drivers/net/wireless/ath/ath6kl/txrx.c|  6 +++---
 drivers/net/wireless/ath/ath6kl/wmi.c |  4 ++--
 drivers/net/wireless/ath/ath6kl/wmi.h |  2 +-
 drivers/net/wireless/ath/ath9k/ath9k.h|  4 ++--
 drivers/net/wireless/ath/ath9k/channel.c  | 14 ++
 drivers/net/wireless/ath/ath9k/gpio.c | 14 ++
 drivers/net/wireless/ath/ath9k/htc.h  |  2 +-
 drivers/net/wireless/ath/ath9k/htc_drv_init.c |  3 +--
 drivers/net/wireless/ath/ath9k/htc_drv_txrx.c |  4 ++--
 drivers/net/wireless/ath/ath9k/init.c |  4 ++--
 drivers/net/wireless/ath/ath9k/link.c |  6 +++---
 drivers/net/wireless/ath/ath9k/main.c |  4 ++--
 drivers/net/wireless/ath/wil6210/main.c   | 15 +++
 drivers/net/wireless/ath/wil6210/p2p.c|  4 ++--
 drivers/net/wireless/ath/wil6210/wil6210.h|  2 +-
 22 files changed, 61 insertions(+), 72 deletions(-)

diff --git a/drivers/net/wireless/ath/ar5523/ar5523.c 
b/drivers/net/wireless/ath/ar5523/ar5523.c
index 68f0463ed8df..b94759daeacc 100644
--- a/drivers/net/wireless/ath/ar5523/ar5523.c
+++ b/drivers/net/wireless/ath/ar5523/ar5523.c
@@ -889,9 +889,9 @@ static void ar5523_tx_work(struct work_struct *work)
mutex_unlock(>mutex);
 }
 
-static void ar5523_tx_wd_timer(unsigned long arg)
+static void ar5523_tx_wd_timer(struct timer_list *t)
 {
-   struct ar5523 *ar = (struct ar5523 *) arg;
+   struct ar5523 *ar = from_timer(ar, t, tx_wd_timer);
 
ar5523_dbg(ar, "TX watchdog timer triggered\n");
ieee80211_queue_work(ar->hw, >tx_wd_work);
@@ -1599,8 +1599,7 @@ static int ar5523_probe(struct usb_interface *intf,
mutex_init(>mutex);
 
INIT_DELAYED_WORK(>stat_work, ar5523_stat_work);
-   init_timer(>tx_wd_timer);
-   setup_timer(>tx_wd_timer, ar5523_tx_wd_timer, (unsigned long) ar);
+   timer_setup(>tx_wd_timer, ar5523_tx_wd_timer, 0);
INIT_WORK(>tx_wd_work, ar5523_tx_wd_work);
INIT_WORK(>tx_work, ar5523_tx_work);
INIT_LIST_HEAD(>tx_queue_pending);
diff --git a/drivers/net/wireless/ath/ath10k/htt_rx.c 
b/drivers/net/wireless/ath/ath10k/htt_rx.c
index a3f5dc78353f..f068376ec565 100644
--- a/drivers/net/wireless/ath/ath10k/htt_rx.c
+++ b/drivers/net/wireless/ath/ath10k/htt_rx.c
@@ -200,9 +200,9 @@ static void ath10k_htt_rx_msdu_buff_replenish(struct 
ath10k_htt *htt)
spin_unlock_bh(>rx_ring.lock);
 }
 
-static void ath10k_htt_rx_ring_refill_retry(unsigned long arg)
+static void ath10k_htt_rx_ring_refill_retry(struct timer_list *t)
 {
-   struct ath10k_htt *htt = (struct ath10k_htt *)arg;
+   struct ath10k_htt *htt = from_timer(htt, t, rx_ring.refill_retry_timer);
 
ath10k_htt_rx_msdu_buff_replenish(htt);
 }
@@ -507,7 +507,7 @@ int ath10k_htt_rx_alloc(struct ath10k_htt *htt)
*htt->rx_ring.alloc_idx.vaddr = 0;
 
/* Initialize the Rx refill retry timer */
-   setup_timer(timer, ath10k_htt_rx_ring_refill_retry, (unsigned long)htt);
+   timer_setup(timer, ath10k_htt_rx_ring_refill_retry, 0);
 
spin_lock_init(>rx_ring.lock);
 
diff --git a/drivers/net/wireless/ath/ath10k/pci.c 
b/drivers/net/wireless/ath/ath10k/pci.c
index 195dafb98131..2b975bb3f67e 100644
--- a/drivers/net/wireless/ath/ath10k/pci.c
+++ b/drivers/net/wireless/ath/ath10k/pci.c
@@ -585,10 +585,10 @@ static void ath10k_pci_sleep(struct ath10k *ar)
spin_unlock_irqrestore(_pci->ps_lock, flags);
 }
 
-static void ath10k_pci_ps_timer(unsigned long ptr)
+static void ath10k_pci_ps_timer(struct timer_list *t)
 {
-   struct ath10k *ar = (void *)ptr;
-   struct ath10k_pci *ar_pci = ath10k_pci_priv(ar);
+   struct ath10k_pci *ar_pci = from_timer(ar_pci, t, ps_timer);
+   struct ath10k *ar = ar_pci->ar;
unsigned long flags;
 
spin_lock_irqsave(_pci->ps_lock, flags);
@@ -838,9 +838,10 @@ void ath10k_pci_rx_post(struct ath10k *ar)
ath10k_pci_rx_post_pipe(_pci->pipe_info[i]);
 }
 
-void ath10k_pci_rx_replenish_retry(unsigned long ptr)
+void ath10k_pci_rx_replenish_retry(struct timer_list *t)
 {
-   struct ath10k *ar = (void *)ptr;
+   struct ath10k_pci *ar_pci = from_timer(ar_pci, t, rx_post_ret

[PATCH] wireless: iwlegacy: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Stanislaw Gruszka <sgrus...@redhat.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/intel/iwlegacy/3945-mac.c |  2 +-
 drivers/net/wireless/intel/iwlegacy/3945-rs.c  | 10 +++---
 drivers/net/wireless/intel/iwlegacy/4965-mac.c |  9 -
 drivers/net/wireless/intel/iwlegacy/common.c   |  4 ++--
 drivers/net/wireless/intel/iwlegacy/common.h   |  2 +-
 5 files changed, 11 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/intel/iwlegacy/3945-mac.c 
b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
index 329f3a63dadd..4b53ebf00c7f 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-mac.c
@@ -3429,7 +3429,7 @@ il3945_setup_deferred_work(struct il_priv *il)
 
il3945_hw_setup_deferred_work(il);
 
-   setup_timer(>watchdog, il_bg_watchdog, (unsigned long)il);
+   timer_setup(>watchdog, il_bg_watchdog, 0);
 
tasklet_init(>irq_tasklet,
 (void (*)(unsigned long))il3945_irq_tasklet,
diff --git a/drivers/net/wireless/intel/iwlegacy/3945-rs.c 
b/drivers/net/wireless/intel/iwlegacy/3945-rs.c
index b2f35dfbc01b..e8983c6a2b7b 100644
--- a/drivers/net/wireless/intel/iwlegacy/3945-rs.c
+++ b/drivers/net/wireless/intel/iwlegacy/3945-rs.c
@@ -181,9 +181,9 @@ il3945_rate_scale_flush_wins(struct il3945_rs_sta *rs_sta)
 #define IL_AVERAGE_PACKETS 1500
 
 static void
-il3945_bg_rate_scale_flush(unsigned long data)
+il3945_bg_rate_scale_flush(struct timer_list *t)
 {
-   struct il3945_rs_sta *rs_sta = (void *)data;
+   struct il3945_rs_sta *rs_sta = from_timer(rs_sta, t, rate_scale_flush);
struct il_priv *il __maybe_unused = rs_sta->il;
int unflushed = 0;
unsigned long flags;
@@ -360,9 +360,6 @@ il3945_rs_rate_init(struct il_priv *il, struct 
ieee80211_sta *sta, u8 sta_id)
rs_sta->flush_time = RATE_FLUSH;
rs_sta->last_tx_packets = 0;
 
-   rs_sta->rate_scale_flush.data = (unsigned long)rs_sta;
-   rs_sta->rate_scale_flush.function = il3945_bg_rate_scale_flush;
-
for (i = 0; i < RATE_COUNT_3945; i++)
il3945_clear_win(_sta->win[i]);
 
@@ -415,8 +412,7 @@ il3945_rs_alloc_sta(void *il_priv, struct ieee80211_sta 
*sta, gfp_t gfp)
rs_sta = >rs_sta;
 
spin_lock_init(_sta->lock);
-   init_timer(_sta->rate_scale_flush);
-
+   timer_setup(_sta->rate_scale_flush, il3945_bg_rate_scale_flush, 0);
D_RATE("leave\n");
 
return rs_sta;
diff --git a/drivers/net/wireless/intel/iwlegacy/4965-mac.c 
b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
index 65eba2c24292..de63f2518f23 100644
--- a/drivers/net/wireless/intel/iwlegacy/4965-mac.c
+++ b/drivers/net/wireless/intel/iwlegacy/4965-mac.c
@@ -4074,9 +4074,9 @@ il4965_hdl_alive(struct il_priv *il, struct il_rx_buf 
*rxb)
  * used for calibrating the TXPOWER.
  */
 static void
-il4965_bg_stats_periodic(unsigned long data)
+il4965_bg_stats_periodic(struct timer_list *t)
 {
-   struct il_priv *il = (struct il_priv *)data;
+   struct il_priv *il = from_timer(il, t, stats_periodic);
 
if (test_bit(S_EXIT_PENDING, >status))
return;
@@ -6258,10 +6258,9 @@ il4965_setup_deferred_work(struct il_priv *il)
 
INIT_WORK(>txpower_work, il4965_bg_txpower_work);
 
-   setup_timer(>stats_periodic, il4965_bg_stats_periodic,
-   (unsigned long)il);
+   timer_setup(>stats_periodic, il4965_bg_stats_periodic, 0);
 
-   setup_timer(>watchdog, il_bg_watchdog, (unsigned long)il);
+   timer_setup(>watchdog, il_bg_watchdog, 0);
 
tasklet_init(>irq_tasklet,
 (void (*)(unsigned long))il4965_irq_tasklet,
diff --git a/drivers/net/wireless/intel/iwlegacy/common.c 
b/drivers/net/wireless/intel/iwlegacy/common.c
index 8d5acda92a9b..558bb16bfd46 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.c
+++ b/drivers/net/wireless/intel/iwlegacy/common.c
@@ -4844,9 +4844,9 @@ il_check_stuck_queue(struct il_priv *il, int cnt)
  * we reset the firmware. If everything is fine just rearm the timer.
  */
 void
-il_bg_watchdog(unsigned long data)
+il_bg_watchdog(struct timer_list *t)
 {
-   struct il_priv *il = (struct il_priv *)data;
+   struct il_priv *il = from_timer(il, t, watchdog);
int cnt;
unsigned long timeout;
 
diff --git a/drivers/net/wireless/intel/iwlegacy/common.h 
b/drivers/net/wireless/intel/iwlegacy/common.h
index 18c60c92e3a3..dc6a74a05983 100644
--- a/drivers/net/wireless/intel/iwlegacy/common.h
+++ b/drivers/net/wireless/intel/iwlegacy/comm

[PATCH] rtlwifi: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Larry Finger <larry.fin...@lwfinger.net>
Cc: Chaoming Li <chaoming...@realsil.com.cn>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Ping-Ke Shih <pks...@realtek.com>
Cc: Arvind Yadav <arvind.yadav...@gmail.com>
Cc: Souptick Joarder <jrdr.li...@gmail.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/realtek/rtlwifi/base.c | 21 +++--
 drivers/net/wireless/realtek/rtlwifi/base.h |  4 ++--
 drivers/net/wireless/realtek/rtlwifi/core.c |  2 +-
 drivers/net/wireless/realtek/rtlwifi/ps.c   |  2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.c |  6 --
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/dm.h |  2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.c |  6 --
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/hw.h |  2 +-
 drivers/net/wireless/realtek/rtlwifi/rtl8188ee/sw.c | 12 
 9 files changed, 29 insertions(+), 28 deletions(-)

diff --git a/drivers/net/wireless/realtek/rtlwifi/base.c 
b/drivers/net/wireless/realtek/rtlwifi/base.c
index ea18aa7afecb..ef97a3c36d51 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.c
+++ b/drivers/net/wireless/realtek/rtlwifi/base.c
@@ -461,10 +461,10 @@ static void _rtl_init_deferred_work(struct ieee80211_hw 
*hw)
struct rtl_priv *rtlpriv = rtl_priv(hw);
 
/* <1> timer */
-   setup_timer(>works.watchdog_timer,
-   rtl_watch_dog_timer_callback, (unsigned long)hw);
-   setup_timer(>works.dualmac_easyconcurrent_retrytimer,
-   rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw);
+   timer_setup(>works.watchdog_timer,
+   rtl_watch_dog_timer_callback, 0);
+   timer_setup(>works.dualmac_easyconcurrent_retrytimer,
+   rtl_easy_concurrent_retrytimer_callback, 0);
/* <2> work queue */
rtlpriv->works.hw = hw;
rtlpriv->works.rtl_wq = alloc_workqueue("%s", 0, 0, rtlpriv->cfg->name);
@@ -1975,10 +1975,10 @@ void rtl_watchdog_wq_callback(void *data)
rtl_scan_list_expire(hw);
 }
 
-void rtl_watch_dog_timer_callback(unsigned long data)
+void rtl_watch_dog_timer_callback(struct timer_list *t)
 {
-   struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
-   struct rtl_priv *rtlpriv = rtl_priv(hw);
+   struct rtl_priv *rtlpriv = from_timer(rtlpriv, t, works.watchdog_timer);
+   struct ieee80211_hw *hw = rtlpriv->hw;
 
queue_delayed_work(rtlpriv->works.rtl_wq,
   >works.watchdog_wq, 0);
@@ -2084,10 +2084,11 @@ void rtl_c2hcmd_wq_callback(void *data)
rtl_c2hcmd_launcher(hw, 1);
 }
 
-void rtl_easy_concurrent_retrytimer_callback(unsigned long data)
+void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t)
 {
-   struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
-   struct rtl_priv *rtlpriv = rtl_priv(hw);
+   struct rtl_priv *rtlpriv =
+   from_timer(rtlpriv, t, works.dualmac_easyconcurrent_retrytimer);
+   struct ieee80211_hw *hw = rtlpriv->hw;
struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
 
if (buddy_priv == NULL)
diff --git a/drivers/net/wireless/realtek/rtlwifi/base.h 
b/drivers/net/wireless/realtek/rtlwifi/base.h
index b56d1b7f5567..23f1564811b8 100644
--- a/drivers/net/wireless/realtek/rtlwifi/base.h
+++ b/drivers/net/wireless/realtek/rtlwifi/base.h
@@ -120,7 +120,7 @@ void rtl_init_rx_config(struct ieee80211_hw *hw);
 void rtl_init_rfkill(struct ieee80211_hw *hw);
 void rtl_deinit_rfkill(struct ieee80211_hw *hw);
 
-void rtl_watch_dog_timer_callback(unsigned long data);
+void rtl_watch_dog_timer_callback(struct timer_list *t);
 void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
 
 bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
@@ -169,7 +169,7 @@ int rtl_send_smps_action(struct ieee80211_hw *hw,
 u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
 void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
 u8 rtl_tid_to_ac(u8 tid);
-void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
+void rtl_easy_concurrent_retrytimer_callback(struct timer_list *t);
 extern struct rtl_global_var rtl_global_var;
 void rtl_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation);
 
diff --git a/drivers/net/wireless/realtek/rtlwifi/core.c 
b/drivers/net/wireless/realtek/rtlwifi/core.c
index 294a6b43d1bc..e025cb06443d 100644
--- a/drivers/net/wireless/realtek/rtlwifi/core.c
+++ b/drivers/net/wireless/realtek/rtlwifi/core.c
@@ -160,7 +160,7 @@ static int rtl_op_start(struct ieee80211_hw *hw)

[PATCH] wireless: qtnfmac: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Igor Mitsyanko <imitsya...@quantenna.com>
Cc: Avinash Patil <avina...@quantenna.com>
Cc: Sergey Matyukevich <smatyukev...@quantenna.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Kamlesh Rath <kr...@quantenna.com>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/quantenna/qtnfmac/cfg80211.c | 7 +++
 drivers/net/wireless/quantenna/qtnfmac/core.c | 2 +-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c 
b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
index 32bf72c0399f..ac1b9bd5ed90 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/cfg80211.c
@@ -581,9 +581,9 @@ qtnf_del_station(struct wiphy *wiphy, struct net_device 
*dev,
return ret;
 }
 
-static void qtnf_scan_timeout(unsigned long data)
+static void qtnf_scan_timeout(struct timer_list *t)
 {
-   struct qtnf_wmac *mac = (struct qtnf_wmac *)data;
+   struct qtnf_wmac *mac = from_timer(mac, t, scan_timeout);
 
pr_warn("mac%d scan timed out\n", mac->macid);
qtnf_scan_done(mac, true);
@@ -602,8 +602,7 @@ qtnf_scan(struct wiphy *wiphy, struct cfg80211_scan_request 
*request)
return -EFAULT;
}
 
-   mac->scan_timeout.data = (unsigned long)mac;
-   mac->scan_timeout.function = qtnf_scan_timeout;
+   mac->scan_timeout.function = (TIMER_FUNC_TYPE)qtnf_scan_timeout;
mod_timer(>scan_timeout,
  jiffies + QTNF_SCAN_TIMEOUT_SEC * HZ);
 
diff --git a/drivers/net/wireless/quantenna/qtnfmac/core.c 
b/drivers/net/wireless/quantenna/qtnfmac/core.c
index 5e60180482d1..aa7f146278a7 100644
--- a/drivers/net/wireless/quantenna/qtnfmac/core.c
+++ b/drivers/net/wireless/quantenna/qtnfmac/core.c
@@ -289,7 +289,7 @@ static struct qtnf_wmac *qtnf_core_mac_alloc(struct 
qtnf_bus *bus,
mac->iflist[i].vifid = i;
qtnf_sta_list_init(>iflist[i].sta_list);
mutex_init(>mac_lock);
-   init_timer(>scan_timeout);
+   setup_timer(>scan_timeout, NULL, 0);
    }
 
qtnf_mac_init_primary_intf(mac);
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] mac80211: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Johannes Berg <johan...@sipsolutions.net>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 net/mac80211/ibss.c |  7 +++
 net/mac80211/ieee80211_i.h  |  3 ++-
 net/mac80211/led.c  | 11 ++-
 net/mac80211/main.c |  3 +--
 net/mac80211/mesh.c | 27 ---
 net/mac80211/mesh.h |  2 +-
 net/mac80211/mesh_hwmp.c|  4 ++--
 net/mac80211/mesh_pathtbl.c |  3 +--
 net/mac80211/mlme.c | 32 ++--
 net/mac80211/ocb.c  | 10 +-
 net/mac80211/sta_info.c |  7 +++
 11 files changed, 50 insertions(+), 59 deletions(-)

diff --git a/net/mac80211/ibss.c b/net/mac80211/ibss.c
index e9c6aa3ed05b..db07e0de9a03 100644
--- a/net/mac80211/ibss.c
+++ b/net/mac80211/ibss.c
@@ -1711,10 +1711,10 @@ void ieee80211_ibss_work(struct ieee80211_sub_if_data 
*sdata)
sdata_unlock(sdata);
 }
 
-static void ieee80211_ibss_timer(unsigned long data)
+static void ieee80211_ibss_timer(struct timer_list *t)
 {
struct ieee80211_sub_if_data *sdata =
-   (struct ieee80211_sub_if_data *) data;
+   from_timer(sdata, t, u.ibss.timer);
 
ieee80211_queue_work(>local->hw, >work);
 }
@@ -1723,8 +1723,7 @@ void ieee80211_ibss_setup_sdata(struct 
ieee80211_sub_if_data *sdata)
 {
struct ieee80211_if_ibss *ifibss = >u.ibss;
 
-   setup_timer(>timer, ieee80211_ibss_timer,
-   (unsigned long) sdata);
+   timer_setup(>timer, ieee80211_ibss_timer, 0);
INIT_LIST_HEAD(>incomplete_stations);
spin_lock_init(>incomplete_lock);
INIT_WORK(>csa_connection_drop_work,
diff --git a/net/mac80211/ieee80211_i.h b/net/mac80211/ieee80211_i.h
index 68f874e73561..885d00b41911 100644
--- a/net/mac80211/ieee80211_i.h
+++ b/net/mac80211/ieee80211_i.h
@@ -1057,6 +1057,7 @@ struct tpt_led_trigger {
const struct ieee80211_tpt_blink *blink_table;
unsigned int blink_table_len;
struct timer_list timer;
+   struct ieee80211_local *local;
unsigned long prev_traffic;
unsigned long tx_bytes, rx_bytes;
unsigned int active, want;
@@ -1932,7 +1933,7 @@ static inline int ieee80211_ac_from_tid(int tid)
 
 void ieee80211_dynamic_ps_enable_work(struct work_struct *work);
 void ieee80211_dynamic_ps_disable_work(struct work_struct *work);
-void ieee80211_dynamic_ps_timer(unsigned long data);
+void ieee80211_dynamic_ps_timer(struct timer_list *t);
 void ieee80211_send_nullfunc(struct ieee80211_local *local,
 struct ieee80211_sub_if_data *sdata,
 bool powersave);
diff --git a/net/mac80211/led.c b/net/mac80211/led.c
index 0505845b7ab8..ba0b507ea691 100644
--- a/net/mac80211/led.c
+++ b/net/mac80211/led.c
@@ -248,10 +248,10 @@ static unsigned long tpt_trig_traffic(struct 
ieee80211_local *local,
return DIV_ROUND_UP(delta, 1024 / 8);
 }
 
-static void tpt_trig_timer(unsigned long data)
+static void tpt_trig_timer(struct timer_list *t)
 {
-   struct ieee80211_local *local = (void *)data;
-   struct tpt_led_trigger *tpt_trig = local->tpt_led_trigger;
+   struct tpt_led_trigger *tpt_trig = from_timer(tpt_trig, t, timer);
+   struct ieee80211_local *local = tpt_trig->local;
struct led_classdev *led_cdev;
unsigned long on, off, tpt;
int i;
@@ -306,8 +306,9 @@ __ieee80211_create_tpt_led_trigger(struct ieee80211_hw *hw,
tpt_trig->blink_table = blink_table;
tpt_trig->blink_table_len = blink_table_len;
tpt_trig->want = flags;
+   tpt_trig->local = local;
 
-   setup_timer(_trig->timer, tpt_trig_timer, (unsigned long)local);
+   timer_setup(_trig->timer, tpt_trig_timer, 0);
 
local->tpt_led_trigger = tpt_trig;
 
@@ -326,7 +327,7 @@ static void ieee80211_start_tpt_led_trig(struct 
ieee80211_local *local)
tpt_trig_traffic(local, tpt_trig);
tpt_trig->running = true;
 
-   tpt_trig_timer((unsigned long)local);
+   tpt_trig_timer(_trig->timer);
mod_timer(_trig->timer, round_jiffies(jiffies + HZ));
 }
 
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 8aa1f5b6a051..e054a2fd8d38 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -633,8 +633,7 @@ struct ieee80211_hw *ieee80211_alloc_hw_nm(size_t 
priv_data_len,
  ieee80211_dynamic_ps_enable_work);
INIT_WORK(>dynamic_ps_disable_work,
  ieee80211_dynamic_ps_disable_work);
-   setup_timer(>dynamic_ps_timer,
-   ieee80211_dynamic_ps_ti

[PATCH] staging/wilc1000: Convert timers to use timer_setup()

2017-10-16 Thread Kees Cook
As part of removing the timer_list.data field, this converts the wilc1000
driver to using from_timer and an explicit per-timer data field, since
there doesn't appear to be a way to sanely resolve vif from hif_drv.

Cc: Aditya Shankar <aditya.shan...@microchip.com>
Cc: Ganesh Krishna <ganesh.kris...@microchip.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: linux-wireless@vger.kernel.org
Cc: de...@driverdev.osuosl.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/staging/wilc1000/host_interface.c | 39 +--
 drivers/staging/wilc1000/host_interface.h |  5 +++
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c |  4 +--
 3 files changed, 28 insertions(+), 20 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 7b620658ec38..c16f96308a97 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -238,6 +238,7 @@ static struct completion hif_driver_comp;
 static struct completion hif_wait_response;
 static struct mutex hif_deinit_lock;
 static struct timer_list periodic_rssi;
+static struct wilc_vif *periodic_rssi_vif;
 
 u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
 
@@ -2272,7 +2273,7 @@ static int Handle_RemainOnChan(struct wilc_vif *vif,
 ERRORHANDLER:
{
P2P_LISTEN_STATE = 1;
-   hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
+   hif_drv->remain_on_ch_timer_vif = vif;
mod_timer(_drv->remain_on_ch_timer,
  jiffies +
  msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
@@ -2360,11 +2361,13 @@ static u32 Handle_ListenStateExpired(struct wilc_vif 
*vif,
return result;
 }
 
-static void ListenTimerCB(unsigned long arg)
+static void ListenTimerCB(struct timer_list *t)
 {
+   struct host_if_drv *hif_drv = from_timer(hif_drv, t,
+ remain_on_ch_timer);
+   struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
s32 result = 0;
struct host_if_msg msg;
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
 
del_timer(>hif_drv->remain_on_ch_timer);
 
@@ -2643,9 +2646,10 @@ static void host_if_work(struct work_struct *work)
complete(_thread_comp);
 }
 
-static void TimerCB_Scan(unsigned long arg)
+static void TimerCB_Scan(struct timer_list *t)
 {
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
+   struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
+   struct wilc_vif *vif = hif_drv->scan_timer_vif;
struct host_if_msg msg;
 
memset(, 0, sizeof(struct host_if_msg));
@@ -2655,9 +2659,11 @@ static void TimerCB_Scan(unsigned long arg)
wilc_enqueue_cmd();
 }
 
-static void TimerCB_Connect(unsigned long arg)
+static void TimerCB_Connect(struct timer_list *t)
 {
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
+   struct host_if_drv *hif_drv = from_timer(hif_drv, t,
+ connect_timer);
+   struct wilc_vif *vif = hif_drv->connect_timer_vif;
struct host_if_msg msg;
 
memset(, 0, sizeof(struct host_if_msg));
@@ -3040,7 +3046,7 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, 
const u8 *ssid,
return -EFAULT;
}
 
-   hif_drv->connect_timer.data = (unsigned long)vif;
+   hif_drv->connect_timer_vif = vif;
mod_timer(_drv->connect_timer,
  jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
 
@@ -3283,7 +3289,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 
scan_type,
return -EINVAL;
}
 
-   hif_drv->scan_timer.data = (unsigned long)vif;
+   hif_drv->scan_timer_vif = vif;
mod_timer(_drv->scan_timer,
  jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
 
@@ -3309,9 +3315,9 @@ int wilc_hif_set_cfg(struct wilc_vif *vif,
return wilc_enqueue_cmd();
 }
 
-static void GetPeriodicRSSI(unsigned long arg)
+static void GetPeriodicRSSI(struct timer_list *unused)
 {
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
+   struct wilc_vif *vif = periodic_rssi_vif;
 
if (!vif->hif_drv) {
netdev_err(vif->ndev, "Driver handler is NULL\n");
@@ -3321,7 +3327,6 @@ static void GetPeriodicRSSI(unsigned long arg)
if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
wilc_get_statistics(vif, >wilc->dummy_statistics);
 
-   periodic_rssi.data = (unsigned long)vif;
mod_timer(_rssi, jiffies + msecs_to_jiffies(5000));
 }
 
@@ -3374,14 +3379,14 @@ int wilc_init(struct net_device *dev, struct 
host_if_drv **hif_drv_handler)
goto _fail_;
}
 
-   setup_timer(_rssi, GetPerio

Re: [PATCH] rtl8xxxu: mark expected switch fall-throughs

2017-10-11 Thread Kees Cook
On Wed, Oct 11, 2017 at 7:32 AM, Gustavo A. R. Silva
<garsi...@embeddedor.com> wrote:
> Quoting Jes Sorensen <jes.soren...@gmail.com>:
>> On 10/11/2017 04:41 AM, Kalle Valo wrote:
>>> Jes Sorensen <jes.soren...@gmail.com> writes:
>>>> On 10/10/2017 03:30 PM, Gustavo A. R. Silva wrote:
>>>>>
>>>>> In preparation to enabling -Wimplicit-fallthrough, mark switch cases
>>>>> where we are expecting to fall through.
>>>>
>>>> While this isn't harmful, to me this looks like pointless patch churn
>>>> for zero gain and it's just ugly.
>>>
>>> In general I find it useful to mark fall through cases. And it's just a
>>> comment with two words, so they cannot hurt your eyes that much.
>>
>> I don't see them being harmful in the code, but I don't see them of much
>> use either. If it happened as part of natural code development, fine. My
>> objection is to people running around doing this systematically causing
>> patch churn for little to zero gain.
>
> I understand that you think this is of zero gain for you, but as Florian
> Fainelli pointed out:
>
> "That is the canonical way to tell static analyzers and compilers that
> fall throughs are wanted and not accidental mistakes in the code. For
> people that deal with these kinds of errors, it's quite helpful, unless
> you suggest disabling that particular GCC warning specific for that
> file/directory?"
>
> this is very helpful for people working on fixing issues reported by static
> analyzers. It saves a huge amount of time when dealing with False Positives.
> Also, there are cases when an apparently intentional fall-through turns out
> to be an actual missing break or continue.
>
> So there is an ongoing effort to detect such cases and avoid them to show up
> in the future by at least warning people about a potential issue in their
> code. And this is helpful for everybody.

This is an unfortunate omission in the C language, and thankfully both
gcc and clang have stepped up to solve this the same way static
analyzers have solved it. It's not exactly pretty, but it does both
document the intention for humans and provide a way for analyzers to
report issues. Having the compiler help us not make mistakes is quite
handy, and with Gustavo grinding through all the Coverity warnings,
he's found actual bugs with missing "break"s, so I think this has a
demonstrable benefit to the code-base as a whole. It makes things
unambiguous to someone else reviewing the code.

-Kees

-- 
Kees Cook
Pixel Security


Re: net/wireless/ray_cs: Convert timers to use

2017-10-10 Thread Kees Cook
On Tue, Oct 10, 2017 at 1:26 AM, Kalle Valo <kv...@codeaurora.org> wrote:
> Kees Cook <keesc...@chromium.org> wrote:
>
>> In preparation for unconditionally passing the struct timer_list pointer to
>> all timer callbacks, switch to using the new timer_setup() and from_timer()
>> to pass the timer pointer explicitly.
>>
>> Cc: Kalle Valo <kv...@codeaurora.org>
>> Cc: linux-wireless@vger.kernel.org
>> Cc: net...@vger.kernel.org
>> Cc: Thomas Gleixner <t...@linutronix.de>
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>
> I'll apply this once I have fast forwarded wireless-drivers-next to
> -rc3. I'll also fix the title, what was it supposed to say?

It was truncated from "net/wireless/ray_cs: Convert timers to use
timer_setup()"; I've fixed that glitch in my workflow now.

> Patch set to Awaiting Upstream.

Thanks!

-Kees

-- 
Kees Cook
Pixel Security


[PATCH] timer: Remove meaningless .data/.function assignments

2017-10-09 Thread Kees Cook
Several timer users needlessly reset their .function/.data fields during
their timer callback, but nothing else changes them. Some users do not
use their .data field at all. Each instance is removed here.

Cc: Krzysztof Halasa <k...@pm.waw.pl>
Cc: Aditya Shankar <aditya.shan...@microchip.com>
Cc: Ganesh Krishna <ganesh.kris...@microchip.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Jens Axboe <ax...@fb.com>
Cc: net...@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Cc: de...@driverdev.osuosl.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
Acked-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> # for staging
Acked-by: Krzysztof Halasa <k...@pm.waw.pl> # for wan/hdlc*
Acked-by: Jens Axboe <ax...@kernel.dk> # for amiflop
---
This should go via the timer/core tree, please. It's been acked by each
of the maintainers. Thanks!
---
 drivers/block/amiflop.c   | 3 +--
 drivers/net/wan/hdlc_cisco.c  | 2 --
 drivers/net/wan/hdlc_fr.c | 2 --
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 +---
 4 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index 49908c74bfcb..4e3fb9f104af 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -323,7 +323,7 @@ static void fd_deselect (int drive)
 
 }
 
-static void motor_on_callback(unsigned long nr)
+static void motor_on_callback(unsigned long ignored)
 {
if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
complete_all(_on_completion);
@@ -344,7 +344,6 @@ static int fd_motor_on(int nr)
fd_select(nr);
 
reinit_completion(_on_completion);
-   motor_on_timer.data = nr;
mod_timer(_on_timer, jiffies + HZ/2);
 
on_attempts = 10;
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index a408abc25512..f4b0ab34f048 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -276,8 +276,6 @@ static void cisco_timer(unsigned long arg)
spin_unlock(>lock);
 
st->timer.expires = jiffies + st->settings.interval * HZ;
-   st->timer.function = cisco_timer;
-   st->timer.data = arg;
add_timer(>timer);
 }
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index 78596e42a3f3..07f265fa2826 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -644,8 +644,6 @@ static void fr_timer(unsigned long arg)
state(hdlc)->settings.t391 * HZ;
}
 
-   state(hdlc)->timer.function = fr_timer;
-   state(hdlc)->timer.data = arg;
add_timer((hdlc)->timer);
 }
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index ac5aaafa461c..60f088babf27 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -266,7 +266,7 @@ static void update_scan_time(void)
last_scanned_shadow[i].time_scan = jiffies;
 }
 
-static void remove_network_from_shadow(unsigned long arg)
+static void remove_network_from_shadow(unsigned long unused)
 {
unsigned long now = jiffies;
int i, j;
@@ -287,7 +287,6 @@ static void remove_network_from_shadow(unsigned long arg)
}
 
if (last_scanned_cnt != 0) {
-   hAgingTimer.data = arg;
mod_timer(, jiffies + msecs_to_jiffies(AGING_TIME));
}
 }
@@ -304,7 +303,6 @@ static int is_network_in_shadow(struct network_info 
*pstrNetworkInfo,
int i;
 
if (last_scanned_cnt == 0) {
-   hAgingTimer.data = (unsigned long)user_void;
mod_timer(, jiffies + msecs_to_jiffies(AGING_TIME));
state = -1;
} else {
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH v2] net/mac80211/mesh_plink: Convert timers to use timer_setup()

2017-10-05 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly. This requires adding a pointer back
to the sta_info since container_of() can't resolve the sta_info.

Cc: Johannes Berg <johan...@sipsolutions.net>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
This requires commit 686fef928bba ("timer: Prepare to change timer
callback argument type") in v4.14-rc3, but should be otherwise
stand-alone.

v2:
- make mesh_plink_timer non-static and use it in timer_setup() call directly.
---
 net/mac80211/mesh.h   |  1 +
 net/mac80211/mesh_plink.c | 10 --
 net/mac80211/sta_info.c   |  4 +++-
 net/mac80211/sta_info.h   |  2 ++
 4 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/net/mac80211/mesh.h b/net/mac80211/mesh.h
index 7e5f271e3c30..465b7853edc0 100644
--- a/net/mac80211/mesh.h
+++ b/net/mac80211/mesh.h
@@ -275,6 +275,7 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data 
*sdata,
   u8 *hw_addr, struct ieee802_11_elems *ie);
 bool mesh_peer_accepts_plinks(struct ieee802_11_elems *ie);
 u32 mesh_accept_plinks_update(struct ieee80211_sub_if_data *sdata);
+void mesh_plink_timer(struct timer_list *t);
 void mesh_plink_broken(struct sta_info *sta);
 u32 mesh_plink_deactivate(struct sta_info *sta);
 u32 mesh_plink_open(struct sta_info *sta);
diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index f69c6c38ca43..e79adb4164f3 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -604,8 +604,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data 
*sdata,
ieee80211_mbss_info_change_notify(sdata, changed);
 }
 
-static void mesh_plink_timer(unsigned long data)
+void mesh_plink_timer(struct timer_list *t)
 {
+   struct mesh_sta *mesh = from_timer(mesh, t, plink_timer);
struct sta_info *sta;
u16 reason = 0;
struct ieee80211_sub_if_data *sdata;
@@ -617,7 +618,7 @@ static void mesh_plink_timer(unsigned long data)
 * del_timer_sync() this timer after having made sure
 * it cannot be readded (by deleting the plink.)
 */
-   sta = (struct sta_info *) data;
+   sta = mesh->plink_sta;
 
if (sta->sdata->local->quiescing)
return;
@@ -697,11 +698,8 @@ static void mesh_plink_timer(unsigned long data)
 
 static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout)
 {
-   sta->mesh->plink_timer.expires = jiffies + msecs_to_jiffies(timeout);
-   sta->mesh->plink_timer.data = (unsigned long) sta;
-   sta->mesh->plink_timer.function = mesh_plink_timer;
sta->mesh->plink_timeout = timeout;
-   add_timer(>mesh->plink_timer);
+   mod_timer(>mesh->plink_timer, jiffies + msecs_to_jiffies(timeout));
 }
 
 static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 69615016d5bf..6c254a9d5f11 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -329,10 +329,12 @@ struct sta_info *sta_info_alloc(struct 
ieee80211_sub_if_data *sdata,
sta->mesh = kzalloc(sizeof(*sta->mesh), gfp);
if (!sta->mesh)
goto free;
+   sta->mesh->plink_sta = sta;
spin_lock_init(>mesh->plink_lock);
if (ieee80211_vif_is_mesh(>vif) &&
!sdata->u.mesh.user_mpm)
-   init_timer(>mesh->plink_timer);
+   timer_setup(>mesh->plink_timer, mesh_plink_timer,
+   0);
sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
}
 #endif
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 3acbdfa9f649..21d9760ce5c3 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -344,6 +344,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  * @plink_state: peer link state
  * @plink_timeout: timeout of peer link
  * @plink_timer: peer link watch timer
+ * @plink_sta: peer link watch timer's sta_info
  * @t_offset: timing offset relative to this host
  * @t_offset_setpoint: reference timing offset of this sta to be used when
  * calculating clockdrift
@@ -356,6 +357,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  */
 struct mesh_sta {
    struct timer_list plink_timer;
+   struct sta_info *plink_sta;
 
s64 t_offset;
s64 t_offset_setpoint;
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] net/mac80211/mesh_plink: Convert timers to use

2017-10-04 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly. This requires adding a pointer back
to the sta_info since container_of() can't resolve the sta_info.

Cc: Johannes Berg <johan...@sipsolutions.net>
Cc: "David S. Miller" <da...@davemloft.net>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
This requires commit 686fef928bba ("timer: Prepare to change timer
callback argument type") in v4.14-rc3, but should be otherwise
stand-alone.
---
 net/mac80211/mesh_plink.c | 9 +
 net/mac80211/sta_info.c   | 2 +-
 net/mac80211/sta_info.h   | 2 ++
 3 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/net/mac80211/mesh_plink.c b/net/mac80211/mesh_plink.c
index f69c6c38ca43..fcc02beaee6d 100644
--- a/net/mac80211/mesh_plink.c
+++ b/net/mac80211/mesh_plink.c
@@ -604,8 +604,9 @@ void mesh_neighbour_update(struct ieee80211_sub_if_data 
*sdata,
ieee80211_mbss_info_change_notify(sdata, changed);
 }
 
-static void mesh_plink_timer(unsigned long data)
+static void mesh_plink_timer(struct timer_list *t)
 {
+   struct mesh_sta *mesh = from_timer(mesh, t, plink_timer);
struct sta_info *sta;
u16 reason = 0;
struct ieee80211_sub_if_data *sdata;
@@ -617,7 +618,7 @@ static void mesh_plink_timer(unsigned long data)
 * del_timer_sync() this timer after having made sure
 * it cannot be readded (by deleting the plink.)
 */
-   sta = (struct sta_info *) data;
+   sta = mesh->plink_sta;
 
if (sta->sdata->local->quiescing)
return;
@@ -698,8 +699,8 @@ static void mesh_plink_timer(unsigned long data)
 static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout)
 {
sta->mesh->plink_timer.expires = jiffies + msecs_to_jiffies(timeout);
-   sta->mesh->plink_timer.data = (unsigned long) sta;
-   sta->mesh->plink_timer.function = mesh_plink_timer;
+   sta->mesh->plink_sta = sta;
+   sta->mesh->plink_timer.function = (TIMER_FUNC_TYPE)mesh_plink_timer;
sta->mesh->plink_timeout = timeout;
add_timer(>mesh->plink_timer);
 }
diff --git a/net/mac80211/sta_info.c b/net/mac80211/sta_info.c
index 69615016d5bf..5e5de9455e4e 100644
--- a/net/mac80211/sta_info.c
+++ b/net/mac80211/sta_info.c
@@ -332,7 +332,7 @@ struct sta_info *sta_info_alloc(struct 
ieee80211_sub_if_data *sdata,
spin_lock_init(>mesh->plink_lock);
if (ieee80211_vif_is_mesh(>vif) &&
!sdata->u.mesh.user_mpm)
-   init_timer(>mesh->plink_timer);
+   timer_setup(>mesh->plink_timer, NULL, 0);
sta->mesh->nonpeer_pm = NL80211_MESH_POWER_ACTIVE;
}
 #endif
diff --git a/net/mac80211/sta_info.h b/net/mac80211/sta_info.h
index 3acbdfa9f649..21d9760ce5c3 100644
--- a/net/mac80211/sta_info.h
+++ b/net/mac80211/sta_info.h
@@ -344,6 +344,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  * @plink_state: peer link state
  * @plink_timeout: timeout of peer link
  * @plink_timer: peer link watch timer
+ * @plink_sta: peer link watch timer's sta_info
  * @t_offset: timing offset relative to this host
  * @t_offset_setpoint: reference timing offset of this sta to be used when
  * calculating clockdrift
@@ -356,6 +357,7 @@ DECLARE_EWMA(mesh_fail_avg, 20, 8)
  */
 struct mesh_sta {
struct timer_list plink_timer;
+   struct sta_info *plink_sta;
 
s64 t_offset;
s64 t_offset_setpoint;
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] net/wireless/ray_cs: Convert timers to use

2017-10-04 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
This requires commit 686fef928bba ("timer: Prepare to change timer
callback argument type") in v4.14-rc3, but should be otherwise
stand-alone.
---
 drivers/net/wireless/ray_cs.c | 53 ---
 1 file changed, 24 insertions(+), 29 deletions(-)

diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 170cd504e8ff..d8afcdfca1ed 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -92,7 +92,7 @@ static const struct iw_handler_def ray_handler_def;
 /* Prototypes for raylink functions **/
 static void authenticate(ray_dev_t *local);
 static int build_auth_frame(ray_dev_t *local, UCHAR *dest, int auth_type);
-static void authenticate_timeout(u_long);
+static void authenticate_timeout(struct timer_list *t);
 static int get_free_ccs(ray_dev_t *local);
 static int get_free_tx_ccs(ray_dev_t *local);
 static void init_startup_params(ray_dev_t *local);
@@ -102,7 +102,7 @@ static int ray_init(struct net_device *dev);
 static int interrupt_ecf(ray_dev_t *local, int ccs);
 static void ray_reset(struct net_device *dev);
 static void ray_update_parm(struct net_device *dev, UCHAR objid, UCHAR *value, 
int len);
-static void verify_dl_startup(u_long);
+static void verify_dl_startup(struct timer_list *t);
 
 /* Prototypes for interrpt time functions **/
 static irqreturn_t ray_interrupt(int reg, void *dev_id);
@@ -120,9 +120,8 @@ static void associate(ray_dev_t *local);
 
 /* Card command functions */
 static int dl_startup_params(struct net_device *dev);
-static void join_net(u_long local);
-static void start_net(u_long local);
-/* void start_net(ray_dev_t *local); */
+static void join_net(struct timer_list *t);
+static void start_net(struct timer_list *t);
 
 /*===*/
 /* Parameters that can be set with 'insmod' */
@@ -323,7 +322,7 @@ static int ray_probe(struct pcmcia_device *p_dev)
dev_dbg(_dev->dev, "ray_cs ray_attach calling ether_setup.)\n");
netif_stop_queue(dev);
 
-   init_timer(>timer);
+   timer_setup(>timer, NULL, 0);
 
this_device = p_dev;
return ray_config(p_dev);
@@ -570,8 +569,7 @@ static int dl_startup_params(struct net_device *dev)
local->card_status = CARD_DL_PARAM;
/* Start kernel timer to wait for dl startup to complete. */
local->timer.expires = jiffies + HZ / 2;
-   local->timer.data = (long)local;
-   local->timer.function = verify_dl_startup;
+   local->timer.function = (TIMER_FUNC_TYPE)verify_dl_startup;
add_timer(>timer);
dev_dbg(>dev,
  "ray_cs dl_startup_params started timer for verify_dl_startup\n");
@@ -641,9 +639,9 @@ static void init_startup_params(ray_dev_t *local)
 } /* init_startup_params */
 
 /*===*/
-static void verify_dl_startup(u_long data)
+static void verify_dl_startup(struct timer_list *t)
 {
-   ray_dev_t *local = (ray_dev_t *) data;
+   ray_dev_t *local = from_timer(local, t, timer);
struct ccs __iomem *pccs = ccs_base(local) + local->dl_param_ccs;
UCHAR status;
struct pcmcia_device *link = local->finder;
@@ -676,16 +674,16 @@ static void verify_dl_startup(u_long data)
return;
}
if (local->sparm.b4.a_network_type == ADHOC)
-   start_net((u_long) local);
+   start_net(>timer);
else
-   join_net((u_long) local);
+   join_net(>timer);
 } /* end verify_dl_startup */
 
 /*===*/
 /* Command card to start a network */
-static void start_net(u_long data)
+static void start_net(struct timer_list *t)
 {
-   ray_dev_t *local = (ray_dev_t *) data;
+   ray_dev_t *local = from_timer(local, t, timer);
struct ccs __iomem *pccs;
int ccsindex;
struct pcmcia_device *link = local->finder;
@@ -710,9 +708,9 @@ static void start_net(u_long data)
 
 /*===*/
 /* Command card to join a network */
-static void join_net(u_long data)
+static void join_net(struct timer_list *t)
 {
-   ray_dev_t *local = (ray_dev_t *) data;
+   ray_dev_t *local = from_timer(local, t, timer);
 
struct ccs __iomem *pccs;
in

[PATCH] net/cw1200: Convert timers to use timer_setup()

2017-10-04 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new timer_setup() and from_timer()
to pass the timer pointer explicitly.

Cc: Solomon Peachy <pi...@shaftnet.org>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: linux-wireless@vger.kernel.org
Cc: net...@vger.kernel.org
Cc: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
This requires commit 686fef928bba ("timer: Prepare to change timer
callback argument type") in v4.14-rc3, but should be otherwise
stand-alone.
---
 drivers/net/wireless/st/cw1200/pm.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/st/cw1200/pm.c 
b/drivers/net/wireless/st/cw1200/pm.c
index d2202ae92bdd..ded23df1ac1d 100644
--- a/drivers/net/wireless/st/cw1200/pm.c
+++ b/drivers/net/wireless/st/cw1200/pm.c
@@ -91,7 +91,7 @@ struct cw1200_suspend_state {
u8 prev_ps_mode;
 };
 
-static void cw1200_pm_stay_awake_tmo(unsigned long arg)
+static void cw1200_pm_stay_awake_tmo(struct timer_list *unused)
 {
/* XXX what's the point of this ? */
 }
@@ -101,8 +101,7 @@ int cw1200_pm_init(struct cw1200_pm_state *pm,
 {
spin_lock_init(>lock);
 
-   setup_timer(>stay_awake, cw1200_pm_stay_awake_tmo,
-   (unsigned long)pm);
+   timer_setup(>stay_awake, cw1200_pm_stay_awake_tmo, 0);
 
    return 0;
 }
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] staging/wilc1000: Convert timers to use timer_setup()

2017-10-04 Thread Kees Cook
As part of removing the timer_list.data field, this converts the wilc1000
driver to using from_timer and an explicit per-timer data field, since
there doesn't appear to be a way to sanely resolve vif from hif_drv.

Cc: Aditya Shankar <aditya.shan...@microchip.com>
Cc: Ganesh Krishna <ganesh.kris...@microchip.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: linux-wireless@vger.kernel.org
Cc: de...@driverdev.osuosl.org
Cc: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
This requires commit 686fef928bba ("timer: Prepare to change timer
callback argument type") in v4.14-rc3, but should be otherwise
stand-alone.
---
 drivers/staging/wilc1000/host_interface.c | 39 +--
 drivers/staging/wilc1000/host_interface.h |  5 
 2 files changed, 27 insertions(+), 17 deletions(-)

diff --git a/drivers/staging/wilc1000/host_interface.c 
b/drivers/staging/wilc1000/host_interface.c
index 7b620658ec38..c16f96308a97 100644
--- a/drivers/staging/wilc1000/host_interface.c
+++ b/drivers/staging/wilc1000/host_interface.c
@@ -238,6 +238,7 @@ static struct completion hif_driver_comp;
 static struct completion hif_wait_response;
 static struct mutex hif_deinit_lock;
 static struct timer_list periodic_rssi;
+static struct wilc_vif *periodic_rssi_vif;
 
 u8 wilc_multicast_mac_addr_list[WILC_MULTICAST_TABLE_SIZE][ETH_ALEN];
 
@@ -2272,7 +2273,7 @@ static int Handle_RemainOnChan(struct wilc_vif *vif,
 ERRORHANDLER:
{
P2P_LISTEN_STATE = 1;
-   hif_drv->remain_on_ch_timer.data = (unsigned long)vif;
+   hif_drv->remain_on_ch_timer_vif = vif;
mod_timer(_drv->remain_on_ch_timer,
  jiffies +
  msecs_to_jiffies(pstrHostIfRemainOnChan->duration));
@@ -2360,11 +2361,13 @@ static u32 Handle_ListenStateExpired(struct wilc_vif 
*vif,
return result;
 }
 
-static void ListenTimerCB(unsigned long arg)
+static void ListenTimerCB(struct timer_list *t)
 {
+   struct host_if_drv *hif_drv = from_timer(hif_drv, t,
+ remain_on_ch_timer);
+   struct wilc_vif *vif = hif_drv->remain_on_ch_timer_vif;
s32 result = 0;
struct host_if_msg msg;
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
 
del_timer(>hif_drv->remain_on_ch_timer);
 
@@ -2643,9 +2646,10 @@ static void host_if_work(struct work_struct *work)
complete(_thread_comp);
 }
 
-static void TimerCB_Scan(unsigned long arg)
+static void TimerCB_Scan(struct timer_list *t)
 {
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
+   struct host_if_drv *hif_drv = from_timer(hif_drv, t, scan_timer);
+   struct wilc_vif *vif = hif_drv->scan_timer_vif;
struct host_if_msg msg;
 
memset(, 0, sizeof(struct host_if_msg));
@@ -2655,9 +2659,11 @@ static void TimerCB_Scan(unsigned long arg)
wilc_enqueue_cmd();
 }
 
-static void TimerCB_Connect(unsigned long arg)
+static void TimerCB_Connect(struct timer_list *t)
 {
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
+   struct host_if_drv *hif_drv = from_timer(hif_drv, t,
+ connect_timer);
+   struct wilc_vif *vif = hif_drv->connect_timer_vif;
struct host_if_msg msg;
 
memset(, 0, sizeof(struct host_if_msg));
@@ -3040,7 +3046,7 @@ int wilc_set_join_req(struct wilc_vif *vif, u8 *bssid, 
const u8 *ssid,
return -EFAULT;
}
 
-   hif_drv->connect_timer.data = (unsigned long)vif;
+   hif_drv->connect_timer_vif = vif;
mod_timer(_drv->connect_timer,
  jiffies + msecs_to_jiffies(HOST_IF_CONNECT_TIMEOUT));
 
@@ -3283,7 +3289,7 @@ int wilc_scan(struct wilc_vif *vif, u8 scan_source, u8 
scan_type,
return -EINVAL;
}
 
-   hif_drv->scan_timer.data = (unsigned long)vif;
+   hif_drv->scan_timer_vif = vif;
mod_timer(_drv->scan_timer,
  jiffies + msecs_to_jiffies(HOST_IF_SCAN_TIMEOUT));
 
@@ -3309,9 +3315,9 @@ int wilc_hif_set_cfg(struct wilc_vif *vif,
return wilc_enqueue_cmd();
 }
 
-static void GetPeriodicRSSI(unsigned long arg)
+static void GetPeriodicRSSI(struct timer_list *unused)
 {
-   struct wilc_vif *vif = (struct wilc_vif *)arg;
+   struct wilc_vif *vif = periodic_rssi_vif;
 
if (!vif->hif_drv) {
netdev_err(vif->ndev, "Driver handler is NULL\n");
@@ -3321,7 +3327,6 @@ static void GetPeriodicRSSI(unsigned long arg)
if (vif->hif_drv->hif_state == HOST_IF_CONNECTED)
wilc_get_statistics(vif, >wilc->dummy_statistics);
 
-   periodic_rssi.data = (unsigned long)vif;
mod_timer(_rssi, jiffies + msecs_to_jiffies(5000));
 }
 
@@ -3374,14 +3379,14 @@

[PATCH 00/13] timer: Start conversion to timer_setup()

2017-10-04 Thread Kees Cook
Hi,

This is the first of many timer infrastructure cleanups to simplify the
timer API[1]. All of these patches are expected to land via the timer
tree, so Acks (or corrections) appreciated.

These patches refactor various users of timer API that are NOT just using
init_timer() or setup_timer() (which is the vast majority of users,
and are being converted separately). These changes are focused on the
lesser-used init_timer_*(), TIMER_*INITIALIZER(), and DEFINE_TIMER()
methods of preparing a timer.

Thanks!

-Kees

[1] https://git.kernel.org/linus/686fef928bba6be13cabe639f154af7d72b63120



[PATCH 04/13] timer: Remove init_timer_pinned() in favor of timer_setup()

2017-10-04 Thread Kees Cook
This refactors the only users of init_timer_pinned() to use
the new timer_setup() and from_timer(). Drops the definition of
init_timer_pinned().

Cc: Chris Metcalf <cmetc...@mellanox.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: net...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/ethernet/tile/tilepro.c | 9 -
 include/linux/timer.h   | 2 --
 2 files changed, 4 insertions(+), 7 deletions(-)

diff --git a/drivers/net/ethernet/tile/tilepro.c 
b/drivers/net/ethernet/tile/tilepro.c
index 49ccee4b9aec..56d06282fbde 100644
--- a/drivers/net/ethernet/tile/tilepro.c
+++ b/drivers/net/ethernet/tile/tilepro.c
@@ -608,9 +608,9 @@ static void tile_net_schedule_egress_timer(struct 
tile_net_cpu *info)
  * ISSUE: Maybe instead track number of expected completions, and free
  * only that many, resetting to zero if "pending" is ever false.
  */
-static void tile_net_handle_egress_timer(unsigned long arg)
+static void tile_net_handle_egress_timer(struct timer_list *t)
 {
-   struct tile_net_cpu *info = (struct tile_net_cpu *)arg;
+   struct tile_net_cpu *info = from_timer(info, t, egress_timer);
struct net_device *dev = info->napi.dev;
 
/* The timer is no longer scheduled. */
@@ -1004,9 +1004,8 @@ static void tile_net_register(void *dev_ptr)
BUG();
 
/* Initialize the egress timer. */
-   init_timer_pinned(>egress_timer);
-   info->egress_timer.data = (long)info;
-   info->egress_timer.function = tile_net_handle_egress_timer;
+   timer_setup(>egress_timer, tile_net_handle_egress_timer,
+   TIMER_PINNED);
 
u64_stats_init(>stats.syncp);
 
diff --git a/include/linux/timer.h b/include/linux/timer.h
index b10c4bdc6fbd..9da903562ed4 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -128,8 +128,6 @@ static inline void init_timer_on_stack_key(struct 
timer_list *timer,
 
 #define init_timer(timer)  \
__init_timer((timer), 0)
-#define init_timer_pinned(timer)   \
-   __init_timer((timer), TIMER_PINNED)
 #define init_timer_deferrable(timer)   \
__init_timer((timer), TIMER_DEFERRABLE)
 
-- 
2.7.4



[PATCH 03/13] timer: Remove init_timer_on_stack() in favor of timer_setup_on_stack()

2017-10-04 Thread Kees Cook
Remove uses of init_timer_on_stack() with open-coded function and data
assignments that could be expressed using timer_setup_on_stack(). Several
were removed from the stack entirely since there was a one-to-one mapping
of parent structure to timer, those are switched to using timer_setup()
instead. All related callbacks were adjusted to use from_timer().

Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Pavel Machek <pa...@ucw.cz>
Cc: Len Brown <len.br...@intel.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Stefan Richter <stef...@s5r6.in-berlin.de>
Cc: Sudip Mukherjee <sudipm.mukher...@gmail.com>
Cc: Martin Schwidefsky <schwidef...@de.ibm.com>
Cc: Heiko Carstens <heiko.carst...@de.ibm.com>
Cc: Julian Wiedmann <j...@linux.vnet.ibm.com>
Cc: Ursula Braun <ubr...@linux.vnet.ibm.com>
Cc: Michael Reed <m...@sgi.com>
Cc: "James E.J. Bottomley" <j...@linux.vnet.ibm.com>
Cc: "Martin K. Petersen" <martin.peter...@oracle.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: linux...@vger.kernel.org
Cc: linux1394-de...@lists.sourceforge.net
Cc: linux-s...@vger.kernel.org
Cc: linux-s...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/base/power/main.c   |  8 +++-
 drivers/firewire/core-transaction.c | 10 +-
 drivers/parport/ieee1284.c  | 21 +++--
 drivers/s390/char/tape.h|  1 +
 drivers/s390/char/tape_std.c| 18 ++
 drivers/s390/net/lcs.c  | 16 ++--
 drivers/s390/net/lcs.h  |  1 +
 drivers/scsi/qla1280.c  | 14 +-
 drivers/scsi/qla1280.h  |  1 +
 include/linux/parport.h |  1 +
 include/linux/timer.h   |  2 --
 11 files changed, 36 insertions(+), 57 deletions(-)

diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c
index 770b1539a083..ae47b2ec84b4 100644
--- a/drivers/base/power/main.c
+++ b/drivers/base/power/main.c
@@ -478,9 +478,9 @@ struct dpm_watchdog {
  * There's not much we can do here to recover so panic() to
  * capture a crash-dump in pstore.
  */
-static void dpm_watchdog_handler(unsigned long data)
+static void dpm_watchdog_handler(struct timer_list *t)
 {
-   struct dpm_watchdog *wd = (void *)data;
+   struct dpm_watchdog *wd = from_timer(wd, t, timer);
 
dev_emerg(wd->dev, " DPM device timeout \n");
show_stack(wd->tsk, NULL);
@@ -500,11 +500,9 @@ static void dpm_watchdog_set(struct dpm_watchdog *wd, 
struct device *dev)
wd->dev = dev;
wd->tsk = current;
 
-   init_timer_on_stack(timer);
+   timer_setup_on_stack(timer, dpm_watchdog_handler, 0);
/* use same timeout value for both suspend and resume */
timer->expires = jiffies + HZ * CONFIG_DPM_WATCHDOG_TIMEOUT;
-   timer->function = dpm_watchdog_handler;
-   timer->data = (unsigned long)wd;
add_timer(timer);
 }
 
diff --git a/drivers/firewire/core-transaction.c 
b/drivers/firewire/core-transaction.c
index d6a09b9cd8cc..4372f9e4b0da 100644
--- a/drivers/firewire/core-transaction.c
+++ b/drivers/firewire/core-transaction.c
@@ -137,9 +137,9 @@ int fw_cancel_transaction(struct fw_card *card,
 }
 EXPORT_SYMBOL(fw_cancel_transaction);
 
-static void split_transaction_timeout_callback(unsigned long data)
+static void split_transaction_timeout_callback(struct timer_list *timer)
 {
-   struct fw_transaction *t = (struct fw_transaction *)data;
+   struct fw_transaction *t = from_timer(t, timer, split_timeout_timer);
struct fw_card *card = t->card;
unsigned long flags;
 
@@ -373,8 +373,8 @@ void fw_send_request(struct fw_card *card, struct 
fw_transaction *t, int tcode,
t->tlabel = tlabel;
t->card = card;
t->is_split_transaction = false;
-   setup_timer(>split_timeout_timer,
-   split_transaction_timeout_callback, (unsigned long)t);
+   timer_setup(>split_timeout_timer,
+   split_transaction_timeout_callback, 0);
t->callback = callback;
t->callback_data = callback_data;
 
@@ -423,7 +423,7 @@ int fw_run_transaction(struct fw_card *card, int tcode, int 
destination_id,
struct transaction_callback_data d;
struct fw_transaction t;
 
-   init_timer_on_stack(_timeout_timer);
+   timer_setup_on_stack(_timeout_timer, NULL, 0);
init_completion();
d.payload = payload;
fw_send_request(card, , tcode, destination_id, generation, speed,
diff --git a/drivers/parport/ieee1284.c b/drivers/parport/ieee1284.c
index 74cc6dd982d2..2d1a5c737c6e 100644
--- a/drivers/parport/ieee1284.c
+++ b/drivers/parport/ieee1284.c
@@ -44,10 +44,11 @@ static void parport_ieee1284_wakeup (struct parport *port)
up (>physport->ieee1284.irq

[PATCH 01/13] timer: Convert schedule_timeout() to use from_timer()

2017-10-04 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer to
all timer callbacks, switch to using the new from_timer() helper and passing
the timer pointer explicitly. Since this special timer is on the stack, it
needs to have a wrapper structure to carry state once .data is eliminated.

Cc: John Stultz <john.stu...@linaro.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Stephen Boyd <sb...@codeaurora.org>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 include/linux/timer.h |  8 
 kernel/time/timer.c   | 26 +++---
 2 files changed, 27 insertions(+), 7 deletions(-)

diff --git a/include/linux/timer.h b/include/linux/timer.h
index 6383c528b148..5ef5c9e41a09 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -179,6 +179,14 @@ static inline void timer_setup(struct timer_list *timer,
  (TIMER_DATA_TYPE)timer, flags);
 }
 
+static inline void timer_setup_on_stack(struct timer_list *timer,
+  void (*callback)(struct timer_list *),
+  unsigned int flags)
+{
+   __setup_timer_on_stack(timer, (TIMER_FUNC_TYPE)callback,
+  (TIMER_DATA_TYPE)timer, flags);
+}
+
 #define from_timer(var, callback_timer, timer_fieldname) \
container_of(callback_timer, typeof(*var), timer_fieldname)
 
diff --git a/kernel/time/timer.c b/kernel/time/timer.c
index f2674a056c26..38613ced2324 100644
--- a/kernel/time/timer.c
+++ b/kernel/time/timer.c
@@ -1668,9 +1668,20 @@ void run_local_timers(void)
raise_softirq(TIMER_SOFTIRQ);
 }
 
-static void process_timeout(unsigned long __data)
+/*
+ * Since schedule_timeout()'s timer is defined on the stack, it must store
+ * the target task on the stack as well.
+ */
+struct process_timer {
+   struct timer_list timer;
+   struct task_struct *task;
+};
+
+static void process_timeout(struct timer_list *t)
 {
-   wake_up_process((struct task_struct *)__data);
+   struct process_timer *timeout = from_timer(timeout, t, timer);
+
+   wake_up_process(timeout->task);
 }
 
 /**
@@ -1704,7 +1715,7 @@ static void process_timeout(unsigned long __data)
  */
 signed long __sched schedule_timeout(signed long timeout)
 {
-   struct timer_list timer;
+   struct process_timer timer;
unsigned long expire;
 
switch (timeout)
@@ -1738,13 +1749,14 @@ signed long __sched schedule_timeout(signed long 
timeout)
 
expire = timeout + jiffies;
 
-   setup_timer_on_stack(, process_timeout, (unsigned long)current);
-   __mod_timer(, expire, false);
+   timer.task = current;
+   timer_setup_on_stack(, process_timeout, 0);
+   __mod_timer(, expire, false);
schedule();
-   del_singleshot_timer_sync();
+   del_singleshot_timer_sync();
 
/* Remove the timer from the object tracker */
-   destroy_timer_on_stack();
+   destroy_timer_on_stack();
 
timeout = expire - jiffies;
 
-- 
2.7.4



[PATCH 05/13] timer: Remove init_timer_deferrable() in favor of timer_setup()

2017-10-04 Thread Kees Cook
This refactors the only users of init_timer_deferrable() to use
the new timer_setup() and from_timer(). Removes definition of
init_timer_deferrable().

Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org>
Cc: Michael Ellerman <m...@ellerman.id.au>
Cc: Sebastian Reichel <s...@kernel.org>
Cc: Harish Patil <harish.pa...@cavium.com>
Cc: Manish Chopra <manish.cho...@cavium.com>
Cc: Kalle Valo <kv...@qca.qualcomm.com>
Cc: linuxppc-...@lists.ozlabs.org
Cc: net...@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 arch/powerpc/mm/numa.c   | 12 +--
 drivers/hsi/clients/ssi_protocol.c   | 32 
 drivers/net/ethernet/qlogic/qlge/qlge_main.c | 11 --
 drivers/net/vxlan.c  |  8 +++
 drivers/net/wireless/ath/ath6kl/recovery.c   |  9 
 include/linux/timer.h|  2 --
 6 files changed, 34 insertions(+), 40 deletions(-)

diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index b95c584ce19d..f9b6107d6854 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -1453,7 +1453,7 @@ static void topology_schedule_update(void)
schedule_work(_work);
 }
 
-static void topology_timer_fn(unsigned long ignored)
+static void topology_timer_fn(struct timer_list *unused)
 {
if (prrn_enabled && cpumask_weight(_associativity_changes_mask))
topology_schedule_update();
@@ -1463,14 +1463,11 @@ static void topology_timer_fn(unsigned long ignored)
reset_topology_timer();
}
 }
-static struct timer_list topology_timer =
-   TIMER_INITIALIZER(topology_timer_fn, 0, 0);
+static struct timer_list topology_timer;
 
 static void reset_topology_timer(void)
 {
-   topology_timer.data = 0;
-   topology_timer.expires = jiffies + 60 * HZ;
-   mod_timer(_timer, topology_timer.expires);
+   mod_timer(_timer, jiffies + 60 * HZ);
 }
 
 #ifdef CONFIG_SMP
@@ -1530,7 +1527,8 @@ int start_topology_update(void)
prrn_enabled = 0;
vphn_enabled = 1;
setup_cpu_associativity_change_counters();
-   init_timer_deferrable(_timer);
+   timer_setup(_timer, topology_timer_fn,
+   TIMER_DEFERRABLE);
reset_topology_timer();
}
}
diff --git a/drivers/hsi/clients/ssi_protocol.c 
b/drivers/hsi/clients/ssi_protocol.c
index 93d28c0ec8bf..67af03d3aeb3 100644
--- a/drivers/hsi/clients/ssi_protocol.c
+++ b/drivers/hsi/clients/ssi_protocol.c
@@ -464,10 +464,10 @@ static void ssip_error(struct hsi_client *cl)
hsi_async_read(cl, msg);
 }
 
-static void ssip_keep_alive(unsigned long data)
+static void ssip_keep_alive(struct timer_list *t)
 {
-   struct hsi_client *cl = (struct hsi_client *)data;
-   struct ssi_protocol *ssi = hsi_client_drvdata(cl);
+   struct ssi_protocol *ssi = from_timer(ssi, t, keep_alive);
+   struct hsi_client *cl = ssi->cl;
 
dev_dbg(>device, "Keep alive kick in: m(%d) r(%d) s(%d)\n",
ssi->main_state, ssi->recv_state, ssi->send_state);
@@ -490,9 +490,19 @@ static void ssip_keep_alive(unsigned long data)
spin_unlock(>lock);
 }
 
-static void ssip_wd(unsigned long data)
+static void ssip_rx_wd(struct timer_list *t)
+{
+   struct ssi_protocol *ssi = from_timer(ssi, t, rx_wd);
+   struct hsi_client *cl = ssi->cl;
+
+   dev_err(>device, "Watchdog trigerred\n");
+   ssip_error(cl);
+}
+
+static void ssip_tx_wd(unsigned long data)
 {
-   struct hsi_client *cl = (struct hsi_client *)data;
+   struct ssi_protocol *ssi = from_timer(ssi, t, tx_wd);
+   struct hsi_client *cl = ssi->cl;
 
dev_err(>device, "Watchdog trigerred\n");
ssip_error(cl);
@@ -1084,15 +1094,9 @@ static int ssi_protocol_probe(struct device *dev)
}
 
spin_lock_init(>lock);
-   init_timer_deferrable(>rx_wd);
-   init_timer_deferrable(>tx_wd);
-   init_timer(>keep_alive);
-   ssi->rx_wd.data = (unsigned long)cl;
-   ssi->rx_wd.function = ssip_wd;
-   ssi->tx_wd.data = (unsigned long)cl;
-   ssi->tx_wd.function = ssip_wd;
-   ssi->keep_alive.data = (unsigned long)cl;
-   ssi->keep_alive.function = ssip_keep_alive;
+   timer_setup(>rx_wd, ssip_rx_wd, TIMER_DEFERRABLE);
+   timer_setup(>tx_wd, ssip_tx_wd, TIMER_DEFERRABLE);
+   timer_setup(>keep_alive, ssip_keep_alive, 0);
INIT_LIST_HEAD(>txqueue);
INIT_LIST_HEAD(>cmdqueue);
atomic_set(>tx_usecnt, 0);
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c 
b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 9feec7009443..29fea74bff2e 100644
--- a/drivers/ne

[PATCH 08/13] timer: Remove unused static initializer macros

2017-10-04 Thread Kees Cook
This removes the now unused TIMER_*INITIALIZER macros:

TIMER_INITIALIZER
TIMER_PINNED_INITIALIZER
TIMER_DEFERRED_INITIALIZER
TIMER_PINNED_DEFERRED_INITIALIZER

Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 include/linux/timer.h | 12 
 1 file changed, 12 deletions(-)

diff --git a/include/linux/timer.h b/include/linux/timer.h
index 4f7476e4a727..a33220311361 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -73,18 +73,6 @@ struct timer_list {
__FILE__ ":" __stringify(__LINE__)) \
}
 
-#define TIMER_INITIALIZER(_function, _expires, _data)  \
-   __TIMER_INITIALIZER((_function), (_expires), (_data), 0)
-
-#define TIMER_PINNED_INITIALIZER(_function, _expires, _data)   \
-   __TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_PINNED)
-
-#define TIMER_DEFERRED_INITIALIZER(_function, _expires, _data) \
-   __TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_DEFERRABLE)
-
-#define TIMER_PINNED_DEFERRED_INITIALIZER(_function, _expires, _data)  \
-   __TIMER_INITIALIZER((_function), (_expires), (_data), TIMER_DEFERRABLE 
| TIMER_PINNED)
-
 #define DEFINE_TIMER(_name, _function, _expires, _data)\
struct timer_list _name =   \
__TIMER_INITIALIZER(_function, _expires, _data, 0)
-- 
2.7.4



[PATCH 10/13] timer: Remove expires and data arguments from DEFINE_TIMER

2017-10-04 Thread Kees Cook
Drop the arguments from the macro and adjust all callers with the
following script:

  perl -pi -e 's/DEFINE_TIMER\((.*), 0, 0\);/DEFINE_TIMER($1);/g;' \
$(git grep DEFINE_TIMER | cut -d: -f1 | sort -u | grep -v timer.h)

Signed-off-by: Kees Cook <keesc...@chromium.org>
Acked-by: Geert Uytterhoeven <ge...@linux-m68k.org> # for m68k parts
---
 arch/arm/mach-ixp4xx/dsmg600-setup.c  | 2 +-
 arch/arm/mach-ixp4xx/nas100d-setup.c  | 2 +-
 arch/m68k/amiga/amisound.c| 2 +-
 arch/m68k/mac/macboing.c  | 2 +-
 arch/mips/mti-malta/malta-display.c   | 2 +-
 arch/parisc/kernel/pdc_cons.c | 2 +-
 arch/s390/mm/cmm.c| 2 +-
 drivers/atm/idt77105.c| 4 ++--
 drivers/atm/iphase.c  | 2 +-
 drivers/block/ataflop.c   | 8 
 drivers/char/dtlk.c   | 2 +-
 drivers/char/hangcheck-timer.c| 2 +-
 drivers/char/nwbutton.c   | 2 +-
 drivers/char/rtc.c| 2 +-
 drivers/input/touchscreen/s3c2410_ts.c| 2 +-
 drivers/net/cris/eth_v10.c| 6 +++---
 drivers/net/hamradio/yam.c| 2 +-
 drivers/net/wireless/atmel/at76c50x-usb.c | 2 +-
 drivers/staging/speakup/main.c| 2 +-
 drivers/staging/speakup/synth.c   | 2 +-
 drivers/tty/cyclades.c| 2 +-
 drivers/tty/isicom.c  | 2 +-
 drivers/tty/moxa.c| 2 +-
 drivers/tty/rocket.c  | 2 +-
 drivers/tty/vt/keyboard.c | 2 +-
 drivers/tty/vt/vt.c   | 2 +-
 drivers/watchdog/alim7101_wdt.c   | 2 +-
 drivers/watchdog/machzwd.c| 2 +-
 drivers/watchdog/mixcomwd.c   | 2 +-
 drivers/watchdog/sbc60xxwdt.c | 2 +-
 drivers/watchdog/sc520_wdt.c  | 2 +-
 drivers/watchdog/via_wdt.c| 2 +-
 drivers/watchdog/w83877f_wdt.c| 2 +-
 drivers/xen/grant-table.c | 2 +-
 fs/pstore/platform.c  | 2 +-
 include/linux/timer.h | 4 ++--
 kernel/irq/spurious.c | 2 +-
 lib/random32.c| 2 +-
 net/atm/mpc.c | 2 +-
 net/decnet/dn_route.c | 2 +-
 net/ipv6/ip6_flowlabel.c  | 2 +-
 net/netrom/nr_loopback.c  | 2 +-
 security/keys/gc.c| 2 +-
 sound/oss/midibuf.c   | 2 +-
 sound/oss/soundcard.c | 2 +-
 sound/oss/sys_timer.c | 2 +-
 sound/oss/uart6850.c  | 2 +-
 47 files changed, 54 insertions(+), 54 deletions(-)

diff --git a/arch/arm/mach-ixp4xx/dsmg600-setup.c 
b/arch/arm/mach-ixp4xx/dsmg600-setup.c
index b3bd0e137f6d..b3689a141ec6 100644
--- a/arch/arm/mach-ixp4xx/dsmg600-setup.c
+++ b/arch/arm/mach-ixp4xx/dsmg600-setup.c
@@ -174,7 +174,7 @@ static int power_button_countdown;
 #define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
 
 static void dsmg600_power_handler(unsigned long data);
-static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler, 0, 0);
+static DEFINE_TIMER(dsmg600_power_timer, dsmg600_power_handler);
 
 static void dsmg600_power_handler(unsigned long data)
 {
diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c 
b/arch/arm/mach-ixp4xx/nas100d-setup.c
index 4e0f762bc651..562d05f9888e 100644
--- a/arch/arm/mach-ixp4xx/nas100d-setup.c
+++ b/arch/arm/mach-ixp4xx/nas100d-setup.c
@@ -197,7 +197,7 @@ static int power_button_countdown;
 #define PBUTTON_HOLDDOWN_COUNT 4 /* 2 secs */
 
 static void nas100d_power_handler(unsigned long data);
-static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler, 0, 0);
+static DEFINE_TIMER(nas100d_power_timer, nas100d_power_handler);
 
 static void nas100d_power_handler(unsigned long data)
 {
diff --git a/arch/m68k/amiga/amisound.c b/arch/m68k/amiga/amisound.c
index 90a60d758f8b..a23f48181fd6 100644
--- a/arch/m68k/amiga/amisound.c
+++ b/arch/m68k/amiga/amisound.c
@@ -66,7 +66,7 @@ void __init amiga_init_sound(void)
 }
 
 static void nosound( unsigned long ignored );
-static DEFINE_TIMER(sound_timer, nosound, 0, 0);
+static DEFINE_TIMER(sound_timer, nosound);
 
 void amiga_mksound( unsigned int hz, unsigned int ticks )
 {
diff --git a/arch/m68k/mac/macboing.c b/arch/m68k/mac/macboing.c
index ffaa1f6439ae..9a52aff183d0 100644
--- a/arch/m68k/mac/macboing.c
+++ b/arch/m68k/mac/macboing.c
@@ -56,7 +56,7 @@ static void ( *mac_special_bell )( unsigned int, unsigned 
int, unsigned int );
 /*
  * our timer to start/continue/stop the bell
  */
-static DEFINE_TIMER(mac_sound_timer, mac_nosound, 0, 0);
+static DEFINE_TIMER(mac_sound_timer, mac_nosound);
 
 /*
  * Sort of initialize the sound chip (called from mac_mksound on the first
diff --git a/arch/mips/mti-malta/malta-display.c 
b/arch/mips/mti-malta/malta-display.c
index ac813158b9b8..063de44

[PATCH 11/13] timer: Remove expires argument from __TIMER_INITIALIZER()

2017-10-04 Thread Kees Cook
The expires field is normally initialized during the first mod_timer()
call. It was unused by all callers, so remove it from the macro.

Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 include/linux/kthread.h   | 2 +-
 include/linux/timer.h | 5 ++---
 include/linux/workqueue.h | 2 +-
 3 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 82e197eeac91..0d622b350d3f 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -117,7 +117,7 @@ struct kthread_delayed_work {
 #define KTHREAD_DELAYED_WORK_INIT(dwork, fn) { \
.work = KTHREAD_WORK_INIT((dwork).work, (fn)),  \
.timer = __TIMER_INITIALIZER(kthread_delayed_work_timer_fn, \
-0, (unsigned long)&(dwork),\
+(unsigned long)&(dwork),   \
 TIMER_IRQSAFE),\
}
 
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 91e5a2cc81b5..10685c33e679 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -63,10 +63,9 @@ struct timer_list {
 
 #define TIMER_TRACE_FLAGMASK   (TIMER_MIGRATING | TIMER_DEFERRABLE | 
TIMER_PINNED | TIMER_IRQSAFE)
 
-#define __TIMER_INITIALIZER(_function, _expires, _data, _flags) { \
+#define __TIMER_INITIALIZER(_function, _data, _flags) {\
.entry = { .next = TIMER_ENTRY_STATIC },\
.function = (_function),\
-   .expires = (_expires),  \
.data = (_data),\
.flags = (_flags),  \
__TIMER_LOCKDEP_MAP_INITIALIZER(\
@@ -75,7 +74,7 @@ struct timer_list {
 
 #define DEFINE_TIMER(_name, _function) \
struct timer_list _name =   \
-   __TIMER_INITIALIZER(_function, 0, 0, 0)
+   __TIMER_INITIALIZER(_function, 0, 0)
 
 void init_timer_key(struct timer_list *timer, unsigned int flags,
const char *name, struct lock_class_key *key);
diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index 1c49431f3121..f4960260feaf 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -176,7 +176,7 @@ struct execute_work {
 #define __DELAYED_WORK_INITIALIZER(n, f, tflags) { \
.work = __WORK_INITIALIZER((n).work, (f)),  \
.timer = __TIMER_INITIALIZER(delayed_work_timer_fn, \
-0, (unsigned long)&(n),\
+(unsigned long)&(n),   \
 (tflags) | TIMER_IRQSAFE), \
}
 
-- 
2.7.4



[PATCH 13/13] workqueue: Convert callback to use from_timer()

2017-10-04 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer
to all timer callbacks, switch workqueue to use from_timer() and pass the
timer pointer explicitly.

Cc: Tejun Heo <t...@kernel.org>
Cc: Lai Jiangshan <jiangshan...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 include/linux/workqueue.h | 15 ---
 kernel/workqueue.c|  7 +++
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/include/linux/workqueue.h b/include/linux/workqueue.h
index f4960260feaf..f3c47a05fd06 100644
--- a/include/linux/workqueue.h
+++ b/include/linux/workqueue.h
@@ -17,7 +17,7 @@ struct workqueue_struct;
 
 struct work_struct;
 typedef void (*work_func_t)(struct work_struct *work);
-void delayed_work_timer_fn(unsigned long __data);
+void delayed_work_timer_fn(struct timer_list *t);
 
 /*
  * The first word is the work queue pointer and the flags rolled into
@@ -175,8 +175,8 @@ struct execute_work {
 
 #define __DELAYED_WORK_INITIALIZER(n, f, tflags) { \
.work = __WORK_INITIALIZER((n).work, (f)),  \
-   .timer = __TIMER_INITIALIZER(delayed_work_timer_fn, \
-(unsigned long)&(n),   \
+   .timer = __TIMER_INITIALIZER((TIMER_FUNC_TYPE)delayed_work_timer_fn,\
+(TIMER_DATA_TYPE)&(n.timer),   \
 (tflags) | TIMER_IRQSAFE), \
}
 
@@ -241,8 +241,9 @@ static inline unsigned int work_static(struct work_struct 
*work) { return 0; }
 #define __INIT_DELAYED_WORK(_work, _func, _tflags) \
do {\
INIT_WORK(&(_work)->work, (_func)); \
-   __setup_timer(&(_work)->timer, delayed_work_timer_fn,   \
- (unsigned long)(_work),   \
+   __setup_timer(&(_work)->timer,  \
+ (TIMER_FUNC_TYPE)delayed_work_timer_fn,   \
+ (TIMER_DATA_TYPE)&(_work)->timer, \
  (_tflags) | TIMER_IRQSAFE);   \
} while (0)
 
@@ -250,8 +251,8 @@ static inline unsigned int work_static(struct work_struct 
*work) { return 0; }
do {\
INIT_WORK_ONSTACK(&(_work)->work, (_func)); \
__setup_timer_on_stack(&(_work)->timer, \
-  delayed_work_timer_fn,   \
-  (unsigned long)(_work),  \
+  (TIMER_FUNC_TYPE)delayed_work_timer_fn,\
+  (TIMER_DATA_TYPE)&(_work)->timer,\
   (_tflags) | TIMER_IRQSAFE);  \
} while (0)
 
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index a5361fc6215d..c77fdf6bf24f 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -1492,9 +1492,9 @@ bool queue_work_on(int cpu, struct workqueue_struct *wq,
 }
 EXPORT_SYMBOL(queue_work_on);
 
-void delayed_work_timer_fn(unsigned long __data)
+void delayed_work_timer_fn(struct timer_list *t)
 {
-   struct delayed_work *dwork = (struct delayed_work *)__data;
+   struct delayed_work *dwork = from_timer(dwork, t, timer);
 
/* should have been called from irqsafe timer with irq already off */
__queue_work(dwork->cpu, dwork->wq, >work);
@@ -1508,8 +1508,7 @@ static void __queue_delayed_work(int cpu, struct 
workqueue_struct *wq,
struct work_struct *work = >work;
 
WARN_ON_ONCE(!wq);
-   WARN_ON_ONCE(timer->function != delayed_work_timer_fn ||
-timer->data != (unsigned long)dwork);
+   WARN_ON_ONCE(timer->function != (TIMER_FUNC_TYPE)delayed_work_timer_fn);
WARN_ON_ONCE(timer_pending(timer));
WARN_ON_ONCE(!list_empty(>entry));
 
-- 
2.7.4



[PATCH 12/13] kthread: Convert callback to use from_timer()

2017-10-04 Thread Kees Cook
In preparation for unconditionally passing the struct timer_list pointer
to all timer callbacks, switch kthread to use from_timer() and pass the
timer pointer explicitly.

Cc: Andrew Morton <a...@linux-foundation.org>
Cc: Petr Mladek <pmla...@suse.com>
Cc: Tejun Heo <t...@kernel.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: Oleg Nesterov <o...@redhat.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 include/linux/kthread.h | 10 +-
 kernel/kthread.c| 10 --
 2 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/include/linux/kthread.h b/include/linux/kthread.h
index 0d622b350d3f..35cbe3b0ce5b 100644
--- a/include/linux/kthread.h
+++ b/include/linux/kthread.h
@@ -75,7 +75,7 @@ extern int tsk_fork_get_node(struct task_struct *tsk);
  */
 struct kthread_work;
 typedef void (*kthread_work_func_t)(struct kthread_work *work);
-void kthread_delayed_work_timer_fn(unsigned long __data);
+void kthread_delayed_work_timer_fn(struct timer_list *t);
 
 enum {
KTW_FREEZABLE   = 1 << 0,   /* freeze during suspend */
@@ -116,8 +116,8 @@ struct kthread_delayed_work {
 
 #define KTHREAD_DELAYED_WORK_INIT(dwork, fn) { \
.work = KTHREAD_WORK_INIT((dwork).work, (fn)),  \
-   .timer = __TIMER_INITIALIZER(kthread_delayed_work_timer_fn, \
-(unsigned long)&(dwork),   \
+   .timer = 
__TIMER_INITIALIZER((TIMER_FUNC_TYPE)kthread_delayed_work_timer_fn,\
+(TIMER_DATA_TYPE)&(dwork.timer),   \
 TIMER_IRQSAFE),\
}
 
@@ -164,8 +164,8 @@ extern void __kthread_init_worker(struct kthread_worker 
*worker,
do {\
kthread_init_work(&(dwork)->work, (fn));\
__setup_timer(&(dwork)->timer,  \
- kthread_delayed_work_timer_fn,\
- (unsigned long)(dwork),   \
+ (TIMER_FUNC_TYPE)kthread_delayed_work_timer_fn,\
+ (TIMER_DATA_TYPE)&(dwork)->timer, \
  TIMER_IRQSAFE);   \
} while (0)
 
diff --git a/kernel/kthread.c b/kernel/kthread.c
index 1c19edf82427..ba3992c8c375 100644
--- a/kernel/kthread.c
+++ b/kernel/kthread.c
@@ -798,15 +798,14 @@ EXPORT_SYMBOL_GPL(kthread_queue_work);
 /**
  * kthread_delayed_work_timer_fn - callback that queues the associated kthread
  * delayed work when the timer expires.
- * @__data: pointer to the data associated with the timer
+ * @t: pointer to the expired timer
  *
  * The format of the function is defined by struct timer_list.
  * It should have been called from irqsafe timer with irq already off.
  */
-void kthread_delayed_work_timer_fn(unsigned long __data)
+void kthread_delayed_work_timer_fn(struct timer_list *t)
 {
-   struct kthread_delayed_work *dwork =
-   (struct kthread_delayed_work *)__data;
+   struct kthread_delayed_work *dwork = from_timer(dwork, t, timer);
struct kthread_work *work = >work;
struct kthread_worker *worker = work->worker;
 
@@ -837,8 +836,7 @@ void __kthread_queue_delayed_work(struct kthread_worker 
*worker,
struct timer_list *timer = >timer;
struct kthread_work *work = >work;
 
-   WARN_ON_ONCE(timer->function != kthread_delayed_work_timer_fn ||
-timer->data != (unsigned long)dwork);
+   WARN_ON_ONCE(timer->function != 
(TIMER_FUNC_TYPE)kthread_delayed_work_timer_fn);
 
/*
 * If @delay is 0, queue @dwork->work immediately.  This is for
-- 
2.7.4



[PATCH 09/13] timer: Remove users of expire and data arguments to DEFINE_TIMER

2017-10-04 Thread Kees Cook
The expire and data arguments of DEFINE_TIMER are only used in two places
and are ignored by the code (malta-display.c only uses mod_timer(),
never add_timer(), so the preset expires value is ignored). Set both
sets of arguments to zero.

Cc: Ralf Baechle <r...@linux-mips.org>
Cc: Wim Van Sebroeck <w...@iguana.be>
Cc: Guenter Roeck <li...@roeck-us.net>
Cc: Geert Uytterhoeven <ge...@linux-m68k.org>
Cc: linux-m...@linux-mips.org
Cc: linux-watch...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 arch/mips/mti-malta/malta-display.c | 6 +++---
 drivers/watchdog/alim7101_wdt.c | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/arch/mips/mti-malta/malta-display.c 
b/arch/mips/mti-malta/malta-display.c
index d4f807191ecd..ac813158b9b8 100644
--- a/arch/mips/mti-malta/malta-display.c
+++ b/arch/mips/mti-malta/malta-display.c
@@ -36,10 +36,10 @@ void mips_display_message(const char *str)
}
 }
 
-static void scroll_display_message(unsigned long data);
-static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, HZ, 0);
+static void scroll_display_message(unsigned long unused);
+static DEFINE_TIMER(mips_scroll_timer, scroll_display_message, 0, 0);
 
-static void scroll_display_message(unsigned long data)
+static void scroll_display_message(unsigned long unused)
 {
mips_display_message(_string[display_count++]);
if (display_count == max_display_count)
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 665e0e7dfe1e..3c1f6ac68ea9 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -71,7 +71,7 @@ MODULE_PARM_DESC(use_gpio,
"Use the gpio watchdog (required by old cobalt boards).");
 
 static void wdt_timer_ping(unsigned long);
-static DEFINE_TIMER(timer, wdt_timer_ping, 0, 1);
+static DEFINE_TIMER(timer, wdt_timer_ping, 0, 0);
 static unsigned long next_heartbeat;
 static unsigned long wdt_is_open;
 static char wdt_expect_close;
@@ -87,7 +87,7 @@ MODULE_PARM_DESC(nowayout,
  * Whack the dog
  */
 
-static void wdt_timer_ping(unsigned long data)
+static void wdt_timer_ping(unsigned long unused)
 {
/* If we got a heartbeat pulse within the WDT_US_INTERVAL
 * we agree to ping the WDT
-- 
2.7.4



[PATCH 06/13] timer: Remove users of TIMER_DEFERRED_INITIALIZER

2017-10-04 Thread Kees Cook
This removes uses of TIMER_DEFERRED_INITIALIZER and chooses a location
to call timer_setup() from before add_timer() or mod_timer() is called.
Adjusts callbacks to use from_timer() as needed.

Cc: Martin Schwidefsky <schwidef...@de.ibm.com>
Cc: Heiko Carstens <heiko.carst...@de.ibm.com>
Cc: Tejun Heo <t...@kernel.org>
Cc: Lai Jiangshan <jiangshan...@gmail.com>
Cc: linux-s...@vger.kernel.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 arch/s390/kernel/lgr.c  | 6 +++---
 arch/s390/kernel/topology.c | 6 +++---
 kernel/workqueue.c  | 8 +++-
 3 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/arch/s390/kernel/lgr.c b/arch/s390/kernel/lgr.c
index ae7dff110054..bf9622f0e6b1 100644
--- a/arch/s390/kernel/lgr.c
+++ b/arch/s390/kernel/lgr.c
@@ -153,14 +153,13 @@ static void lgr_timer_set(void);
 /*
  * LGR timer callback
  */
-static void lgr_timer_fn(unsigned long ignored)
+static void lgr_timer_fn(struct timer_list *unused)
 {
lgr_info_log();
lgr_timer_set();
 }
 
-static struct timer_list lgr_timer =
-   TIMER_DEFERRED_INITIALIZER(lgr_timer_fn, 0, 0);
+static struct timer_list lgr_timer;
 
 /*
  * Setup next LGR timer
@@ -181,6 +180,7 @@ static int __init lgr_init(void)
debug_register_view(lgr_dbf, _hex_ascii_view);
lgr_info_get(_info_last);
debug_event(lgr_dbf, 1, _info_last, sizeof(lgr_info_last));
+   timer_setup(_timer, lgr_timer_fn, TIMER_DEFERRABLE);
lgr_timer_set();
return 0;
 }
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index ed0bdd220e1a..d7ece9888c29 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -320,15 +320,14 @@ static void topology_flush_work(void)
flush_work(_work);
 }
 
-static void topology_timer_fn(unsigned long ignored)
+static void topology_timer_fn(struct timer_list *unused)
 {
if (ptf(PTF_CHECK))
topology_schedule_update();
set_topology_timer();
 }
 
-static struct timer_list topology_timer =
-   TIMER_DEFERRED_INITIALIZER(topology_timer_fn, 0, 0);
+static struct timer_list topology_timer;
 
 static atomic_t topology_poll = ATOMIC_INIT(0);
 
@@ -597,6 +596,7 @@ static struct ctl_table topology_dir_table[] = {
 
 static int __init topology_init(void)
 {
+   timer_setup(_timer, topology_timer_fn, TIMER_DEFERRABLE);
if (MACHINE_HAS_TOPOLOGY)
set_topology_timer();
else
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 64d0edf428f8..a5361fc6215d 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -5390,11 +5390,8 @@ static void workqueue_sysfs_unregister(struct 
workqueue_struct *wq)  { }
  */
 #ifdef CONFIG_WQ_WATCHDOG
 
-static void wq_watchdog_timer_fn(unsigned long data);
-
 static unsigned long wq_watchdog_thresh = 30;
-static struct timer_list wq_watchdog_timer =
-   TIMER_DEFERRED_INITIALIZER(wq_watchdog_timer_fn, 0, 0);
+static struct timer_list wq_watchdog_timer;
 
 static unsigned long wq_watchdog_touched = INITIAL_JIFFIES;
 static DEFINE_PER_CPU(unsigned long, wq_watchdog_touched_cpu) = 
INITIAL_JIFFIES;
@@ -5408,7 +5405,7 @@ static void wq_watchdog_reset_touched(void)
per_cpu(wq_watchdog_touched_cpu, cpu) = jiffies;
 }
 
-static void wq_watchdog_timer_fn(unsigned long data)
+static void wq_watchdog_timer_fn(struct timer_list *unused)
 {
unsigned long thresh = READ_ONCE(wq_watchdog_thresh) * HZ;
bool lockup_detected = false;
@@ -5510,6 +5507,7 @@ module_param_cb(watchdog_thresh, _watchdog_thresh_ops, 
_watchdog_thresh,
 
 static void wq_watchdog_init(void)
 {
+   timer_setup(_watchdog_timer, wq_watchdog_timer_fn, TIMER_DEFERRABLE);
wq_watchdog_set_thresh(wq_watchdog_thresh);
 }
 
-- 
2.7.4



[PATCH 02/13] timer: Remove init_timer_pinned_deferrable() in favor of timer_setup()

2017-10-04 Thread Kees Cook
This refactors the only user of init_timer_pinned_deferrable() to use the
new timer_setup() and from_timer(). Adds a pointer back to the policy,
and drops the definition of init_timer_pinned_deferrable().

Cc: "Rafael J. Wysocki" <r...@rjwysocki.net>
Cc: Viresh Kumar <viresh.ku...@linaro.org>
Cc: Benjamin Herrenschmidt <b...@kernel.crashing.org>
Cc: Paul Mackerras <pau...@samba.org>
Cc: Michael Ellerman <m...@ellerman.id.au>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: linux...@vger.kernel.org
Cc: linuxppc-...@lists.ozlabs.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/cpufreq/powernv-cpufreq.c | 13 +++--
 include/linux/timer.h |  2 --
 2 files changed, 7 insertions(+), 8 deletions(-)

diff --git a/drivers/cpufreq/powernv-cpufreq.c 
b/drivers/cpufreq/powernv-cpufreq.c
index 3ff5160451b4..b6d7c4c98d0a 100644
--- a/drivers/cpufreq/powernv-cpufreq.c
+++ b/drivers/cpufreq/powernv-cpufreq.c
@@ -90,6 +90,7 @@ struct global_pstate_info {
int last_gpstate_idx;
spinlock_t gpstate_lock;
struct timer_list timer;
+   struct cpufreq_policy *policy;
 };
 
 static struct cpufreq_frequency_table powernv_freqs[POWERNV_MAX_PSTATES+1];
@@ -625,10 +626,10 @@ static inline void  queue_gpstate_timer(struct 
global_pstate_info *gpstates)
  * according quadratic equation. Queues a new timer if it is still not equal
  * to local pstate
  */
-void gpstate_timer_handler(unsigned long data)
+void gpstate_timer_handler(struct timer_list *t)
 {
-   struct cpufreq_policy *policy = (struct cpufreq_policy *)data;
-   struct global_pstate_info *gpstates = policy->driver_data;
+   struct global_pstate_info *gpstates = from_timer(gpstates, t, timer);
+   struct cpufreq_policy *policy = gpstates->policy;
int gpstate_idx, lpstate_idx;
unsigned long val;
unsigned int time_diff = jiffies_to_msecs(jiffies)
@@ -800,9 +801,9 @@ static int powernv_cpufreq_cpu_init(struct cpufreq_policy 
*policy)
policy->driver_data = gpstates;
 
/* initialize timer */
-   init_timer_pinned_deferrable(>timer);
-   gpstates->timer.data = (unsigned long)policy;
-   gpstates->timer.function = gpstate_timer_handler;
+   gpstates->policy = policy;
+   timer_setup(>timer, gpstate_timer_handler,
+   TIMER_PINNED | TIMER_DEFERRABLE);
gpstates->timer.expires = jiffies +
msecs_to_jiffies(GPSTATE_TIMER_INTERVAL);
spin_lock_init(>gpstate_lock);
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 5ef5c9e41a09..d11e819a86e2 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -132,8 +132,6 @@ static inline void init_timer_on_stack_key(struct 
timer_list *timer,
__init_timer((timer), TIMER_PINNED)
 #define init_timer_deferrable(timer)   \
__init_timer((timer), TIMER_DEFERRABLE)
-#define init_timer_pinned_deferrable(timer)\
-   __init_timer((timer), TIMER_DEFERRABLE | TIMER_PINNED)
 #define init_timer_on_stack(timer) \
__init_timer_on_stack((timer), 0)
 
-- 
2.7.4



[PATCH 07/13] timer: Remove last user of TIMER_INITIALIZER

2017-10-04 Thread Kees Cook
Drops the last user of TIMER_INITIALIZER and adapts timer.h to use the
internal version.

Cc: Arnd Bergmann <a...@arndb.de>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Mark Gross <mark.gr...@intel.com>
Cc: Thomas Gleixner <t...@linutronix.de>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/char/tlclk.c  | 12 +---
 include/linux/timer.h |  2 +-
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/drivers/char/tlclk.c b/drivers/char/tlclk.c
index 6210bff46341..8eeb4190207d 100644
--- a/drivers/char/tlclk.c
+++ b/drivers/char/tlclk.c
@@ -184,9 +184,8 @@ static unsigned int telclk_interrupt;
 static int int_events; /* Event that generate a interrupt */
 static int got_event;  /* if events processing have been done */
 
-static void switchover_timeout(unsigned long data);
-static struct timer_list switchover_timer =
-   TIMER_INITIALIZER(switchover_timeout , 0, 0);
+static void switchover_timeout(struct timer_list *t);
+static struct timer_list switchover_timer;
 static unsigned long tlclk_timer_data;
 
 static struct tlclk_alarms *alarm_events;
@@ -805,7 +804,7 @@ static int __init tlclk_init(void)
goto out3;
}
 
-   init_timer(_timer);
+   timer_setup(_timer, switchover_timeout, 0);
 
ret = misc_register(_miscdev);
if (ret < 0) {
@@ -855,9 +854,9 @@ static void __exit tlclk_cleanup(void)
 
 }
 
-static void switchover_timeout(unsigned long data)
+static void switchover_timeout(struct timer_list *unused)
 {
-   unsigned long flags = *(unsigned long *) data;
+   unsigned long flags = tlclk_timer_data;
 
if ((flags & 1)) {
if ((inb(TLCLK_REG1) & 0x08) != (flags & 0x08))
@@ -922,7 +921,6 @@ static irqreturn_t tlclk_interrupt(int irq, void *dev_id)
/* TIMEOUT in ~10ms */
switchover_timer.expires = jiffies + msecs_to_jiffies(10);
tlclk_timer_data = inb(TLCLK_REG1);
-   switchover_timer.data = (unsigned long) _timer_data;
mod_timer(_timer, switchover_timer.expires);
} else {
got_event = 1;
diff --git a/include/linux/timer.h b/include/linux/timer.h
index 10cc45ca5803..4f7476e4a727 100644
--- a/include/linux/timer.h
+++ b/include/linux/timer.h
@@ -87,7 +87,7 @@ struct timer_list {
 
 #define DEFINE_TIMER(_name, _function, _expires, _data)\
struct timer_list _name =   \
-   TIMER_INITIALIZER(_function, _expires, _data)
+   __TIMER_INITIALIZER(_function, _expires, _data, 0)
 
 void init_timer_key(struct timer_list *timer, unsigned int flags,
const char *name, struct lock_class_key *key);
-- 
2.7.4



[PATCH v2 13/31] timer: Remove meaningless .data/.function assignments

2017-09-20 Thread Kees Cook
Several timer users needlessly reset their .function/.data fields during
their timer callback, but nothing else changes them. Some users do not
use their .data field at all. Each instance is removed here.

Cc: Krzysztof Halasa <k...@pm.waw.pl>
Cc: Aditya Shankar <aditya.shan...@microchip.com>
Cc: Ganesh Krishna <ganesh.kris...@microchip.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Jens Axboe <ax...@fb.com>
Cc: net...@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Cc: de...@driverdev.osuosl.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
Acked-by: Greg Kroah-Hartman <gre...@linuxfoundation.org> # for staging
Acked-by: Krzysztof Halasa <k...@pm.waw.pl> # for wan/hdlc*
Acked-by: Jens Axboe <ax...@kernel.dk> # for amiflop
---
 drivers/block/amiflop.c   | 3 +--
 drivers/net/wan/hdlc_cisco.c  | 2 --
 drivers/net/wan/hdlc_fr.c | 2 --
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 +---
 4 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index c4b1cba27178..6680d75bc857 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -323,7 +323,7 @@ static void fd_deselect (int drive)
 
 }
 
-static void motor_on_callback(unsigned long nr)
+static void motor_on_callback(unsigned long ignored)
 {
if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
complete_all(_on_completion);
@@ -344,7 +344,6 @@ static int fd_motor_on(int nr)
fd_select(nr);
 
reinit_completion(_on_completion);
-   motor_on_timer.data = nr;
mod_timer(_on_timer, jiffies + HZ/2);
 
on_attempts = 10;
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index c696d42f4502..6c98d85f2773 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -276,8 +276,6 @@ static void cisco_timer(unsigned long arg)
spin_unlock(>lock);
 
st->timer.expires = jiffies + st->settings.interval * HZ;
-   st->timer.function = cisco_timer;
-   st->timer.data = arg;
add_timer(>timer);
 }
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index de42faca076a..7da2424c28a4 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -644,8 +644,6 @@ static void fr_timer(unsigned long arg)
state(hdlc)->settings.t391 * HZ;
}
 
-   state(hdlc)->timer.function = fr_timer;
-   state(hdlc)->timer.data = arg;
add_timer((hdlc)->timer);
 }
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index ac5aaafa461c..60f088babf27 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -266,7 +266,7 @@ static void update_scan_time(void)
last_scanned_shadow[i].time_scan = jiffies;
 }
 
-static void remove_network_from_shadow(unsigned long arg)
+static void remove_network_from_shadow(unsigned long unused)
 {
unsigned long now = jiffies;
int i, j;
@@ -287,7 +287,6 @@ static void remove_network_from_shadow(unsigned long arg)
}
 
if (last_scanned_cnt != 0) {
-   hAgingTimer.data = arg;
mod_timer(, jiffies + msecs_to_jiffies(AGING_TIME));
}
 }
@@ -304,7 +303,6 @@ static int is_network_in_shadow(struct network_info 
*pstrNetworkInfo,
int i;
 
if (last_scanned_cnt == 0) {
-   hAgingTimer.data = (unsigned long)user_void;
mod_timer(, jiffies + msecs_to_jiffies(AGING_TIME));
state = -1;
} else {
-- 
2.7.4



[PATCH 13/31] timer: Remove meaningless .data/.function assignments

2017-08-31 Thread Kees Cook
Several timer users needlessly reset their .function/.data fields during
their timer callback, but nothing else changes them. Some users do not
use their .data field at all. Each instance is removed here.

Cc: Krzysztof Halasa <k...@pm.waw.pl>
Cc: Aditya Shankar <aditya.shan...@microchip.com>
Cc: Ganesh Krishna <ganesh.kris...@microchip.com>
Cc: Greg Kroah-Hartman <gre...@linuxfoundation.org>
Cc: Jens Axboe <ax...@fb.com>
Cc: net...@vger.kernel.org
Cc: linux-wireless@vger.kernel.org
Cc: de...@driverdev.osuosl.org
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/block/amiflop.c   | 3 +--
 drivers/net/wan/hdlc_cisco.c  | 2 --
 drivers/net/wan/hdlc_fr.c | 2 --
 drivers/staging/wilc1000/wilc_wfi_cfgoperations.c | 4 +---
 4 files changed, 2 insertions(+), 9 deletions(-)

diff --git a/drivers/block/amiflop.c b/drivers/block/amiflop.c
index c4b1cba27178..6680d75bc857 100644
--- a/drivers/block/amiflop.c
+++ b/drivers/block/amiflop.c
@@ -323,7 +323,7 @@ static void fd_deselect (int drive)
 
 }
 
-static void motor_on_callback(unsigned long nr)
+static void motor_on_callback(unsigned long ignored)
 {
if (!(ciaa.pra & DSKRDY) || --on_attempts == 0) {
complete_all(_on_completion);
@@ -344,7 +344,6 @@ static int fd_motor_on(int nr)
fd_select(nr);
 
reinit_completion(_on_completion);
-   motor_on_timer.data = nr;
mod_timer(_on_timer, jiffies + HZ/2);
 
on_attempts = 10;
diff --git a/drivers/net/wan/hdlc_cisco.c b/drivers/net/wan/hdlc_cisco.c
index c696d42f4502..6c98d85f2773 100644
--- a/drivers/net/wan/hdlc_cisco.c
+++ b/drivers/net/wan/hdlc_cisco.c
@@ -276,8 +276,6 @@ static void cisco_timer(unsigned long arg)
spin_unlock(>lock);
 
st->timer.expires = jiffies + st->settings.interval * HZ;
-   st->timer.function = cisco_timer;
-   st->timer.data = arg;
add_timer(>timer);
 }
 
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index de42faca076a..7da2424c28a4 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -644,8 +644,6 @@ static void fr_timer(unsigned long arg)
state(hdlc)->settings.t391 * HZ;
}
 
-   state(hdlc)->timer.function = fr_timer;
-   state(hdlc)->timer.data = arg;
add_timer((hdlc)->timer);
 }
 
diff --git a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c 
b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
index 68fd5b3b8b2d..2fca2b017093 100644
--- a/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
+++ b/drivers/staging/wilc1000/wilc_wfi_cfgoperations.c
@@ -275,7 +275,7 @@ static void update_scan_time(void)
last_scanned_shadow[i].time_scan = jiffies;
 }
 
-static void remove_network_from_shadow(unsigned long arg)
+static void remove_network_from_shadow(unsigned long unused)
 {
unsigned long now = jiffies;
int i, j;
@@ -296,7 +296,6 @@ static void remove_network_from_shadow(unsigned long arg)
}
 
if (last_scanned_cnt != 0) {
-   hAgingTimer.data = arg;
mod_timer(, jiffies + msecs_to_jiffies(AGING_TIME));
}
 }
@@ -313,7 +312,6 @@ static int is_network_in_shadow(struct network_info 
*pstrNetworkInfo,
int i;
 
if (last_scanned_cnt == 0) {
-   hAgingTimer.data = (unsigned long)user_void;
mod_timer(, jiffies + msecs_to_jiffies(AGING_TIME));
state = -1;
} else {
-- 
2.7.4



Re: [PATCH 0/6] Constant Time Memory Comparisons Are Important

2017-06-11 Thread Kees Cook
On Sun, Jun 11, 2017 at 1:13 AM, Kalle Valo <kv...@codeaurora.org> wrote:
> "Jason A. Donenfeld" <ja...@zx2c4.com> writes:
>
>> Whenever you're comparing two MACs, it's important to do this using
>> crypto_memneq instead of memcmp. With memcmp, you leak timing information,
>> which could then be used to iteratively forge a MAC.
>
> Do you have any pointers where I could learn more about this?

While not using C specifically, this talks about the problem generally:
https://www.chosenplaintext.ca/articles/beginners-guide-constant-time-cryptography.html

-Kees

-- 
Kees Cook
Pixel Security


Re: [PATCH] nfc: Fix the sockaddr length sanitization in llcp_sock_connect

2017-05-24 Thread Kees Cook
On Wed, May 24, 2017 at 3:26 AM, Mateusz Jurczyk <mjurc...@google.com> wrote:
> Fix the sockaddr length verification in the connect() handler of NFC/LLCP
> sockets, to compare against the size of the actual structure expected on
> input (sockaddr_nfc_llcp) instead of its shorter version (sockaddr_nfc).
>
> Both structures are defined in include/uapi/linux/nfc.h. The fields
> specific to the _llcp extended struct are as follows:
>
>276  __u8 dsap; /* Destination SAP, if known */
>277  __u8 ssap; /* Source SAP to be bound to */
>278  char service_name[NFC_LLCP_MAX_SERVICE_NAME]; /* Service name 
> URI */;
>279  size_t service_name_len;
>
> If the caller doesn't provide a sufficiently long sockaddr buffer, these
> fields remain uninitialized (and they currently originate from the stack
> frame of the top-level sys_connect handler). They are then copied by
> llcp_sock_connect() into internal storage (nfc_llcp_sock structure), and
> could be subsequently read back through the user-mode getsockname()
> function (handled by llcp_sock_getname()). This would result in the
> disclosure of up to ~70 uninitialized bytes from the kernel stack to
> user-mode clients capable of creating AFC_NFC sockets.
>
> Signed-off-by: Mateusz Jurczyk <mjurc...@google.com>

Acked-by: Kees Cook <keesc...@chromium.org>

-Kees

> ---
>  net/nfc/llcp_sock.c | 3 +--
>  1 file changed, 1 insertion(+), 2 deletions(-)
>
> diff --git a/net/nfc/llcp_sock.c b/net/nfc/llcp_sock.c
> index 2ffb18e73df6..d0d12bea65cb 100644
> --- a/net/nfc/llcp_sock.c
> +++ b/net/nfc/llcp_sock.c
> @@ -662,8 +662,7 @@ static int llcp_sock_connect(struct socket *sock, struct 
> sockaddr *_addr,
>
> pr_debug("sock %p sk %p flags 0x%x\n", sock, sk, flags);
>
> -   if (!addr || len < sizeof(struct sockaddr_nfc) ||
> -   addr->sa_family != AF_NFC)
> +   if (!addr || len < sizeof(*addr) || addr->sa_family != AF_NFC)
> return -EINVAL;
>
> if (addr->service_name_len == 0 && addr->dsap == 0)
> --
> 2.13.0.219.gdb65acc882-goog
>



-- 
Kees Cook
Pixel Security


[PATCH] libertas: Remove function entry/exit debugging

2017-05-15 Thread Kees Cook
In at least one place, the enter/exit debugging was not being correctly
matched. Based on mailing list feedback, it was desired to drop all of
these in favor of using ftrace instead.

Suggested-by: Joe Perches <j...@perches.com>
Suggested-by: Kalle Valo <kv...@codeaurora.org>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/marvell/libertas/cfg.c | 104 +
 drivers/net/wireless/marvell/libertas/cmd.c | 116 ++--
 drivers/net/wireless/marvell/libertas/cmdresp.c |   9 --
 drivers/net/wireless/marvell/libertas/defs.h|   9 --
 drivers/net/wireless/marvell/libertas/ethtool.c |   3 -
 drivers/net/wireless/marvell/libertas/if_cs.c   |  36 
 drivers/net/wireless/marvell/libertas/if_sdio.c |  66 +-
 drivers/net/wireless/marvell/libertas/if_spi.c  |  38 ++--
 drivers/net/wireless/marvell/libertas/if_usb.c  |  27 +-
 drivers/net/wireless/marvell/libertas/main.c|  81 +
 drivers/net/wireless/marvell/libertas/mesh.c|  28 --
 drivers/net/wireless/marvell/libertas/rx.c  |   6 --
 drivers/net/wireless/marvell/libertas/tx.c  |   3 -
 13 files changed, 24 insertions(+), 502 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/cfg.c 
b/drivers/net/wireless/marvell/libertas/cfg.c
index a0463fef79b0..71ba2c8d09b5 100644
--- a/drivers/net/wireless/marvell/libertas/cfg.c
+++ b/drivers/net/wireless/marvell/libertas/cfg.c
@@ -443,17 +443,12 @@ static int lbs_cfg_set_monitor_channel(struct wiphy 
*wiphy,
struct lbs_private *priv = wiphy_priv(wiphy);
int ret = -ENOTSUPP;
 
-   lbs_deb_enter_args(LBS_DEB_CFG80211, "freq %d, type %d",
-  chandef->chan->center_freq,
-  cfg80211_get_chandef_type(chandef));
-
if (cfg80211_get_chandef_type(chandef) != NL80211_CHAN_NO_HT)
goto out;
 
ret = lbs_set_channel(priv, chandef->chan->hw_value);
 
  out:
-   lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
 }
 
@@ -464,16 +459,12 @@ static int lbs_cfg_set_mesh_channel(struct wiphy *wiphy,
struct lbs_private *priv = wiphy_priv(wiphy);
int ret = -ENOTSUPP;
 
-   lbs_deb_enter_args(LBS_DEB_CFG80211, "iface %s freq %d",
-  netdev_name(netdev), channel->center_freq);
-
if (netdev != priv->mesh_dev)
goto out;
 
ret = lbs_mesh_set_channel(priv, channel->hw_value);
 
  out:
-   lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d", ret);
return ret;
 }
 
@@ -512,8 +503,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned 
long dummy,
int i;
int ret = -EILSEQ;
 
-   lbs_deb_enter(LBS_DEB_CFG80211);
-
bsssize = get_unaligned_le16(>bssdescriptsize);
 
lbs_deb_scan("scan response: %d BSSs (%d bytes); resp size %d bytes\n",
@@ -665,7 +654,6 @@ static int lbs_ret_scan(struct lbs_private *priv, unsigned 
long dummy,
ret = 0;
 
  done:
-   lbs_deb_leave_args(LBS_DEB_SCAN, "ret %d", ret);
return ret;
 }
 
@@ -693,11 +681,9 @@ static void lbs_scan_worker(struct work_struct *work)
int last_channel;
int running, carrier;
 
-   lbs_deb_enter(LBS_DEB_SCAN);
-
scan_cmd = kzalloc(LBS_SCAN_MAX_CMD_SIZE, GFP_KERNEL);
if (scan_cmd == NULL)
-   goto out_no_scan_cmd;
+   return;
 
/* prepare fixed part of scan command */
scan_cmd->bsstype = CMD_BSS_TYPE_ANY;
@@ -766,16 +752,11 @@ static void lbs_scan_worker(struct work_struct *work)
lbs_deb_scan("scan: waking up waiters\n");
wake_up_all(>scan_q);
}
-
- out_no_scan_cmd:
-   lbs_deb_leave(LBS_DEB_SCAN);
 }
 
 static void _internal_start_scan(struct lbs_private *priv, bool internal,
struct cfg80211_scan_request *request)
 {
-   lbs_deb_enter(LBS_DEB_CFG80211);
-
lbs_deb_scan("scan: ssids %d, channels %d, ie_len %zd\n",
request->n_ssids, request->n_channels, request->ie_len);
 
@@ -785,8 +766,6 @@ static void _internal_start_scan(struct lbs_private *priv, 
bool internal,
 
queue_delayed_work(priv->work_thread, >scan_work,
msecs_to_jiffies(50));
-
-   lbs_deb_leave(LBS_DEB_CFG80211);
 }
 
 /*
@@ -815,8 +794,6 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
struct lbs_private *priv = wiphy_priv(wiphy);
int ret = 0;
 
-   lbs_deb_enter(LBS_DEB_CFG80211);
-
if (priv->scan_req || delayed_work_pending(>scan_work)) {
/* old scan request not yet processed */
ret = -EAGAIN;
@@ -829,7 +806,6 @@ static int lbs_cfg_scan(struct wiphy *wiphy,
ret = -EIO;
 
  out:
-   lbs_deb_leave_args(LBS_DEB_CFG80211, "ret %d&quo

[PATCH v3] libertas: Avoid reading past end of buffer

2017-05-15 Thread Kees Cook
Using memcpy() from a string that is shorter than the length copied means
the destination buffer is being filled with arbitrary data from the kernel
rodata segment. Instead, redefine the stat strings to be ETH_GSTRING_LEN
sizes, like other drivers. This lets us use a single memcpy that does not
leak rodata contents. Additionally adjust indentation to keep checkpatch.pl
happy.

This was found with the future CONFIG_FORTIFY_SOURCE feature.

Cc: Daniel Micay <danielmi...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
v3:
- drop needless "*"; joe
- fix entry/exit in separate patch
v2:
- use ETH_GSTRING_LEN; joe
---
 drivers/net/wireless/marvell/libertas/mesh.c | 26 ++
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/mesh.c 
b/drivers/net/wireless/marvell/libertas/mesh.c
index d0c881dd5846..2229fb448189 100644
--- a/drivers/net/wireless/marvell/libertas/mesh.c
+++ b/drivers/net/wireless/marvell/libertas/mesh.c
@@ -1108,15 +1108,15 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
  * Ethtool related
  */
 
-static const char * const mesh_stat_strings[] = {
-   "drop_duplicate_bcast",
-   "drop_ttl_zero",
-   "drop_no_fwd_route",
-   "drop_no_buffers",
-   "fwded_unicast_cnt",
-   "fwded_bcast_cnt",
-   "drop_blind_table",
-   "tx_failed_cnt"
+static const char mesh_stat_strings[MESH_STATS_NUM][ETH_GSTRING_LEN] = {
+   "drop_duplicate_bcast",
+   "drop_ttl_zero",
+   "drop_no_fwd_route",
+   "drop_no_buffers",
+   "fwded_unicast_cnt",
+   "fwded_bcast_cnt",
+   "drop_blind_table",
+   "tx_failed_cnt"
 };
 
 void lbs_mesh_ethtool_get_stats(struct net_device *dev,
@@ -1170,17 +1170,11 @@ int lbs_mesh_ethtool_get_sset_count(struct net_device 
*dev, int sset)
 void lbs_mesh_ethtool_get_strings(struct net_device *dev,
uint32_t stringset, uint8_t *s)
 {
-   int i;
-
lbs_deb_enter(LBS_DEB_ETHTOOL);
 
switch (stringset) {
case ETH_SS_STATS:
-   for (i = 0; i < MESH_STATS_NUM; i++) {
-   memcpy(s + i * ETH_GSTRING_LEN,
-   mesh_stat_strings[i],
-   ETH_GSTRING_LEN);
-   }
+   memcpy(s, mesh_stat_strings, sizeof(mesh_stat_strings));
break;
}
lbs_deb_enter(LBS_DEB_ETHTOOL);
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] libertas: Avoid reading past end of buffer

2017-05-10 Thread Kees Cook
Using memcpy() from a string that is shorter than the length copied means
the destination buffer is being filled with arbitrary data from the kernel
rodata segment. Instead, redefine the stat strings to be ETH_GSTRING_LEN
sizes, like other drivers. This lets us use a single memcpy that does not
leak rodata contents. Additionally adjust indentation to keep checkpatch.pl
happy.

This was found with the future CONFIG_FORTIFY_SOURCE feature.

Cc: Daniel Micay <danielmi...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
v2: use ETH_GSTRING_LEN; joe
---
 drivers/net/wireless/marvell/libertas/mesh.c | 26 ++
 1 file changed, 10 insertions(+), 16 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/mesh.c 
b/drivers/net/wireless/marvell/libertas/mesh.c
index d0c881dd5846..6076c83ce5ab 100644
--- a/drivers/net/wireless/marvell/libertas/mesh.c
+++ b/drivers/net/wireless/marvell/libertas/mesh.c
@@ -1108,15 +1108,15 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
  * Ethtool related
  */
 
-static const char * const mesh_stat_strings[] = {
-   "drop_duplicate_bcast",
-   "drop_ttl_zero",
-   "drop_no_fwd_route",
-   "drop_no_buffers",
-   "fwded_unicast_cnt",
-   "fwded_bcast_cnt",
-   "drop_blind_table",
-   "tx_failed_cnt"
+static const char mesh_stat_strings[MESH_STATS_NUM][ETH_GSTRING_LEN] = {
+   "drop_duplicate_bcast",
+   "drop_ttl_zero",
+   "drop_no_fwd_route",
+   "drop_no_buffers",
+   "fwded_unicast_cnt",
+   "fwded_bcast_cnt",
+   "drop_blind_table",
+   "tx_failed_cnt"
 };
 
 void lbs_mesh_ethtool_get_stats(struct net_device *dev,
@@ -1170,17 +1170,11 @@ int lbs_mesh_ethtool_get_sset_count(struct net_device 
*dev, int sset)
 void lbs_mesh_ethtool_get_strings(struct net_device *dev,
uint32_t stringset, uint8_t *s)
 {
-   int i;
-
lbs_deb_enter(LBS_DEB_ETHTOOL);
 
switch (stringset) {
case ETH_SS_STATS:
-   for (i = 0; i < MESH_STATS_NUM; i++) {
-   memcpy(s + i * ETH_GSTRING_LEN,
-   mesh_stat_strings[i],
-   ETH_GSTRING_LEN);
-   }
+   memcpy(s, *mesh_stat_strings, sizeof(mesh_stat_strings));
break;
}
lbs_deb_enter(LBS_DEB_ETHTOOL);
-- 
2.7.4


-- 
Kees Cook
Pixel Security


Re: [PATCH] libertas: Avoid reading past end of buffer

2017-05-10 Thread Kees Cook
On Tue, May 9, 2017 at 9:33 PM, Joe Perches <j...@perches.com> wrote:
> On Tue, 2017-05-09 at 16:23 -0700, Kees Cook wrote:
>> Using memcpy() from a string that is shorter than the length copied means
>> the destination buffer is being filled with arbitrary data from the kernel
>> rodata segment. Instead, use strncpy() which will fill the trailing bytes
>> with zeros. Additionally adjust indentation to keep checkpatch.pl happy.
>>
>> This was found with the future CONFIG_FORTIFY_SOURCE feature.
> []
>> diff --git a/drivers/net/wireless/marvell/libertas/mesh.c 
>> b/drivers/net/wireless/marvell/libertas/mesh.c
> []
>> @@ -1177,9 +1177,9 @@ void lbs_mesh_ethtool_get_strings(struct net_device 
>> *dev,
>>   switch (stringset) {
>>   case ETH_SS_STATS:
>>   for (i = 0; i < MESH_STATS_NUM; i++) {
>> - memcpy(s + i * ETH_GSTRING_LEN,
>> - mesh_stat_strings[i],
>> - ETH_GSTRING_LEN);
>> + strncpy(s + i * ETH_GSTRING_LEN,
>> + mesh_stat_strings[i],
>> + ETH_GSTRING_LEN);
>>   }
>
> The better solution is to declare
> mesh_stat_strings in in the normal way
>
> ---
>  drivers/net/wireless/marvell/libertas/mesh.c | 18 +-
>  1 file changed, 9 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/net/wireless/marvell/libertas/mesh.c 
> b/drivers/net/wireless/marvell/libertas/mesh.c
> index d0c881dd5846..a535e7f48d2d 100644
> --- a/drivers/net/wireless/marvell/libertas/mesh.c
> +++ b/drivers/net/wireless/marvell/libertas/mesh.c
> @@ -1108,15 +1108,15 @@ void lbs_mesh_set_txpd(struct lbs_private *priv,
>   * Ethtool related
>   */
>
> -static const char * const mesh_stat_strings[] = {
> -   "drop_duplicate_bcast",
> -   "drop_ttl_zero",
> -   "drop_no_fwd_route",
> -   "drop_no_buffers",
> -   "fwded_unicast_cnt",
> -   "fwded_bcast_cnt",
> -   "drop_blind_table",
> -   "tx_failed_cnt"
> +static const char mesh_stat_strings[][ETH_GSTRING_LEN] = {
> +   "drop_duplicate_bcast",
> +   "drop_ttl_zero",
> +   "drop_no_fwd_route",
> +   "drop_no_buffers",
> +   "fwded_unicast_cnt",
> +   "fwded_bcast_cnt",
> +   "drop_blind_table",
> +   "tx_failed_cnt",
>  };
>
>  void lbs_mesh_ethtool_get_stats(struct net_device *dev,

Ah yeah! And that simplifies the memcpy too, since it can just do it
in one go. New patch on the way...

-Kees

-- 
Kees Cook
Pixel Security


[PATCH] libertas: Avoid reading past end of buffer

2017-05-09 Thread Kees Cook
Using memcpy() from a string that is shorter than the length copied means
the destination buffer is being filled with arbitrary data from the kernel
rodata segment. Instead, use strncpy() which will fill the trailing bytes
with zeros. Additionally adjust indentation to keep checkpatch.pl happy.

This was found with the future CONFIG_FORTIFY_SOURCE feature.

Cc: Daniel Micay <danielmi...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/marvell/libertas/mesh.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/net/wireless/marvell/libertas/mesh.c 
b/drivers/net/wireless/marvell/libertas/mesh.c
index d0c881dd5846..d0b1948ca242 100644
--- a/drivers/net/wireless/marvell/libertas/mesh.c
+++ b/drivers/net/wireless/marvell/libertas/mesh.c
@@ -1177,9 +1177,9 @@ void lbs_mesh_ethtool_get_strings(struct net_device *dev,
switch (stringset) {
case ETH_SS_STATS:
for (i = 0; i < MESH_STATS_NUM; i++) {
-   memcpy(s + i * ETH_GSTRING_LEN,
-   mesh_stat_strings[i],
-   ETH_GSTRING_LEN);
+   strncpy(s + i * ETH_GSTRING_LEN,
+   mesh_stat_strings[i],
+   ETH_GSTRING_LEN);
}
break;
}
-- 
2.7.4


-- 
Kees Cook
Pixel Security


[PATCH] ray_cs: Avoid reading past end of buffer

2017-05-05 Thread Kees Cook
Using memcpy() from a buffer that is shorter than the length copied means
the destination buffer is being filled with arbitrary data from the kernel
rodata segment. In this case, the source was made longer, since it did not
match the destination structure size. Additionally removes a needless cast.

This was found with the future CONFIG_FORTIFY_SOURCE feature.

Cc: Daniel Micay <danielmi...@gmail.com>
Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 drivers/net/wireless/ray_cs.c | 7 +--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index b94479441b0c..170cd504e8ff 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -247,7 +247,10 @@ static const UCHAR b4_default_startup_parms[] = {
0x04, 0x08, /* Noise gain, limit offset */
0x28, 0x28, /* det rssi, med busy offsets */
7,  /* det sync thresh */
-   0, 2, 2 /* test mode, min, max */
+   0, 2, 2,/* test mode, min, max */
+   0,  /* rx/tx delay */
+   0, 0, 0, 0, 0, 0,   /* current BSS id */
+   0   /* hop set */
 };
 
 /*===*/
@@ -597,7 +600,7 @@ static void init_startup_params(ray_dev_t *local)
 *a_beacon_period = hopsa_beacon_period = KuS
 *//* 64ms = 01 */
if (local->fw_ver == 0x55) {
-   memcpy((UCHAR *) >sparm.b4, b4_default_startup_parms,
+   memcpy(>sparm.b4, b4_default_startup_parms,
   sizeof(struct b4_startup_params));
/* Translate sane kus input values to old build 4/5 format */
/* i = hop time in uS truncated to 3 bytes */
-- 
2.7.4


-- 
Kees Cook
Pixel Security


Re: [PATCH v2 1/4] lib: move strtobool to kstrtobool

2016-02-05 Thread Kees Cook
On Thu, Feb 4, 2016 at 3:55 PM, Rasmus Villemoes
<li...@rasmusvillemoes.dk> wrote:
> On Thu, Feb 04 2016, Kees Cook <keesc...@chromium.org> wrote:
>
>> Create the kstrtobool_from_user helper and moves strtobool logic into
>> the new kstrtobool (matching all the other kstrto* functions). Provides
>> an inline wrapper for existing strtobool callers.
>>
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>> ---
>>  include/linux/kernel.h |  3 +++
>>  include/linux/string.h |  6 +-
>>  lib/kstrtox.c  | 35 +++
>>  lib/string.c   | 29 -
>>  4 files changed, 43 insertions(+), 30 deletions(-)
>>
>> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
>> index f31638c6e873..cdc25f47a23f 100644
>> --- a/include/linux/kernel.h
>> +++ b/include/linux/kernel.h
>> @@ -357,6 +357,7 @@ int __must_check kstrtou16(const char *s, unsigned int 
>> base, u16 *res);
>>  int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
>>  int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
>>  int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
>> +int __must_check kstrtobool(const char *s, unsigned int base, bool *res);
>>
>>  int __must_check kstrtoull_from_user(const char __user *s, size_t count, 
>> unsigned int base, unsigned long long *res);
>>  int __must_check kstrtoll_from_user(const char __user *s, size_t count, 
>> unsigned int base, long long *res);
>> @@ -368,6 +369,8 @@ int __must_check kstrtou16_from_user(const char __user 
>> *s, size_t count, unsigne
>>  int __must_check kstrtos16_from_user(const char __user *s, size_t count, 
>> unsigned int base, s16 *res);
>>  int __must_check kstrtou8_from_user(const char __user *s, size_t count, 
>> unsigned int base, u8 *res);
>>  int __must_check kstrtos8_from_user(const char __user *s, size_t count, 
>> unsigned int base, s8 *res);
>> +int __must_check kstrtobool_from_user(const char __user *s, size_t count,
>> +   unsigned int base, bool *res);
>>
>>  static inline int __must_check kstrtou64_from_user(const char __user *s, 
>> size_t count, unsigned int base, u64 *res)
>>  {
>> diff --git a/include/linux/string.h b/include/linux/string.h
>> index 9eebc66d957a..d2fb21b1081d 100644
>> --- a/include/linux/string.h
>> +++ b/include/linux/string.h
>> @@ -128,7 +128,11 @@ extern char **argv_split(gfp_t gfp, const char *str, 
>> int *argcp);
>>  extern void argv_free(char **argv);
>>
>>  extern bool sysfs_streq(const char *s1, const char *s2);
>> -extern int strtobool(const char *s, bool *res);
>> +extern int kstrtobool(const char *s, unsigned int base, bool *res);
>> +static inline int strtobool(const char *s, bool *res)
>> +{
>> + return kstrtobool(s, 0, res);
>> +}
>>
>>  #ifdef CONFIG_BINARY_PRINTF
>>  int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
>> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
>> index 94be244e8441..e18f088704d7 100644
>> --- a/lib/kstrtox.c
>> +++ b/lib/kstrtox.c
>> @@ -321,6 +321,40 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
>>  }
>>  EXPORT_SYMBOL(kstrtos8);
>>
>> +/**
>> + * kstrtobool - convert common user inputs into boolean values
>> + * @s: input string
>> + * @base: ignored
>> + * @res: result
>> + *
>> + * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
>> + * Otherwise it will return -EINVAL.  Value pointed to by res is
>> + * updated upon finding a match.
>> + */
>> +int kstrtobool(const char *s, unsigned int base, bool *res)
>> +{
>
> Being able to create the kstrtobool_from_user with a single macro
> invocation is convenient, but I don't think that justifies the ugliness
> of having an unused parameter. People reading this code or trying to use
> the interface will wonder what it's doing there, and it will generate
> slightly larger code for all the users of strtobool.
>
> So I'd just make a separate explicit definition of kstrtobool_from_user
> (the stack buffer sizing doesn't apply to the strings we want to parse
> anyway, though 11 is of course plenty).

Okay, thanks. So many things were bothering me, but I feared code
duplication would be seen as worse. I'm much happier to drop the
unused argument. :)

I'll send a v3 with all the changes.

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 4/4] param: convert some "on"/"off" users to strtobool

2016-02-05 Thread Kees Cook
This changes several users of manual "on"/"off" parsing to use strtobool.

Some side-effects:
- these uses will now parse y/n/1/0 meaningfully too
- the early_param uses will now bubble up parse errors

Signed-off-by: Kees Cook <keesc...@chromium.org>
Acked-by: Heiko Carstens <heiko.carst...@de.ibm.com>
Acked-by: Michael Ellerman <m...@ellerman.id.au>
Cc: x...@kernel.org
Cc: linuxppc-...@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
---
v3:
- retain __setup return values, andy.shevchenko
- remove unused "base" argument
---
 arch/powerpc/kernel/rtasd.c  |  7 ++-
 arch/powerpc/platforms/pseries/hotplug-cpu.c | 10 ++
 arch/s390/kernel/time.c  |  8 ++--
 arch/s390/kernel/topology.c  |  7 ++-
 arch/x86/kernel/aperture_64.c| 12 ++--
 include/linux/tick.h |  2 +-
 kernel/time/hrtimer.c| 10 ++
 kernel/time/tick-sched.c | 10 ++
 8 files changed, 15 insertions(+), 51 deletions(-)

diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 5a2c049c1c61..0ae5cb84d4e2 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -49,7 +49,7 @@ static unsigned int rtas_error_log_buffer_max;
 static unsigned int event_scan;
 static unsigned int rtas_event_scan_rate;
 
-static int full_rtas_msgs = 0;
+static bool full_rtas_msgs;
 
 /* Stop logging to nvram after first fatal error */
 static int logging_enabled; /* Until we initialize everything,
@@ -592,10 +592,7 @@ __setup("surveillance=", surveillance_setup);
 
 static int __init rtasmsgs_setup(char *str)
 {
-   if (strcmp(str, "on") == 0)
-   full_rtas_msgs = 1;
-   else if (strcmp(str, "off") == 0)
-   full_rtas_msgs = 0;
+   kstrtobool(str, _rtas_msgs);
 
return 1;
 }
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 32274f72fe3f..282837a1d74b 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -47,20 +47,14 @@ static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = 
CPU_STATE_OFFLINE;
 
 static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
 
-static int cede_offline_enabled __read_mostly = 1;
+static bool cede_offline_enabled __read_mostly = true;
 
 /*
  * Enable/disable cede_offline when available.
  */
 static int __init setup_cede_offline(char *str)
 {
-   if (!strcmp(str, "off"))
-   cede_offline_enabled = 0;
-   else if (!strcmp(str, "on"))
-   cede_offline_enabled = 1;
-   else
-   return 0;
-   return 1;
+   return (kstrtobool(str, _offline_enabled) == 0);
 }
 
 __setup("cede_offline=", setup_cede_offline);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 99f84ac31307..580bc7299ec3 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -1433,7 +1433,7 @@ device_initcall(etr_init_sysfs);
 /*
  * Server Time Protocol (STP) code.
  */
-static int stp_online;
+static bool stp_online;
 static struct stp_sstpi stp_info;
 static void *stp_page;
 
@@ -1444,11 +1444,7 @@ static struct timer_list stp_timer;
 
 static int __init early_parse_stp(char *p)
 {
-   if (strncmp(p, "off", 3) == 0)
-   stp_online = 0;
-   else if (strncmp(p, "on", 2) == 0)
-   stp_online = 1;
-   return 0;
+   return kstrtobool(p, _online);
 }
 early_param("stp", early_parse_stp);
 
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 40b8102fdadb..64298a867589 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -37,7 +37,7 @@ static void set_topology_timer(void);
 static void topology_work_fn(struct work_struct *work);
 static struct sysinfo_15_1_x *tl_info;
 
-static int topology_enabled = 1;
+static bool topology_enabled = true;
 static DECLARE_WORK(topology_work, topology_work_fn);
 
 /*
@@ -444,10 +444,7 @@ static const struct cpumask *cpu_book_mask(int cpu)
 
 static int __init early_parse_topology(char *p)
 {
-   if (strncmp(p, "off", 3))
-   return 0;
-   topology_enabled = 0;
-   return 0;
+   return kstrtobool(p, _enabled);
 }
 early_param("topology", early_parse_topology);
 
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 6e85f713641d..0a2bb1f62e72 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -227,19 +227,11 @@ static u32 __init search_agp_bridge(u32 *order, int 
*valid_agp)
return 0;
 }
 
-static int gart_fix_e820 __initdata = 1;
+static bool gart_fix_e820 __initdata = true;
 
 static int __init parse_gart_mem(char *p)
 

[PATCH v3 1/4] lib: move strtobool to kstrtobool

2016-02-05 Thread Kees Cook
Create the kstrtobool_from_user helper and moves strtobool logic into
the new kstrtobool (matching all the other kstrto* functions). Provides
an inline wrapper for existing strtobool callers.

Signed-off-by: Kees Cook <keesc...@chromium.org>
---
v3:
- drop needless "base" argument, rasmus
---
 include/linux/kernel.h |  2 ++
 include/linux/string.h |  6 +-
 lib/kstrtox.c  | 50 ++
 lib/string.c   | 29 -
 4 files changed, 57 insertions(+), 30 deletions(-)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f31638c6e873..f4fa2b29c38c 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -357,6 +357,7 @@ int __must_check kstrtou16(const char *s, unsigned int 
base, u16 *res);
 int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
 int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
 int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
+int __must_check kstrtobool(const char *s, bool *res);
 
 int __must_check kstrtoull_from_user(const char __user *s, size_t count, 
unsigned int base, unsigned long long *res);
 int __must_check kstrtoll_from_user(const char __user *s, size_t count, 
unsigned int base, long long *res);
@@ -368,6 +369,7 @@ int __must_check kstrtou16_from_user(const char __user *s, 
size_t count, unsigne
 int __must_check kstrtos16_from_user(const char __user *s, size_t count, 
unsigned int base, s16 *res);
 int __must_check kstrtou8_from_user(const char __user *s, size_t count, 
unsigned int base, u8 *res);
 int __must_check kstrtos8_from_user(const char __user *s, size_t count, 
unsigned int base, s8 *res);
+int __must_check kstrtobool_from_user(const char __user *s, size_t count, bool 
*res);
 
 static inline int __must_check kstrtou64_from_user(const char __user *s, 
size_t count, unsigned int base, u64 *res)
 {
diff --git a/include/linux/string.h b/include/linux/string.h
index 9eebc66d957a..2217224684c9 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -128,7 +128,11 @@ extern char **argv_split(gfp_t gfp, const char *str, int 
*argcp);
 extern void argv_free(char **argv);
 
 extern bool sysfs_streq(const char *s1, const char *s2);
-extern int strtobool(const char *s, bool *res);
+extern int kstrtobool(const char *s, bool *res);
+static inline int strtobool(const char *s, bool *res)
+{
+   return kstrtobool(s, res);
+}
 
 #ifdef CONFIG_BINARY_PRINTF
 int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index 94be244e8441..e8ba4a013e82 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -321,6 +321,56 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
 }
 EXPORT_SYMBOL(kstrtos8);
 
+/**
+ * kstrtobool - convert common user inputs into boolean values
+ * @s: input string
+ * @res: result
+ *
+ * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
+ * Otherwise it will return -EINVAL.  Value pointed to by res is
+ * updated upon finding a match.
+ */
+int kstrtobool(const char *s, bool *res)
+{
+   if (!s)
+   return -EINVAL;
+
+   switch (s[0]) {
+   case 'y':
+   case 'Y':
+   case '1':
+   *res = true;
+   return 0;
+   case 'n':
+   case 'N':
+   case '0':
+   *res = false;
+   return 0;
+   default:
+   break;
+   }
+
+   return -EINVAL;
+}
+EXPORT_SYMBOL(kstrtobool);
+
+/*
+ * Since "base" would be a nonsense argument, this open-codes the
+ * _from_user helper instead of using the helper macro below.
+ */
+int kstrtobool_from_user(const char __user *s, size_t count, bool *res)
+{
+   /* Longest string needed to differentiate, newline, terminator */
+   char buf[4];
+
+   count = min(count, sizeof(buf) - 1);
+   if (copy_from_user(buf, s, count))
+   return -EFAULT;
+   buf[count] = '\0';
+   return kstrtobool(buf, res);
+}
+EXPORT_SYMBOL(kstrtobool_from_user);
+
 #define kstrto_from_user(f, g, type)   \
 int f(const char __user *s, size_t count, unsigned int base, type *res)
\
 {  \
diff --git a/lib/string.c b/lib/string.c
index 0323c0d5629a..1a90db9bc6e1 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -630,35 +630,6 @@ bool sysfs_streq(const char *s1, const char *s2)
 }
 EXPORT_SYMBOL(sysfs_streq);
 
-/**
- * strtobool - convert common user inputs into boolean values
- * @s: input string
- * @res: result
- *
- * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
- * Otherwise it will return -EINVAL.  Value pointed to by res is
- * updated upon finding a match.
- */
-int strtobool(const char *s, bool *res)
-{
-   switch (s[0]) {
-   case 'y':
-   case 'Y':
-   case '1':
-   *res = t

[PATCH v3 3/4] lib: add "on"/"off" support to kstrtobool

2016-02-05 Thread Kees Cook
Add support for "on" and "off" when converting to boolean.

Signed-off-by: Kees Cook <keesc...@chromium.org>
---
v3:
- add dropped descripion change, andy.shevchenko
---
 lib/kstrtox.c | 20 +---
 1 file changed, 17 insertions(+), 3 deletions(-)

diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index e8ba4a013e82..d8a5cf66c316 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -326,9 +326,9 @@ EXPORT_SYMBOL(kstrtos8);
  * @s: input string
  * @res: result
  *
- * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
- * Otherwise it will return -EINVAL.  Value pointed to by res is
- * updated upon finding a match.
+ * This routine returns 0 iff the first character is one of 'Yy1Nn0', or
+ * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL.  Value
+ * pointed to by res is updated upon finding a match.
  */
 int kstrtobool(const char *s, bool *res)
 {
@@ -346,6 +346,20 @@ int kstrtobool(const char *s, bool *res)
case '0':
*res = false;
return 0;
+   case 'o':
+   case 'O':
+   switch (s[1]) {
+   case 'n':
+   case 'N':
+   *res = true;
+   return 0;
+   case 'f':
+   case 'F':
+   *res = false;
+   return 0;
+   default:
+   break;
+   }
default:
break;
}
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v3 2/4] lib: update single-char callers of strtobool

2016-02-05 Thread Kees Cook
Some callers of strtobool were passing a pointer to unterminated strings.
In preparation of adding multi-character processing to kstrtobool, update
the callers to not pass single-character pointers, and switch to using the
new kstrtobool_from_user helper where possible.

Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Amitkumar Karwar <akar...@marvell.com>
Cc: Nishant Sarmukadam <nisha...@marvell.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Steve French <sfre...@samba.org>
Cc: linux-c...@vger.kernel.org
---
v3:
- drop needless buffer, andy.shevchenko
- drop unused "base" argument
---
 drivers/net/wireless/marvell/mwifiex/debugfs.c | 10 ++---
 fs/cifs/cifs_debug.c   | 56 +++---
 fs/cifs/cifs_debug.h   |  2 +-
 fs/cifs/cifsfs.c   |  6 +--
 fs/cifs/cifsglob.h |  4 +-
 5 files changed, 24 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c 
b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index 0b9c580af988..2eff989c6d9f 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -880,14 +880,12 @@ mwifiex_reset_write(struct file *file,
 {
struct mwifiex_private *priv = file->private_data;
struct mwifiex_adapter *adapter = priv->adapter;
-   char cmd;
bool result;
+   int rc;
 
-   if (copy_from_user(, ubuf, sizeof(cmd)))
-   return -EFAULT;
-
-   if (strtobool(, ))
-   return -EINVAL;
+   rc = kstrtobool_from_user(ubuf, count, );
+   if (rc)
+   return rc;
 
if (!result)
return -EINVAL;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 50b268483302..788e19195991 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -255,7 +255,6 @@ static const struct file_operations 
cifs_debug_data_proc_fops = {
 static ssize_t cifs_stats_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
bool bv;
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
@@ -263,11 +262,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
struct cifs_ses *ses;
struct cifs_tcon *tcon;
 
-   rc = get_user(c, buffer);
-   if (rc)
-   return rc;
-
-   if (strtobool(, ) == 0) {
+   rc = kstrtobool_from_user(buffer, count, );
+   if (rc == 0) {
 #ifdef CONFIG_CIFS_STATS2
atomic_set(, 0);
atomic_set(, 0);
@@ -290,6 +286,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
}
}
spin_unlock(_tcp_ses_lock);
+   } else {
+   return rc;
}
 
return count;
@@ -433,17 +431,17 @@ static int cifsFYI_proc_open(struct inode *inode, struct 
file *file)
 static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
 {
-   char c;
+   char c[2] = { '\0' };
bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = get_user(c[0], buffer);
if (rc)
return rc;
-   if (strtobool(, ) == 0)
+   if (strtobool(c, ) == 0)
cifsFYI = bv;
-   else if ((c > '1') && (c <= '9'))
-   cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
+   else if ((c[0] > '1') && (c[0] <= '9'))
+   cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings 
*/
 
return count;
 }
@@ -471,20 +469,12 @@ static int cifs_linux_ext_proc_open(struct inode *inode, 
struct file *file)
 static ssize_t cifs_linux_ext_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
-   bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = kstrtobool_from_user(buffer, count, );
if (rc)
return rc;
 
-   rc = strtobool(, );
-   if (rc)
-   return rc;
-
-   linuxExtEnabled = bv;
-
return count;
 }
 
@@ -511,20 +501,12 @@ static int cifs_lookup_cache_proc_open(struct inode 
*inode, struct file *file)
 static ssize_t cifs_lookup_cache_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
-   bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = kstrtobool_from_user(buffer, count, );
if (rc)
return rc;
 
-   rc = strtobool(, );
-   if (rc)
-   return rc;
-
-   lookupCacheEnabled = bv;
-
return count;
 }
 
@@ -551,20 +533,12 @@ static int traceSMB_proc_open(struct inode *inode, struct 
file *file)
 static ssize_t traceSMB_proc_write(struct file *fi

Re: [PATCH v2 2/4] lib: update single-char callers of strtobool

2016-02-05 Thread Kees Cook
On Fri, Feb 5, 2016 at 2:46 AM, David Laight <david.lai...@aculab.com> wrote:
> From: Kees Cook
>> Sent: 04 February 2016 21:01
>> Some callers of strtobool were passing a pointer to unterminated strings.
>> In preparation of adding multi-character processing to kstrtobool, update
>> the callers to not pass single-character pointers, and switch to using the
>> new kstrtobool_from_user helper where possible.
>
> Personally I think you should change the name of the function so that the
> compiler (and linker) will pick up places that have not been changed.
> Relying on people to make the required changes will cause problems.

After the single-character users were pointed out, I looked for others
and there aren't any.

> The current code (presumably) treats "no", "nyet" and "nkjkkrkjrkjterkj" as 
> false.
> Changing that behaviour will break things.

There's no change there. All three of those will still be "false".
Perhaps my changelog shouldn't say "unterminated" but rather
"character array".

> If you want to support "on" and "off", then maybe check for the supplied 
> string
> starting with the character sequences "on\0" and "off\0" (as well as any 
> others).
> This doesn't need the input string be '\0' terminated - since you match y and 
> n
> without looking at the 2nd byte.
> You'd have to be extremely unlucky to get a page fault in the 3 bytes
> following an 'o' if the caller supplied a single byte buffer.

I'd prefer to keep the switch statement as short as possible, and I
don't want to do full string compares. And as you say, even fixing the
single-byte callers seems like a needless exercise, but seeing as how
it's a net clean-up, I think it's good they way I've got the series.

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 2/4] lib: update single-char callers of strtobool

2016-02-04 Thread Kees Cook
Some callers of strtobool were passing a pointer to unterminated strings.
In preparation of adding multi-character processing to kstrtobool, update
the callers to not pass single-character pointers, and switch to using the
new kstrtobool_from_user helper where possible.

Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Amitkumar Karwar <akar...@marvell.com>
Cc: Nishant Sarmukadam <nisha...@marvell.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Steve French <sfre...@samba.org>
Cc: linux-c...@vger.kernel.org
---
 drivers/net/wireless/marvell/mwifiex/debugfs.c | 10 ++---
 fs/cifs/cifs_debug.c   | 58 +++---
 fs/cifs/cifs_debug.h   |  2 +-
 fs/cifs/cifsfs.c   |  6 +--
 fs/cifs/cifsglob.h |  4 +-
 5 files changed, 26 insertions(+), 54 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c 
b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index 0b9c580af988..bd061b02bc04 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -880,14 +880,12 @@ mwifiex_reset_write(struct file *file,
 {
struct mwifiex_private *priv = file->private_data;
struct mwifiex_adapter *adapter = priv->adapter;
-   char cmd;
bool result;
+   int rc;
 
-   if (copy_from_user(, ubuf, sizeof(cmd)))
-   return -EFAULT;
-
-   if (strtobool(, ))
-   return -EINVAL;
+   rc = kstrtobool_from_user(ubuf, count, 0, );
+   if (rc)
+   return rc;
 
if (!result)
return -EINVAL;
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 50b268483302..6ee59abcb69b 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -255,7 +255,6 @@ static const struct file_operations 
cifs_debug_data_proc_fops = {
 static ssize_t cifs_stats_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
bool bv;
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
@@ -263,11 +262,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
struct cifs_ses *ses;
struct cifs_tcon *tcon;
 
-   rc = get_user(c, buffer);
-   if (rc)
-   return rc;
-
-   if (strtobool(, ) == 0) {
+   rc = kstrtobool_from_user(buffer, count, 0, );
+   if (rc == 0) {
 #ifdef CONFIG_CIFS_STATS2
atomic_set(, 0);
atomic_set(, 0);
@@ -290,6 +286,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
}
}
spin_unlock(_tcp_ses_lock);
+   } else {
+   return rc;
}
 
return count;
@@ -433,17 +431,17 @@ static int cifsFYI_proc_open(struct inode *inode, struct 
file *file)
 static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
 {
-   char c;
+   char c[2] = { '\0' };
bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = get_user(c[0], buffer);
if (rc)
return rc;
-   if (strtobool(, ) == 0)
+   if (strtobool(c, ) == 0)
cifsFYI = bv;
-   else if ((c > '1') && (c <= '9'))
-   cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
+   else if ((c[0] > '1') && (c[0] <= '9'))
+   cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings 
*/
 
return count;
 }
@@ -471,20 +469,12 @@ static int cifs_linux_ext_proc_open(struct inode *inode, 
struct file *file)
 static ssize_t cifs_linux_ext_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
-   bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = kstrtobool_from_user(buffer, count, 0, );
if (rc)
return rc;
 
-   rc = strtobool(, );
-   if (rc)
-   return rc;
-
-   linuxExtEnabled = bv;
-
return count;
 }
 
@@ -511,20 +501,12 @@ static int cifs_lookup_cache_proc_open(struct inode 
*inode, struct file *file)
 static ssize_t cifs_lookup_cache_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
-   bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = kstrtobool_from_user(buffer, count, 0, );
if (rc)
return rc;
 
-   rc = strtobool(, );
-   if (rc)
-   return rc;
-
-   lookupCacheEnabled = bv;
-
return count;
 }
 
@@ -551,20 +533,12 @@ static int traceSMB_proc_open(struct inode *inode, struct 
file *file)
 static ssize_t traceSMB_proc_write(struct file *file, const char __user 
*buffer,
size_t count, loff_t *ppos)
 {
-   ch

[PATCH v2 3/4] lib: add "on"/"off" support to kstrtobool

2016-02-04 Thread Kees Cook
Add support for "on" and "off" when converting to boolean.

Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 lib/kstrtox.c | 14 ++
 1 file changed, 14 insertions(+)

diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index e18f088704d7..09e83a19a96d 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -347,6 +347,20 @@ int kstrtobool(const char *s, unsigned int base, bool *res)
case '0':
*res = false;
return 0;
+   case 'o':
+   case 'O':
+   switch (s[1]) {
+   case 'n':
+   case 'N':
+   *res = true;
+   return 0;
+   case 'f':
+   case 'F':
+   *res = false;
+   return 0;
+   default:
+   break;
+   }
default:
break;
}
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 0/4] lib: add "on" and "off" to strtobool

2016-02-04 Thread Kees Cook
This consolidates logic for handling "on"/"off" parsing for bools into
the strtobool function, by way of moving it into kstrtobool (with helpers),
and updating various callers.

 arch/powerpc/kernel/rtasd.c|9 ---
 arch/powerpc/platforms/pseries/hotplug-cpu.c   |   10 
 arch/s390/kernel/time.c|8 ---
 arch/s390/kernel/topology.c|7 ---
 arch/x86/kernel/aperture_64.c  |   12 -
 drivers/net/wireless/marvell/mwifiex/debugfs.c |   10 +---
 fs/cifs/cifs_debug.c   |   58 ++---
 fs/cifs/cifs_debug.h   |2 
 fs/cifs/cifsfs.c   |6 +-
 fs/cifs/cifsglob.h |4 -
 include/linux/kernel.h |3 +
 include/linux/string.h |6 ++
 include/linux/tick.h   |2 
 kernel/time/hrtimer.c  |   10 
 kernel/time/tick-sched.c   |   10 
 lib/kstrtox.c  |   49 +
 lib/string.c   |   29 
 17 files changed, 98 insertions(+), 137 deletions(-)

-Kees

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH v2 1/4] lib: move strtobool to kstrtobool

2016-02-04 Thread Kees Cook
Create the kstrtobool_from_user helper and moves strtobool logic into
the new kstrtobool (matching all the other kstrto* functions). Provides
an inline wrapper for existing strtobool callers.

Signed-off-by: Kees Cook <keesc...@chromium.org>
---
 include/linux/kernel.h |  3 +++
 include/linux/string.h |  6 +-
 lib/kstrtox.c  | 35 +++
 lib/string.c   | 29 -
 4 files changed, 43 insertions(+), 30 deletions(-)

diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index f31638c6e873..cdc25f47a23f 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -357,6 +357,7 @@ int __must_check kstrtou16(const char *s, unsigned int 
base, u16 *res);
 int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
 int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
 int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
+int __must_check kstrtobool(const char *s, unsigned int base, bool *res);
 
 int __must_check kstrtoull_from_user(const char __user *s, size_t count, 
unsigned int base, unsigned long long *res);
 int __must_check kstrtoll_from_user(const char __user *s, size_t count, 
unsigned int base, long long *res);
@@ -368,6 +369,8 @@ int __must_check kstrtou16_from_user(const char __user *s, 
size_t count, unsigne
 int __must_check kstrtos16_from_user(const char __user *s, size_t count, 
unsigned int base, s16 *res);
 int __must_check kstrtou8_from_user(const char __user *s, size_t count, 
unsigned int base, u8 *res);
 int __must_check kstrtos8_from_user(const char __user *s, size_t count, 
unsigned int base, s8 *res);
+int __must_check kstrtobool_from_user(const char __user *s, size_t count,
+ unsigned int base, bool *res);
 
 static inline int __must_check kstrtou64_from_user(const char __user *s, 
size_t count, unsigned int base, u64 *res)
 {
diff --git a/include/linux/string.h b/include/linux/string.h
index 9eebc66d957a..d2fb21b1081d 100644
--- a/include/linux/string.h
+++ b/include/linux/string.h
@@ -128,7 +128,11 @@ extern char **argv_split(gfp_t gfp, const char *str, int 
*argcp);
 extern void argv_free(char **argv);
 
 extern bool sysfs_streq(const char *s1, const char *s2);
-extern int strtobool(const char *s, bool *res);
+extern int kstrtobool(const char *s, unsigned int base, bool *res);
+static inline int strtobool(const char *s, bool *res)
+{
+   return kstrtobool(s, 0, res);
+}
 
 #ifdef CONFIG_BINARY_PRINTF
 int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
diff --git a/lib/kstrtox.c b/lib/kstrtox.c
index 94be244e8441..e18f088704d7 100644
--- a/lib/kstrtox.c
+++ b/lib/kstrtox.c
@@ -321,6 +321,40 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
 }
 EXPORT_SYMBOL(kstrtos8);
 
+/**
+ * kstrtobool - convert common user inputs into boolean values
+ * @s: input string
+ * @base: ignored
+ * @res: result
+ *
+ * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
+ * Otherwise it will return -EINVAL.  Value pointed to by res is
+ * updated upon finding a match.
+ */
+int kstrtobool(const char *s, unsigned int base, bool *res)
+{
+   if (!s)
+   return -EINVAL;
+
+   switch (s[0]) {
+   case 'y':
+   case 'Y':
+   case '1':
+   *res = true;
+   return 0;
+   case 'n':
+   case 'N':
+   case '0':
+   *res = false;
+   return 0;
+   default:
+   break;
+   }
+
+   return -EINVAL;
+}
+EXPORT_SYMBOL(kstrtobool);
+
 #define kstrto_from_user(f, g, type)   \
 int f(const char __user *s, size_t count, unsigned int base, type *res)
\
 {  \
@@ -345,3 +379,4 @@ kstrto_from_user(kstrtou16_from_user,   kstrtou16,  
u16);
 kstrto_from_user(kstrtos16_from_user,  kstrtos16,  s16);
 kstrto_from_user(kstrtou8_from_user,   kstrtou8,   u8);
 kstrto_from_user(kstrtos8_from_user,   kstrtos8,   s8);
+kstrto_from_user(kstrtobool_from_user, kstrtobool, bool);
diff --git a/lib/string.c b/lib/string.c
index 0323c0d5629a..1a90db9bc6e1 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -630,35 +630,6 @@ bool sysfs_streq(const char *s1, const char *s2)
 }
 EXPORT_SYMBOL(sysfs_streq);
 
-/**
- * strtobool - convert common user inputs into boolean values
- * @s: input string
- * @res: result
- *
- * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
- * Otherwise it will return -EINVAL.  Value pointed to by res is
- * updated upon finding a match.
- */
-int strtobool(const char *s, bool *res)
-{
-   switch (s[0]) {
-   case 'y':
-   case 'Y':
-   case '1':
-   *res = true;
-   break;
-   case 'n':
-   case 'N':
-   case '0':
-   *res = false;
-   break;
-   d

Re: [PATCH v2 1/4] lib: move strtobool to kstrtobool

2016-02-04 Thread Kees Cook
On Thu, Feb 4, 2016 at 2:43 PM, Andy Shevchenko
<andy.shevche...@gmail.com> wrote:
> On Thu, Feb 4, 2016 at 11:00 PM, Kees Cook <keesc...@chromium.org> wrote:
>> Create the kstrtobool_from_user helper and moves strtobool logic into
>> the new kstrtobool (matching all the other kstrto* functions). Provides
>> an inline wrapper for existing strtobool callers.
>>
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>
> Reviewed-by: Andy Shevchenko <andy.shevche...@gmail.com>
>
> One minor below.

Thanks!

>
>> ---
>>  include/linux/kernel.h |  3 +++
>>  include/linux/string.h |  6 +-
>>  lib/kstrtox.c  | 35 +++
>>  lib/string.c   | 29 -
>>  4 files changed, 43 insertions(+), 30 deletions(-)
>>
>> diff --git a/include/linux/kernel.h b/include/linux/kernel.h
>> index f31638c6e873..cdc25f47a23f 100644
>> --- a/include/linux/kernel.h
>> +++ b/include/linux/kernel.h
>> @@ -357,6 +357,7 @@ int __must_check kstrtou16(const char *s, unsigned int 
>> base, u16 *res);
>>  int __must_check kstrtos16(const char *s, unsigned int base, s16 *res);
>>  int __must_check kstrtou8(const char *s, unsigned int base, u8 *res);
>>  int __must_check kstrtos8(const char *s, unsigned int base, s8 *res);
>> +int __must_check kstrtobool(const char *s, unsigned int base, bool *res);
>>
>>  int __must_check kstrtoull_from_user(const char __user *s, size_t count, 
>> unsigned int base, unsigned long long *res);
>>  int __must_check kstrtoll_from_user(const char __user *s, size_t count, 
>> unsigned int base, long long *res);
>> @@ -368,6 +369,8 @@ int __must_check kstrtou16_from_user(const char __user 
>> *s, size_t count, unsigne
>>  int __must_check kstrtos16_from_user(const char __user *s, size_t count, 
>> unsigned int base, s16 *res);
>>  int __must_check kstrtou8_from_user(const char __user *s, size_t count, 
>> unsigned int base, u8 *res);
>>  int __must_check kstrtos8_from_user(const char __user *s, size_t count, 
>> unsigned int base, s8 *res);
>
>> +int __must_check kstrtobool_from_user(const char __user *s, size_t count,
>> + unsigned int base, bool *res);
>
> We already are using long lines here, perhaps do the same?

I went back and forth on that, and decided that between checkpatch
yelling at me, and trying to be an agent of less entropy, I wrapped
the definition. I am fine either way, though.

-Kees

>
>>
>>  static inline int __must_check kstrtou64_from_user(const char __user *s, 
>> size_t count, unsigned int base, u64 *res)
>>  {
>> diff --git a/include/linux/string.h b/include/linux/string.h
>> index 9eebc66d957a..d2fb21b1081d 100644
>> --- a/include/linux/string.h
>> +++ b/include/linux/string.h
>> @@ -128,7 +128,11 @@ extern char **argv_split(gfp_t gfp, const char *str, 
>> int *argcp);
>>  extern void argv_free(char **argv);
>>
>>  extern bool sysfs_streq(const char *s1, const char *s2);
>> -extern int strtobool(const char *s, bool *res);
>> +extern int kstrtobool(const char *s, unsigned int base, bool *res);
>> +static inline int strtobool(const char *s, bool *res)
>> +{
>> +   return kstrtobool(s, 0, res);
>> +}
>>
>>  #ifdef CONFIG_BINARY_PRINTF
>>  int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
>> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
>> index 94be244e8441..e18f088704d7 100644
>> --- a/lib/kstrtox.c
>> +++ b/lib/kstrtox.c
>> @@ -321,6 +321,40 @@ int kstrtos8(const char *s, unsigned int base, s8 *res)
>>  }
>>  EXPORT_SYMBOL(kstrtos8);
>>
>> +/**
>> + * kstrtobool - convert common user inputs into boolean values
>> + * @s: input string
>> + * @base: ignored
>> + * @res: result
>> + *
>> + * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
>> + * Otherwise it will return -EINVAL.  Value pointed to by res is
>> + * updated upon finding a match.
>> + */
>> +int kstrtobool(const char *s, unsigned int base, bool *res)
>> +{
>> +   if (!s)
>> +   return -EINVAL;
>> +
>> +   switch (s[0]) {
>> +   case 'y':
>> +   case 'Y':
>> +   case '1':
>> +   *res = true;
>> +   return 0;
>> +   case 'n':
>> +   case 'N':
>> +   case '0':
>> +   *res = false;
>> +   return 0;
>> +   default:
>> +   break;
>> +   }
>> +
>

Re: [PATCH v2 2/4] lib: update single-char callers of strtobool

2016-02-04 Thread Kees Cook
On Thu, Feb 4, 2016 at 2:59 PM, Andy Shevchenko
<andy.shevche...@gmail.com> wrote:
> On Thu, Feb 4, 2016 at 11:00 PM, Kees Cook <keesc...@chromium.org> wrote:
>> Some callers of strtobool were passing a pointer to unterminated strings.
>> In preparation of adding multi-character processing to kstrtobool, update
>> the callers to not pass single-character pointers, and switch to using the
>> new kstrtobool_from_user helper where possible.
>
> Looks much better now!
> My comment below.
>
>>
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>> Cc: Amitkumar Karwar <akar...@marvell.com>
>> Cc: Nishant Sarmukadam <nisha...@marvell.com>
>> Cc: Kalle Valo <kv...@codeaurora.org>
>> Cc: Steve French <sfre...@samba.org>
>> Cc: linux-c...@vger.kernel.org
>> ---
>>  drivers/net/wireless/marvell/mwifiex/debugfs.c | 10 ++---
>>  fs/cifs/cifs_debug.c   | 58 
>> +++---
>>  fs/cifs/cifs_debug.h   |  2 +-
>>  fs/cifs/cifsfs.c   |  6 +--
>>  fs/cifs/cifsglob.h |  4 +-
>>  5 files changed, 26 insertions(+), 54 deletions(-)
>>
>> diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c 
>> b/drivers/net/wireless/marvell/mwifiex/debugfs.c
>> index 0b9c580af988..bd061b02bc04 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
>> +++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
>> @@ -880,14 +880,12 @@ mwifiex_reset_write(struct file *file,
>>  {
>> struct mwifiex_private *priv = file->private_data;
>> struct mwifiex_adapter *adapter = priv->adapter;
>> -   char cmd;
>> bool result;
>> +   int rc;
>>
>> -   if (copy_from_user(, ubuf, sizeof(cmd)))
>> -   return -EFAULT;
>> -
>> -   if (strtobool(, ))
>> -   return -EINVAL;
>> +   rc = kstrtobool_from_user(ubuf, count, 0, );
>> +   if (rc)
>> +   return rc;
>>
>> if (!result)
>> return -EINVAL;
>> diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
>> index 50b268483302..6ee59abcb69b 100644
>> --- a/fs/cifs/cifs_debug.c
>> +++ b/fs/cifs/cifs_debug.c
>> @@ -255,7 +255,6 @@ static const struct file_operations 
>> cifs_debug_data_proc_fops = {
>>  static ssize_t cifs_stats_proc_write(struct file *file,
>> const char __user *buffer, size_t count, loff_t *ppos)
>>  {
>> -   char c;
>> bool bv;
>> int rc;
>> struct list_head *tmp1, *tmp2, *tmp3;
>> @@ -263,11 +262,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
>> struct cifs_ses *ses;
>> struct cifs_tcon *tcon;
>>
>> -   rc = get_user(c, buffer);
>> -   if (rc)
>> -   return rc;
>> -
>> -   if (strtobool(, ) == 0) {
>> +   rc = kstrtobool_from_user(buffer, count, 0, );
>> +   if (rc == 0) {
>>  #ifdef CONFIG_CIFS_STATS2
>> atomic_set(, 0);
>> atomic_set(, 0);
>> @@ -290,6 +286,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
>> }
>> }
>> spin_unlock(_tcp_ses_lock);
>> +   } else {
>> +   return rc;
>> }
>>
>> return count;
>> @@ -433,17 +431,17 @@ static int cifsFYI_proc_open(struct inode *inode, 
>> struct file *file)
>>  static ssize_t cifsFYI_proc_write(struct file *file, const char __user 
>> *buffer,
>> size_t count, loff_t *ppos)
>>  {
>> -   char c;
>> +   char c[2] = { '\0' };
>> bool bv;
>> int rc;
>>
>> -   rc = get_user(c, buffer);
>> +   rc = get_user(c[0], buffer);
>
>> if (rc)
>> return rc;
>> -   if (strtobool(, ) == 0)
>> +   if (strtobool(c, ) == 0)
>> cifsFYI = bv;
>> -   else if ((c > '1') && (c <= '9'))
>> -   cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings 
>> */
>> +   else if ((c[0] > '1') && (c[0] <= '9'))
>> +   cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for 
>> meanings */
>>
>> return count;
>>  }
>> @@ -471,20 +469,12 @@ static int cifs_linux_ext_proc_open(struct inode 
>> *inode, struct file *file)
>>  static ssize_t cifs_lin

[PATCH v2 4/4] param: convert some "on"/"off" users to strtobool

2016-02-04 Thread Kees Cook
This changes several users of manual "on"/"off" parsing to use strtobool.
(Which means they will now parse y/n/1/0 meaningfully too.)

Signed-off-by: Kees Cook <keesc...@chromium.org>
Acked-by: Heiko Carstens <heiko.carst...@de.ibm.com>
Acked-by: Michael Ellerman <m...@ellerman.id.au>
Cc: x...@kernel.org
Cc: linuxppc-...@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
---
 arch/powerpc/kernel/rtasd.c  |  9 ++---
 arch/powerpc/platforms/pseries/hotplug-cpu.c | 10 ++
 arch/s390/kernel/time.c  |  8 ++--
 arch/s390/kernel/topology.c  |  7 ++-
 arch/x86/kernel/aperture_64.c| 12 ++--
 include/linux/tick.h |  2 +-
 kernel/time/hrtimer.c| 10 ++
 kernel/time/tick-sched.c | 10 ++
 8 files changed, 15 insertions(+), 53 deletions(-)

diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 5a2c049c1c61..567ed5a2f43a 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -49,7 +49,7 @@ static unsigned int rtas_error_log_buffer_max;
 static unsigned int event_scan;
 static unsigned int rtas_event_scan_rate;
 
-static int full_rtas_msgs = 0;
+static bool full_rtas_msgs;
 
 /* Stop logging to nvram after first fatal error */
 static int logging_enabled; /* Until we initialize everything,
@@ -592,11 +592,6 @@ __setup("surveillance=", surveillance_setup);
 
 static int __init rtasmsgs_setup(char *str)
 {
-   if (strcmp(str, "on") == 0)
-   full_rtas_msgs = 1;
-   else if (strcmp(str, "off") == 0)
-   full_rtas_msgs = 0;
-
-   return 1;
+   return kstrtobool(str, 0, _rtas_msgs);
 }
 __setup("rtasmsgs=", rtasmsgs_setup);
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 32274f72fe3f..b9787cae4108 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -47,20 +47,14 @@ static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = 
CPU_STATE_OFFLINE;
 
 static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
 
-static int cede_offline_enabled __read_mostly = 1;
+static bool cede_offline_enabled __read_mostly = true;
 
 /*
  * Enable/disable cede_offline when available.
  */
 static int __init setup_cede_offline(char *str)
 {
-   if (!strcmp(str, "off"))
-   cede_offline_enabled = 0;
-   else if (!strcmp(str, "on"))
-   cede_offline_enabled = 1;
-   else
-   return 0;
-   return 1;
+   return kstrtobool(str, 0, _offline_enabled);
 }
 
 __setup("cede_offline=", setup_cede_offline);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 99f84ac31307..dff6ce1b84b2 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -1433,7 +1433,7 @@ device_initcall(etr_init_sysfs);
 /*
  * Server Time Protocol (STP) code.
  */
-static int stp_online;
+static bool stp_online;
 static struct stp_sstpi stp_info;
 static void *stp_page;
 
@@ -1444,11 +1444,7 @@ static struct timer_list stp_timer;
 
 static int __init early_parse_stp(char *p)
 {
-   if (strncmp(p, "off", 3) == 0)
-   stp_online = 0;
-   else if (strncmp(p, "on", 2) == 0)
-   stp_online = 1;
-   return 0;
+   return kstrtobool(p, 0, _online);
 }
 early_param("stp", early_parse_stp);
 
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 40b8102fdadb..5d8a80651f61 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -37,7 +37,7 @@ static void set_topology_timer(void);
 static void topology_work_fn(struct work_struct *work);
 static struct sysinfo_15_1_x *tl_info;
 
-static int topology_enabled = 1;
+static bool topology_enabled = true;
 static DECLARE_WORK(topology_work, topology_work_fn);
 
 /*
@@ -444,10 +444,7 @@ static const struct cpumask *cpu_book_mask(int cpu)
 
 static int __init early_parse_topology(char *p)
 {
-   if (strncmp(p, "off", 3))
-   return 0;
-   topology_enabled = 0;
-   return 0;
+   return kstrtobool(p, 0, _enabled);
 }
 early_param("topology", early_parse_topology);
 
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 6e85f713641d..6b423754083a 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -227,19 +227,11 @@ static u32 __init search_agp_bridge(u32 *order, int 
*valid_agp)
return 0;
 }
 
-static int gart_fix_e820 __initdata = 1;
+static bool gart_fix_e820 __initdata = true;
 
 static int __init parse_gart_mem(char *p)
 {
-   if (!p)
-   return -EINVAL;
-
-   if (!strncmp(p, "off", 3))
-   gart_fix_e820 = 0;

Re: [PATCH v2 3/4] lib: add "on"/"off" support to kstrtobool

2016-02-04 Thread Kees Cook
On Thu, Feb 4, 2016 at 3:00 PM, Andy Shevchenko
<andy.shevche...@gmail.com> wrote:
> On Thu, Feb 4, 2016 at 11:00 PM, Kees Cook <keesc...@chromium.org> wrote:
>> Add support for "on" and "off" when converting to boolean.
>>
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>> ---
>>  lib/kstrtox.c | 14 ++
>>  1 file changed, 14 insertions(+)
>>
>> diff --git a/lib/kstrtox.c b/lib/kstrtox.c
>> index e18f088704d7..09e83a19a96d 100644
>> --- a/lib/kstrtox.c
>> +++ b/lib/kstrtox.c
>> @@ -347,6 +347,20 @@ int kstrtobool(const char *s, unsigned int base, bool 
>> *res)
>
> Forgot update description?

Argh, thank you. Good eye. Sent another update.

-Kees

>
>> case '0':
>> *res = false;
>> return 0;
>> +   case 'o':
>> +   case 'O':
>> +   switch (s[1]) {
>> +   case 'n':
>> +   case 'N':
>> +   *res = true;
>> +   return 0;
>> +   case 'f':
>> +   case 'F':
>> +   *res = false;
>> +   return 0;
>> +   default:
>> +   break;
>> +   }
>> default:
>> break;
>> }
>> --
>> 2.6.3
>>
>
>
>
> --
> With Best Regards,
> Andy Shevchenko



-- 
Kees Cook
Chrome OS & Brillo Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH v2 4/4] param: convert some "on"/"off" users to strtobool

2016-02-04 Thread Kees Cook
On Thu, Feb 4, 2016 at 4:11 PM, Kees Cook <keesc...@chromium.org> wrote:
> On Thu, Feb 4, 2016 at 3:04 PM, Andy Shevchenko
> <andy.shevche...@gmail.com> wrote:
>> On Thu, Feb 4, 2016 at 11:00 PM, Kees Cook <keesc...@chromium.org> wrote:
>>> This changes several users of manual "on"/"off" parsing to use strtobool.
>>> (Which means they will now parse y/n/1/0 meaningfully too.)
>>>
>>
>> I like this change, but can you carefully check the acceptance of the
>> returned value?
>> Briefly I saw 1 or 0 as okay in different places.
>
> Maybe I missed something, but I think this is actually a bug fix. The
> two cases are early_param and __setup:
>
> For early_param, the functions are called when walking the command
> line in do_early_param via parse_args in parse_early_options. Any
> non-zero return values produce a warning (in do_early_param not
> parse_args). So this is a bug fix, since the function I touched would
> (almost) always return 0, even with bad values (i.e. fixes unreported
> bad arguments):
>
> early_param early_parse_stp always 0
> early_param early_parse_topology always 0
> early_param parse_gart_mem always 0 unless !p (then -EINVAL)
>
> For __setup, these are handled by obsolete_checksetup via
> unknown_bootoption via parse_args in start_kernel, as a way to merge
> __setup calls that should really be in param (i.e. non-early __setup).
> Return values are bubbled up into parse_args and hit:
>
> default:
> pr_err("%s: `%s' invalid for parameter `%s'\n",
>doing, val ?: "", param);
> break;
>
> So this is also a bug fix, since these __setup functions returned inverted
> values or always failed:
>
> __setup rtasmsgs_setup always 1
> __setup setup_cede_offline 1 on success, otherwise 0
> __setup setup_hrtimer_hres 1 on success, otherwise 0
> __setup setup_tick_nohz 1 on success, otherwise 0
>
> So if you specified any of these, they would trigger a bogus "invalid
> parameter" report.
>
> I will double-check...

I am wrong! __setup functions (as handled by unknown_bootoption) need
to return 1, or they end up in the init environment. I will send a
fix...

-Kees

>
> -Kees
>
>>
>>
>>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>>> Acked-by: Heiko Carstens <heiko.carst...@de.ibm.com>
>>> Acked-by: Michael Ellerman <m...@ellerman.id.au>
>>> Cc: x...@kernel.org
>>> Cc: linuxppc-...@lists.ozlabs.org
>>> Cc: linux-s...@vger.kernel.org
>>> ---
>>>  arch/powerpc/kernel/rtasd.c  |  9 ++---
>>>  arch/powerpc/platforms/pseries/hotplug-cpu.c | 10 ++
>>>  arch/s390/kernel/time.c  |  8 ++--
>>>  arch/s390/kernel/topology.c  |  7 ++-
>>>  arch/x86/kernel/aperture_64.c| 12 ++--
>>>  include/linux/tick.h |  2 +-
>>>  kernel/time/hrtimer.c| 10 ++
>>>  kernel/time/tick-sched.c | 10 ++
>>>  8 files changed, 15 insertions(+), 53 deletions(-)
>>>
>>> diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
>>> index 5a2c049c1c61..567ed5a2f43a 100644
>>> --- a/arch/powerpc/kernel/rtasd.c
>>> +++ b/arch/powerpc/kernel/rtasd.c
>>> @@ -49,7 +49,7 @@ static unsigned int rtas_error_log_buffer_max;
>>>  static unsigned int event_scan;
>>>  static unsigned int rtas_event_scan_rate;
>>>
>>> -static int full_rtas_msgs = 0;
>>> +static bool full_rtas_msgs;
>>>
>>>  /* Stop logging to nvram after first fatal error */
>>>  static int logging_enabled; /* Until we initialize everything,
>>> @@ -592,11 +592,6 @@ __setup("surveillance=", surveillance_setup);
>>>
>>>  static int __init rtasmsgs_setup(char *str)
>>>  {
>>> -   if (strcmp(str, "on") == 0)
>>> -   full_rtas_msgs = 1;
>>> -   else if (strcmp(str, "off") == 0)
>>> -   full_rtas_msgs = 0;
>>> -
>>> -   return 1;
>>> +   return kstrtobool(str, 0, _rtas_msgs);
>>>  }
>>>  __setup("rtasmsgs=", rtasmsgs_setup);
>>> diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
>>> b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>>> index 32274f72fe3f..b9787cae4108 100644
>>> --- a/arch/powerpc/platforms/pseries/ho

Re: [PATCH v2 4/4] param: convert some "on"/"off" users to strtobool

2016-02-04 Thread Kees Cook
On Thu, Feb 4, 2016 at 3:04 PM, Andy Shevchenko
<andy.shevche...@gmail.com> wrote:
> On Thu, Feb 4, 2016 at 11:00 PM, Kees Cook <keesc...@chromium.org> wrote:
>> This changes several users of manual "on"/"off" parsing to use strtobool.
>> (Which means they will now parse y/n/1/0 meaningfully too.)
>>
>
> I like this change, but can you carefully check the acceptance of the
> returned value?
> Briefly I saw 1 or 0 as okay in different places.

Maybe I missed something, but I think this is actually a bug fix. The
two cases are early_param and __setup:

For early_param, the functions are called when walking the command
line in do_early_param via parse_args in parse_early_options. Any
non-zero return values produce a warning (in do_early_param not
parse_args). So this is a bug fix, since the function I touched would
(almost) always return 0, even with bad values (i.e. fixes unreported
bad arguments):

early_param early_parse_stp always 0
early_param early_parse_topology always 0
early_param parse_gart_mem always 0 unless !p (then -EINVAL)

For __setup, these are handled by obsolete_checksetup via
unknown_bootoption via parse_args in start_kernel, as a way to merge
__setup calls that should really be in param (i.e. non-early __setup).
Return values are bubbled up into parse_args and hit:

default:
pr_err("%s: `%s' invalid for parameter `%s'\n",
   doing, val ?: "", param);
break;

So this is also a bug fix, since these __setup functions returned inverted
values or always failed:

__setup rtasmsgs_setup always 1
__setup setup_cede_offline 1 on success, otherwise 0
__setup setup_hrtimer_hres 1 on success, otherwise 0
__setup setup_tick_nohz 1 on success, otherwise 0

So if you specified any of these, they would trigger a bogus "invalid
parameter" report.

I will double-check...

-Kees

>
>
>> Signed-off-by: Kees Cook <keesc...@chromium.org>
>> Acked-by: Heiko Carstens <heiko.carst...@de.ibm.com>
>> Acked-by: Michael Ellerman <m...@ellerman.id.au>
>> Cc: x...@kernel.org
>> Cc: linuxppc-...@lists.ozlabs.org
>> Cc: linux-s...@vger.kernel.org
>> ---
>>  arch/powerpc/kernel/rtasd.c  |  9 ++---
>>  arch/powerpc/platforms/pseries/hotplug-cpu.c | 10 ++
>>  arch/s390/kernel/time.c  |  8 ++--
>>  arch/s390/kernel/topology.c  |  7 ++-
>>  arch/x86/kernel/aperture_64.c| 12 ++--
>>  include/linux/tick.h |  2 +-
>>  kernel/time/hrtimer.c| 10 ++
>>  kernel/time/tick-sched.c | 10 ++
>>  8 files changed, 15 insertions(+), 53 deletions(-)
>>
>> diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
>> index 5a2c049c1c61..567ed5a2f43a 100644
>> --- a/arch/powerpc/kernel/rtasd.c
>> +++ b/arch/powerpc/kernel/rtasd.c
>> @@ -49,7 +49,7 @@ static unsigned int rtas_error_log_buffer_max;
>>  static unsigned int event_scan;
>>  static unsigned int rtas_event_scan_rate;
>>
>> -static int full_rtas_msgs = 0;
>> +static bool full_rtas_msgs;
>>
>>  /* Stop logging to nvram after first fatal error */
>>  static int logging_enabled; /* Until we initialize everything,
>> @@ -592,11 +592,6 @@ __setup("surveillance=", surveillance_setup);
>>
>>  static int __init rtasmsgs_setup(char *str)
>>  {
>> -   if (strcmp(str, "on") == 0)
>> -   full_rtas_msgs = 1;
>> -   else if (strcmp(str, "off") == 0)
>> -   full_rtas_msgs = 0;
>> -
>> -   return 1;
>> +   return kstrtobool(str, 0, _rtas_msgs);
>>  }
>>  __setup("rtasmsgs=", rtasmsgs_setup);
>> diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
>> b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> index 32274f72fe3f..b9787cae4108 100644
>> --- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> +++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
>> @@ -47,20 +47,14 @@ static DEFINE_PER_CPU(enum cpu_state_vals, 
>> current_state) = CPU_STATE_OFFLINE;
>>
>>  static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
>>
>> -static int cede_offline_enabled __read_mostly = 1;
>> +static bool cede_offline_enabled __read_mostly = true;
>>
>>  /*
>>   * Enable/disable cede_offline when available.
>>   */
>>  static int __init setup_cede_offline(char *str)
>>  {
>> -   if (!strcmp(str, "off"))
>> -   cede_offline_enabled = 

Re: [PATCH 1/3] lib: fix callers of strtobool to use char array

2016-02-04 Thread Kees Cook
On Mon, Feb 1, 2016 at 5:17 AM, Andy Shevchenko
<andy.shevche...@gmail.com> wrote:
> On Thu, Jan 28, 2016 at 4:17 PM, Kees Cook <keesc...@chromium.org> wrote:
>> Some callers of strtobool were passing a pointer to unterminated strings.
>> This fixes the issue and consolidates some logic in cifs.
>
> My comments below.
>
> First of all I don't think currently there is an issue in cifs, since
> strbool checks only first character of the input string, or are you
> talking about something else?

Right, no, this is a fix before extending strtobool to parse the
second character in the string (for handling "on" and "off").

>> diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c 
>> b/drivers/net/wireless/marvell/mwifiex/debugfs.c
>> index 0b9c580af988..76af60899c69 100644
>> --- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
>> +++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
>> @@ -880,13 +880,13 @@ mwifiex_reset_write(struct file *file,
>>  {
>> struct mwifiex_private *priv = file->private_data;
>> struct mwifiex_adapter *adapter = priv->adapter;
>> -   char cmd;
>> +   char cmd[2] = { '\0' };
>> bool result;
>>
>> -   if (copy_from_user(, ubuf, sizeof(cmd)))
>> +   if (copy_from_user(cmd, ubuf, sizeof(char)))
>> return -EFAULT;
>>
>> -   if (strtobool(, ))
>> +   if (strtobool(cmd, ))
>> return -EINVAL;
>
> Can we do strtobool_from_user() instead like kstrto*from_user() and
> similar helpers are done?

Yeah, that might clean this up a bit more. I will add it.

>> if (!result)
>> diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
>> index 50b268483302..2f7ffcc9e364 100644
>> --- a/fs/cifs/cifs_debug.c
>> +++ b/fs/cifs/cifs_debug.c
>> @@ -251,11 +251,29 @@ static const struct file_operations 
>> cifs_debug_data_proc_fops = {
>> .release= single_release,
>>  };
>>
>> +static int get_user_bool(const char __user *buffer, bool *store)
>> +{
>> +   char c[2] = { '\0' };
>> +   bool bv;
>> +   int rc;
>> +
>> +   rc = get_user(c[0], buffer);
>> +   if (rc)
>> +   return rc;
>> +
>> +   rc = strtobool(c, );
>> +   if (rc)
>> +   return rc;
>> +
>> +   *store = bv;
>> +
>> +   return 0;
>> +}
>> +
>>  #ifdef CONFIG_CIFS_STATS
>>  static ssize_t cifs_stats_proc_write(struct file *file,
>> const char __user *buffer, size_t count, loff_t *ppos)
>>  {
>> -   char c;
>> bool bv;
>> int rc;
>> struct list_head *tmp1, *tmp2, *tmp3;
>> @@ -263,34 +281,32 @@ static ssize_t cifs_stats_proc_write(struct file *file,
>> struct cifs_ses *ses;
>> struct cifs_tcon *tcon;
>>
>> -   rc = get_user(c, buffer);
>> +   rc = get_user_bool(buffer, );
>> if (rc)
>> return rc;
>>
>> -   if (strtobool(, ) == 0) {
>>  #ifdef CONFIG_CIFS_STATS2
>
> I would suggest to do a separate patch which just changes a pattern
> and thus indentation without changing anything in functionality.

Okay, noted.

>> -   atomic_set(, 0);
>> -   atomic_set(, 0);
>> +   atomic_set(, 0);
>> +   atomic_set(, 0);
>>  #endif /* CONFIG_CIFS_STATS2 */
>> -   spin_lock(_tcp_ses_lock);
>> -   list_for_each(tmp1, _tcp_ses_list) {
>> -   server = list_entry(tmp1, struct TCP_Server_Info,
>> -   tcp_ses_list);
>> -   list_for_each(tmp2, >smb_ses_list) {
>> -   ses = list_entry(tmp2, struct cifs_ses,
>> -smb_ses_list);
>> -   list_for_each(tmp3, >tcon_list) {
>> -   tcon = list_entry(tmp3,
>> - struct cifs_tcon,
>> - tcon_list);
>> -   atomic_set(>num_smbs_sent, 0);
>> -   if (server->ops->clear_stats)
>> -   
>> server->ops->clear_stats(tcon);
>> -   }
>> +   spin_lock(_tcp_ses_lock);
>> +   list_

[PATCH 1/3] lib: fix callers of strtobool to use char array

2016-01-28 Thread Kees Cook
Some callers of strtobool were passing a pointer to unterminated strings.
This fixes the issue and consolidates some logic in cifs.

Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Amitkumar Karwar <akar...@marvell.com>
Cc: Nishant Sarmukadam <nisha...@marvell.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Steve French <sfre...@samba.org>
Cc: linux-c...@vger.kernel.org
---
 drivers/net/wireless/marvell/mwifiex/debugfs.c |   6 +-
 fs/cifs/cifs_debug.c   | 106 -
 fs/cifs/cifs_debug.h   |   2 +-
 fs/cifs/cifsfs.c   |   6 +-
 fs/cifs/cifsglob.h |   4 +-
 5 files changed, 58 insertions(+), 66 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c 
b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index 0b9c580af988..76af60899c69 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -880,13 +880,13 @@ mwifiex_reset_write(struct file *file,
 {
struct mwifiex_private *priv = file->private_data;
struct mwifiex_adapter *adapter = priv->adapter;
-   char cmd;
+   char cmd[2] = { '\0' };
bool result;
 
-   if (copy_from_user(, ubuf, sizeof(cmd)))
+   if (copy_from_user(cmd, ubuf, sizeof(char)))
return -EFAULT;
 
-   if (strtobool(, ))
+   if (strtobool(cmd, ))
return -EINVAL;
 
if (!result)
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 50b268483302..2f7ffcc9e364 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -251,11 +251,29 @@ static const struct file_operations 
cifs_debug_data_proc_fops = {
.release= single_release,
 };
 
+static int get_user_bool(const char __user *buffer, bool *store)
+{
+   char c[2] = { '\0' };
+   bool bv;
+   int rc;
+
+   rc = get_user(c[0], buffer);
+   if (rc)
+   return rc;
+
+   rc = strtobool(c, );
+   if (rc)
+   return rc;
+
+   *store = bv;
+
+   return 0;
+}
+
 #ifdef CONFIG_CIFS_STATS
 static ssize_t cifs_stats_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
bool bv;
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
@@ -263,34 +281,32 @@ static ssize_t cifs_stats_proc_write(struct file *file,
struct cifs_ses *ses;
struct cifs_tcon *tcon;
 
-   rc = get_user(c, buffer);
+   rc = get_user_bool(buffer, );
if (rc)
return rc;
 
-   if (strtobool(, ) == 0) {
 #ifdef CONFIG_CIFS_STATS2
-   atomic_set(, 0);
-   atomic_set(, 0);
+   atomic_set(, 0);
+   atomic_set(, 0);
 #endif /* CONFIG_CIFS_STATS2 */
-   spin_lock(_tcp_ses_lock);
-   list_for_each(tmp1, _tcp_ses_list) {
-   server = list_entry(tmp1, struct TCP_Server_Info,
-   tcp_ses_list);
-   list_for_each(tmp2, >smb_ses_list) {
-   ses = list_entry(tmp2, struct cifs_ses,
-smb_ses_list);
-   list_for_each(tmp3, >tcon_list) {
-   tcon = list_entry(tmp3,
- struct cifs_tcon,
- tcon_list);
-   atomic_set(>num_smbs_sent, 0);
-   if (server->ops->clear_stats)
-   server->ops->clear_stats(tcon);
-   }
+   spin_lock(_tcp_ses_lock);
+   list_for_each(tmp1, _tcp_ses_list) {
+   server = list_entry(tmp1, struct TCP_Server_Info,
+   tcp_ses_list);
+   list_for_each(tmp2, >smb_ses_list) {
+   ses = list_entry(tmp2, struct cifs_ses,
+smb_ses_list);
+   list_for_each(tmp3, >tcon_list) {
+   tcon = list_entry(tmp3,
+ struct cifs_tcon,
+ tcon_list);
+   atomic_set(>num_smbs_sent, 0);
+   if (server->ops->clear_stats)
+   server->ops->clear_stats(tcon);
}
}
-   spin_unlock(_tcp_ses_lock);
}
+   spin_unlock(_tcp_ses_lock);
 
return count;
 }
@@ -433,17 +449,17 @@ static int cifsFYI_proc_open(struct inode *inode, struct 
file *file)
 static ssize_t cifsFYI_proc_write(struct fil

[PATCH 2/3] lib: add "on" and "off" to strtobool

2016-01-28 Thread Kees Cook
Several places in the kernel expect to use "on" and "off" for their
boolean signifiers, so add them to strtobool.

Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Rasmus Villemoes <li...@rasmusvillemoes.dk>
Cc: Daniel Borkmann <dan...@iogearbox.net>
---
 lib/string.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/lib/string.c b/lib/string.c
index 0323c0d5629a..091570708db7 100644
--- a/lib/string.c
+++ b/lib/string.c
@@ -635,12 +635,15 @@ EXPORT_SYMBOL(sysfs_streq);
  * @s: input string
  * @res: result
  *
- * This routine returns 0 iff the first character is one of 'Yy1Nn0'.
- * Otherwise it will return -EINVAL.  Value pointed to by res is
- * updated upon finding a match.
+ * This routine returns 0 iff the first character is one of 'Yy1Nn0', or
+ * [oO][NnFf] for "on" and "off". Otherwise it will return -EINVAL.  Value
+ * pointed to by res is updated upon finding a match.
  */
 int strtobool(const char *s, bool *res)
 {
+   if (!s)
+   return -EINVAL;
+
switch (s[0]) {
case 'y':
case 'Y':
@@ -652,6 +655,21 @@ int strtobool(const char *s, bool *res)
case '0':
*res = false;
break;
+   case 'o':
+   case 'O':
+   switch (s[1]) {
+   case 'n':
+   case 'N':
+   *res = true;
+   break;
+   case 'f':
+   case 'F':
+   *res = false;
+   break;
+   default:
+   return -EINVAL;
+   }
+   break;
default:
return -EINVAL;
}
-- 
2.6.3

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH 3/3] param: convert some "on"/"off" users to strtobool

2016-01-28 Thread Kees Cook
This changes several users of manual "on"/"off" parsing to use strtobool.

Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: x...@kernel.org
Cc: linuxppc-...@lists.ozlabs.org
Cc: linux-s...@vger.kernel.org
---
 arch/powerpc/kernel/rtasd.c  | 10 +++---
 arch/powerpc/platforms/pseries/hotplug-cpu.c | 11 +++
 arch/s390/kernel/time.c  |  8 ++--
 arch/s390/kernel/topology.c  |  8 +++-
 arch/x86/kernel/aperture_64.c| 13 +++--
 include/linux/tick.h |  2 +-
 kernel/time/hrtimer.c| 11 +++
 kernel/time/tick-sched.c | 11 +++
 8 files changed, 21 insertions(+), 53 deletions(-)

diff --git a/arch/powerpc/kernel/rtasd.c b/arch/powerpc/kernel/rtasd.c
index 5a2c049c1c61..984e67e91ba3 100644
--- a/arch/powerpc/kernel/rtasd.c
+++ b/arch/powerpc/kernel/rtasd.c
@@ -21,6 +21,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -49,7 +50,7 @@ static unsigned int rtas_error_log_buffer_max;
 static unsigned int event_scan;
 static unsigned int rtas_event_scan_rate;
 
-static int full_rtas_msgs = 0;
+static bool full_rtas_msgs;
 
 /* Stop logging to nvram after first fatal error */
 static int logging_enabled; /* Until we initialize everything,
@@ -592,11 +593,6 @@ __setup("surveillance=", surveillance_setup);
 
 static int __init rtasmsgs_setup(char *str)
 {
-   if (strcmp(str, "on") == 0)
-   full_rtas_msgs = 1;
-   else if (strcmp(str, "off") == 0)
-   full_rtas_msgs = 0;
-
-   return 1;
+   return strtobool(str, _rtas_msgs);
 }
 __setup("rtasmsgs=", rtasmsgs_setup);
diff --git a/arch/powerpc/platforms/pseries/hotplug-cpu.c 
b/arch/powerpc/platforms/pseries/hotplug-cpu.c
index 32274f72fe3f..bb333e9fd77a 100644
--- a/arch/powerpc/platforms/pseries/hotplug-cpu.c
+++ b/arch/powerpc/platforms/pseries/hotplug-cpu.c
@@ -27,6 +27,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -47,20 +48,14 @@ static DEFINE_PER_CPU(enum cpu_state_vals, current_state) = 
CPU_STATE_OFFLINE;
 
 static enum cpu_state_vals default_offline_state = CPU_STATE_OFFLINE;
 
-static int cede_offline_enabled __read_mostly = 1;
+static bool cede_offline_enabled __read_mostly = true;
 
 /*
  * Enable/disable cede_offline when available.
  */
 static int __init setup_cede_offline(char *str)
 {
-   if (!strcmp(str, "off"))
-   cede_offline_enabled = 0;
-   else if (!strcmp(str, "on"))
-   cede_offline_enabled = 1;
-   else
-   return 0;
-   return 1;
+   return strtobool(str, _offline_enabled);
 }
 
 __setup("cede_offline=", setup_cede_offline);
diff --git a/arch/s390/kernel/time.c b/arch/s390/kernel/time.c
index 99f84ac31307..afc7fc9684ba 100644
--- a/arch/s390/kernel/time.c
+++ b/arch/s390/kernel/time.c
@@ -1433,7 +1433,7 @@ device_initcall(etr_init_sysfs);
 /*
  * Server Time Protocol (STP) code.
  */
-static int stp_online;
+static bool stp_online;
 static struct stp_sstpi stp_info;
 static void *stp_page;
 
@@ -1444,11 +1444,7 @@ static struct timer_list stp_timer;
 
 static int __init early_parse_stp(char *p)
 {
-   if (strncmp(p, "off", 3) == 0)
-   stp_online = 0;
-   else if (strncmp(p, "on", 2) == 0)
-   stp_online = 1;
-   return 0;
+   return strtobool(p, _online);
 }
 early_param("stp", early_parse_stp);
 
diff --git a/arch/s390/kernel/topology.c b/arch/s390/kernel/topology.c
index 40b8102fdadb..10e388216307 100644
--- a/arch/s390/kernel/topology.c
+++ b/arch/s390/kernel/topology.c
@@ -15,6 +15,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -37,7 +38,7 @@ static void set_topology_timer(void);
 static void topology_work_fn(struct work_struct *work);
 static struct sysinfo_15_1_x *tl_info;
 
-static int topology_enabled = 1;
+static bool topology_enabled = true;
 static DECLARE_WORK(topology_work, topology_work_fn);
 
 /*
@@ -444,10 +445,7 @@ static const struct cpumask *cpu_book_mask(int cpu)
 
 static int __init early_parse_topology(char *p)
 {
-   if (strncmp(p, "off", 3))
-   return 0;
-   topology_enabled = 0;
-   return 0;
+   return strtobool(p, _enabled);
 }
 early_param("topology", early_parse_topology);
 
diff --git a/arch/x86/kernel/aperture_64.c b/arch/x86/kernel/aperture_64.c
index 6e85f713641d..6608b00a516a 100644
--- a/arch/x86/kernel/aperture_64.c
+++ b/arch/x86/kernel/aperture_64.c
@@ -20,6 +20,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -227,19 +228,11 @@ static u32 __init search_agp_bridge(u32 *order, int 
*valid_agp)
return 0;
 }
 
-static int gart_fix_e820 __initdata = 1;
+static bool gart_fix_e820 __i

[PATCH 0/3] lib: add "on" and "off" to strtobool

2016-01-28 Thread Kees Cook
This consolidates logic for handling "on"/"off" parsing for bools into
the existing strtobool function. This requires making sure callers are
passing NULL-terminated strings.

-Kees

--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [PATCH] lib: fix callers of strtobool to use char array

2016-01-27 Thread Kees Cook
On Wed, Jan 27, 2016 at 4:58 PM, Joe Perches <j...@perches.com> wrote:
> On Wed, 2016-01-27 at 16:45 -0800, Kees Cook wrote:
>> Some callers of strtobool were passing a pointer to unterminated strings.
>> This fixes the issue and consolidates some logic in cifs.
>
> This may be incomplete as it duplicates the behavior for
> the old number of characters, but this is not a solution
> for the entry of a bool that is "on" or "off".

As in, the on/off patch is missing? Yes, that's been sent separately,
but I wanted to make sure these changes weren't upsetting to the two
users.

>> diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
> []
>> @@ -290,7 +305,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
>>   }
>>   }
>>   spin_unlock(_tcp_ses_lock);
>> - }
>> + } else
>> + return rc;
>
> Likely better to reverse the test and unindent the
> preceding block.
>
> Otherwise, please make sure to use the general brace
> form of when one branch needs braces, the other branch
> should have them too.

Okay, sure, I'll rework this and send it together with the on/off patch.

-Kees

-- 
Kees Cook
Chrome OS & Brillo Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[PATCH] lib: fix callers of strtobool to use char array

2016-01-27 Thread Kees Cook
Some callers of strtobool were passing a pointer to unterminated strings.
This fixes the issue and consolidates some logic in cifs.

Signed-off-by: Kees Cook <keesc...@chromium.org>
Cc: Amitkumar Karwar <akar...@marvell.com>
Cc: Nishant Sarmukadam <nisha...@marvell.com>
Cc: Kalle Valo <kv...@codeaurora.org>
Cc: Steve French <sfre...@samba.org>
Cc: linux-c...@vger.kernel.org
---
This is preparation for adding "on"/"off" support to strtobool(), and I
want to make sure the solution isn't upsetting to the two callers. :)
---
 drivers/net/wireless/marvell/mwifiex/debugfs.c |  6 +-
 fs/cifs/cifs_debug.c   | 78 --
 fs/cifs/cifs_debug.h   |  2 +-
 fs/cifs/cifsfs.c   |  6 +-
 fs/cifs/cifsglob.h |  4 +-
 5 files changed, 44 insertions(+), 52 deletions(-)

diff --git a/drivers/net/wireless/marvell/mwifiex/debugfs.c 
b/drivers/net/wireless/marvell/mwifiex/debugfs.c
index 0b9c580af988..76af60899c69 100644
--- a/drivers/net/wireless/marvell/mwifiex/debugfs.c
+++ b/drivers/net/wireless/marvell/mwifiex/debugfs.c
@@ -880,13 +880,13 @@ mwifiex_reset_write(struct file *file,
 {
struct mwifiex_private *priv = file->private_data;
struct mwifiex_adapter *adapter = priv->adapter;
-   char cmd;
+   char cmd[2] = { '\0' };
bool result;
 
-   if (copy_from_user(, ubuf, sizeof(cmd)))
+   if (copy_from_user(cmd, ubuf, sizeof(char)))
return -EFAULT;
 
-   if (strtobool(, ))
+   if (strtobool(cmd, ))
return -EINVAL;
 
if (!result)
diff --git a/fs/cifs/cifs_debug.c b/fs/cifs/cifs_debug.c
index 50b268483302..cafe464fa1b7 100644
--- a/fs/cifs/cifs_debug.c
+++ b/fs/cifs/cifs_debug.c
@@ -251,11 +251,29 @@ static const struct file_operations 
cifs_debug_data_proc_fops = {
.release= single_release,
 };
 
+static int get_user_bool(const char __user *buffer, bool *store)
+{
+   char c[2] = { '\0' };
+   bool bv;
+   int rc;
+
+   rc = get_user(c[0], buffer);
+   if (rc)
+   return rc;
+
+   rc = strtobool(c, );
+   if (rc)
+   return rc;
+
+   *store = bv;
+
+   return 0;
+}
+
 #ifdef CONFIG_CIFS_STATS
 static ssize_t cifs_stats_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
bool bv;
int rc;
struct list_head *tmp1, *tmp2, *tmp3;
@@ -263,11 +281,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
struct cifs_ses *ses;
struct cifs_tcon *tcon;
 
-   rc = get_user(c, buffer);
-   if (rc)
-   return rc;
-
-   if (strtobool(, ) == 0) {
+   rc = get_user_bool(buffer, );
+   if (rc == 0) {
 #ifdef CONFIG_CIFS_STATS2
atomic_set(, 0);
atomic_set(, 0);
@@ -290,7 +305,8 @@ static ssize_t cifs_stats_proc_write(struct file *file,
}
}
spin_unlock(_tcp_ses_lock);
-   }
+   } else
+   return rc;
 
return count;
 }
@@ -433,17 +449,17 @@ static int cifsFYI_proc_open(struct inode *inode, struct 
file *file)
 static ssize_t cifsFYI_proc_write(struct file *file, const char __user *buffer,
size_t count, loff_t *ppos)
 {
-   char c;
+   char c[2] = { '\0' };
bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = get_user(c[0], buffer);
if (rc)
return rc;
-   if (strtobool(, ) == 0)
+   if (strtobool(c, ) == 0)
cifsFYI = bv;
-   else if ((c > '1') && (c <= '9'))
-   cifsFYI = (int) (c - '0'); /* see cifs_debug.h for meanings */
+   else if ((c[0] > '1') && (c[0] <= '9'))
+   cifsFYI = (int) (c[0] - '0'); /* see cifs_debug.h for meanings 
*/
 
return count;
 }
@@ -471,20 +487,12 @@ static int cifs_linux_ext_proc_open(struct inode *inode, 
struct file *file)
 static ssize_t cifs_linux_ext_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
-   bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = get_user_bool(buffer, );
if (rc)
return rc;
 
-   rc = strtobool(, );
-   if (rc)
-   return rc;
-
-   linuxExtEnabled = bv;
-
return count;
 }
 
@@ -511,20 +519,12 @@ static int cifs_lookup_cache_proc_open(struct inode 
*inode, struct file *file)
 static ssize_t cifs_lookup_cache_proc_write(struct file *file,
const char __user *buffer, size_t count, loff_t *ppos)
 {
-   char c;
-   bool bv;
int rc;
 
-   rc = get_user(c, buffer);
+   rc = get_user_bool(buffer, );
if (rc)
return rc;
 
-   rc = st

Re: Linux Firmware Signing

2015-09-03 Thread Kees Cook
[removed bounced email addresses]

On Wed, Sep 2, 2015 at 2:37 PM, Luis R. Rodriguez <mcg...@suse.com> wrote:
> On Wed, Sep 02, 2015 at 01:54:43PM -0700, Kees Cook wrote:
>> On Wed, Sep 2, 2015 at 11:46 AM, Luis R. Rodriguez <mcg...@suse.com> wrote:
>> > On Tue, Sep 01, 2015 at 11:35:05PM -0400, Mimi Zohar wrote:
>> >> > OK great, I think that instead of passing the actual routine name we 
>> >> > should
>> >> > instead pass an enum type for to the LSM, that'd be easier to parse and 
>> >> > we'd
>> >> > then have each case well documented. Each LSM then could add its own
>> >> > documetnation for this and can switch on it. If we went with a name 
>> >> > we'd have
>> >> > to to use something like __func__ and then parse that, its not clear if 
>> >> > we need
>> >> > to get that specific.
>> >>
>> >> Agreed.  IMA already defines an enumeration.
>> >>
>> >> /* IMA policy related functions */
>> >> enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK,
>> >>  FIRMWARE_CHECK, POLICY_CHECK, POST_SETATTR };
>> >>
>> >
>> > We want something that is not only useful for IMA but any other LSM,
>> > and FILE_CHECK seems very broad, not sure what BPRM_CHECK is even upon
>> > inspecting kernel code. Likewise for POST_SETATTR. POLICY_CHECK might
>> > be broad, perhaps its best we define then a generic set of enums to
>> > which IMA can map them to then and let it decide. This would ensure
>> > that the kernel defines each use caes for file inspection carefully,
>> > documents and defines them and if an LSM wants to bunch a set together
>> > it can do so easily with a switch statement to map set of generic
>> > file checks in kernel to a group it already handles.
>> >
>> > For instance at least in the short term we'd try to unify:
>> >
>> > security_kernel_fw_from_file()
>> > security_kernel_module_from_file()
>> >
>> > to perhaps:
>> >
>> > security_kernel_from_file()
>> >
>> > As far, as far as I can tell, the only ones we'd be ready to start
>> > grouping immediately or with small amount of work rather soon:
>> >
>> > /**
>> >  *
>> >  * enum security_filecheck - known kernel security file checks types
>> >  *
>> >  * @__SECURITY_FILECHECK_UNSPEC: attribute 0 reserved
>> >  * @SECURITY_FILECHECK_MODULE: the file being processed is a Linux kernel 
>> > module
>> >  * @SECURITY_FILECHECK_SYSDATA: the file being processed is either a 
>> > firmware
>> >  *  file or a system data file read from /lib/firmware/* by 
>> > firmware_class
>>
>> I'd prefer a distinct category for firmware, as it carries an
>> implication that it is an executable blob of some sort (I know not all
>> are, though).
>
> The ship has sailed in terms of folks using frimrware API for things
> that are not-firmware per se. The first one I am aware of was the
> EEPROM override for the p54 driver. The other similar one was CPU
> microcode, but that's a bit more close to home with "firmware". We
> could ask users on the new system data request API I am building
> to describe the type of file being used, as I agree differentiating
> this for security purposes might be important. So other than just
> file type we could have sub type category, then we could have,
>
> SECURITY_FILECHECK_SYSDATA, and then:

I object to executable code being called data. :)

> SECURITY_FILE_SYSDATA_FW
> SECURITY_FILE_SYSDATA_MICROCODE
> SECURITY_FILE_SYSDATA_EEPROM
> SECURITY_FILE_SYSDATA_POLICY (for 802.11 regulatory I suppose)

The exception to the firmware loading is data, so the primary name
should be firmware. Regardless, if we want distinct objects, just name
them:

SECURITY_FILE_FIRMWARE
SECURITY_FILE_SYSDATA

Do we need finer-grain sub types?

>
> If we do this then we could juse have:
>
> SECURITY_FILECHECK_KEXEC and on that have substypes:
>
> SECURITY_FILE_KEXEC_KERNEL
> SECURITY_FILE_KEXEC_INITRAMFS
>
> Would that be desirable and help grow this to be easily extensible?
>
>   Luis

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Linux Firmware Signing

2015-09-02 Thread Kees Cook
On Tue, Sep 1, 2015 at 8:44 PM, Mimi Zohar <zo...@linux.vnet.ibm.com> wrote:
> On Tue, 2015-09-01 at 20:08 -0700, Kees Cook wrote:
>> On Tue, Sep 1, 2015 at 4:43 PM, Luis R. Rodriguez <mcg...@suse.com> wrote:
>> > On Mon, Aug 31, 2015 at 10:18:55AM -0400, Mimi Zohar wrote:
>> >> > > eBPF/seccomp
>> >
>> > OK I knew nothing about this but I just looked into it, here are my notes:
>> >
>> >   * old BPF - how far do we want to go? This goes so far as to parsing
>> > user passed void __user *arg data through ioctls which typically
>> > gets copy_from_user()'d and eventually gets BPF_PROG_RUN().
>> >
>> >   * eBPF:
>> >  seccomp() & prctl_set_seccomp()
>> > |
>> > V
>> >  do_seccomp()
>> > |
>> > V
>> >  seccomp_set_mode_filter()
>> > |
>> > V
>> >  seccomp_prepare_user_filter()
>> > |
>> > V
>> > bpf_prog_create_from_user() (seccomp) \
>> > bpf_prog_create()  > bpf_prepare_filter()
>> > sk_attach_filter()/
>> >
>> > All approaches come from user passed data, nothing fd based.
>> >
>> > For both old BPF and eBPF then:
>> >
>> > If we wanted to be paranoid I suppose the Machine Owner Key (MOK)
>> > Paul had mentioned up could be used to vet for passed filters, or
>> > a new interface to enable fd based filters. This really would limit
>> > the dynamic nature of these features though.
>> >
>> > eBPF / secccomp would not be the only place in the kernel that would 
>> > have
>> > issues with user passed data, we have tons of places the same applies 
>> > so
>> > implicating the old BPF / eBPF / seccomp approaches can easily 
>> > implicate
>> > many other areas of the kernel, that's pretty huge but from the looks 
>> > of
>> > it below you seem to enable that to be a possibility for us to 
>> > consider.
>>
>> At the time (LSS 2014?) I argued that seccomp policies come from
>> binaries, which are already being measured. And that policies only
>> further restrict a process, so there seems to be to be little risk in
>> continuing to leave them unmeasured.
>
> What do you mean by "measured"?  Who is doing the measurement?  Could
> someone detect a change in measurement?

I meant from the perspective of IMA. The binary would have already
been evaluated when it executed, and it's what's installing the
seccomp filter. And since seccomp filters can only reduce privilege,
it seems like they're not worth getting processed by IMA. But I might
not understand the requirements! :)

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Linux Firmware Signing

2015-09-02 Thread Kees Cook
On Wed, Sep 2, 2015 at 11:46 AM, Luis R. Rodriguez <mcg...@suse.com> wrote:
> On Tue, Sep 01, 2015 at 11:35:05PM -0400, Mimi Zohar wrote:
>> > OK great, I think that instead of passing the actual routine name we should
>> > instead pass an enum type for to the LSM, that'd be easier to parse and 
>> > we'd
>> > then have each case well documented. Each LSM then could add its own
>> > documetnation for this and can switch on it. If we went with a name we'd 
>> > have
>> > to to use something like __func__ and then parse that, its not clear if we 
>> > need
>> > to get that specific.
>>
>> Agreed.  IMA already defines an enumeration.
>>
>> /* IMA policy related functions */
>> enum ima_hooks { FILE_CHECK = 1, MMAP_CHECK, BPRM_CHECK, MODULE_CHECK,
>>  FIRMWARE_CHECK, POLICY_CHECK, POST_SETATTR };
>>
>
> We want something that is not only useful for IMA but any other LSM,
> and FILE_CHECK seems very broad, not sure what BPRM_CHECK is even upon
> inspecting kernel code. Likewise for POST_SETATTR. POLICY_CHECK might
> be broad, perhaps its best we define then a generic set of enums to
> which IMA can map them to then and let it decide. This would ensure
> that the kernel defines each use caes for file inspection carefully,
> documents and defines them and if an LSM wants to bunch a set together
> it can do so easily with a switch statement to map set of generic
> file checks in kernel to a group it already handles.
>
> For instance at least in the short term we'd try to unify:
>
> security_kernel_fw_from_file()
> security_kernel_module_from_file()
>
> to perhaps:
>
> security_kernel_from_file()
>
> As far, as far as I can tell, the only ones we'd be ready to start
> grouping immediately or with small amount of work rather soon:
>
> /**
>  *
>  * enum security_filecheck - known kernel security file checks types
>  *
>  * @__SECURITY_FILECHECK_UNSPEC: attribute 0 reserved
>  * @SECURITY_FILECHECK_MODULE: the file being processed is a Linux kernel 
> module
>  * @SECURITY_FILECHECK_SYSDATA: the file being processed is either a firmware
>  *  file or a system data file read from /lib/firmware/* by firmware_class

I'd prefer a distinct category for firmware, as it carries an
implication that it is an executable blob of some sort (I know not all
are, though).

-Kees

>  * @SECURITY_FILECHECK_KEXEC_KERNEL: the file being processed is a kernel file
>  *  used by kexec
>  * @SECURITY_FILECHECK_KEXEC_INITRAMFS: the file being processed is an 
> initramfs
>  *  used by kexec
>
>  * The kernel reads files directly from the filesystem for a series of
>  * operations.  The list of files the kernel reads from the filesystem are
>  * limited and each type of file consumed may have a different format and
>  * security vetting procedures. The kernel enables LSMs to vet for these files
>  * through a shared LSM hook prior to consumption. This list documents the
>  * different special kernel file types read by the kernel, it enables LSMs
>  * to vet for each differently if needed.
> enum security_filecheck {
> SECURITY_FILECHECK_UNSPEC,
> SECURITY_FILECHECK_MODULE,
> SECURITY_FILECHECK_SYSDATA,
> SECURITY_FILECHECK_KEXEC_KERNEL,
> SECURITY_FILECHECK_KEXEC_INITRAMFS,
> };
>
> Provided the MOK thing or alternative gets addressed we could also soon add
> something for SELinux policy files but that needs to be discussed further
> it seems. If MOK is used would SECURITY_FILECHECK_POLICY_MOK be OK? Again
> this would likely need further discussion, its why I didn't list it above.
>
>   Luis



-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Linux Firmware Signing

2015-09-01 Thread Kees Cook
On Tue, Sep 1, 2015 at 4:43 PM, Luis R. Rodriguez <mcg...@suse.com> wrote:
> On Mon, Aug 31, 2015 at 10:18:55AM -0400, Mimi Zohar wrote:
>> > > eBPF/seccomp
>
> OK I knew nothing about this but I just looked into it, here are my notes:
>
>   * old BPF - how far do we want to go? This goes so far as to parsing
> user passed void __user *arg data through ioctls which typically
> gets copy_from_user()'d and eventually gets BPF_PROG_RUN().
>
>   * eBPF:
>  seccomp() & prctl_set_seccomp()
> |
> V
>  do_seccomp()
> |
> V
>  seccomp_set_mode_filter()
> |
> V
>  seccomp_prepare_user_filter()
> |
> V
> bpf_prog_create_from_user() (seccomp) \
> bpf_prog_create()  > bpf_prepare_filter()
> sk_attach_filter()/
>
> All approaches come from user passed data, nothing fd based.
>
> For both old BPF and eBPF then:
>
> If we wanted to be paranoid I suppose the Machine Owner Key (MOK)
> Paul had mentioned up could be used to vet for passed filters, or
> a new interface to enable fd based filters. This really would limit
> the dynamic nature of these features though.
>
> eBPF / secccomp would not be the only place in the kernel that would have
> issues with user passed data, we have tons of places the same applies so
> implicating the old BPF / eBPF / seccomp approaches can easily implicate
> many other areas of the kernel, that's pretty huge but from the looks of
> it below you seem to enable that to be a possibility for us to consider.

At the time (LSS 2014?) I argued that seccomp policies come from
binaries, which are already being measured. And that policies only
further restrict a process, so there seems to be to be little risk in
continuing to leave them unmeasured.

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: Linux Firmware Signing

2015-09-01 Thread Kees Cook
hook for each new purpose, we'd just be sharing the same
> fetch / LSM hook. Please discuss and let me know if this still stands, I'll
> work towards any agreed upon direction with the fw signing code.
>
> And again, there may other parts of the kernel that do similar work, just
> as we found out about SELinux policy files. Those need to be identified
> and studied separatley. I guess we can use grammar to hunt these down.
>
>   Luis

-Kees

-- 
Kees Cook
Chrome OS Security
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


  1   2   >