From: Sasha Levin Date: Sun, 13 Oct 2024 02:48:16 +0000 (-0400) Subject: Fixes for 4.19 X-Git-Tag: v5.10.227~62 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=acdc37c06febc7221b6da6f66e97f096e528b23d;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 4.19 Signed-off-by: Sasha Levin --- diff --git a/queue-4.19/bluetooth-rfcomm-fix-possible-deadlock-in-rfcomm_sk_.patch b/queue-4.19/bluetooth-rfcomm-fix-possible-deadlock-in-rfcomm_sk_.patch new file mode 100644 index 00000000000..68c462c3186 --- /dev/null +++ b/queue-4.19/bluetooth-rfcomm-fix-possible-deadlock-in-rfcomm_sk_.patch @@ -0,0 +1,51 @@ +From 4dd4d2d7c091dd321be9b4381fd15e7e07759530 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 30 Sep 2024 13:26:21 -0400 +Subject: Bluetooth: RFCOMM: FIX possible deadlock in rfcomm_sk_state_change + +From: Luiz Augusto von Dentz + +[ Upstream commit 08d1914293dae38350b8088980e59fbc699a72fe ] + +rfcomm_sk_state_change attempts to use sock_lock so it must never be +called with it locked but rfcomm_sock_ioctl always attempt to lock it +causing the following trace: + +====================================================== +WARNING: possible circular locking dependency detected +6.8.0-syzkaller-08951-gfe46a7dd189e #0 Not tainted +------------------------------------------------------ +syz-executor386/5093 is trying to acquire lock: +ffff88807c396258 (sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM){+.+.}-{0:0}, at: lock_sock include/net/sock.h:1671 [inline] +ffff88807c396258 (sk_lock-AF_BLUETOOTH-BTPROTO_RFCOMM){+.+.}-{0:0}, at: rfcomm_sk_state_change+0x5b/0x310 net/bluetooth/rfcomm/sock.c:73 + +but task is already holding lock: +ffff88807badfd28 (&d->lock){+.+.}-{3:3}, at: __rfcomm_dlc_close+0x226/0x6a0 net/bluetooth/rfcomm/core.c:491 + +Reported-by: syzbot+d7ce59b06b3eb14fd218@syzkaller.appspotmail.com +Tested-by: syzbot+d7ce59b06b3eb14fd218@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=d7ce59b06b3eb14fd218 +Fixes: 3241ad820dbb ("[Bluetooth] Add timestamp support to L2CAP, RFCOMM and SCO") +Signed-off-by: Luiz Augusto von Dentz +Signed-off-by: Sasha Levin +--- + net/bluetooth/rfcomm/sock.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/net/bluetooth/rfcomm/sock.c b/net/bluetooth/rfcomm/sock.c +index 78830efe89d73..8f53cc0d9682a 100644 +--- a/net/bluetooth/rfcomm/sock.c ++++ b/net/bluetooth/rfcomm/sock.c +@@ -872,9 +872,7 @@ static int rfcomm_sock_ioctl(struct socket *sock, unsigned int cmd, unsigned lon + + if (err == -ENOIOCTLCMD) { + #ifdef CONFIG_BT_RFCOMM_TTY +- lock_sock(sk); + err = rfcomm_dev_ioctl(sk, cmd, (void __user *) arg); +- release_sock(sk); + #else + err = -EOPNOTSUPP; + #endif +-- +2.43.0 + diff --git a/queue-4.19/clk-add-devm_-clk_get_optional-functions.patch b/queue-4.19/clk-add-devm_-clk_get_optional-functions.patch new file mode 100644 index 00000000000..82c02275f4e --- /dev/null +++ b/queue-4.19/clk-add-devm_-clk_get_optional-functions.patch @@ -0,0 +1,129 @@ +From 95fb980022b8dca629ee43003bb5204f7af43f85 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 3 Dec 2018 11:13:09 +0000 +Subject: clk: Add (devm_)clk_get_optional() functions + +From: Phil Edworthy + +[ Upstream commit 60b8f0ddf1a927ef02141a6610fd52575134f821 ] + +This adds clk_get_optional() and devm_clk_get_optional() functions to get +optional clocks. + +They behave the same as (devm_)clk_get() except where there is no clock +producer. In this case, instead of returning -ENOENT, the function +returns NULL. This makes error checking simpler and allows +clk_prepare_enable, etc to be called on the returned reference +without additional checks. + +Signed-off-by: Phil Edworthy +Reviewed-by: Andy Shevchenko +Cc: Russell King +[sboyd@kernel.org: Document in devres.txt] +Signed-off-by: Stephen Boyd +Stable-dep-of: a6191a3d1811 ("gpio: aspeed: Use devm_clk api to manage clock source") +Signed-off-by: Sasha Levin +--- + Documentation/driver-model/devres.txt | 1 + + drivers/clk/clk-devres.c | 11 ++++++++ + include/linux/clk.h | 36 +++++++++++++++++++++++++++ + 3 files changed, 48 insertions(+) + +diff --git a/Documentation/driver-model/devres.txt b/Documentation/driver-model/devres.txt +index 43681ca0837f8..5a2d8c7ce2474 100644 +--- a/Documentation/driver-model/devres.txt ++++ b/Documentation/driver-model/devres.txt +@@ -235,6 +235,7 @@ certainly invest a bit more effort into libata core layer). + + CLOCK + devm_clk_get() ++ devm_clk_get_optional() + devm_clk_put() + devm_clk_hw_register() + devm_of_clk_add_hw_provider() +diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c +index d854e26a8ddbc..a062389ccd3d5 100644 +--- a/drivers/clk/clk-devres.c ++++ b/drivers/clk/clk-devres.c +@@ -34,6 +34,17 @@ struct clk *devm_clk_get(struct device *dev, const char *id) + } + EXPORT_SYMBOL(devm_clk_get); + ++struct clk *devm_clk_get_optional(struct device *dev, const char *id) ++{ ++ struct clk *clk = devm_clk_get(dev, id); ++ ++ if (clk == ERR_PTR(-ENOENT)) ++ return NULL; ++ ++ return clk; ++} ++EXPORT_SYMBOL(devm_clk_get_optional); ++ + struct clk_bulk_devres { + struct clk_bulk_data *clks; + int num_clks; +diff --git a/include/linux/clk.h b/include/linux/clk.h +index 0a2382d3f68c8..55b08adaaa3c1 100644 +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -388,6 +388,17 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + */ + struct clk *devm_clk_get(struct device *dev, const char *id); + ++/** ++ * devm_clk_get_optional - lookup and obtain a managed reference to an optional ++ * clock producer. ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Behaves the same as devm_clk_get() except where there is no clock producer. ++ * In this case, instead of returning -ENOENT, the function returns NULL. ++ */ ++struct clk *devm_clk_get_optional(struct device *dev, const char *id); ++ + /** + * devm_get_clk_from_child - lookup and obtain a managed reference to a + * clock producer from child node. +@@ -655,6 +666,12 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id) + return NULL; + } + ++static inline struct clk *devm_clk_get_optional(struct device *dev, ++ const char *id) ++{ ++ return NULL; ++} ++ + static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) + { +@@ -774,6 +791,25 @@ static inline void clk_bulk_disable_unprepare(int num_clks, + clk_bulk_unprepare(num_clks, clks); + } + ++/** ++ * clk_get_optional - lookup and obtain a reference to an optional clock ++ * producer. ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Behaves the same as clk_get() except where there is no clock producer. In ++ * this case, instead of returning -ENOENT, the function returns NULL. ++ */ ++static inline struct clk *clk_get_optional(struct device *dev, const char *id) ++{ ++ struct clk *clk = clk_get(dev, id); ++ ++ if (clk == ERR_PTR(-ENOENT)) ++ return NULL; ++ ++ return clk; ++} ++ + #if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK) + struct clk *of_clk_get(struct device_node *np, int index); + struct clk *of_clk_get_by_name(struct device_node *np, const char *name); +-- +2.43.0 + diff --git a/queue-4.19/clk-generalize-devm_clk_get-a-bit.patch b/queue-4.19/clk-generalize-devm_clk_get-a-bit.patch new file mode 100644 index 00000000000..5908cdbbb8a --- /dev/null +++ b/queue-4.19/clk-generalize-devm_clk_get-a-bit.patch @@ -0,0 +1,124 @@ +From 1583f97aa966964d56d12a7d4ce0600fc0357956 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 May 2022 09:57:35 +0200 +Subject: clk: generalize devm_clk_get() a bit +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit abae8e57e49aa75f6db76aa866c775721523908f ] + +Allow to add an exit hook to devm managed clocks. Also use +clk_get_optional() in devm_clk_get_optional instead of open coding it. +The generalisation will be used in the next commit to add some more +devm_clk helpers. + +Reviewed-by: Jonathan Cameron +Reviewed-by: Alexandru Ardelean +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/20220520075737.758761-3-u.kleine-koenig@pengutronix.de +Signed-off-by: Stephen Boyd +Stable-dep-of: a6191a3d1811 ("gpio: aspeed: Use devm_clk api to manage clock source") +Signed-off-by: Sasha Levin +--- + drivers/clk/clk-devres.c | 66 +++++++++++++++++++++++++++++----------- + 1 file changed, 49 insertions(+), 17 deletions(-) + +diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c +index a062389ccd3d5..3a45b4d0d502d 100644 +--- a/drivers/clk/clk-devres.c ++++ b/drivers/clk/clk-devres.c +@@ -9,39 +9,71 @@ + #include + #include + ++struct devm_clk_state { ++ struct clk *clk; ++ void (*exit)(struct clk *clk); ++}; ++ + static void devm_clk_release(struct device *dev, void *res) + { +- clk_put(*(struct clk **)res); ++ struct devm_clk_state *state = *(struct devm_clk_state **)res; ++ ++ if (state->exit) ++ state->exit(state->clk); ++ ++ clk_put(state->clk); + } + +-struct clk *devm_clk_get(struct device *dev, const char *id) ++static struct clk *__devm_clk_get(struct device *dev, const char *id, ++ struct clk *(*get)(struct device *dev, const char *id), ++ int (*init)(struct clk *clk), ++ void (*exit)(struct clk *clk)) + { +- struct clk **ptr, *clk; ++ struct devm_clk_state *state; ++ struct clk *clk; ++ int ret; + +- ptr = devres_alloc(devm_clk_release, sizeof(*ptr), GFP_KERNEL); +- if (!ptr) ++ state = devres_alloc(devm_clk_release, sizeof(*state), GFP_KERNEL); ++ if (!state) + return ERR_PTR(-ENOMEM); + +- clk = clk_get(dev, id); +- if (!IS_ERR(clk)) { +- *ptr = clk; +- devres_add(dev, ptr); +- } else { +- devres_free(ptr); ++ clk = get(dev, id); ++ if (IS_ERR(clk)) { ++ ret = PTR_ERR(clk); ++ goto err_clk_get; + } + ++ if (init) { ++ ret = init(clk); ++ if (ret) ++ goto err_clk_init; ++ } ++ ++ state->clk = clk; ++ state->exit = exit; ++ ++ devres_add(dev, state); ++ + return clk; ++ ++err_clk_init: ++ ++ clk_put(clk); ++err_clk_get: ++ ++ devres_free(state); ++ return ERR_PTR(ret); ++} ++ ++struct clk *devm_clk_get(struct device *dev, const char *id) ++{ ++ return __devm_clk_get(dev, id, clk_get, NULL, NULL); + } + EXPORT_SYMBOL(devm_clk_get); + + struct clk *devm_clk_get_optional(struct device *dev, const char *id) + { +- struct clk *clk = devm_clk_get(dev, id); +- +- if (clk == ERR_PTR(-ENOENT)) +- return NULL; +- +- return clk; ++ return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL); + } + EXPORT_SYMBOL(devm_clk_get_optional); + +-- +2.43.0 + diff --git a/queue-4.19/clk-provide-new-devm_clk-helpers-for-prepared-and-en.patch b/queue-4.19/clk-provide-new-devm_clk-helpers-for-prepared-and-en.patch new file mode 100644 index 00000000000..19efda79ecb --- /dev/null +++ b/queue-4.19/clk-provide-new-devm_clk-helpers-for-prepared-and-en.patch @@ -0,0 +1,214 @@ +From 06cb2e94f188cb1eecbb0b6138cc1ec2257a3e1e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 20 May 2022 09:57:36 +0200 +Subject: clk: Provide new devm_clk helpers for prepared and enabled clocks +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Uwe Kleine-König + +[ Upstream commit 7ef9651e9792b08eb310c6beb202cbc947f43cab ] + +When a driver keeps a clock prepared (or enabled) during the whole +lifetime of the driver, these helpers allow to simplify the drivers. + +Reviewed-by: Jonathan Cameron +Reviewed-by: Alexandru Ardelean +Signed-off-by: Uwe Kleine-König +Link: https://lore.kernel.org/r/20220520075737.758761-4-u.kleine-koenig@pengutronix.de +Signed-off-by: Stephen Boyd +Stable-dep-of: a6191a3d1811 ("gpio: aspeed: Use devm_clk api to manage clock source") +Signed-off-by: Sasha Levin +--- + drivers/clk/clk-devres.c | 27 ++++++++++ + include/linux/clk.h | 109 +++++++++++++++++++++++++++++++++++++++ + 2 files changed, 136 insertions(+) + +diff --git a/drivers/clk/clk-devres.c b/drivers/clk/clk-devres.c +index 3a45b4d0d502d..cec0e58d92d65 100644 +--- a/drivers/clk/clk-devres.c ++++ b/drivers/clk/clk-devres.c +@@ -71,12 +71,39 @@ struct clk *devm_clk_get(struct device *dev, const char *id) + } + EXPORT_SYMBOL(devm_clk_get); + ++struct clk *devm_clk_get_prepared(struct device *dev, const char *id) ++{ ++ return __devm_clk_get(dev, id, clk_get, clk_prepare, clk_unprepare); ++} ++EXPORT_SYMBOL_GPL(devm_clk_get_prepared); ++ ++struct clk *devm_clk_get_enabled(struct device *dev, const char *id) ++{ ++ return __devm_clk_get(dev, id, clk_get, ++ clk_prepare_enable, clk_disable_unprepare); ++} ++EXPORT_SYMBOL_GPL(devm_clk_get_enabled); ++ + struct clk *devm_clk_get_optional(struct device *dev, const char *id) + { + return __devm_clk_get(dev, id, clk_get_optional, NULL, NULL); + } + EXPORT_SYMBOL(devm_clk_get_optional); + ++struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id) ++{ ++ return __devm_clk_get(dev, id, clk_get_optional, ++ clk_prepare, clk_unprepare); ++} ++EXPORT_SYMBOL_GPL(devm_clk_get_optional_prepared); ++ ++struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id) ++{ ++ return __devm_clk_get(dev, id, clk_get_optional, ++ clk_prepare_enable, clk_disable_unprepare); ++} ++EXPORT_SYMBOL_GPL(devm_clk_get_optional_enabled); ++ + struct clk_bulk_devres { + struct clk_bulk_data *clks; + int num_clks; +diff --git a/include/linux/clk.h b/include/linux/clk.h +index 55b08adaaa3c1..fb4c86360e5ad 100644 +--- a/include/linux/clk.h ++++ b/include/linux/clk.h +@@ -388,6 +388,47 @@ int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + */ + struct clk *devm_clk_get(struct device *dev, const char *id); + ++/** ++ * devm_clk_get_prepared - devm_clk_get() + clk_prepare() ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Context: May sleep. ++ * ++ * Return: a struct clk corresponding to the clock producer, or ++ * valid IS_ERR() condition containing errno. The implementation ++ * uses @dev and @id to determine the clock consumer, and thereby ++ * the clock producer. (IOW, @id may be identical strings, but ++ * clk_get may return different clock producers depending on @dev.) ++ * ++ * The returned clk (if valid) is prepared. Drivers must however assume ++ * that the clock is not enabled. ++ * ++ * The clock will automatically be unprepared and freed when the device ++ * is unbound from the bus. ++ */ ++struct clk *devm_clk_get_prepared(struct device *dev, const char *id); ++ ++/** ++ * devm_clk_get_enabled - devm_clk_get() + clk_prepare_enable() ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Context: May sleep. ++ * ++ * Return: a struct clk corresponding to the clock producer, or ++ * valid IS_ERR() condition containing errno. The implementation ++ * uses @dev and @id to determine the clock consumer, and thereby ++ * the clock producer. (IOW, @id may be identical strings, but ++ * clk_get may return different clock producers depending on @dev.) ++ * ++ * The returned clk (if valid) is prepared and enabled. ++ * ++ * The clock will automatically be disabled, unprepared and freed ++ * when the device is unbound from the bus. ++ */ ++struct clk *devm_clk_get_enabled(struct device *dev, const char *id); ++ + /** + * devm_clk_get_optional - lookup and obtain a managed reference to an optional + * clock producer. +@@ -399,6 +440,50 @@ struct clk *devm_clk_get(struct device *dev, const char *id); + */ + struct clk *devm_clk_get_optional(struct device *dev, const char *id); + ++/** ++ * devm_clk_get_optional_prepared - devm_clk_get_optional() + clk_prepare() ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Context: May sleep. ++ * ++ * Return: a struct clk corresponding to the clock producer, or ++ * valid IS_ERR() condition containing errno. The implementation ++ * uses @dev and @id to determine the clock consumer, and thereby ++ * the clock producer. If no such clk is found, it returns NULL ++ * which serves as a dummy clk. That's the only difference compared ++ * to devm_clk_get_prepared(). ++ * ++ * The returned clk (if valid) is prepared. Drivers must however ++ * assume that the clock is not enabled. ++ * ++ * The clock will automatically be unprepared and freed when the ++ * device is unbound from the bus. ++ */ ++struct clk *devm_clk_get_optional_prepared(struct device *dev, const char *id); ++ ++/** ++ * devm_clk_get_optional_enabled - devm_clk_get_optional() + ++ * clk_prepare_enable() ++ * @dev: device for clock "consumer" ++ * @id: clock consumer ID ++ * ++ * Context: May sleep. ++ * ++ * Return: a struct clk corresponding to the clock producer, or ++ * valid IS_ERR() condition containing errno. The implementation ++ * uses @dev and @id to determine the clock consumer, and thereby ++ * the clock producer. If no such clk is found, it returns NULL ++ * which serves as a dummy clk. That's the only difference compared ++ * to devm_clk_get_enabled(). ++ * ++ * The returned clk (if valid) is prepared and enabled. ++ * ++ * The clock will automatically be disabled, unprepared and freed ++ * when the device is unbound from the bus. ++ */ ++struct clk *devm_clk_get_optional_enabled(struct device *dev, const char *id); ++ + /** + * devm_get_clk_from_child - lookup and obtain a managed reference to a + * clock producer from child node. +@@ -666,12 +751,36 @@ static inline struct clk *devm_clk_get(struct device *dev, const char *id) + return NULL; + } + ++static inline struct clk *devm_clk_get_prepared(struct device *dev, ++ const char *id) ++{ ++ return NULL; ++} ++ ++static inline struct clk *devm_clk_get_enabled(struct device *dev, ++ const char *id) ++{ ++ return NULL; ++} ++ + static inline struct clk *devm_clk_get_optional(struct device *dev, + const char *id) + { + return NULL; + } + ++static inline struct clk *devm_clk_get_optional_prepared(struct device *dev, ++ const char *id) ++{ ++ return NULL; ++} ++ ++static inline struct clk *devm_clk_get_optional_enabled(struct device *dev, ++ const char *id) ++{ ++ return NULL; ++} ++ + static inline int __must_check devm_clk_bulk_get(struct device *dev, int num_clks, + struct clk_bulk_data *clks) + { +-- +2.43.0 + diff --git a/queue-4.19/gpio-aspeed-add-the-flush-write-to-ensure-the-write-.patch b/queue-4.19/gpio-aspeed-add-the-flush-write-to-ensure-the-write-.patch new file mode 100644 index 00000000000..b6b7ca86018 --- /dev/null +++ b/queue-4.19/gpio-aspeed-add-the-flush-write-to-ensure-the-write-.patch @@ -0,0 +1,44 @@ +From c336c9f98eb83f2b7f0956f9a95f4fa22c9801b4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 16:14:44 +0800 +Subject: gpio: aspeed: Add the flush write to ensure the write complete. + +From: Billy Tsai + +[ Upstream commit 1bb5a99e1f3fd27accb804aa0443a789161f843c ] + +Performing a dummy read ensures that the register write operation is fully +completed, mitigating any potential bus delays that could otherwise impact +the frequency of bitbang usage. E.g., if the JTAG application uses GPIO to +control the JTAG pins (TCK, TMS, TDI, TDO, and TRST), and the application +sets the TCK clock to 1 MHz, the GPIO's high/low transitions will rely on +a delay function to ensure the clock frequency does not exceed 1 MHz. +However, this can lead to rapid toggling of the GPIO because the write +operation is POSTed and does not wait for a bus acknowledgment. + +Fixes: 361b79119a4b ("gpio: Add Aspeed driver") +Reviewed-by: Andrew Jeffery +Signed-off-by: Billy Tsai +Link: https://lore.kernel.org/r/20241008081450.1490955-2-billy_tsai@aspeedtech.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-aspeed.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c +index ba1cd971d50b6..5cc80678ac352 100644 +--- a/drivers/gpio/gpio-aspeed.c ++++ b/drivers/gpio/gpio-aspeed.c +@@ -407,6 +407,8 @@ static void __aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, + gpio->dcache[GPIO_BANK(offset)] = reg; + + iowrite32(reg, addr); ++ /* Flush write */ ++ ioread32(addr); + } + + static void aspeed_gpio_set(struct gpio_chip *gc, unsigned int offset, +-- +2.43.0 + diff --git a/queue-4.19/gpio-aspeed-use-devm_clk-api-to-manage-clock-source.patch b/queue-4.19/gpio-aspeed-use-devm_clk-api-to-manage-clock-source.patch new file mode 100644 index 00000000000..b2d3fdcf56a --- /dev/null +++ b/queue-4.19/gpio-aspeed-use-devm_clk-api-to-manage-clock-source.patch @@ -0,0 +1,37 @@ +From 4519ac5ee265d3c03cb6248dd9d29badb61dc5cf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 8 Oct 2024 16:14:45 +0800 +Subject: gpio: aspeed: Use devm_clk api to manage clock source + +From: Billy Tsai + +[ Upstream commit a6191a3d18119184237f4ee600039081ad992320 ] + +Replace of_clk_get with devm_clk_get_enabled to manage the clock source. + +Fixes: 5ae4cb94b313 ("gpio: aspeed: Add debounce support") +Reviewed-by: Andrew Jeffery +Signed-off-by: Billy Tsai +Link: https://lore.kernel.org/r/20241008081450.1490955-3-billy_tsai@aspeedtech.com +Signed-off-by: Bartosz Golaszewski +Signed-off-by: Sasha Levin +--- + drivers/gpio/gpio-aspeed.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpio-aspeed.c b/drivers/gpio/gpio-aspeed.c +index 5cc80678ac352..cab3d9a4018ab 100644 +--- a/drivers/gpio/gpio-aspeed.c ++++ b/drivers/gpio/gpio-aspeed.c +@@ -1176,7 +1176,7 @@ static int __init aspeed_gpio_probe(struct platform_device *pdev) + if (!gpio_id) + return -EINVAL; + +- gpio->clk = of_clk_get(pdev->dev.of_node, 0); ++ gpio->clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(gpio->clk)) { + dev_warn(&pdev->dev, + "Failed to get clock from devicetree, debouncing disabled\n"); +-- +2.43.0 + diff --git a/queue-4.19/igb-do-not-bring-the-device-up-after-non-fatal-error.patch b/queue-4.19/igb-do-not-bring-the-device-up-after-non-fatal-error.patch new file mode 100644 index 00000000000..2bd91aa9ea1 --- /dev/null +++ b/queue-4.19/igb-do-not-bring-the-device-up-after-non-fatal-error.patch @@ -0,0 +1,96 @@ +From 8a8386bf8ad87733b52024e3700f93961b426d37 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 24 Sep 2024 15:06:01 -0600 +Subject: igb: Do not bring the device up after non-fatal error + +From: Mohamed Khalfella + +[ Upstream commit 330a699ecbfc9c26ec92c6310686da1230b4e7eb ] + +Commit 004d25060c78 ("igb: Fix igb_down hung on surprise removal") +changed igb_io_error_detected() to ignore non-fatal pcie errors in order +to avoid hung task that can happen when igb_down() is called multiple +times. This caused an issue when processing transient non-fatal errors. +igb_io_resume(), which is called after igb_io_error_detected(), assumes +that device is brought down by igb_io_error_detected() if the interface +is up. This resulted in panic with stacktrace below. + +[ T3256] igb 0000:09:00.0 haeth0: igb: haeth0 NIC Link is Down +[ T292] pcieport 0000:00:1c.5: AER: Uncorrected (Non-Fatal) error received: 0000:09:00.0 +[ T292] igb 0000:09:00.0: PCIe Bus Error: severity=Uncorrected (Non-Fatal), type=Transaction Layer, (Requester ID) +[ T292] igb 0000:09:00.0: device [8086:1537] error status/mask=00004000/00000000 +[ T292] igb 0000:09:00.0: [14] CmpltTO [ 200.105524,009][ T292] igb 0000:09:00.0: AER: TLP Header: 00000000 00000000 00000000 00000000 +[ T292] pcieport 0000:00:1c.5: AER: broadcast error_detected message +[ T292] igb 0000:09:00.0: Non-correctable non-fatal error reported. +[ T292] pcieport 0000:00:1c.5: AER: broadcast mmio_enabled message +[ T292] pcieport 0000:00:1c.5: AER: broadcast resume message +[ T292] ------------[ cut here ]------------ +[ T292] kernel BUG at net/core/dev.c:6539! +[ T292] invalid opcode: 0000 [#1] PREEMPT SMP +[ T292] RIP: 0010:napi_enable+0x37/0x40 +[ T292] Call Trace: +[ T292] +[ T292] ? die+0x33/0x90 +[ T292] ? do_trap+0xdc/0x110 +[ T292] ? napi_enable+0x37/0x40 +[ T292] ? do_error_trap+0x70/0xb0 +[ T292] ? napi_enable+0x37/0x40 +[ T292] ? napi_enable+0x37/0x40 +[ T292] ? exc_invalid_op+0x4e/0x70 +[ T292] ? napi_enable+0x37/0x40 +[ T292] ? asm_exc_invalid_op+0x16/0x20 +[ T292] ? napi_enable+0x37/0x40 +[ T292] igb_up+0x41/0x150 +[ T292] igb_io_resume+0x25/0x70 +[ T292] report_resume+0x54/0x70 +[ T292] ? report_frozen_detected+0x20/0x20 +[ T292] pci_walk_bus+0x6c/0x90 +[ T292] ? aer_print_port_info+0xa0/0xa0 +[ T292] pcie_do_recovery+0x22f/0x380 +[ T292] aer_process_err_devices+0x110/0x160 +[ T292] aer_isr+0x1c1/0x1e0 +[ T292] ? disable_irq_nosync+0x10/0x10 +[ T292] irq_thread_fn+0x1a/0x60 +[ T292] irq_thread+0xe3/0x1a0 +[ T292] ? irq_set_affinity_notifier+0x120/0x120 +[ T292] ? irq_affinity_notify+0x100/0x100 +[ T292] kthread+0xe2/0x110 +[ T292] ? kthread_complete_and_exit+0x20/0x20 +[ T292] ret_from_fork+0x2d/0x50 +[ T292] ? kthread_complete_and_exit+0x20/0x20 +[ T292] ret_from_fork_asm+0x11/0x20 +[ T292] + +To fix this issue igb_io_resume() checks if the interface is running and +the device is not down this means igb_io_error_detected() did not bring +the device down and there is no need to bring it up. + +Signed-off-by: Mohamed Khalfella +Reviewed-by: Yuanyuan Zhong +Fixes: 004d25060c78 ("igb: Fix igb_down hung on surprise removal") +Reviewed-by: Simon Horman +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c +index 01138fc93ea10..3a65dccc08ba8 100644 +--- a/drivers/net/ethernet/intel/igb/igb_main.c ++++ b/drivers/net/ethernet/intel/igb/igb_main.c +@@ -9151,6 +9151,10 @@ static void igb_io_resume(struct pci_dev *pdev) + struct igb_adapter *adapter = netdev_priv(netdev); + + if (netif_running(netdev)) { ++ if (!test_bit(__IGB_DOWN, &adapter->state)) { ++ dev_dbg(&pdev->dev, "Resuming from non-fatal error, do nothing.\n"); ++ return; ++ } + if (igb_up(adapter)) { + dev_err(&pdev->dev, "igb_up failed after reset\n"); + return; +-- +2.43.0 + diff --git a/queue-4.19/net-ibm-emac-mal-fix-wrong-goto.patch b/queue-4.19/net-ibm-emac-mal-fix-wrong-goto.patch new file mode 100644 index 00000000000..7d122b0270c --- /dev/null +++ b/queue-4.19/net-ibm-emac-mal-fix-wrong-goto.patch @@ -0,0 +1,36 @@ +From c0ca70380a1ae91a910ef8c9a52753d8ebf99a2b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 7 Oct 2024 16:57:11 -0700 +Subject: net: ibm: emac: mal: fix wrong goto + +From: Rosen Penev + +[ Upstream commit 08c8acc9d8f3f70d62dd928571368d5018206490 ] + +dcr_map is called in the previous if and therefore needs to be unmapped. + +Fixes: 1ff0fcfcb1a6 ("ibm_newemac: Fix new MAL feature handling") +Signed-off-by: Rosen Penev +Link: https://patch.msgid.link/20241007235711.5714-1-rosenp@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/ibm/emac/mal.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ethernet/ibm/emac/mal.c b/drivers/net/ethernet/ibm/emac/mal.c +index fff09dcf9e346..9b3ba4db3222f 100644 +--- a/drivers/net/ethernet/ibm/emac/mal.c ++++ b/drivers/net/ethernet/ibm/emac/mal.c +@@ -581,7 +581,7 @@ static int mal_probe(struct platform_device *ofdev) + printk(KERN_ERR "%pOF: Support for 405EZ not enabled!\n", + ofdev->dev.of_node); + err = -ENODEV; +- goto fail; ++ goto fail_unmap; + #endif + } + +-- +2.43.0 + diff --git a/queue-4.19/netfilter-br_netfilter-fix-panic-with-metadata_dst-s.patch b/queue-4.19/netfilter-br_netfilter-fix-panic-with-metadata_dst-s.patch new file mode 100644 index 00000000000..16f3b7f3ca1 --- /dev/null +++ b/queue-4.19/netfilter-br_netfilter-fix-panic-with-metadata_dst-s.patch @@ -0,0 +1,179 @@ +From 647ce0012b65a215e2a3807ab3a6e5754afc6fbd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 08:43:59 -0700 +Subject: netfilter: br_netfilter: fix panic with metadata_dst skb + +From: Andy Roulin + +[ Upstream commit f9ff7665cd128012868098bbd07e28993e314fdb ] + +Fix a kernel panic in the br_netfilter module when sending untagged +traffic via a VxLAN device. +This happens during the check for fragmentation in br_nf_dev_queue_xmit. + +It is dependent on: +1) the br_netfilter module being loaded; +2) net.bridge.bridge-nf-call-iptables set to 1; +3) a bridge with a VxLAN (single-vxlan-device) netdevice as a bridge port; +4) untagged frames with size higher than the VxLAN MTU forwarded/flooded + +When forwarding the untagged packet to the VxLAN bridge port, before +the netfilter hooks are called, br_handle_egress_vlan_tunnel is called and +changes the skb_dst to the tunnel dst. The tunnel_dst is a metadata type +of dst, i.e., skb_valid_dst(skb) is false, and metadata->dst.dev is NULL. + +Then in the br_netfilter hooks, in br_nf_dev_queue_xmit, there's a check +for frames that needs to be fragmented: frames with higher MTU than the +VxLAN device end up calling br_nf_ip_fragment, which in turns call +ip_skb_dst_mtu. + +The ip_dst_mtu tries to use the skb_dst(skb) as if it was a valid dst +with valid dst->dev, thus the crash. + +This case was never supported in the first place, so drop the packet +instead. + +PING 10.0.0.2 (10.0.0.2) from 0.0.0.0 h1-eth0: 2000(2028) bytes of data. +[ 176.291791] Unable to handle kernel NULL pointer dereference at +virtual address 0000000000000110 +[ 176.292101] Mem abort info: +[ 176.292184] ESR = 0x0000000096000004 +[ 176.292322] EC = 0x25: DABT (current EL), IL = 32 bits +[ 176.292530] SET = 0, FnV = 0 +[ 176.292709] EA = 0, S1PTW = 0 +[ 176.292862] FSC = 0x04: level 0 translation fault +[ 176.293013] Data abort info: +[ 176.293104] ISV = 0, ISS = 0x00000004, ISS2 = 0x00000000 +[ 176.293488] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 +[ 176.293787] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 +[ 176.293995] user pgtable: 4k pages, 48-bit VAs, pgdp=0000000043ef5000 +[ 176.294166] [0000000000000110] pgd=0000000000000000, +p4d=0000000000000000 +[ 176.294827] Internal error: Oops: 0000000096000004 [#1] PREEMPT SMP +[ 176.295252] Modules linked in: vxlan ip6_udp_tunnel udp_tunnel veth +br_netfilter bridge stp llc ipv6 crct10dif_ce +[ 176.295923] CPU: 0 PID: 188 Comm: ping Not tainted +6.8.0-rc3-g5b3fbd61b9d1 #2 +[ 176.296314] Hardware name: linux,dummy-virt (DT) +[ 176.296535] pstate: 80000005 (Nzcv daif -PAN -UAO -TCO -DIT -SSBS +BTYPE=--) +[ 176.296808] pc : br_nf_dev_queue_xmit+0x390/0x4ec [br_netfilter] +[ 176.297382] lr : br_nf_dev_queue_xmit+0x2ac/0x4ec [br_netfilter] +[ 176.297636] sp : ffff800080003630 +[ 176.297743] x29: ffff800080003630 x28: 0000000000000008 x27: +ffff6828c49ad9f8 +[ 176.298093] x26: ffff6828c49ad000 x25: 0000000000000000 x24: +00000000000003e8 +[ 176.298430] x23: 0000000000000000 x22: ffff6828c4960b40 x21: +ffff6828c3b16d28 +[ 176.298652] x20: ffff6828c3167048 x19: ffff6828c3b16d00 x18: +0000000000000014 +[ 176.298926] x17: ffffb0476322f000 x16: ffffb7e164023730 x15: +0000000095744632 +[ 176.299296] x14: ffff6828c3f1c880 x13: 0000000000000002 x12: +ffffb7e137926a70 +[ 176.299574] x11: 0000000000000001 x10: ffff6828c3f1c898 x9 : +0000000000000000 +[ 176.300049] x8 : ffff6828c49bf070 x7 : 0008460f18d5f20e x6 : +f20e0100bebafeca +[ 176.300302] x5 : ffff6828c7f918fe x4 : ffff6828c49bf070 x3 : +0000000000000000 +[ 176.300586] x2 : 0000000000000000 x1 : ffff6828c3c7ad00 x0 : +ffff6828c7f918f0 +[ 176.300889] Call trace: +[ 176.301123] br_nf_dev_queue_xmit+0x390/0x4ec [br_netfilter] +[ 176.301411] br_nf_post_routing+0x2a8/0x3e4 [br_netfilter] +[ 176.301703] nf_hook_slow+0x48/0x124 +[ 176.302060] br_forward_finish+0xc8/0xe8 [bridge] +[ 176.302371] br_nf_hook_thresh+0x124/0x134 [br_netfilter] +[ 176.302605] br_nf_forward_finish+0x118/0x22c [br_netfilter] +[ 176.302824] br_nf_forward_ip.part.0+0x264/0x290 [br_netfilter] +[ 176.303136] br_nf_forward+0x2b8/0x4e0 [br_netfilter] +[ 176.303359] nf_hook_slow+0x48/0x124 +[ 176.303803] __br_forward+0xc4/0x194 [bridge] +[ 176.304013] br_flood+0xd4/0x168 [bridge] +[ 176.304300] br_handle_frame_finish+0x1d4/0x5c4 [bridge] +[ 176.304536] br_nf_hook_thresh+0x124/0x134 [br_netfilter] +[ 176.304978] br_nf_pre_routing_finish+0x29c/0x494 [br_netfilter] +[ 176.305188] br_nf_pre_routing+0x250/0x524 [br_netfilter] +[ 176.305428] br_handle_frame+0x244/0x3cc [bridge] +[ 176.305695] __netif_receive_skb_core.constprop.0+0x33c/0xecc +[ 176.306080] __netif_receive_skb_one_core+0x40/0x8c +[ 176.306197] __netif_receive_skb+0x18/0x64 +[ 176.306369] process_backlog+0x80/0x124 +[ 176.306540] __napi_poll+0x38/0x17c +[ 176.306636] net_rx_action+0x124/0x26c +[ 176.306758] __do_softirq+0x100/0x26c +[ 176.307051] ____do_softirq+0x10/0x1c +[ 176.307162] call_on_irq_stack+0x24/0x4c +[ 176.307289] do_softirq_own_stack+0x1c/0x2c +[ 176.307396] do_softirq+0x54/0x6c +[ 176.307485] __local_bh_enable_ip+0x8c/0x98 +[ 176.307637] __dev_queue_xmit+0x22c/0xd28 +[ 176.307775] neigh_resolve_output+0xf4/0x1a0 +[ 176.308018] ip_finish_output2+0x1c8/0x628 +[ 176.308137] ip_do_fragment+0x5b4/0x658 +[ 176.308279] ip_fragment.constprop.0+0x48/0xec +[ 176.308420] __ip_finish_output+0xa4/0x254 +[ 176.308593] ip_finish_output+0x34/0x130 +[ 176.308814] ip_output+0x6c/0x108 +[ 176.308929] ip_send_skb+0x50/0xf0 +[ 176.309095] ip_push_pending_frames+0x30/0x54 +[ 176.309254] raw_sendmsg+0x758/0xaec +[ 176.309568] inet_sendmsg+0x44/0x70 +[ 176.309667] __sys_sendto+0x110/0x178 +[ 176.309758] __arm64_sys_sendto+0x28/0x38 +[ 176.309918] invoke_syscall+0x48/0x110 +[ 176.310211] el0_svc_common.constprop.0+0x40/0xe0 +[ 176.310353] do_el0_svc+0x1c/0x28 +[ 176.310434] el0_svc+0x34/0xb4 +[ 176.310551] el0t_64_sync_handler+0x120/0x12c +[ 176.310690] el0t_64_sync+0x190/0x194 +[ 176.311066] Code: f9402e61 79402aa2 927ff821 f9400023 (f9408860) +[ 176.315743] ---[ end trace 0000000000000000 ]--- +[ 176.316060] Kernel panic - not syncing: Oops: Fatal exception in +interrupt +[ 176.316371] Kernel Offset: 0x37e0e3000000 from 0xffff800080000000 +[ 176.316564] PHYS_OFFSET: 0xffff97d780000000 +[ 176.316782] CPU features: 0x0,88000203,3c020000,0100421b +[ 176.317210] Memory Limit: none +[ 176.317527] ---[ end Kernel panic - not syncing: Oops: Fatal +Exception in interrupt ]---\ + +Fixes: 11538d039ac6 ("bridge: vlan dst_metadata hooks in ingress and egress paths") +Reviewed-by: Ido Schimmel +Signed-off-by: Andy Roulin +Acked-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/20241001154400.22787-2-aroulin@nvidia.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/bridge/br_netfilter_hooks.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c +index 35642dc96852a..75e35fae6f244 100644 +--- a/net/bridge/br_netfilter_hooks.c ++++ b/net/bridge/br_netfilter_hooks.c +@@ -37,6 +37,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -737,6 +738,10 @@ static int br_nf_dev_queue_xmit(struct net *net, struct sock *sk, struct sk_buff + return br_dev_queue_push_xmit(net, sk, skb); + } + ++ /* Fragmentation on metadata/template dst is not supported */ ++ if (unlikely(!skb_valid_dst(skb))) ++ goto drop; ++ + /* This is wrong! We should preserve the original fragment + * boundaries by preserving frag_list rather than refragmenting. + */ +-- +2.43.0 + diff --git a/queue-4.19/nfs-remove-print_overflow_msg.patch b/queue-4.19/nfs-remove-print_overflow_msg.patch new file mode 100644 index 00000000000..67212b3b894 --- /dev/null +++ b/queue-4.19/nfs-remove-print_overflow_msg.patch @@ -0,0 +1,2608 @@ +From ab6c97c17638b1f02502162a7290a59730c6d32b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 11 Feb 2019 11:24:21 -0500 +Subject: NFS: Remove print_overflow_msg() + +From: Chuck Lever + +[ Upstream commit eb72f484a5eb94c53a241e6a7811270fb25200ad ] + +This issue is now captured by a trace point in the RPC client. + +Signed-off-by: Chuck Lever +Signed-off-by: Anna Schumaker +Stable-dep-of: 6dbf1f341b6b ("SUNRPC: Fix integer overflow in decode_rc_list()") +Signed-off-by: Sasha Levin +--- + fs/lockd/clnt4xdr.c | 14 -- + fs/lockd/clntxdr.c | 14 -- + fs/nfs/callback_xdr.c | 59 +++--- + fs/nfs/nfs2xdr.c | 84 +++----- + fs/nfs/nfs3xdr.c | 163 +++++---------- + fs/nfs/nfs42xdr.c | 21 +- + fs/nfs/nfs4xdr.c | 451 +++++++++++------------------------------ + fs/nfsd/nfs4callback.c | 13 -- + 8 files changed, 219 insertions(+), 600 deletions(-) + +diff --git a/fs/lockd/clnt4xdr.c b/fs/lockd/clnt4xdr.c +index 214a2fa1f1e39..7df6324ccb8ab 100644 +--- a/fs/lockd/clnt4xdr.c ++++ b/fs/lockd/clnt4xdr.c +@@ -74,17 +74,6 @@ static void nlm4_compute_offsets(const struct nlm_lock *lock, + *l_len = loff_t_to_s64(fl->fl_end - fl->fl_start + 1); + } + +-/* +- * Handle decode buffer overflows out-of-line. +- */ +-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +-{ +- dprintk("lockd: %s prematurely hit the end of our receive buffer. " +- "Remaining buffer length is %tu words.\n", +- func, xdr->end - xdr->p); +-} +- +- + /* + * Encode/decode NLMv4 basic data types + * +@@ -176,7 +165,6 @@ static int decode_cookie(struct xdr_stream *xdr, + dprintk("NFS: returned cookie was too long: %u\n", length); + return -EIO; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -236,7 +224,6 @@ static int decode_nlm4_stat(struct xdr_stream *xdr, __be32 *stat) + __func__, be32_to_cpup(p)); + return -EIO; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -309,7 +296,6 @@ static int decode_nlm4_holder(struct xdr_stream *xdr, struct nlm_res *result) + out: + return error; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +diff --git a/fs/lockd/clntxdr.c b/fs/lockd/clntxdr.c +index 747b9c8c940ac..4df62f6355295 100644 +--- a/fs/lockd/clntxdr.c ++++ b/fs/lockd/clntxdr.c +@@ -70,17 +70,6 @@ static void nlm_compute_offsets(const struct nlm_lock *lock, + *l_len = loff_t_to_s32(fl->fl_end - fl->fl_start + 1); + } + +-/* +- * Handle decode buffer overflows out-of-line. +- */ +-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +-{ +- dprintk("lockd: %s prematurely hit the end of our receive buffer. " +- "Remaining buffer length is %tu words.\n", +- func, xdr->end - xdr->p); +-} +- +- + /* + * Encode/decode NLMv3 basic data types + * +@@ -173,7 +162,6 @@ static int decode_cookie(struct xdr_stream *xdr, + dprintk("NFS: returned cookie was too long: %u\n", length); + return -EIO; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -231,7 +219,6 @@ static int decode_nlm_stat(struct xdr_stream *xdr, + __func__, be32_to_cpup(p)); + return -EIO; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -303,7 +290,6 @@ static int decode_nlm_holder(struct xdr_stream *xdr, struct nlm_res *result) + out: + return error; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c +index 2f84c612838c4..38dc33c537ab6 100644 +--- a/fs/nfs/callback_xdr.c ++++ b/fs/nfs/callback_xdr.c +@@ -72,16 +72,6 @@ static int nfs4_encode_void(struct svc_rqst *rqstp, __be32 *p) + return xdr_ressize_check(rqstp, p); + } + +-static __be32 *read_buf(struct xdr_stream *xdr, size_t nbytes) +-{ +- __be32 *p; +- +- p = xdr_inline_decode(xdr, nbytes); +- if (unlikely(p == NULL)) +- printk(KERN_WARNING "NFS: NFSv4 callback reply buffer overflowed!\n"); +- return p; +-} +- + static __be32 decode_string(struct xdr_stream *xdr, unsigned int *len, + const char **str, size_t maxlen) + { +@@ -98,13 +88,13 @@ static __be32 decode_fh(struct xdr_stream *xdr, struct nfs_fh *fh) + { + __be32 *p; + +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + fh->size = ntohl(*p); + if (fh->size > NFS4_FHSIZE) + return htonl(NFS4ERR_BADHANDLE); +- p = read_buf(xdr, fh->size); ++ p = xdr_inline_decode(xdr, fh->size); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + memcpy(&fh->data[0], p, fh->size); +@@ -117,11 +107,11 @@ static __be32 decode_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) + __be32 *p; + unsigned int attrlen; + +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + attrlen = ntohl(*p); +- p = read_buf(xdr, attrlen << 2); ++ p = xdr_inline_decode(xdr, attrlen << 2); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + if (likely(attrlen > 0)) +@@ -135,7 +125,7 @@ static __be32 decode_stateid(struct xdr_stream *xdr, nfs4_stateid *stateid) + { + __be32 *p; + +- p = read_buf(xdr, NFS4_STATEID_SIZE); ++ p = xdr_inline_decode(xdr, NFS4_STATEID_SIZE); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + memcpy(stateid->data, p, NFS4_STATEID_SIZE); +@@ -156,7 +146,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound + status = decode_string(xdr, &hdr->taglen, &hdr->tag, CB_OP_TAGLEN_MAXSZ); + if (unlikely(status != 0)) + return status; +- p = read_buf(xdr, 12); ++ p = xdr_inline_decode(xdr, 12); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + hdr->minorversion = ntohl(*p++); +@@ -176,7 +166,7 @@ static __be32 decode_compound_hdr_arg(struct xdr_stream *xdr, struct cb_compound + static __be32 decode_op_hdr(struct xdr_stream *xdr, unsigned int *op) + { + __be32 *p; +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE_HDR); + *op = ntohl(*p); +@@ -205,7 +195,7 @@ static __be32 decode_recall_args(struct svc_rqst *rqstp, + status = decode_delegation_stateid(xdr, &args->stateid); + if (unlikely(status != 0)) + return status; +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + args->truncate = ntohl(*p); +@@ -227,7 +217,7 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, + __be32 status = 0; + uint32_t iomode; + +- p = read_buf(xdr, 4 * sizeof(uint32_t)); ++ p = xdr_inline_decode(xdr, 4 * sizeof(uint32_t)); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + +@@ -245,14 +235,14 @@ static __be32 decode_layoutrecall_args(struct svc_rqst *rqstp, + if (unlikely(status != 0)) + return status; + +- p = read_buf(xdr, 2 * sizeof(uint64_t)); ++ p = xdr_inline_decode(xdr, 2 * sizeof(uint64_t)); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + p = xdr_decode_hyper(p, &args->cbl_range.offset); + p = xdr_decode_hyper(p, &args->cbl_range.length); + return decode_layout_stateid(xdr, &args->cbl_stateid); + } else if (args->cbl_recall_type == RETURN_FSID) { +- p = read_buf(xdr, 2 * sizeof(uint64_t)); ++ p = xdr_inline_decode(xdr, 2 * sizeof(uint64_t)); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + p = xdr_decode_hyper(p, &args->cbl_fsid.major); +@@ -273,7 +263,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, + __be32 status = 0; + + /* Num of device notifications */ +- p = read_buf(xdr, sizeof(uint32_t)); ++ p = xdr_inline_decode(xdr, sizeof(uint32_t)); + if (unlikely(p == NULL)) { + status = htonl(NFS4ERR_BADXDR); + goto out; +@@ -292,7 +282,8 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, + for (i = 0; i < n; i++) { + struct cb_devicenotifyitem *dev = &args->devs[i]; + +- p = read_buf(xdr, (4 * sizeof(uint32_t)) + NFS4_DEVICEID4_SIZE); ++ p = xdr_inline_decode(xdr, (4 * sizeof(uint32_t)) + ++ NFS4_DEVICEID4_SIZE); + if (unlikely(p == NULL)) { + status = htonl(NFS4ERR_BADXDR); + goto err; +@@ -323,7 +314,7 @@ __be32 decode_devicenotify_args(struct svc_rqst *rqstp, + p += XDR_QUADLEN(NFS4_DEVICEID4_SIZE); + + if (dev->cbd_layout_type == NOTIFY_DEVICEID4_CHANGE) { +- p = read_buf(xdr, sizeof(uint32_t)); ++ p = xdr_inline_decode(xdr, sizeof(uint32_t)); + if (unlikely(p == NULL)) { + status = htonl(NFS4ERR_BADXDR); + goto err; +@@ -355,7 +346,7 @@ static __be32 decode_sessionid(struct xdr_stream *xdr, + { + __be32 *p; + +- p = read_buf(xdr, NFS4_MAX_SESSIONID_LEN); ++ p = xdr_inline_decode(xdr, NFS4_MAX_SESSIONID_LEN); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + +@@ -375,13 +366,13 @@ static __be32 decode_rc_list(struct xdr_stream *xdr, + goto out; + + status = htonl(NFS4ERR_RESOURCE); +- p = read_buf(xdr, sizeof(uint32_t)); ++ p = xdr_inline_decode(xdr, sizeof(uint32_t)); + if (unlikely(p == NULL)) + goto out; + + rc_list->rcl_nrefcalls = ntohl(*p++); + if (rc_list->rcl_nrefcalls) { +- p = read_buf(xdr, ++ p = xdr_inline_decode(xdr, + rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); + if (unlikely(p == NULL)) + goto out; +@@ -414,7 +405,7 @@ static __be32 decode_cb_sequence_args(struct svc_rqst *rqstp, + if (status) + return status; + +- p = read_buf(xdr, 5 * sizeof(uint32_t)); ++ p = xdr_inline_decode(xdr, 5 * sizeof(uint32_t)); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_RESOURCE); + +@@ -457,7 +448,7 @@ static __be32 decode_recallany_args(struct svc_rqst *rqstp, + uint32_t bitmap[2]; + __be32 *p, status; + +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + args->craa_objs_to_keep = ntohl(*p++); +@@ -476,7 +467,7 @@ static __be32 decode_recallslot_args(struct svc_rqst *rqstp, + struct cb_recallslotargs *args = argp; + __be32 *p; + +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + args->crsa_target_highest_slotid = ntohl(*p++); +@@ -488,14 +479,14 @@ static __be32 decode_lockowner(struct xdr_stream *xdr, struct cb_notify_lock_arg + __be32 *p; + unsigned int len; + +- p = read_buf(xdr, 12); ++ p = xdr_inline_decode(xdr, 12); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + + p = xdr_decode_hyper(p, &args->cbnl_owner.clientid); + len = be32_to_cpu(*p); + +- p = read_buf(xdr, len); ++ p = xdr_inline_decode(xdr, len); + if (unlikely(p == NULL)) + return htonl(NFS4ERR_BADXDR); + +@@ -533,7 +524,7 @@ static __be32 decode_write_response(struct xdr_stream *xdr, + __be32 *p; + + /* skip the always zero field */ +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + goto out; + p++; +@@ -573,7 +564,7 @@ static __be32 decode_offload_args(struct svc_rqst *rqstp, + return status; + + /* decode status */ +- p = read_buf(xdr, 4); ++ p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) + goto out; + args->error = ntohl(*p++); +diff --git a/fs/nfs/nfs2xdr.c b/fs/nfs/nfs2xdr.c +index 040a05f0e61ef..6968d6ffe84fa 100644 +--- a/fs/nfs/nfs2xdr.c ++++ b/fs/nfs/nfs2xdr.c +@@ -79,17 +79,6 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, + xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); + } + +-/* +- * Handle decode buffer overflows out-of-line. +- */ +-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +-{ +- dprintk("NFS: %s prematurely hit the end of our receive buffer. " +- "Remaining buffer length is %tu words.\n", +- func, xdr->end - xdr->p); +-} +- +- + /* + * Encode/decode NFSv2 basic data types + * +@@ -110,8 +99,8 @@ static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_pgio_res *result) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + count = be32_to_cpup(p); + recvd = xdr_read_pages(xdr, count); + if (unlikely(count > recvd)) +@@ -125,9 +114,6 @@ static int decode_nfsdata(struct xdr_stream *xdr, struct nfs_pgio_res *result) + "count %u > recvd %u\n", count, recvd); + count = recvd; + goto out; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -157,13 +143,10 @@ static int decode_stat(struct xdr_stream *xdr, enum nfs_stat *status) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + *status = be32_to_cpup(p); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -205,14 +188,11 @@ static int decode_fhandle(struct xdr_stream *xdr, struct nfs_fh *fh) + __be32 *p; + + p = xdr_inline_decode(xdr, NFS2_FHSIZE); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + fh->size = NFS2_FHSIZE; + memcpy(fh->data, p, NFS2_FHSIZE); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -282,8 +262,8 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) + __be32 *p; + + p = xdr_inline_decode(xdr, NFS_fattr_sz << 2); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + + fattr->valid |= NFS_ATTR_FATTR_V2; + +@@ -325,9 +305,6 @@ static int decode_fattr(struct xdr_stream *xdr, struct nfs_fattr *fattr) + out_gid: + dprintk("NFS: returned invalid gid\n"); + return -EINVAL; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -416,23 +393,20 @@ static int decode_filename_inline(struct xdr_stream *xdr, + u32 count; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + count = be32_to_cpup(p); + if (count > NFS3_MAXNAMLEN) + goto out_nametoolong; + p = xdr_inline_decode(xdr, count); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + *name = (const char *)p; + *length = count; + return 0; + out_nametoolong: + dprintk("NFS: returned filename too long: %u\n", count); + return -ENAMETOOLONG; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -455,8 +429,8 @@ static int decode_path(struct xdr_stream *xdr) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + length = be32_to_cpup(p); + if (unlikely(length >= xdr->buf->page_len || length > NFS_MAXPATHLEN)) + goto out_size; +@@ -472,9 +446,6 @@ static int decode_path(struct xdr_stream *xdr) + dprintk("NFS: server cheating in pathname result: " + "length %u > received %u\n", length, recvd); + return -EIO; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -951,12 +922,12 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + int error; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + if (*p++ == xdr_zero) { + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + if (*p++ == xdr_zero) + return -EAGAIN; + entry->eof = 1; +@@ -964,8 +935,8 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + } + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + entry->ino = be32_to_cpup(p); + + error = decode_filename_inline(xdr, &entry->name, &entry->len); +@@ -978,17 +949,13 @@ int nfs2_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + */ + entry->prev_cookie = entry->cookie; + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + entry->cookie = be32_to_cpup(p); + + entry->d_type = DT_UNKNOWN; + + return 0; +- +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EAGAIN; + } + + /* +@@ -1052,17 +1019,14 @@ static int decode_info(struct xdr_stream *xdr, struct nfs2_fsstat *result) + __be32 *p; + + p = xdr_inline_decode(xdr, NFS_info_sz << 2); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + result->tsize = be32_to_cpup(p++); + result->bsize = be32_to_cpup(p++); + result->blocks = be32_to_cpup(p++); + result->bfree = be32_to_cpup(p++); + result->bavail = be32_to_cpup(p); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int nfs2_xdr_dec_statfsres(struct rpc_rqst *req, struct xdr_stream *xdr, +diff --git a/fs/nfs/nfs3xdr.c b/fs/nfs/nfs3xdr.c +index 0ed419bb02b0f..ebe7d1ce00e39 100644 +--- a/fs/nfs/nfs3xdr.c ++++ b/fs/nfs/nfs3xdr.c +@@ -119,17 +119,6 @@ static void prepare_reply_buffer(struct rpc_rqst *req, struct page **pages, + xdr_inline_pages(&req->rq_rcv_buf, replen << 2, pages, base, len); + } + +-/* +- * Handle decode buffer overflows out-of-line. +- */ +-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +-{ +- dprintk("NFS: %s prematurely hit the end of our receive buffer. " +- "Remaining buffer length is %tu words.\n", +- func, xdr->end - xdr->p); +-} +- +- + /* + * Encode/decode NFSv3 basic data types + * +@@ -152,13 +141,10 @@ static int decode_uint32(struct xdr_stream *xdr, u32 *value) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + *value = be32_to_cpup(p); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_uint64(struct xdr_stream *xdr, u64 *value) +@@ -166,13 +152,10 @@ static int decode_uint64(struct xdr_stream *xdr, u64 *value) + __be32 *p; + + p = xdr_inline_decode(xdr, 8); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + xdr_decode_hyper(p, value); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -212,14 +195,14 @@ static int decode_inline_filename3(struct xdr_stream *xdr, + u32 count; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + count = be32_to_cpup(p); + if (count > NFS3_MAXNAMLEN) + goto out_nametoolong; + p = xdr_inline_decode(xdr, count); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + *name = (const char *)p; + *length = count; + return 0; +@@ -227,9 +210,6 @@ static int decode_inline_filename3(struct xdr_stream *xdr, + out_nametoolong: + dprintk("NFS: returned filename too long: %u\n", count); + return -ENAMETOOLONG; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -250,8 +230,8 @@ static int decode_nfspath3(struct xdr_stream *xdr) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + count = be32_to_cpup(p); + if (unlikely(count >= xdr->buf->page_len || count > NFS3_MAXPATHLEN)) + goto out_nametoolong; +@@ -268,9 +248,6 @@ static int decode_nfspath3(struct xdr_stream *xdr) + dprintk("NFS: server cheating in pathname result: " + "count %u > recvd %u\n", count, recvd); + return -EIO; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -304,13 +281,10 @@ static int decode_cookieverf3(struct xdr_stream *xdr, __be32 *verifier) + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_COOKIEVERFSIZE); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + memcpy(verifier, p, NFS3_COOKIEVERFSIZE); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -331,13 +305,10 @@ static int decode_writeverf3(struct xdr_stream *xdr, struct nfs_write_verifier * + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_WRITEVERFSIZE); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + memcpy(verifier->data, p, NFS3_WRITEVERFSIZE); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -365,13 +336,10 @@ static int decode_nfsstat3(struct xdr_stream *xdr, enum nfs_stat *status) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + *status = be32_to_cpup(p); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -454,23 +422,20 @@ static int decode_nfs_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + length = be32_to_cpup(p++); + if (unlikely(length > NFS3_FHSIZE)) + goto out_toobig; + p = xdr_inline_decode(xdr, length); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + fh->size = length; + memcpy(fh->data, p, length); + return 0; + out_toobig: + dprintk("NFS: file handle size (%u) too big\n", length); + return -E2BIG; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static void zero_nfs_fh3(struct nfs_fh *fh) +@@ -656,8 +621,8 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_fattr_sz << 2); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + + p = xdr_decode_ftype3(p, &fmode); + +@@ -691,9 +656,6 @@ static int decode_fattr3(struct xdr_stream *xdr, struct nfs_fattr *fattr) + out_gid: + dprintk("NFS: returned invalid gid\n"); + return -EINVAL; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -711,14 +673,11 @@ static int decode_post_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + if (*p != xdr_zero) + return decode_fattr3(xdr, fattr); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -734,8 +693,8 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) + __be32 *p; + + p = xdr_inline_decode(xdr, NFS3_wcc_attr_sz << 2); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + + fattr->valid |= NFS_ATTR_FATTR_PRESIZE + | NFS_ATTR_FATTR_PRECHANGE +@@ -748,9 +707,6 @@ static int decode_wcc_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) + fattr->pre_change_attr = nfs_timespec_to_change_attr(&fattr->pre_ctime); + + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -774,14 +730,11 @@ static int decode_pre_op_attr(struct xdr_stream *xdr, struct nfs_fattr *fattr) + __be32 *p; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + if (*p != xdr_zero) + return decode_wcc_attr(xdr, fattr); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr) +@@ -809,15 +762,12 @@ static int decode_wcc_data(struct xdr_stream *xdr, struct nfs_fattr *fattr) + static int decode_post_op_fh3(struct xdr_stream *xdr, struct nfs_fh *fh) + { + __be32 *p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + if (*p != xdr_zero) + return decode_nfs_fh3(xdr, fh); + zero_nfs_fh3(fh); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -1641,8 +1591,8 @@ static int decode_read3resok(struct xdr_stream *xdr, + __be32 *p; + + p = xdr_inline_decode(xdr, 4 + 4 + 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + count = be32_to_cpup(p++); + eof = be32_to_cpup(p++); + ocount = be32_to_cpup(p++); +@@ -1665,9 +1615,6 @@ static int decode_read3resok(struct xdr_stream *xdr, + count = recvd; + eof = 0; + goto out; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int nfs3_xdr_dec_read3res(struct rpc_rqst *req, struct xdr_stream *xdr, +@@ -1726,22 +1673,18 @@ static int decode_write3resok(struct xdr_stream *xdr, + __be32 *p; + + p = xdr_inline_decode(xdr, 4 + 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + result->count = be32_to_cpup(p++); + result->verf->committed = be32_to_cpup(p++); + if (unlikely(result->verf->committed > NFS_FILE_SYNC)) + goto out_badvalue; + if (decode_writeverf3(xdr, &result->verf->verifier)) +- goto out_eio; ++ return -EIO; + return result->count; + out_badvalue: + dprintk("NFS: bad stable_how value: %u\n", result->verf->committed); + return -EIO; +-out_overflow: +- print_overflow_msg(__func__, xdr); +-out_eio: +- return -EIO; + } + + static int nfs3_xdr_dec_write3res(struct rpc_rqst *req, struct xdr_stream *xdr, +@@ -2005,12 +1948,12 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + u64 new_cookie; + + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + if (*p == xdr_zero) { + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + if (*p == xdr_zero) + return -EAGAIN; + entry->eof = 1; +@@ -2046,8 +1989,8 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + + /* In fact, a post_op_fh3: */ + p = xdr_inline_decode(xdr, 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EAGAIN; + if (*p != xdr_zero) { + error = decode_nfs_fh3(xdr, entry->fh); + if (unlikely(error)) { +@@ -2064,9 +2007,6 @@ int nfs3_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + + return 0; + +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EAGAIN; + out_truncated: + dprintk("NFS: directory entry contains invalid file handle\n"); + *entry = old; +@@ -2178,8 +2118,8 @@ static int decode_fsstat3resok(struct xdr_stream *xdr, + __be32 *p; + + p = xdr_inline_decode(xdr, 8 * 6 + 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + p = xdr_decode_size3(p, &result->tbytes); + p = xdr_decode_size3(p, &result->fbytes); + p = xdr_decode_size3(p, &result->abytes); +@@ -2188,9 +2128,6 @@ static int decode_fsstat3resok(struct xdr_stream *xdr, + xdr_decode_size3(p, &result->afiles); + /* ignore invarsec */ + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int nfs3_xdr_dec_fsstat3res(struct rpc_rqst *req, +@@ -2250,8 +2187,8 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr, + __be32 *p; + + p = xdr_inline_decode(xdr, 4 * 7 + 8 + 8 + 4); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + result->rtmax = be32_to_cpup(p++); + result->rtpref = be32_to_cpup(p++); + result->rtmult = be32_to_cpup(p++); +@@ -2265,9 +2202,6 @@ static int decode_fsinfo3resok(struct xdr_stream *xdr, + /* ignore properties */ + result->lease_time = 0; + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int nfs3_xdr_dec_fsinfo3res(struct rpc_rqst *req, +@@ -2323,15 +2257,12 @@ static int decode_pathconf3resok(struct xdr_stream *xdr, + __be32 *p; + + p = xdr_inline_decode(xdr, 4 * 6); +- if (unlikely(p == NULL)) +- goto out_overflow; ++ if (unlikely(!p)) ++ return -EIO; + result->max_link = be32_to_cpup(p++); + result->max_namelen = be32_to_cpup(p); + /* ignore remaining fields */ + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int nfs3_xdr_dec_pathconf3res(struct rpc_rqst *req, +diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c +index eee011de3f58b..d66e1025b4a4c 100644 +--- a/fs/nfs/nfs42xdr.c ++++ b/fs/nfs/nfs42xdr.c +@@ -404,7 +404,7 @@ static int decode_write_response(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + count = be32_to_cpup(p); + if (count > 1) + return -EREMOTEIO; +@@ -412,18 +412,14 @@ static int decode_write_response(struct xdr_stream *xdr, + status = decode_opaque_fixed(xdr, &res->stateid, + NFS4_STATEID_SIZE); + if (unlikely(status)) +- goto out_overflow; ++ return -EIO; + } + p = xdr_inline_decode(xdr, 8 + 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + p = xdr_decode_hyper(p, &res->count); + res->verifier.committed = be32_to_cpup(p); + return decode_verifier(xdr, &res->verifier.verifier); +- +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_copy_requirements(struct xdr_stream *xdr, +@@ -432,14 +428,11 @@ static int decode_copy_requirements(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 4 + 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + res->consecutive = be32_to_cpup(p++); + res->synchronous = be32_to_cpup(p++); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_copy(struct xdr_stream *xdr, struct nfs42_copy_res *res) +@@ -484,15 +477,11 @@ static int decode_seek(struct xdr_stream *xdr, struct nfs42_seek_res *res) + + p = xdr_inline_decode(xdr, 4 + 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + res->sr_eof = be32_to_cpup(p++); + p = xdr_decode_hyper(p, &res->sr_offset); + return 0; +- +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_layoutstats(struct xdr_stream *xdr) +diff --git a/fs/nfs/nfs4xdr.c b/fs/nfs/nfs4xdr.c +index f0021e3b8efdd..767448b015cff 100644 +--- a/fs/nfs/nfs4xdr.c ++++ b/fs/nfs/nfs4xdr.c +@@ -3144,22 +3144,12 @@ static void nfs4_xdr_enc_free_stateid(struct rpc_rqst *req, + } + #endif /* CONFIG_NFS_V4_1 */ + +-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +-{ +- dprintk("nfs: %s: prematurely hit end of receive buffer. " +- "Remaining buffer length is %tu words.\n", +- func, xdr->end - xdr->p); +-} +- + static int decode_opaque_inline(struct xdr_stream *xdr, unsigned int *len, char **string) + { + ssize_t ret = xdr_stream_decode_opaque_inline(xdr, (void **)string, + NFS4_OPAQUE_LIMIT); +- if (unlikely(ret < 0)) { +- if (ret == -EBADMSG) +- print_overflow_msg(__func__, xdr); ++ if (unlikely(ret < 0)) + return -EIO; +- } + *len = ret; + return 0; + } +@@ -3170,22 +3160,19 @@ static int decode_compound_hdr(struct xdr_stream *xdr, struct compound_hdr *hdr) + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + hdr->status = be32_to_cpup(p++); + hdr->taglen = be32_to_cpup(p); + + p = xdr_inline_decode(xdr, hdr->taglen + 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + hdr->tag = (char *)p; + p += XDR_QUADLEN(hdr->taglen); + hdr->nops = be32_to_cpup(p); + if (unlikely(hdr->nops < 1)) + return nfs4_stat_to_errno(hdr->status); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, +@@ -3214,7 +3201,6 @@ static bool __decode_op_hdr(struct xdr_stream *xdr, enum nfs_opnum4 expected, + *nfs_retval = -EREMOTEIO; + return false; + out_overflow: +- print_overflow_msg(__func__, xdr); + *nfs_retval = -EIO; + return false; + } +@@ -3235,10 +3221,9 @@ static int decode_ace(struct xdr_stream *xdr, void *ace) + char *str; + + p = xdr_inline_decode(xdr, 12); +- if (likely(p)) +- return decode_opaque_inline(xdr, &strlen, &str); +- print_overflow_msg(__func__, xdr); +- return -EIO; ++ if (unlikely(!p)) ++ return -EIO; ++ return decode_opaque_inline(xdr, &strlen, &str); + } + + static ssize_t +@@ -3249,10 +3234,9 @@ decode_bitmap4(struct xdr_stream *xdr, uint32_t *bitmap, size_t sz) + ret = xdr_stream_decode_uint32_array(xdr, bitmap, sz); + if (likely(ret >= 0)) + return ret; +- if (ret == -EMSGSIZE) +- return sz; +- print_overflow_msg(__func__, xdr); +- return -EIO; ++ if (ret != -EMSGSIZE) ++ return -EIO; ++ return sz; + } + + static int decode_attr_bitmap(struct xdr_stream *xdr, uint32_t *bitmap) +@@ -3268,13 +3252,10 @@ static int decode_attr_length(struct xdr_stream *xdr, uint32_t *attrlen, unsigne + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *attrlen = be32_to_cpup(p); + *savep = xdr_stream_pos(xdr); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_supported(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *bitmask) +@@ -3303,7 +3284,7 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * + if (likely(bitmap[0] & FATTR4_WORD0_TYPE)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *type = be32_to_cpup(p); + if (*type < NF4REG || *type > NF4NAMEDATTR) { + dprintk("%s: bad type %d\n", __func__, *type); +@@ -3314,9 +3295,6 @@ static int decode_attr_type(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t * + } + dprintk("%s: type=0%o\n", __func__, nfs_type2fmt[*type]); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_fh_expire_type(struct xdr_stream *xdr, +@@ -3330,15 +3308,12 @@ static int decode_attr_fh_expire_type(struct xdr_stream *xdr, + if (likely(bitmap[0] & FATTR4_WORD0_FH_EXPIRE_TYPE)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *type = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_FH_EXPIRE_TYPE; + } + dprintk("%s: expire type=0x%x\n", __func__, *type); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *change) +@@ -3352,7 +3327,7 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t + if (likely(bitmap[0] & FATTR4_WORD0_CHANGE)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, change); + bitmap[0] &= ~FATTR4_WORD0_CHANGE; + ret = NFS_ATTR_FATTR_CHANGE; +@@ -3360,9 +3335,6 @@ static int decode_attr_change(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t + dprintk("%s: change attribute=%Lu\n", __func__, + (unsigned long long)*change); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *size) +@@ -3376,16 +3348,13 @@ static int decode_attr_size(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t * + if (likely(bitmap[0] & FATTR4_WORD0_SIZE)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, size); + bitmap[0] &= ~FATTR4_WORD0_SIZE; + ret = NFS_ATTR_FATTR_SIZE; + } + dprintk("%s: file size=%Lu\n", __func__, (unsigned long long)*size); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +@@ -3398,15 +3367,12 @@ static int decode_attr_link_support(struct xdr_stream *xdr, uint32_t *bitmap, ui + if (likely(bitmap[0] & FATTR4_WORD0_LINK_SUPPORT)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *res = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_LINK_SUPPORT; + } + dprintk("%s: link support=%s\n", __func__, *res == 0 ? "false" : "true"); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +@@ -3419,15 +3385,12 @@ static int decode_attr_symlink_support(struct xdr_stream *xdr, uint32_t *bitmap, + if (likely(bitmap[0] & FATTR4_WORD0_SYMLINK_SUPPORT)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *res = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_SYMLINK_SUPPORT; + } + dprintk("%s: symlink support=%s\n", __func__, *res == 0 ? "false" : "true"); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs_fsid *fsid) +@@ -3442,7 +3405,7 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs + if (likely(bitmap[0] & FATTR4_WORD0_FSID)) { + p = xdr_inline_decode(xdr, 16); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + p = xdr_decode_hyper(p, &fsid->major); + xdr_decode_hyper(p, &fsid->minor); + bitmap[0] &= ~FATTR4_WORD0_FSID; +@@ -3452,9 +3415,6 @@ static int decode_attr_fsid(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs + (unsigned long long)fsid->major, + (unsigned long long)fsid->minor); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +@@ -3467,15 +3427,12 @@ static int decode_attr_lease_time(struct xdr_stream *xdr, uint32_t *bitmap, uint + if (likely(bitmap[0] & FATTR4_WORD0_LEASE_TIME)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *res = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_LEASE_TIME; + } + dprintk("%s: file size=%u\n", __func__, (unsigned int)*res); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t *res) +@@ -3487,14 +3444,11 @@ static int decode_attr_error(struct xdr_stream *xdr, uint32_t *bitmap, int32_t * + if (likely(bitmap[0] & FATTR4_WORD0_RDATTR_ERROR)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + bitmap[0] &= ~FATTR4_WORD0_RDATTR_ERROR; + *res = -be32_to_cpup(p); + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_exclcreat_supported(struct xdr_stream *xdr, +@@ -3526,13 +3480,13 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru + if (likely(bitmap[0] & FATTR4_WORD0_FILEHANDLE)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p); + if (len > NFS4_FHSIZE) + return -EIO; + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + if (fh != NULL) { + memcpy(fh->data, p, len); + fh->size = len; +@@ -3540,9 +3494,6 @@ static int decode_attr_filehandle(struct xdr_stream *xdr, uint32_t *bitmap, stru + bitmap[0] &= ~FATTR4_WORD0_FILEHANDLE; + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +@@ -3555,15 +3506,12 @@ static int decode_attr_aclsupport(struct xdr_stream *xdr, uint32_t *bitmap, uint + if (likely(bitmap[0] & FATTR4_WORD0_ACLSUPPORT)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *res = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_ACLSUPPORT; + } + dprintk("%s: ACLs supported=%u\n", __func__, (unsigned int)*res); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) +@@ -3577,16 +3525,13 @@ static int decode_attr_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t + if (likely(bitmap[0] & FATTR4_WORD0_FILEID)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, fileid); + bitmap[0] &= ~FATTR4_WORD0_FILEID; + ret = NFS_ATTR_FATTR_FILEID; + } + dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *fileid) +@@ -3600,16 +3545,13 @@ static int decode_attr_mounted_on_fileid(struct xdr_stream *xdr, uint32_t *bitma + if (likely(bitmap[1] & FATTR4_WORD1_MOUNTED_ON_FILEID)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, fileid); + bitmap[1] &= ~FATTR4_WORD1_MOUNTED_ON_FILEID; + ret = NFS_ATTR_FATTR_MOUNTED_ON_FILEID; + } + dprintk("%s: fileid=%Lu\n", __func__, (unsigned long long)*fileid); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +@@ -3623,15 +3565,12 @@ static int decode_attr_files_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin + if (likely(bitmap[0] & FATTR4_WORD0_FILES_AVAIL)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[0] &= ~FATTR4_WORD0_FILES_AVAIL; + } + dprintk("%s: files avail=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +@@ -3645,15 +3584,12 @@ static int decode_attr_files_free(struct xdr_stream *xdr, uint32_t *bitmap, uint + if (likely(bitmap[0] & FATTR4_WORD0_FILES_FREE)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[0] &= ~FATTR4_WORD0_FILES_FREE; + } + dprintk("%s: files free=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +@@ -3667,15 +3603,12 @@ static int decode_attr_files_total(struct xdr_stream *xdr, uint32_t *bitmap, uin + if (likely(bitmap[0] & FATTR4_WORD0_FILES_TOTAL)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[0] &= ~FATTR4_WORD0_FILES_TOTAL; + } + dprintk("%s: files total=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) +@@ -3686,7 +3619,7 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + n = be32_to_cpup(p); + if (n == 0) + goto root_path; +@@ -3718,9 +3651,6 @@ static int decode_pathname(struct xdr_stream *xdr, struct nfs4_pathname *path) + dprintk(" status %d", status); + status = -EIO; + goto out; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, struct nfs4_fs_locations *res) +@@ -3745,7 +3675,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st + goto out; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ goto out_eio; + n = be32_to_cpup(p); + for (res->nlocations = 0; res->nlocations < n; res->nlocations++) { + u32 m; +@@ -3756,7 +3686,7 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st + loc = &res->locations[res->nlocations]; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ goto out_eio; + m = be32_to_cpup(p); + + dprintk("%s: servers:\n", __func__); +@@ -3794,8 +3724,6 @@ static int decode_attr_fs_locations(struct xdr_stream *xdr, uint32_t *bitmap, st + out: + dprintk("%s: fs_locations done, error = %d\n", __func__, status); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); + out_eio: + status = -EIO; + goto out; +@@ -3812,15 +3740,12 @@ static int decode_attr_maxfilesize(struct xdr_stream *xdr, uint32_t *bitmap, uin + if (likely(bitmap[0] & FATTR4_WORD0_MAXFILESIZE)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[0] &= ~FATTR4_WORD0_MAXFILESIZE; + } + dprintk("%s: maxfilesize=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxlink) +@@ -3834,15 +3759,12 @@ static int decode_attr_maxlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ + if (likely(bitmap[0] & FATTR4_WORD0_MAXLINK)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *maxlink = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_MAXLINK; + } + dprintk("%s: maxlink=%u\n", __func__, *maxlink); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *maxname) +@@ -3856,15 +3778,12 @@ static int decode_attr_maxname(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ + if (likely(bitmap[0] & FATTR4_WORD0_MAXNAME)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *maxname = be32_to_cpup(p); + bitmap[0] &= ~FATTR4_WORD0_MAXNAME; + } + dprintk("%s: maxname=%u\n", __func__, *maxname); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +@@ -3879,7 +3798,7 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ + uint64_t maxread; + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, &maxread); + if (maxread > 0x7FFFFFFF) + maxread = 0x7FFFFFFF; +@@ -3888,9 +3807,6 @@ static int decode_attr_maxread(struct xdr_stream *xdr, uint32_t *bitmap, uint32_ + } + dprintk("%s: maxread=%lu\n", __func__, (unsigned long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *res) +@@ -3905,7 +3821,7 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 + uint64_t maxwrite; + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, &maxwrite); + if (maxwrite > 0x7FFFFFFF) + maxwrite = 0x7FFFFFFF; +@@ -3914,9 +3830,6 @@ static int decode_attr_maxwrite(struct xdr_stream *xdr, uint32_t *bitmap, uint32 + } + dprintk("%s: maxwrite=%lu\n", __func__, (unsigned long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *mode) +@@ -3931,7 +3844,7 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m + if (likely(bitmap[1] & FATTR4_WORD1_MODE)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + tmp = be32_to_cpup(p); + *mode = tmp & ~S_IFMT; + bitmap[1] &= ~FATTR4_WORD1_MODE; +@@ -3939,9 +3852,6 @@ static int decode_attr_mode(struct xdr_stream *xdr, uint32_t *bitmap, umode_t *m + } + dprintk("%s: file mode=0%o\n", __func__, (unsigned int)*mode); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t *nlink) +@@ -3955,16 +3865,13 @@ static int decode_attr_nlink(struct xdr_stream *xdr, uint32_t *bitmap, uint32_t + if (likely(bitmap[1] & FATTR4_WORD1_NUMLINKS)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + *nlink = be32_to_cpup(p); + bitmap[1] &= ~FATTR4_WORD1_NUMLINKS; + ret = NFS_ATTR_FATTR_NLINK; + } + dprintk("%s: nlink=%u\n", __func__, (unsigned int)*nlink); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static ssize_t decode_nfs4_string(struct xdr_stream *xdr, +@@ -4009,10 +3916,9 @@ static int decode_attr_owner(struct xdr_stream *xdr, uint32_t *bitmap, + return NFS_ATTR_FATTR_OWNER; + } + out: +- if (len != -EBADMSG) +- return 0; +- print_overflow_msg(__func__, xdr); +- return -EIO; ++ if (len == -EBADMSG) ++ return -EIO; ++ return 0; + } + + static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, +@@ -4044,10 +3950,9 @@ static int decode_attr_group(struct xdr_stream *xdr, uint32_t *bitmap, + return NFS_ATTR_FATTR_GROUP; + } + out: +- if (len != -EBADMSG) +- return 0; +- print_overflow_msg(__func__, xdr); +- return -EIO; ++ if (len == -EBADMSG) ++ return -EIO; ++ return 0; + } + + static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rdev) +@@ -4064,7 +3969,7 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + major = be32_to_cpup(p++); + minor = be32_to_cpup(p); + tmp = MKDEV(major, minor); +@@ -4075,9 +3980,6 @@ static int decode_attr_rdev(struct xdr_stream *xdr, uint32_t *bitmap, dev_t *rde + } + dprintk("%s: rdev=(0x%x:0x%x)\n", __func__, major, minor); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +@@ -4091,15 +3993,12 @@ static int decode_attr_space_avail(struct xdr_stream *xdr, uint32_t *bitmap, uin + if (likely(bitmap[1] & FATTR4_WORD1_SPACE_AVAIL)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[1] &= ~FATTR4_WORD1_SPACE_AVAIL; + } + dprintk("%s: space avail=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +@@ -4113,15 +4012,12 @@ static int decode_attr_space_free(struct xdr_stream *xdr, uint32_t *bitmap, uint + if (likely(bitmap[1] & FATTR4_WORD1_SPACE_FREE)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[1] &= ~FATTR4_WORD1_SPACE_FREE; + } + dprintk("%s: space free=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *res) +@@ -4135,15 +4031,12 @@ static int decode_attr_space_total(struct xdr_stream *xdr, uint32_t *bitmap, uin + if (likely(bitmap[1] & FATTR4_WORD1_SPACE_TOTAL)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + bitmap[1] &= ~FATTR4_WORD1_SPACE_TOTAL; + } + dprintk("%s: space total=%Lu\n", __func__, (unsigned long long)*res); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint64_t *used) +@@ -4157,7 +4050,7 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint + if (likely(bitmap[1] & FATTR4_WORD1_SPACE_USED)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, used); + bitmap[1] &= ~FATTR4_WORD1_SPACE_USED; + ret = NFS_ATTR_FATTR_SPACE_USED; +@@ -4165,9 +4058,6 @@ static int decode_attr_space_used(struct xdr_stream *xdr, uint32_t *bitmap, uint + dprintk("%s: space used=%Lu\n", __func__, + (unsigned long long)*used); + return ret; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static __be32 * +@@ -4187,12 +4077,9 @@ static int decode_attr_time(struct xdr_stream *xdr, struct timespec *time) + + p = xdr_inline_decode(xdr, nfstime4_maxsz << 2); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_nfstime4(p, time); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_time_access(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) +@@ -4263,19 +4150,19 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, + if (likely(bitmap[2] & FATTR4_WORD2_SECURITY_LABEL)) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + lfs = be32_to_cpup(p++); + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + pi = be32_to_cpup(p++); + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p++); + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + if (len < NFS4_MAXLABELLEN) { + if (label && label->len) { + if (label->len < len) +@@ -4296,10 +4183,6 @@ static int decode_attr_security_label(struct xdr_stream *xdr, uint32_t *bitmap, + label->len, label->pi, label->lfs); + } + return status; +- +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_attr_time_modify(struct xdr_stream *xdr, uint32_t *bitmap, struct timespec *time) +@@ -4343,14 +4226,11 @@ static int decode_change_info(struct xdr_stream *xdr, struct nfs4_change_info *c + + p = xdr_inline_decode(xdr, 20); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + cinfo->atomic = be32_to_cpup(p++); + p = xdr_decode_hyper(p, &cinfo->before); + xdr_decode_hyper(p, &cinfo->after); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) +@@ -4364,24 +4244,19 @@ static int decode_access(struct xdr_stream *xdr, u32 *supported, u32 *access) + return status; + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + supp = be32_to_cpup(p++); + acc = be32_to_cpup(p); + *supported = supp; + *access = acc; + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_opaque_fixed(struct xdr_stream *xdr, void *buf, size_t len) + { + ssize_t ret = xdr_stream_decode_opaque_fixed(xdr, buf, len); +- if (unlikely(ret < 0)) { +- print_overflow_msg(__func__, xdr); ++ if (unlikely(ret < 0)) + return -EIO; +- } + return 0; + } + +@@ -4464,13 +4339,11 @@ static int decode_create(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) + return status; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + bmlen = be32_to_cpup(p); + p = xdr_inline_decode(xdr, bmlen << 2); + if (likely(p)) + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -4578,13 +4451,10 @@ static int decode_threshold_hint(struct xdr_stream *xdr, + if (likely(bitmap[0] & hint_bit)) { + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, res); + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_first_threshold_item4(struct xdr_stream *xdr, +@@ -4597,10 +4467,8 @@ static int decode_first_threshold_item4(struct xdr_stream *xdr, + + /* layout type */ + p = xdr_inline_decode(xdr, 4); +- if (unlikely(!p)) { +- print_overflow_msg(__func__, xdr); ++ if (unlikely(!p)) + return -EIO; +- } + res->l_type = be32_to_cpup(p); + + /* thi_hintset bitmap */ +@@ -4658,7 +4526,7 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr, + return -EREMOTEIO; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + num = be32_to_cpup(p); + if (num == 0) + return 0; +@@ -4671,9 +4539,6 @@ static int decode_attr_mdsthreshold(struct xdr_stream *xdr, + bitmap[2] &= ~FATTR4_WORD2_MDSTHRESHOLD; + } + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_getfattr_attrs(struct xdr_stream *xdr, uint32_t *bitmap, +@@ -4861,7 +4726,7 @@ static int decode_pnfs_layout_types(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + fsinfo->nlayouttypes = be32_to_cpup(p); + + /* pNFS is not supported by the underlying file system */ +@@ -4871,7 +4736,7 @@ static int decode_pnfs_layout_types(struct xdr_stream *xdr, + /* Decode and set first layout type, move xdr->p past unused types */ + p = xdr_inline_decode(xdr, fsinfo->nlayouttypes * 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + /* If we get too many, then just cap it at the max */ + if (fsinfo->nlayouttypes > NFS_MAX_LAYOUT_TYPES) { +@@ -4883,9 +4748,6 @@ static int decode_pnfs_layout_types(struct xdr_stream *xdr, + for(i = 0; i < fsinfo->nlayouttypes; ++i) + fsinfo->layouttype[i] = be32_to_cpup(p++); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + /* +@@ -4919,10 +4781,8 @@ static int decode_attr_layout_blksize(struct xdr_stream *xdr, uint32_t *bitmap, + *res = 0; + if (bitmap[2] & FATTR4_WORD2_LAYOUT_BLKSIZE) { + p = xdr_inline_decode(xdr, 4); +- if (unlikely(!p)) { +- print_overflow_msg(__func__, xdr); ++ if (unlikely(!p)) + return -EIO; +- } + *res = be32_to_cpup(p); + bitmap[2] &= ~FATTR4_WORD2_LAYOUT_BLKSIZE; + } +@@ -4941,10 +4801,8 @@ static int decode_attr_clone_blksize(struct xdr_stream *xdr, uint32_t *bitmap, + *res = 0; + if (bitmap[2] & FATTR4_WORD2_CLONE_BLKSIZE) { + p = xdr_inline_decode(xdr, 4); +- if (unlikely(!p)) { +- print_overflow_msg(__func__, xdr); ++ if (unlikely(!p)) + return -EIO; +- } + *res = be32_to_cpup(p); + bitmap[2] &= ~FATTR4_WORD2_CLONE_BLKSIZE; + } +@@ -5020,19 +4878,16 @@ static int decode_getfh(struct xdr_stream *xdr, struct nfs_fh *fh) + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p); + if (len > NFS4_FHSIZE) + return -EIO; + fh->size = len; + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + memcpy(fh->data, p, len); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_link(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) +@@ -5056,7 +4911,7 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) + + p = xdr_inline_decode(xdr, 32); /* read 32 bytes */ + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + p = xdr_decode_hyper(p, &offset); /* read 2 8-byte long words */ + p = xdr_decode_hyper(p, &length); + type = be32_to_cpup(p++); /* 4 byte read */ +@@ -5073,11 +4928,9 @@ static int decode_lock_denied (struct xdr_stream *xdr, struct file_lock *fl) + p = xdr_decode_hyper(p, &clientid); /* read 8 bytes */ + namelen = be32_to_cpup(p); /* read 4 bytes */ /* have read all 32 bytes now */ + p = xdr_inline_decode(xdr, namelen); /* variable size field */ +- if (likely(p)) +- return -NFS4ERR_DENIED; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; ++ if (likely(!p)) ++ return -EIO; ++ return -NFS4ERR_DENIED; + } + + static int decode_lock(struct xdr_stream *xdr, struct nfs_lock_res *res) +@@ -5146,7 +4999,7 @@ static int decode_space_limit(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 12); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + limit_type = be32_to_cpup(p++); + switch (limit_type) { + case NFS4_LIMIT_SIZE: +@@ -5160,9 +5013,6 @@ static int decode_space_limit(struct xdr_stream *xdr, + maxsize >>= PAGE_SHIFT; + *pagemod_limit = min_t(u64, maxsize, ULONG_MAX); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_rw_delegation(struct xdr_stream *xdr, +@@ -5177,7 +5027,7 @@ static int decode_rw_delegation(struct xdr_stream *xdr, + return status; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->do_recall = be32_to_cpup(p); + + switch (delegation_type) { +@@ -5190,9 +5040,6 @@ static int decode_rw_delegation(struct xdr_stream *xdr, + return -EIO; + } + return decode_ace(xdr, NULL); +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) +@@ -5202,7 +5049,7 @@ static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + why_no_delegation = be32_to_cpup(p); + switch (why_no_delegation) { + case WND4_CONTENTION: +@@ -5211,9 +5058,6 @@ static int decode_no_delegation(struct xdr_stream *xdr, struct nfs_openres *res) + /* Ignore for now */ + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) +@@ -5223,7 +5067,7 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + delegation_type = be32_to_cpup(p); + res->delegation_type = 0; + switch (delegation_type) { +@@ -5236,9 +5080,6 @@ static int decode_delegation(struct xdr_stream *xdr, struct nfs_openres *res) + return decode_no_delegation(xdr, res); + } + return -EIO; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) +@@ -5260,7 +5101,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->rflags = be32_to_cpup(p++); + bmlen = be32_to_cpup(p); + if (bmlen > 10) +@@ -5268,7 +5109,7 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) + + p = xdr_inline_decode(xdr, bmlen << 2); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + savewords = min_t(uint32_t, bmlen, NFS4_BITMAP_SIZE); + for (i = 0; i < savewords; ++i) + res->attrset[i] = be32_to_cpup(p++); +@@ -5279,9 +5120,6 @@ static int decode_open(struct xdr_stream *xdr, struct nfs_openres *res) + xdr_error: + dprintk("%s: Bitmap too large! Length = %u\n", __func__, bmlen); + return -EIO; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_open_confirm(struct xdr_stream *xdr, struct nfs_open_confirmres *res) +@@ -5330,7 +5168,7 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, + return status; + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + eof = be32_to_cpup(p++); + count = be32_to_cpup(p); + recvd = xdr_read_pages(xdr, count); +@@ -5343,9 +5181,6 @@ static int decode_read(struct xdr_stream *xdr, struct rpc_rqst *req, + res->eof = eof; + res->count = count; + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_readdir(struct xdr_stream *xdr, struct rpc_rqst *req, struct nfs4_readdir_res *readdir) +@@ -5378,7 +5213,7 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) + /* Convert length of symlink */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p); + if (len >= rcvbuf->page_len || len <= 0) { + dprintk("nfs: server returned giant symlink!\n"); +@@ -5399,9 +5234,6 @@ static int decode_readlink(struct xdr_stream *xdr, struct rpc_rqst *req) + */ + xdr_terminate_string(rcvbuf, len); + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_remove(struct xdr_stream *xdr, struct nfs4_change_info *cinfo) +@@ -5504,7 +5336,6 @@ static int decode_setattr(struct xdr_stream *xdr) + return status; + if (decode_bitmap4(xdr, NULL, 0) >= 0) + return 0; +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -5516,7 +5347,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_re + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + opnum = be32_to_cpup(p++); + if (opnum != OP_SETCLIENTID) { + dprintk("nfs: decode_setclientid: Server returned operation" +@@ -5527,7 +5358,7 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_re + if (nfserr == NFS_OK) { + p = xdr_inline_decode(xdr, 8 + NFS4_VERIFIER_SIZE); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + p = xdr_decode_hyper(p, &res->clientid); + memcpy(res->confirm.data, p, NFS4_VERIFIER_SIZE); + } else if (nfserr == NFSERR_CLID_INUSE) { +@@ -5536,28 +5367,25 @@ static int decode_setclientid(struct xdr_stream *xdr, struct nfs4_setclientid_re + /* skip netid string */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p); + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + /* skip uaddr string */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p); + p = xdr_inline_decode(xdr, len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + return -NFSERR_CLID_INUSE; + } else + return nfs4_stat_to_errno(nfserr); + + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_setclientid_confirm(struct xdr_stream *xdr) +@@ -5576,13 +5404,10 @@ static int decode_write(struct xdr_stream *xdr, struct nfs_pgio_res *res) + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->count = be32_to_cpup(p++); + res->verf->committed = be32_to_cpup(p++); + return decode_write_verifier(xdr, &res->verf->verifier); +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_delegreturn(struct xdr_stream *xdr) +@@ -5598,30 +5423,24 @@ static int decode_secinfo_gss(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + oid_len = be32_to_cpup(p); + if (oid_len > GSS_OID_MAX_LEN) +- goto out_err; ++ return -EINVAL; + + p = xdr_inline_decode(xdr, oid_len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + memcpy(flavor->flavor_info.oid.data, p, oid_len); + flavor->flavor_info.oid.len = oid_len; + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + flavor->flavor_info.qop = be32_to_cpup(p++); + flavor->flavor_info.service = be32_to_cpup(p); + + return 0; +- +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; +-out_err: +- return -EINVAL; + } + + static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) +@@ -5633,7 +5452,7 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + res->flavors->num_flavors = 0; + num_flavors = be32_to_cpup(p); +@@ -5645,7 +5464,7 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + sec_flavor->flavor = be32_to_cpup(p); + + if (sec_flavor->flavor == RPC_AUTH_GSS) { +@@ -5659,9 +5478,6 @@ static int decode_secinfo_common(struct xdr_stream *xdr, struct nfs4_secinfo_res + status = 0; + out: + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_secinfo(struct xdr_stream *xdr, struct nfs4_secinfo_res *res) +@@ -5715,11 +5531,11 @@ static int decode_exchange_id(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + xdr_decode_hyper(p, &res->clientid); + p = xdr_inline_decode(xdr, 12); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->seqid = be32_to_cpup(p++); + res->flags = be32_to_cpup(p++); + +@@ -5743,7 +5559,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, + /* server_owner4.so_minor_id */ + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + p = xdr_decode_hyper(p, &res->server_owner->minor_id); + + /* server_owner4.so_major_id */ +@@ -5763,7 +5579,7 @@ static int decode_exchange_id(struct xdr_stream *xdr, + /* Implementation Id */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + impl_id_count = be32_to_cpup(p++); + + if (impl_id_count) { +@@ -5782,16 +5598,13 @@ static int decode_exchange_id(struct xdr_stream *xdr, + /* nii_date */ + p = xdr_inline_decode(xdr, 12); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + p = xdr_decode_hyper(p, &res->impl_id->date.seconds); + res->impl_id->date.nseconds = be32_to_cpup(p); + + /* if there's more than one entry, ignore the rest */ + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_chan_attrs(struct xdr_stream *xdr, +@@ -5802,7 +5615,7 @@ static int decode_chan_attrs(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 28); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + val = be32_to_cpup(p++); /* headerpadsz */ + if (val) + return -EINVAL; /* no support for header padding yet */ +@@ -5820,12 +5633,9 @@ static int decode_chan_attrs(struct xdr_stream *xdr, + if (nr_attrs == 1) { + p = xdr_inline_decode(xdr, 4); /* skip rdma_attrs */ + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_sessionid(struct xdr_stream *xdr, struct nfs4_sessionid *sid) +@@ -5848,7 +5658,7 @@ static int decode_bind_conn_to_session(struct xdr_stream *xdr, + /* dir flags, rdma mode bool */ + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + res->dir = be32_to_cpup(p++); + if (res->dir == 0 || res->dir > NFS4_CDFS4_BOTH) +@@ -5859,9 +5669,6 @@ static int decode_bind_conn_to_session(struct xdr_stream *xdr, + res->use_conn_in_rdma_mode = true; + + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_create_session(struct xdr_stream *xdr, +@@ -5879,7 +5686,7 @@ static int decode_create_session(struct xdr_stream *xdr, + /* seqid, flags */ + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->seqid = be32_to_cpup(p++); + res->flags = be32_to_cpup(p); + +@@ -5888,9 +5695,6 @@ static int decode_create_session(struct xdr_stream *xdr, + if (!status) + status = decode_chan_attrs(xdr, &res->bc_attrs); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_destroy_session(struct xdr_stream *xdr, void *dummy) +@@ -5971,7 +5775,6 @@ static int decode_sequence(struct xdr_stream *xdr, + res->sr_status = status; + return status; + out_overflow: +- print_overflow_msg(__func__, xdr); + status = -EIO; + goto out_err; + #else /* CONFIG_NFS_V4_1 */ +@@ -5999,7 +5802,7 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, + if (status == -ETOOSMALL) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + pdev->mincount = be32_to_cpup(p); + dprintk("%s: Min count too small. mincnt = %u\n", + __func__, pdev->mincount); +@@ -6009,7 +5812,7 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + type = be32_to_cpup(p++); + if (type != pdev->layout_type) { + dprintk("%s: layout mismatch req: %u pdev: %u\n", +@@ -6023,19 +5826,19 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, + */ + pdev->mincount = be32_to_cpup(p); + if (xdr_read_pages(xdr, pdev->mincount) != pdev->mincount) +- goto out_overflow; ++ return -EIO; + + /* Parse notification bitmap, verifying that it is zero. */ + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + len = be32_to_cpup(p); + if (len) { + uint32_t i; + + p = xdr_inline_decode(xdr, 4 * len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + + res->notification = be32_to_cpup(p++); + for (i = 1; i < len; i++) { +@@ -6047,9 +5850,6 @@ static int decode_getdeviceinfo(struct xdr_stream *xdr, + } + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, +@@ -6119,7 +5919,6 @@ static int decode_layoutget(struct xdr_stream *xdr, struct rpc_rqst *req, + res->status = status; + return status; + out_overflow: +- print_overflow_msg(__func__, xdr); + status = -EIO; + goto out; + } +@@ -6135,16 +5934,13 @@ static int decode_layoutreturn(struct xdr_stream *xdr, + return status; + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->lrs_present = be32_to_cpup(p); + if (res->lrs_present) + status = decode_layout_stateid(xdr, &res->stateid); + else + nfs4_stateid_copy(&res->stateid, &invalid_stateid); + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_layoutcommit(struct xdr_stream *xdr, +@@ -6162,19 +5958,16 @@ static int decode_layoutcommit(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + sizechanged = be32_to_cpup(p); + + if (sizechanged) { + /* throw away new size */ + p = xdr_inline_decode(xdr, 8); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + } + return 0; +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EIO; + } + + static int decode_test_stateid(struct xdr_stream *xdr, +@@ -6190,21 +5983,17 @@ static int decode_test_stateid(struct xdr_stream *xdr, + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + num_res = be32_to_cpup(p++); + if (num_res != 1) +- goto out; ++ return -EIO; + + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EIO; + res->status = be32_to_cpup(p++); + + return status; +-out_overflow: +- print_overflow_msg(__func__, xdr); +-out: +- return -EIO; + } + + static int decode_free_stateid(struct xdr_stream *xdr, +@@ -7574,11 +7363,11 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + uint64_t new_cookie; + __be32 *p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EAGAIN; + if (*p == xdr_zero) { + p = xdr_inline_decode(xdr, 4); + if (unlikely(!p)) +- goto out_overflow; ++ return -EAGAIN; + if (*p == xdr_zero) + return -EAGAIN; + entry->eof = 1; +@@ -7587,13 +7376,13 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + + p = xdr_inline_decode(xdr, 12); + if (unlikely(!p)) +- goto out_overflow; ++ return -EAGAIN; + p = xdr_decode_hyper(p, &new_cookie); + entry->len = be32_to_cpup(p); + + p = xdr_inline_decode(xdr, entry->len); + if (unlikely(!p)) +- goto out_overflow; ++ return -EAGAIN; + entry->name = (const char *) p; + + /* +@@ -7605,14 +7394,14 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + entry->fattr->valid = 0; + + if (decode_attr_bitmap(xdr, bitmap) < 0) +- goto out_overflow; ++ return -EAGAIN; + + if (decode_attr_length(xdr, &len, &savep) < 0) +- goto out_overflow; ++ return -EAGAIN; + + if (decode_getfattr_attrs(xdr, bitmap, entry->fattr, entry->fh, + NULL, entry->label, entry->server) < 0) +- goto out_overflow; ++ return -EAGAIN; + if (entry->fattr->valid & NFS_ATTR_FATTR_MOUNTED_ON_FILEID) + entry->ino = entry->fattr->mounted_on_fileid; + else if (entry->fattr->valid & NFS_ATTR_FATTR_FILEID) +@@ -7626,10 +7415,6 @@ int nfs4_decode_dirent(struct xdr_stream *xdr, struct nfs_entry *entry, + entry->cookie = new_cookie; + + return 0; +- +-out_overflow: +- print_overflow_msg(__func__, xdr); +- return -EAGAIN; + } + + /* +diff --git a/fs/nfsd/nfs4callback.c b/fs/nfsd/nfs4callback.c +index 519d994c0c4c0..e6c7448d3d89a 100644 +--- a/fs/nfsd/nfs4callback.c ++++ b/fs/nfsd/nfs4callback.c +@@ -59,16 +59,6 @@ struct nfs4_cb_compound_hdr { + int status; + }; + +-/* +- * Handle decode buffer overflows out-of-line. +- */ +-static void print_overflow_msg(const char *func, const struct xdr_stream *xdr) +-{ +- dprintk("NFS: %s prematurely hit the end of our receive buffer. " +- "Remaining buffer length is %tu words.\n", +- func, xdr->end - xdr->p); +-} +- + static __be32 *xdr_encode_empty_array(__be32 *p) + { + *p++ = xdr_zero; +@@ -238,7 +228,6 @@ static int decode_cb_op_status(struct xdr_stream *xdr, + *status = nfs_cb_stat_to_errno(be32_to_cpup(p)); + return 0; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + out_unexpected: + dprintk("NFSD: Callback server returned operation %d but " +@@ -307,7 +296,6 @@ static int decode_cb_compound4res(struct xdr_stream *xdr, + hdr->nops = be32_to_cpup(p); + return 0; + out_overflow: +- print_overflow_msg(__func__, xdr); + return -EIO; + } + +@@ -435,7 +423,6 @@ static int decode_cb_sequence4resok(struct xdr_stream *xdr, + cb->cb_seq_status = status; + return status; + out_overflow: +- print_overflow_msg(__func__, xdr); + status = -EIO; + goto out; + } +-- +2.43.0 + diff --git a/queue-4.19/ppp-fix-ppp_async_encode-illegal-access.patch b/queue-4.19/ppp-fix-ppp_async_encode-illegal-access.patch new file mode 100644 index 00000000000..25a1330367f --- /dev/null +++ b/queue-4.19/ppp-fix-ppp_async_encode-illegal-access.patch @@ -0,0 +1,91 @@ +From 2953597552a45540c1b8cf9f4e51b92b1abbb5b7 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 9 Oct 2024 18:58:02 +0000 +Subject: ppp: fix ppp_async_encode() illegal access + +From: Eric Dumazet + +[ Upstream commit 40dddd4b8bd08a69471efd96107a4e1c73fabefc ] + +syzbot reported an issue in ppp_async_encode() [1] + +In this case, pppoe_sendmsg() is called with a zero size. +Then ppp_async_encode() is called with an empty skb. + +BUG: KMSAN: uninit-value in ppp_async_encode drivers/net/ppp/ppp_async.c:545 [inline] + BUG: KMSAN: uninit-value in ppp_async_push+0xb4f/0x2660 drivers/net/ppp/ppp_async.c:675 + ppp_async_encode drivers/net/ppp/ppp_async.c:545 [inline] + ppp_async_push+0xb4f/0x2660 drivers/net/ppp/ppp_async.c:675 + ppp_async_send+0x130/0x1b0 drivers/net/ppp/ppp_async.c:634 + ppp_channel_bridge_input drivers/net/ppp/ppp_generic.c:2280 [inline] + ppp_input+0x1f1/0xe60 drivers/net/ppp/ppp_generic.c:2304 + pppoe_rcv_core+0x1d3/0x720 drivers/net/ppp/pppoe.c:379 + sk_backlog_rcv+0x13b/0x420 include/net/sock.h:1113 + __release_sock+0x1da/0x330 net/core/sock.c:3072 + release_sock+0x6b/0x250 net/core/sock.c:3626 + pppoe_sendmsg+0x2b8/0xb90 drivers/net/ppp/pppoe.c:903 + sock_sendmsg_nosec net/socket.c:729 [inline] + __sock_sendmsg+0x30f/0x380 net/socket.c:744 + ____sys_sendmsg+0x903/0xb60 net/socket.c:2602 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2656 + __sys_sendmmsg+0x3c1/0x960 net/socket.c:2742 + __do_sys_sendmmsg net/socket.c:2771 [inline] + __se_sys_sendmmsg net/socket.c:2768 [inline] + __x64_sys_sendmmsg+0xbc/0x120 net/socket.c:2768 + x64_sys_call+0xb6e/0x3ba0 arch/x86/include/generated/asm/syscalls_64.h:308 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Uninit was created at: + slab_post_alloc_hook mm/slub.c:4092 [inline] + slab_alloc_node mm/slub.c:4135 [inline] + kmem_cache_alloc_node_noprof+0x6bf/0xb80 mm/slub.c:4187 + kmalloc_reserve+0x13d/0x4a0 net/core/skbuff.c:587 + __alloc_skb+0x363/0x7b0 net/core/skbuff.c:678 + alloc_skb include/linux/skbuff.h:1322 [inline] + sock_wmalloc+0xfe/0x1a0 net/core/sock.c:2732 + pppoe_sendmsg+0x3a7/0xb90 drivers/net/ppp/pppoe.c:867 + sock_sendmsg_nosec net/socket.c:729 [inline] + __sock_sendmsg+0x30f/0x380 net/socket.c:744 + ____sys_sendmsg+0x903/0xb60 net/socket.c:2602 + ___sys_sendmsg+0x28d/0x3c0 net/socket.c:2656 + __sys_sendmmsg+0x3c1/0x960 net/socket.c:2742 + __do_sys_sendmmsg net/socket.c:2771 [inline] + __se_sys_sendmmsg net/socket.c:2768 [inline] + __x64_sys_sendmmsg+0xbc/0x120 net/socket.c:2768 + x64_sys_call+0xb6e/0x3ba0 arch/x86/include/generated/asm/syscalls_64.h:308 + do_syscall_x64 arch/x86/entry/common.c:52 [inline] + do_syscall_64+0xcd/0x1e0 arch/x86/entry/common.c:83 + entry_SYSCALL_64_after_hwframe+0x77/0x7f + +CPU: 1 UID: 0 PID: 5411 Comm: syz.1.14 Not tainted 6.12.0-rc1-syzkaller-00165-g360c1f1f24c6 #0 +Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 09/13/2024 + +Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") +Reported-by: syzbot+1d121645899e7692f92a@syzkaller.appspotmail.com +Signed-off-by: Eric Dumazet +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20241009185802.3763282-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/ppp/ppp_async.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c +index fb1e28a298929..14e8ad3f93544 100644 +--- a/drivers/net/ppp/ppp_async.c ++++ b/drivers/net/ppp/ppp_async.c +@@ -555,7 +555,7 @@ ppp_async_encode(struct asyncppp *ap) + * and 7 (code-reject) must be sent as though no options + * had been negotiated. + */ +- islcp = proto == PPP_LCP && 1 <= data[2] && data[2] <= 7; ++ islcp = proto == PPP_LCP && count >= 3 && 1 <= data[2] && data[2] <= 7; + + if (i == 0) { + if (islcp) +-- +2.43.0 + diff --git a/queue-4.19/series b/queue-4.19/series index c5b7b9a1f63..796c9761af7 100644 --- a/queue-4.19/series +++ b/queue-4.19/series @@ -246,3 +246,16 @@ usb-chipidea-udc-enable-suspend-interrupt-after-usb-.patch tools-iio-add-memory-allocation-failure-check-for-tr.patch driver-core-bus-return-eio-instead-of-0-when-show-st.patch fbdev-sisfb-fix-strbuf-array-overflow.patch +nfs-remove-print_overflow_msg.patch +sunrpc-fix-integer-overflow-in-decode_rc_list.patch +tcp-fix-tcp_enter_recovery-to-zero-retrans_stamp-whe.patch +netfilter-br_netfilter-fix-panic-with-metadata_dst-s.patch +bluetooth-rfcomm-fix-possible-deadlock-in-rfcomm_sk_.patch +gpio-aspeed-add-the-flush-write-to-ensure-the-write-.patch +clk-add-devm_-clk_get_optional-functions.patch +clk-generalize-devm_clk_get-a-bit.patch +clk-provide-new-devm_clk-helpers-for-prepared-and-en.patch +gpio-aspeed-use-devm_clk-api-to-manage-clock-source.patch +igb-do-not-bring-the-device-up-after-non-fatal-error.patch +net-ibm-emac-mal-fix-wrong-goto.patch +ppp-fix-ppp_async_encode-illegal-access.patch diff --git a/queue-4.19/sunrpc-fix-integer-overflow-in-decode_rc_list.patch b/queue-4.19/sunrpc-fix-integer-overflow-in-decode_rc_list.patch new file mode 100644 index 00000000000..f2a419211ba --- /dev/null +++ b/queue-4.19/sunrpc-fix-integer-overflow-in-decode_rc_list.patch @@ -0,0 +1,37 @@ +From 614be209eb1bed41caf677ab110c8b6e0b231fb8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 19 Sep 2024 11:50:33 +0300 +Subject: SUNRPC: Fix integer overflow in decode_rc_list() + +From: Dan Carpenter + +[ Upstream commit 6dbf1f341b6b35bcc20ff95b6b315e509f6c5369 ] + +The math in "rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)" could have an +integer overflow. Add bounds checking on rc_list->rcl_nrefcalls to fix +that. + +Fixes: 4aece6a19cf7 ("nfs41: cb_sequence xdr implementation") +Signed-off-by: Dan Carpenter +Signed-off-by: Anna Schumaker +Signed-off-by: Sasha Levin +--- + fs/nfs/callback_xdr.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/fs/nfs/callback_xdr.c b/fs/nfs/callback_xdr.c +index 38dc33c537ab6..8f8b3a7868e8d 100644 +--- a/fs/nfs/callback_xdr.c ++++ b/fs/nfs/callback_xdr.c +@@ -372,6 +372,8 @@ static __be32 decode_rc_list(struct xdr_stream *xdr, + + rc_list->rcl_nrefcalls = ntohl(*p++); + if (rc_list->rcl_nrefcalls) { ++ if (unlikely(rc_list->rcl_nrefcalls > xdr->buf->len)) ++ goto out; + p = xdr_inline_decode(xdr, + rc_list->rcl_nrefcalls * 2 * sizeof(uint32_t)); + if (unlikely(p == NULL)) +-- +2.43.0 + diff --git a/queue-4.19/tcp-fix-tcp_enter_recovery-to-zero-retrans_stamp-whe.patch b/queue-4.19/tcp-fix-tcp_enter_recovery-to-zero-retrans_stamp-whe.patch new file mode 100644 index 00000000000..d36b82c0793 --- /dev/null +++ b/queue-4.19/tcp-fix-tcp_enter_recovery-to-zero-retrans_stamp-whe.patch @@ -0,0 +1,153 @@ +From 22ee31626d04e3865cdd532c2d7eb17318b19ab4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 1 Oct 2024 20:05:16 +0000 +Subject: tcp: fix tcp_enter_recovery() to zero retrans_stamp when it's safe + +From: Neal Cardwell + +[ Upstream commit b41b4cbd9655bcebcce941bef3601db8110335be ] + +Fix tcp_enter_recovery() so that if there are no retransmits out then +we zero retrans_stamp when entering fast recovery. This is necessary +to fix two buggy behaviors. + +Currently a non-zero retrans_stamp value can persist across multiple +back-to-back loss recovery episodes. This is because we generally only +clears retrans_stamp if we are completely done with loss recoveries, +and get to tcp_try_to_open() and find !tcp_any_retrans_done(sk). This +behavior causes two bugs: + +(1) When a loss recovery episode (CA_Loss or CA_Recovery) is followed +immediately by a new CA_Recovery, the retrans_stamp value can persist +and can be a time before this new CA_Recovery episode starts. That +means that timestamp-based undo will be using the wrong retrans_stamp +(a value that is too old) when comparing incoming TS ecr values to +retrans_stamp to see if the current fast recovery episode can be +undone. + +(2) If there is a roughly minutes-long sequence of back-to-back fast +recovery episodes, one after another (e.g. in a shallow-buffered or +policed bottleneck), where each fast recovery successfully makes +forward progress and recovers one window of sequence space (but leaves +at least one retransmit in flight at the end of the recovery), +followed by several RTOs, then the ETIMEDOUT check may be using the +wrong retrans_stamp (a value set at the start of the first fast +recovery in the sequence). This can cause a very premature ETIMEDOUT, +killing the connection prematurely. + +This commit changes the code to zero retrans_stamp when entering fast +recovery, when this is known to be safe (no retransmits are out in the +network). That ensures that when starting a fast recovery episode, and +it is safe to do so, retrans_stamp is set when we send the fast +retransmit packet. That addresses both bug (1) and bug (2) by ensuring +that (if no retransmits are out when we start a fast recovery) we use +the initial fast retransmit of this fast recovery as the time value +for undo and ETIMEDOUT calculations. + +This makes intuitive sense, since the start of a new fast recovery +episode (in a scenario where no lost packets are out in the network) +means that the connection has made forward progress since the last RTO +or fast recovery, and we should thus "restart the clock" used for both +undo and ETIMEDOUT logic. + +Note that if when we start fast recovery there *are* retransmits out +in the network, there can still be undesirable (1)/(2) issues. For +example, after this patch we can still have the (1) and (2) problems +in cases like this: + ++ round 1: sender sends flight 1 + ++ round 2: sender receives SACKs and enters fast recovery 1, + retransmits some packets in flight 1 and then sends some new data as + flight 2 + ++ round 3: sender receives some SACKs for flight 2, notes losses, and + retransmits some packets to fill the holes in flight 2 + ++ fast recovery has some lost retransmits in flight 1 and continues + for one or more rounds sending retransmits for flight 1 and flight 2 + ++ fast recovery 1 completes when snd_una reaches high_seq at end of + flight 1 + ++ there are still holes in the SACK scoreboard in flight 2, so we + enter fast recovery 2, but some retransmits in the flight 2 sequence + range are still in flight (retrans_out > 0), so we can't execute the + new retrans_stamp=0 added here to clear retrans_stamp + +It's not yet clear how to fix these remaining (1)/(2) issues in an +efficient way without breaking undo behavior, given that retrans_stamp +is currently used for undo and ETIMEDOUT. Perhaps the optimal (but +expensive) strategy would be to set retrans_stamp to the timestamp of +the earliest outstanding retransmit when entering fast recovery. But +at least this commit makes things better. + +Note that this does not change the semantics of retrans_stamp; it +simply makes retrans_stamp accurate in some cases where it was not +before: + +(1) Some loss recovery, followed by an immediate entry into a fast +recovery, where there are no retransmits out when entering the fast +recovery. + +(2) When a TFO server has a SYNACK retransmit that sets retrans_stamp, +and then the ACK that completes the 3-way handshake has SACK blocks +that trigger a fast recovery. In this case when entering fast recovery +we want to zero out the retrans_stamp from the TFO SYNACK retransmit, +and set the retrans_stamp based on the timestamp of the fast recovery. + +We introduce a tcp_retrans_stamp_cleanup() helper, because this +two-line sequence already appears in 3 places and is about to appear +in 2 more as a result of this bug fix patch series. Once this bug fix +patches series in the net branch makes it into the net-next branch +we'll update the 3 other call sites to use the new helper. + +This is a long-standing issue. The Fixes tag below is chosen to be the +oldest commit at which the patch will apply cleanly, which is from +Linux v3.5 in 2012. + +Fixes: 1fbc340514fc ("tcp: early retransmit: tcp_enter_recovery()") +Signed-off-by: Neal Cardwell +Signed-off-by: Yuchung Cheng +Signed-off-by: Eric Dumazet +Link: https://patch.msgid.link/20241001200517.2756803-3-ncardwell.sw@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + net/ipv4/tcp_input.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c +index 2437a196c1392..0f2320d821ffd 100644 +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -2320,6 +2320,16 @@ static bool tcp_any_retrans_done(const struct sock *sk) + return false; + } + ++/* If loss recovery is finished and there are no retransmits out in the ++ * network, then we clear retrans_stamp so that upon the next loss recovery ++ * retransmits_timed_out() and timestamp-undo are using the correct value. ++ */ ++static void tcp_retrans_stamp_cleanup(struct sock *sk) ++{ ++ if (!tcp_any_retrans_done(sk)) ++ tcp_sk(sk)->retrans_stamp = 0; ++} ++ + static void DBGUNDO(struct sock *sk, const char *msg) + { + #if FASTRETRANS_DEBUG > 1 +@@ -2662,6 +2672,9 @@ void tcp_enter_recovery(struct sock *sk, bool ece_ack) + struct tcp_sock *tp = tcp_sk(sk); + int mib_idx; + ++ /* Start the clock with our fast retransmit, for undo and ETIMEDOUT. */ ++ tcp_retrans_stamp_cleanup(sk); ++ + if (tcp_is_reno(tp)) + mib_idx = LINUX_MIB_TCPRENORECOVERY; + else +-- +2.43.0 +