let ERR_PTR BUILD_BUG_ON when we know its argument is not a valid errno
Subsystems (6)
PATCH 1/1 let ERR_PTR BUILD_BUG_ON when we know its argument is not a valid errno
---
allmodconfig compile tested (on x86_64)
should be applied after:net/sunrpc/xprtrdma: fix svc_rdma_create out of memory error path
jfs: 0 is not valid errno value
--- include/linux/err.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
include/linux/err.h +3 -1
@@ -19,11 +19,13 @@#define IS_ERR_VALUE (x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline void *ERR_PTR (long error) +static inline void *__ERR_PTR (long error) {return (void *) error; } +#define ERR_PTR (error) (BUILD_BUG_ON(!IS_ERR_VALUE(error)), __ERR_PTR(error)) +static inline long PTR_ERR (const void *ptr) {return (long ) ptr;
Quoted 20 lines · On Sun, 11 May 2008 22:12:14 +0200 Marcin Slusarz <[email protected]>…
Signed-off-by Marcin Slusarz <[email protected]>Cc Andrew Morton <[email protected]>---
allmodconfig compile tested (onx86_64)should be applied after:
net/sunrpc/xprtrdma: fixsvc_rdma_createout of memory error path
jfs: 0 is not valid errno value--- include/linux/err.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)include/linux/err.h +0
-1@@ -19,11 +19,13 @@#define IS_ERR_VALUE (x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline void *ERR_PTR (long error)
include/linux/err.h line 31
Quoted 10 lines
include/linux/err.h +3
-0+static inline void *__ERR_PTR (long error) {return (void *) error; } +#define ERR_PTR (error) (BUILD_BUG_ON(!IS_ERR_VALUE(error)), __ERR_PTR(error)) +static inline long PTR_ERR (const void *ptr) {return (long ) ptr;
Not sure about this one. BUILD_BUG_ON only makes sense if the value is a compile-time constant. I think the code as you have it will take this:
int e = foo(); p = ERR_PTR(e);
and will attempt to evaluate sizeof() on a negative-sized array at runtime. The conmpile will laugh and throw that all away, but it's a bit weird.
Plus I'd have thought that the amount of code which does ERR_PTR(-EFOO) is fairly small, but perhaps that's wrong.
If I _am_ wrong then I do think it'd be saner to only do the BUILD_BUG_ON() if __builtin_constant_p(error) evaluates true. And even then I do think we'd like to see a more lengthy justification of why the kernel needs this check. More lengthy than zero, anyway...
(If a compile-time check is needed then why not a runtime one also?)
Thanks.
Quoted 41 lines · Andrew Morton
Quoted 20 lines · On Sun, 11 May 2008 22:12:14 +0200 Marcin Slusarz <[email protected]>…
Signed-off-by Marcin Slusarz <[email protected]>Cc Andrew Morton <[email protected]>---
allmodconfig compile tested (onx86_64)should be applied after:
net/sunrpc/xprtrdma: fixsvc_rdma_createout of memory error path
jfs: 0 is not valid errno value--- include/linux/err.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)include/linux/err.h +0
-1@@ -19,11 +19,13 @@#define IS_ERR_VALUE (x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline void *ERR_PTR (long error)include/linux/err.h line 31
Quoted 10 lines
include/linux/err.h +3
-0+static inline void *__ERR_PTR (long error) {return (void *) error; } +#define ERR_PTR (error) (BUILD_BUG_ON(!IS_ERR_VALUE(error)), __ERR_PTR(error)) +static inline long PTR_ERR (const void *ptr) {return (long ) ptr;Not sure about this one.
BUILD_BUG_ONonly makes sense if the value is a compile-time constant. I think the code as you have it will take this:int e = foo(); p = ERR_PTR(e);
Quoted 6 lines
and will attempt to evaluate
sizeof()on a negative-sized array at runtime. The conmpile will laugh and throw that all away, but it's a bit weird.Plus I'd have thought that the amount of code which does
ERR_PTR(-EFOO)is fairly small, but perhaps that's wrong.
$ git grep 'ERR_PTR(-E[A-Z]*)' | wc -l 1431
Quoted 2 lines
If I _am_ wrong then I do think it'd be saner to only do the
BUILD_BUG_ON()if__builtin_constant_p(error)evaluates true. And even
I thought BUILD_BUG_ON uses __builtin_constant_p internally and it was a big mistake (see below).
Quoted 2 lines
then I do think we'd like to see a more lengthy justification of why the kernel needs this check.
Well, I think it's better to find more errors at compile time, than on rare runtime situation (error handling).
This patch found 2 errors on current sources (but one of them was harmless).
Quoted 3 lines
More lengthy than zero, anyway...
(If a compile-time check is needed then why not a runtime one also?)
I'm not sure - it would make kernel slightly bigger. I'll check that.
Today I discovered, that this patch causes funny runtime errors (/proc is mounted, but many applications think it's not), so ignore this patch for now. I'll prepare second version.
Marcin
cover Sanity checks for ERR_PTR argument
This little patchset adds sanity checks to ERR_PTR.
[PATCH 1/6] ERR_PTR: if errno value is known at compile time, make sure it's valid [PATCH 2/6] ERR_PTR: add ERR_OR_0_PTR
[PATCH 3/6] vfs: open_exec cleanup
[PATCH 4/6] procfs: switch ERR_PTR to ERR_OR_0_PTR when "error" might be 0 [PATCH 5/6] vfs: fix ERR_PTR abuse in generic_readlink
[PATCH 6/6] ERR_PTR: warn when ERR_PTR parameter is not errno value
The most important are patches 1 and 6. 2nd patch adds another ERR_PTR-like helper. The rest (3-5) fix false positives found by 6th patch.
--- fs/exec.c | 44 ++++++++++++++++++++++---------------------- fs/namei.c | 15 ++++++++------- fs/proc/base.c | 4 ++-- include/linux/err.h | 14 +++++++++++++- 4 files changed, 45 insertions(+), 32 deletions(-)
---
PATCH 1/6 ERR_PTR: if errno value is known at compile time, make sure it's valid
In reply to Marcin SlusarzERR_PTR is easy to call with wrong argument (positive errno), and this error lead to catastrophic event - oops or kernel panic (dereference of invalid pointer).
As most of error handling code paths are rarely tested, this kind of bug can be hidden for years.
(Currently there are > 1400 calls of ERR_PTR with constant argument.)
--- include/linux/err.h | 4 +++- 1 files changed, 3 insertions(+), 1 deletions(-)
include/linux/err.h +3 -1
@@ -19,11 +19,13 @@#define IS_ERR_VALUE (x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline void *ERR_PTR (long error) +static inline void *__ERR_PTR (long error) {return (void *) error; } +#define ERR_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && !IS_ERR_VALUE(error)), __ERR_PTR(error)) +static inline long PTR_ERR (const void *ptr) {return (long ) ptr;
Signature · 1 line
1.5.4.5
Re: [PATCH 1/6] ERR_PTR: if errno value is known at compile time, make sure it's valid
Quoted 12 lines · Marcin Slusarz
ERR_PTRis easy to call with wrong argument (positive errno), and this error lead to catastrophic event - oops or kernel panic (dereference of invalid pointer).As most of error handling code paths are rarely tested, this kind of bug can be hidden for years.
(Currently there are > 1400 calls of
ERR_PTRwith constant argument.)
include/linux/err.h line 27
Quoted 10 lines
include/linux/err.h +2
-1@@ -19,11 +19,13 @@#define IS_ERR_VALUE (x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline void *ERR_PTR (long error) +static inline void *__ERR_PTR (long error) {return (void *) error; } +#define ERR_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && !IS_ERR_VALUE(error)), __ERR_PTR(error))
This needs comment that this construct must be a macro, otherwise gcc does something stupid and doesn't break the build (at least in the case below). BTW, I used grep(1) to find it.
[PATCH] xprtrdma: fix ERR_PTR(E typo
---
net/sunrpc/xprtrdma/svc_rdma_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/sunrpc/xprtrdma/svc_rdma_transport.c +1 -1
@@ -661,7 +661,7 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, cma_xprt =rdma_create_xprt (serv,1 );if (!cma_xprt) -return ERR_PTR (ENOMEM ); +return ERR_PTR (-ENOMEM ); xprt = &cma_xprt->sc_xprt; listen_id =rdma_create_id (rdma_listen_handler, cma_xprt,RDMA_PS_TCP );
Re: [PATCH 1/6] ERR_PTR: if errno value is known at compile time, make sure it's valid
Quoted 22 lines · Alexey Dobriyan
Quoted 21 lines · Marcin Slusarz
ERR_PTRis easy to call with wrong argument (positive errno), and this error lead to catastrophic event - oops or kernel panic (dereference of invalid pointer).As most of error handling code paths are rarely tested, this kind of bug can be hidden for years.
(Currently there are > 1400 calls of
ERR_PTRwith constant argument.)include/linux/err.h +1
-1@@ -19,11 +19,13 @@#define IS_ERR_VALUE (x) unlikely((x) >= (unsigned long)-MAX_ERRNO) -static inline void *ERR_PTR (long error) +static inline void *__ERR_PTR (long error) {return (void *) error; }
Quoted 5 lines
include/linux/err.h line 27
Quoted 1 line
include/linux/err.h +1
-0+#define ERR_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && !IS_ERR_VALUE(error)), __ERR_PTR(error))This needs comment that this construct must be a macro, otherwise gcc does something stupid and doesn't break the build (at least in the case below).
Thanks, added to new version.
Quoted 1 line
BTW, I used grep(1) to find it.
http://lkml.org/lkml/2008/5/11/159
Quoted 21 lines
[PATCH] xprtrdma: fix ERR_PTR(E typo
Signed-off-by Alexey Dobriyan <[email protected]>---
net/sunrpc/xprtrdma/svc_rdma_transport.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)net/sunrpc/xprtrdma/svc_rdma_transport.c +1
-1@@ -661,7 +661,7 @@ static struct svc_xprt *svc_rdma_create(struct svc_serv *serv, cma_xprt =rdma_create_xprt (serv,1 );if (!cma_xprt) -return ERR_PTR (ENOMEM ); +return ERR_PTR (-ENOMEM ); xprt = &cma_xprt->sc_xprt; listen_id =rdma_create_id (rdma_listen_handler, cma_xprt,RDMA_PS_TCP );
PATCH 2/6 ERR_PTR: add ERR_OR_0_PTR
In reply to Marcin SlusarzSome codepaths call ERR_PTR with possibly 0 argument, which is not a valid errno and rely on conversion from 0 to NULL pointer. Add ERR_OR_0_PTR function which accepts errnos and 0 as an argument.
--- include/linux/err.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)
include/linux/err.h +7 -0
@@ -26,6 +26,13 @@ static inline void *__ERR_PTR(long error)#define ERR_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && !IS_ERR_VALUE(error)), __ERR_PTR(error)) +static inline void *__ERR_OR_0_PTR (long error) +{ +return (void *) error; +} + +#define ERR_OR_0_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && error && !IS_ERR_VALUE(error)), __ERR_OR_0_PTR(error)) +static inline long PTR_ERR (const void *ptr) {return (long ) ptr;
Signature · 1 line
1.5.4.5
Re: [PATCH 2/6] ERR_PTR: add ERR_OR_0_PTR
Hi Marcin,
Quoted 15 lines · Marcin Slusarz
Some codepaths call
ERR_PTRwith possibly 0 argument, which is not a valid errno and rely on conversion from 0 to NULL pointer. AddERR_OR_0_PTRfunction which accepts errnos and 0 as an argument.Signed-off-by Marcin Slusarz <[email protected]>Cc Andrew Morton <[email protected]>--- include/linux/err.h | 7 +++++++ 1 files changed, 7 insertions(+), 0 deletions(-)include/linux/err.h +0
-0
include/linux/err.h static inline void *__ERR_PTR(long error) · line 34
Quoted 9 lines
include/linux/err.h +6
-0@@ -26,6 +26,13 @@ static inline void *__ERR_PTR(long error)#define ERR_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && !IS_ERR_VALUE(error)), __ERR_PTR(error)) +static inline void *__ERR_OR_0_PTR (long error) +{ +return (void *) error; +} + +#define ERR_OR_0_PTR (error) (BUILD_BUG_ON(__builtin_constant_p(error) && error && !IS_ERR_VALUE(error)), __ERR_OR_0_PTR(error))
ERR_OR_0_PTR could use __ERR_PTR() too.
And please break those lines ;)
Hannes
Re: [PATCH 2/6] ERR_PTR: add ERR_OR_0_PTR
In reply to Marcin SlusarzQuoted 3 lines · Marcin Slusarz
Some codepaths call
ERR_PTRwith possibly 0 argument, which is not a valid errno and rely on conversion from 0 to NULL pointer. AddERR_OR_0_PTRfunction which accepts errnos and 0 as an argument.
Sorry, no. ERR_PTR(0) is perfectly valid, you just don't want to return the actualy value. E.g. we have a common idiom of:
some_ptr = ERR_PTR(err); if (IS_ERR(some_ptr)) goto out_handle_err;
and obsfucating this with new syntactic sugar is not a good idea.
Al Viro
maintainerRe: [PATCH 2/6] ERR_PTR: add ERR_OR_0_PTR
Quoted 5 lines · Christoph Hellwig
Quoted 3 lines · Marcin Slusarz
Some codepaths call
ERR_PTRwith possibly 0 argument, which is not a valid errno and rely on conversion from 0 to NULL pointer. AddERR_OR_0_PTRfunction which accepts errnos and 0 as an argument.
Quoted 8 lines
Sorry, no.
ERR_PTR(0)is perfectly valid, you just don't want to return the actualy value. E.g. we have a common idiom of:some_ptr = ERR_PTR(err); if (IS_ERR(some_ptr)) goto out_handle_err;and obsfucating this with new syntactic sugar is not a good idea.
Um... Could somebody explain WTF is wrong with declaring that ERR_PTR(0) is NULL? Sure, if we run into a target where converting non-constant integer with value zero to void * does not result in null pointer, we'll need to adjust ERR_PTR(). So. Fscking. What?
a) it's not a lot of adjustment, to start with b) any such target will require much more work on porting anyway;
this part will be trivial.
PATCH 3/6 vfs: open_exec cleanup
In reply to Marcin Slusarzopen_exec is needlessly indented, calls ERR_PTR with 0 argument (which is not valid errno) and jumps into middle of function just to return value.
So clean it up a bit.
--- fs/exec.c | 44 ++++++++++++++++++++++---------------------- 1 files changed, 22 insertions(+), 22 deletions(-)
fs/exec.c +22 -22
@@ -656,34 +656,34 @@ struct file *open_exec(const char *name)struct nameidata nd;int err;struct file *file; +struct inode *inode; err =path_lookup_open (AT_FDCWD , name,LOOKUP_FOLLOW , &nd,FMODE_READ |FMODE_EXEC ); - file =ERR_PTR (err); - -if (!err) { -struct inode *inode = nd.path.dentry->d_inode; - file =ERR_PTR (-EACCES ); -if (S_ISREG (inode->i_mode)) { -int err =vfs_permission (&nd,MAY_EXEC ); - file =ERR_PTR (err); -if (!err) { - file =nameidata_to_filp (&nd, -O_RDONLY |O_LARGEFILE ); -if (!IS_ERR (file)) { - err =deny_write_access (file); -if (err) { -fput (file); - file =ERR_PTR (err); - } +if (err) +return ERR_PTR (err); + + inode = nd.path.dentry->d_inode; + file =ERR_PTR (-EACCES ); +if (S_ISREG (inode->i_mode)) { +int err =vfs_permission (&nd,MAY_EXEC ); +if (!err) { + file =nameidata_to_filp (&nd,O_RDONLY |O_LARGEFILE ); +if (!IS_ERR (file)) { + err =deny_write_access (file); +if (err) { +fput (file); + file =ERR_PTR (err); } -out: -return file; } + goto out; } -release_open_intent (&nd); -path_put (&nd.path); +else + file =ERR_PTR (err); } - goto out; +release_open_intent (&nd); +path_put (&nd.path); +out: +return file; }EXPORT_SYMBOL (open_exec);
Signature · 1 line
1.5.4.5
Re: [PATCH 3/6] vfs: open_exec cleanup
Quoted 4 lines · Marcin Slusarz
open_execis needlessly indented, callsERR_PTRwith 0 argument (which is not valid errno) and jumps into middle of function just to return value.
So clean it up a bit.
Still looks rather messy. See below for a better version.
fs/exec.c +29 -27
@@ -654,38 +654,40 @@ EXPORT_SYMBOL(setup_arg_pages);struct file *open_exec (const char *name) {struct nameidata nd; -int err;struct file *file; +int err; - err =path_lookup_open (AT_FDCWD , name,LOOKUP_FOLLOW , &nd,FMODE_READ |FMODE_EXEC ); - file =ERR_PTR (err); + err =path_lookup_open (AT_FDCWD , name,LOOKUP_FOLLOW , &nd, +FMODE_READ |FMODE_EXEC ); +if (err) + goto out; -if (!err) { -struct inode *inode = nd.path.dentry->d_inode; - file =ERR_PTR (-EACCES ); -if (S_ISREG (inode->i_mode)) { -int err =vfs_permission (&nd,MAY_EXEC ); - file =ERR_PTR (err); -if (!err) { - file =nameidata_to_filp (&nd, -O_RDONLY |O_LARGEFILE ); -if (!IS_ERR (file)) { - err =deny_write_access (file); -if (err) { -fput (file); - file =ERR_PTR (err); - } - } -out: -return file; - } - } -release_open_intent (&nd); -path_put (&nd.path); + err = -EACCES ; +if (!S_ISREG (nd.path.dentry->d_inode->i_mode)) + goto out_path_put; + + err =vfs_permission (&nd,MAY_EXEC ); +if (err) + goto out_path_put; + + file =nameidata_to_filp (&nd,O_RDONLY |O_LARGEFILE ); +if (IS_ERR (file)) +return file; + + err =deny_write_access (file); +if (err) { +fput (file); + goto out; } - goto out; -} +return file; + + out_path_put: +release_open_intent (&nd); +path_put (&nd.path); + out: +return ERR_PTR (err); +}EXPORT_SYMBOL (open_exec); int kernel_read(struct file *file, unsigned long offset,
Marcin Slusarz
Reviewed-byRe: [PATCH 3/6] vfs: open_exec cleanup
Quoted 7 lines · Christoph Hellwig
Quoted 4 lines · Marcin Slusarz
open_execis needlessly indented, callsERR_PTRwith 0 argument (which is not valid errno) and jumps into middle of function just to return value.
So clean it up a bit.Still looks rather messy. See below for a better version.
looks much better, thanks
Quoted 76 lines
Signed-off-by Christoph Hellwig <[email protected]>Index:
linux-2.6/fs/exec.c
===================================================================fs/exec.c +29
-27@@ -654,38 +654,40 @@ EXPORT_SYMBOL(setup_arg_pages);struct file *open_exec (const char *name) {struct nameidata nd; -int err;struct file *file; +int err; - err =path_lookup_open (AT_FDCWD , name,LOOKUP_FOLLOW , &nd,FMODE_READ |FMODE_EXEC ); - file =ERR_PTR (err); + err =path_lookup_open (AT_FDCWD , name,LOOKUP_FOLLOW , &nd, +FMODE_READ |FMODE_EXEC ); +if (err) + goto out; -if (!err) { -struct inode *inode = nd.path.dentry->d_inode; - file =ERR_PTR (-EACCES ); -if (S_ISREG (inode->i_mode)) { -int err =vfs_permission (&nd,MAY_EXEC ); - file =ERR_PTR (err); -if (!err) { - file =nameidata_to_filp (&nd, -O_RDONLY |O_LARGEFILE ); -if (!IS_ERR (file)) { - err =deny_write_access (file); -if (err) { -fput (file); - file =ERR_PTR (err); - } - } -out: -return file; - } - } -release_open_intent (&nd); -path_put (&nd.path); + err = -EACCES ; +if (!S_ISREG (nd.path.dentry->d_inode->i_mode)) + goto out_path_put; + + err =vfs_permission (&nd,MAY_EXEC ); +if (err) + goto out_path_put; + + file =nameidata_to_filp (&nd,O_RDONLY |O_LARGEFILE ); +if (IS_ERR (file)) +return file; + + err =deny_write_access (file); +if (err) { +fput (file); + goto out; } - goto out; -} +return file; + + out_path_put: +release_open_intent (&nd); +path_put (&nd.path); + out: +return ERR_PTR (err); +}EXPORT_SYMBOL (open_exec); int kernel_read(struct file *file, unsigned long offset,
PATCH 4/6 procfs: switch ERR_PTR to ERR_OR_0_PTR when "error" might be 0
In reply to Marcin Slusarzproc_pid_follow_link and proc_self_follow_link call ERR_PTR with 0 argument (invalid errno) in most of situtations.
Replace ERR_PTR calls with ERR_OR_0_PTR which accepts 0 argument.
--- fs/proc/base.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-)
fs/proc/base.c +2 -2
@@ -1292,7 +1292,7 @@ static void *proc_pid_follow_link(struct dentry *dentry, struct nameidata *nd) error =PROC_I (inode)->op.proc_get_link (inode, &nd->path); nd->last_type =LAST_BIND ; out: -return ERR_PTR (error); +return ERR_OR_0_PTR (error); }static int do_proc_readlink (struct path *path,char __user *buffer,int buflen)
@@ -2228,7 +2228,7 @@ static void *proc_self_follow_link(struct dentry *dentry, struct nameidata *nd)if (!tgid)return ERR_PTR (-ENOENT );sprintf (tmp,"%d" ,task_tgid_nr_ns (current, ns)); -return ERR_PTR (vfs_follow_link (nd,tmp)); +return ERR_OR_0_PTR (vfs_follow_link (nd,tmp)); }static const struct inode_operations proc_self_inode_operations = {
Signature · 1 line
1.5.4.5
PATCH 5/6 vfs: fix ERR_PTR abuse in generic_readlink
In reply to Marcin Slusarzgeneric_readlink calls ERR_PTR for negative and positive values (vfs_readlink returns length of "link"), but it should not (not an errno) and does not need to.
--- fs/namei.c | 15 ++++++++------- 1 files changed, 8 insertions(+), 7 deletions(-)
fs/namei.c +8 -7
@@ -2853,16 +2853,17 @@ int generic_readlink(struct dentry *dentry, char __user *buffer, int buflen) {struct nameidata nd;void *cookie; +int res; nd.depth =0 ; cookie = dentry->d_inode->i_op->follow_link (dentry, &nd); -if (!IS_ERR (cookie)) { -int res =vfs_readlink (dentry, buffer, buflen,nd_get_link (&nd)); -if (dentry->d_inode->i_op->put_link) - dentry->d_inode->i_op->put_link (dentry, &nd, cookie); - cookie =ERR_PTR (res); - } -return PTR_ERR (cookie); +if (IS_ERR (cookie)) +return PTR_ERR (cookie); + + res =vfs_readlink (dentry, buffer, buflen,nd_get_link (&nd)); +if (dentry->d_inode->i_op->put_link) + dentry->d_inode->i_op->put_link (dentry, &nd, cookie); +return res; }int vfs_follow_link (struct nameidata *nd,const char *link)
Signature · 1 line
1.5.4.5
PATCH 6/6 ERR_PTR: warn when ERR_PTR parameter is not errno value
In reply to Marcin SlusarzCheck at runtime whether error argument of ERR_PTR and ERR_OR_0_PTR is valid. It can catch bugs which possibly lead to oops or panic earlier.
Currently there are > 600 calls of ERR_PTR with non-constant argument in Linux kernel sources.
--- include/linux/err.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)
include/linux/err.h +3 -0
@@ -3,6 +3,7 @@#include <linux/compiler.h> +#include <asm/bug.h> #include <asm/errno.h> /*
@@ -21,6 +22,7 @@static inline void *__ERR_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error));return (void *) error; }
@@ -28,6 +30,7 @@ static inline void *__ERR_PTR(long error)static inline void *__ERR_OR_0_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error) && error);return (void *) error; }
Signature · 1 line
1.5.4.5
Re: [PATCH 6/6] ERR_PTR: warn when ERR_PTR parameter is not errno value
Hi Marcin,
Quoted 33 lines · Marcin Slusarz
Check at runtime whether error argument of
ERR_PTRandERR_OR_0_PTRis valid. It can catch bugs which possibly lead to oops or panic earlier.Currently there are > 600 calls of
ERR_PTRwith non-constant argument in Linux kernel sources.Signed-off-by Marcin Slusarz <[email protected]>Cc Andrew Morton <[email protected]>--- include/linux/err.h | 3 +++ 1 files changed, 3 insertions(+), 0 deletions(-)include/linux/err.h +2
-0@@ -3,6 +3,7 @@#include <linux/compiler.h> +#include <asm/bug.h> #include <asm/errno.h> /* @@ -21,6 +22,7 @@static inline void *__ERR_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error));return (void *) error; }
include/linux/err.h static inline void *__ERR_PTR(long error) · line 35
Quoted 6 lines
include/linux/err.h +1
-0@@ -28,6 +30,7 @@ static inline void *__ERR_PTR(long error)static inline void *__ERR_OR_0_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error) && error);return (void *) error; }
How about WARN_ON_ONCE() instead? That would warn once for each erroneous user which should be enough.
Hannes
Re: [PATCH 6/6] ERR_PTR: warn when ERR_PTR parameter is not errno value
Quoted 28 lines · Johannes Weiner
Quoted 26 lines · Marcin Slusarz
Check at runtime whether error argument of
ERR_PTRandERR_OR_0_PTRis valid. It can catch bugs which possibly lead to oops or panic earlier.Currently there are > 600 calls of
ERR_PTRwith non-constant argument in Linux kernel sources.include/linux/err.h +2
-0@@ -3,6 +3,7 @@#include <linux/compiler.h> +#include <asm/bug.h> #include <asm/errno.h> /* @@ -21,6 +22,7 @@static inline void *__ERR_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error));return (void *) error; }@@ -28,6 +30,7 @@ static inline void *__ERR_PTR(long error)
Quoted 8 lines
include/linux/err.h static inline void *__ERR_PTR(long error) · line 35
Quoted 5 lines
include/linux/err.h +1
-0static inline void *__ERR_OR_0_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error) && error);return (void *) error; }How about
WARN_ON_ONCE()instead? That would warn once for each erroneous user which should be enough.
And blow up .bss ?
Re: [PATCH 6/6] ERR_PTR: warn when ERR_PTR parameter is not errno value
Hi,
Quoted 38 lines · Alexey Dobriyan
Quoted 28 lines · Johannes Weiner
Quoted 26 lines · Marcin Slusarz
Check at runtime whether error argument of
ERR_PTRandERR_OR_0_PTRis valid. It can catch bugs which possibly lead to oops or panic earlier.Currently there are > 600 calls of
ERR_PTRwith non-constant argument in Linux kernel sources.include/linux/err.h +2
-0@@ -3,6 +3,7 @@#include <linux/compiler.h> +#include <asm/bug.h> #include <asm/errno.h> /* @@ -21,6 +22,7 @@static inline void *__ERR_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error));return (void *) error; }@@ -28,6 +30,7 @@ static inline void *__ERR_PTR(long error)Quoted 8 lines
include/linux/err.h static inline void *__ERR_PTR(long error) · line 35
Quoted 5 lines
include/linux/err.h +1
-0static inline void *__ERR_OR_0_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error) && error);return (void *) error; }How about
WARN_ON_ONCE()instead? That would warn once for each erroneous user which should be enough.
Quoted 1 line
And blow up .bss ?
Well, okay. Perhaps ratelimiting? I really prefer a bigger image size over a spammed dmesg.
Hannes
Re: [PATCH 6/6] ERR_PTR: warn when ERR_PTR parameter is not errno value
Quoted 42 lines · Johannes Weiner
Hi,
Quoted 38 lines · Alexey Dobriyan
Quoted 36 lines · Johannes Weiner
Quoted 25 lines · Marcin Slusarz
Check at runtime whether error argument of
ERR_PTRandERR_OR_0_PTRis valid. It can catch bugs which possibly lead to oops or panic earlier.Currently there are > 600 calls of
ERR_PTRwith non-constant argument in Linux kernel sources.include/linux/err.h +2
-0@@ -3,6 +3,7 @@#include <linux/compiler.h> +#include <asm/bug.h> #include <asm/errno.h> /* @@ -21,6 +22,7 @@static inline void *__ERR_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error));return (void *) error; }include/linux/err.h static inline void *__ERR_PTR(long error) · line 35
Quoted 6 lines
include/linux/err.h +1
-0@@ -28,6 +30,7 @@ static inline void *__ERR_PTR(long error)static inline void *__ERR_OR_0_PTR (long error) { +WARN_ON (!IS_ERR_VALUE (error) && error);return (void *) error; }How about
WARN_ON_ONCE()instead? That would warn once for each erroneous user which should be enough.
Quoted 4 lines
Quoted 1 line
And blow up .bss ?
Well, okay. Perhaps ratelimiting? I really prefer a bigger image size over a spammed dmesg.
Well, when I add 0 as a valid argument for ERR_PTR, this check won't add too many false positives, so I think simple WARN_ON is safe.
Marcin