* [PATCH] Kill a sparse warning in binfmt_elf.c
@ 2004-10-06 22:45 Arun Sharma
2004-10-07 18:11 ` Valdis.Kletnieks
0 siblings, 1 reply; 9+ messages in thread
From: Arun Sharma @ 2004-10-06 22:45 UTC (permalink / raw)
To: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 112 bytes --]
The attached patch kills a sparse warning in binfmt_elf.c:dump_write() by adding a __user annotation.
-Arun
[-- Attachment #2: sparse-binfmt.patch --]
[-- Type: text/plain, Size: 539 bytes --]
Kill a sparse warning in 2.6.9-rc3.
Signed-off-by: Arun Sharma <arun.sharma@intel.com>
===== fs/binfmt_elf.c 1.88 vs edited =====
--- 1.88/fs/binfmt_elf.c Wed Sep 22 13:34:05 2004
+++ edited/fs/binfmt_elf.c Wed Oct 6 13:16:37 2004
@@ -1032,7 +1032,7 @@
*/
static int dump_write(struct file *file, const void *addr, int nr)
{
- return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
+ return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
}
static int dump_seek(struct file *file, off_t off)
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-06 22:45 [PATCH] Kill a sparse warning in binfmt_elf.c Arun Sharma
@ 2004-10-07 18:11 ` Valdis.Kletnieks
2004-10-07 18:49 ` Arun Sharma
0 siblings, 1 reply; 9+ messages in thread
From: Valdis.Kletnieks @ 2004-10-07 18:11 UTC (permalink / raw)
To: Arun Sharma; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 742 bytes --]
On Wed, 06 Oct 2004 15:45:02 PDT, Arun Sharma said:
> The attached patch kills a sparse warning in binfmt_elf.c:dump_write() by
> adding a __user annotation.
> static int dump_write(struct file *file, const void *addr, int nr)
> {
> - return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
> + return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
> }
wouldn't it be more useful to put the annotation into the *prototype* for
the dump_write() function, so that we get sparse typechecking for the
caller(s) of this function? Your fix just kills the warning - when the *real*
problem is that we're called with a 'void *' that we then cast to something
without any real double check on what it is....
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 18:11 ` Valdis.Kletnieks
@ 2004-10-07 18:49 ` Arun Sharma
2004-10-07 18:54 ` Valdis.Kletnieks
0 siblings, 1 reply; 9+ messages in thread
From: Arun Sharma @ 2004-10-07 18:49 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: linux-kernel
On 10/7/2004 11:11 AM, Valdis.Kletnieks@vt.edu wrote:
> On Wed, 06 Oct 2004 15:45:02 PDT, Arun Sharma said:
>
>> The attached patch kills a sparse warning in binfmt_elf.c:dump_write() by
>> adding a __user annotation.
>
>> static int dump_write(struct file *file, const void *addr, int nr)
>> {
>> - return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
>> + return file->f_op->write(file, (const char __user *) addr, nr, &file->f_pos) == nr;
>> }
>
> wouldn't it be more useful to put the annotation into the *prototype* for
> the dump_write() function, so that we get sparse typechecking for the
> caller(s) of this function? Your fix just kills the warning - when the *real*
> problem is that we're called with a 'void *' that we then cast to something
> without any real double check on what it is....
dump_write() is a static function without a prototype.
-Arun
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 18:49 ` Arun Sharma
@ 2004-10-07 18:54 ` Valdis.Kletnieks
2004-10-07 19:01 ` Arun Sharma
2004-10-07 19:16 ` David S. Miller
0 siblings, 2 replies; 9+ messages in thread
From: Valdis.Kletnieks @ 2004-10-07 18:54 UTC (permalink / raw)
To: Arun Sharma; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1003 bytes --]
On Thu, 07 Oct 2004 11:49:24 PDT, Arun Sharma said:
> >> static int dump_write(struct file *file, const void *addr, int nr)
> >> {
> >> - return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
> >> + return file->f_op->write(file, (const char __user *) addr, nr, &file->f
_pos) == nr;
> >> }
> >
> > wouldn't it be more useful to put the annotation into the *prototype* for
> > the dump_write() function, so that we get sparse typechecking for the
> > caller(s) of this function? Your fix just kills the warning - when the *re
al*
> > problem is that we're called with a 'void *' that we then cast to something
> > without any real double check on what it is....
>
> dump_write() is a static function without a prototype.
static int dump_write(struct file *file, const char __user *addr, int nr)
{
return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
}
And then go find the callers and make sure what they're passing is a
'const char __user *' rather than a 'const void *'....
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 18:54 ` Valdis.Kletnieks
@ 2004-10-07 19:01 ` Arun Sharma
2004-10-07 19:16 ` Valdis.Kletnieks
2004-10-07 19:16 ` David S. Miller
1 sibling, 1 reply; 9+ messages in thread
From: Arun Sharma @ 2004-10-07 19:01 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: linux-kernel
On 10/7/2004 11:54 AM, Valdis.Kletnieks@vt.edu wrote:
> And then go find the callers and make sure what they're passing is a
> 'const char __user *' rather than a 'const void *'....
Many callers in binfmt_elf.c are passing pointers that are kernel addresses. But file_operations->write() is expecting a __user pointer. The intention of the cast is to explicitly say that's an okay thing to do.
-Arun
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 18:54 ` Valdis.Kletnieks
2004-10-07 19:01 ` Arun Sharma
@ 2004-10-07 19:16 ` David S. Miller
2004-10-07 19:27 ` Valdis.Kletnieks
1 sibling, 1 reply; 9+ messages in thread
From: David S. Miller @ 2004-10-07 19:16 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: arun.sharma, linux-kernel
On Thu, 07 Oct 2004 14:54:57 -0400
Valdis.Kletnieks@vt.edu wrote:
> > dump_write() is a static function without a prototype.
>
> static int dump_write(struct file *file, const char __user *addr, int nr)
> {
> return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
> }
>
> And then go find the callers and make sure what they're passing is a
> 'const char __user *' rather than a 'const void *'....
The caller's aren't, that is the point. They run dump_write()
with set_fs(KERNEL_DS), which allows kernel pointers to be treated
as user ones in system call handling paths, which is why the cast
is needed somewhere.
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 19:01 ` Arun Sharma
@ 2004-10-07 19:16 ` Valdis.Kletnieks
2004-10-07 22:07 ` Arun Sharma
0 siblings, 1 reply; 9+ messages in thread
From: Valdis.Kletnieks @ 2004-10-07 19:16 UTC (permalink / raw)
To: Arun Sharma; +Cc: linux-kernel
[-- Attachment #1: Type: text/plain, Size: 1450 bytes --]
On Thu, 07 Oct 2004 12:01:19 PDT, Arun Sharma said:
> Many callers in binfmt_elf.c are passing pointers that are kernel addresses.
> But file_operations->write() is expecting a __user pointer. The intention of
> the cast is to explicitly say that's an okay thing to do.
Right. My point was that if you're fixing the warning, you should do the
*whole* job by making sure that what *you* got in that 'void *' is a __user
pointer, rather than just saying "we know write() wants a __user".
So for instance, up a level in writenote():
#define DUMP_WRITE(addr, nr) do { if (!dump_write(file, (addr), (nr))) return 0; } while(0)
#define DUMP_SEEK(off) do { if (!dump_seek(file, (off))) return 0; } while(0)
static int writenote(struct memelfnote *men, struct file *file)
{
struct elf_note en;
en.n_namesz = strlen(men->name) + 1;
en.n_descsz = men->datasz;
en.n_type = men->type;
DUMP_WRITE(&en, sizeof(en));
DUMP_WRITE(men->name, en.n_namesz);
Is men->name a __user pointer? Should it be? Can it be something else?
struct memelfnote
{
const char *name;
int type;
unsigned int datasz;
void *data;
};
Hmm.. there it's a 'const char *name', but we feed it to a 'const void *'
and then you cast it to a __user. Either that *name should be __user
as well, or you tagged something as a __user that might not be.
*That*s what I'm talking about....
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 19:16 ` David S. Miller
@ 2004-10-07 19:27 ` Valdis.Kletnieks
0 siblings, 0 replies; 9+ messages in thread
From: Valdis.Kletnieks @ 2004-10-07 19:27 UTC (permalink / raw)
To: David S. Miller; +Cc: arun.sharma, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 638 bytes --]
On Thu, 07 Oct 2004 12:16:23 PDT, "David S. Miller" said:
> The caller's aren't, that is the point. They run dump_write()
> with set_fs(KERNEL_DS), which allows kernel pointers to be treated
> as user ones in system call handling paths, which is why the cast
> is needed somewhere.
Right - and my point is that putting one cast way down at the bottom
to quiet a warning doesn't do much good - the cast should be pushed
up to as close to that set_fs() as feasible. Otherwise if some other,
new, caller surfaces and bogusly passes something *else* in that
void * pointer, it gets a lot harder for sparse and similar to do their
jobs.
[-- Attachment #2: Type: application/pgp-signature, Size: 226 bytes --]
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH] Kill a sparse warning in binfmt_elf.c
2004-10-07 19:16 ` Valdis.Kletnieks
@ 2004-10-07 22:07 ` Arun Sharma
0 siblings, 0 replies; 9+ messages in thread
From: Arun Sharma @ 2004-10-07 22:07 UTC (permalink / raw)
To: Valdis.Kletnieks; +Cc: linux-kernel
On 10/7/2004 12:16 PM, Valdis.Kletnieks@vt.edu wrote:
> Hmm.. there it's a 'const char *name', but we feed it to a 'const void *'
> and then you cast it to a __user.
I'm not very concerned about const char * being cast to const void *. That's not the focus of the patch[1]. The focus of the patch is really __user.
> Either that *name should be __user
> as well, or you tagged something as a __user that might not be.
>
Certain interfaces such as get_user() will fail if you pass a kernel pointer and unconditionally cast it to __user (without doing a set_fs(KERNEL_DS)). But file_operations->write() is not one of them and hence the patch.
-Arun
[1] If you insist on this, you should change all the calls to memcpy() as well.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2004-10-08 1:36 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-10-06 22:45 [PATCH] Kill a sparse warning in binfmt_elf.c Arun Sharma
2004-10-07 18:11 ` Valdis.Kletnieks
2004-10-07 18:49 ` Arun Sharma
2004-10-07 18:54 ` Valdis.Kletnieks
2004-10-07 19:01 ` Arun Sharma
2004-10-07 19:16 ` Valdis.Kletnieks
2004-10-07 22:07 ` Arun Sharma
2004-10-07 19:16 ` David S. Miller
2004-10-07 19:27 ` Valdis.Kletnieks
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).