kernel/taskstats.c: fix bogus nlmsg_free()
PATCH 1/1 kernel/taskstats.c: fix bogus nlmsg_free()
We'd better not nlmsg_free on a pointer containing an undefined value (and without having anything allocated)...
Spotted by the Coverity checker.
---
kernel/taskstats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
kernel/taskstats.c renamed from kernel/taskstats.c.old +6 -6
@@ -383,67 +383,67 @@static int cgroupstats_user_cmd (struct sk_buff *skb,struct genl_info *info) {int rc =0 ;struct sk_buff *rep_skb;struct cgroupstats *stats;struct nlattr *na;size_t size;u32 fd;struct file *file;int fput_needed; na = info->attrs[CGROUPSTATS_CMD_ATTR_FD ];if (!na)return -EINVAL ; fd =nla_get_u32 (info->attrs[CGROUPSTATS_CMD_ATTR_FD ]); file =fget_light (fd, &fput_needed);if (file) { size =nla_total_size (sizeof (struct cgroupstats )); rc =prepare_reply (info,CGROUPSTATS_CMD_NEW , &rep_skb, size);if (rc <0 ) - goto err; +return rc; na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS ,sizeof (struct cgroupstats )); stats =nla_data (na);memset (stats,0 ,sizeof (*stats)); rc =cgroupstats_build (stats, file->f_dentry); + +fput_light (file, fput_needed); +if (rc <0 ) goto err; -fput_light (file, fput_needed);return send_reply (rep_skb, info->snd_pid); +err: +nlmsg_free (rep_skb); } -err: -if (file) -fput_light (file, fput_needed); -nlmsg_free (rep_skb);return rc; }static int taskstats_user_cmd (struct sk_buff *skb,struct genl_info *info) {int rc =0 ;struct sk_buff *rep_skb;struct taskstats *stats;size_t size;cpumask_t mask; rc =parse (info->attrs[TASKSTATS_CMD_ATTR_REGISTER_CPUMASK ], &mask);if (rc <0 )return rc;if (rc ==0 )return add_del_listener (info->snd_pid, &mask,REGISTER ); rc =parse (info->attrs[TASKSTATS_CMD_ATTR_DEREGISTER_CPUMASK ], &mask);if (rc <0 )return rc;if (rc ==0 )return add_del_listener (info->snd_pid, &mask,DEREGISTER );/*
Quoted 32 lines · Adrian Bunk
We'd better not
nlmsg_freeon a pointer containing an undefined value (and without having anything allocated)...Spotted by the Coverity checker.
Signed-off-by Adrian Bunk <[email protected]>---
kernel/taskstats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)kernel/taskstats.c renamed from kernel/taskstats.c.old +0
-0@@ -383,67 +383,67 @@static int cgroupstats_user_cmd (struct sk_buff *skb,struct genl_info *info) {int rc =0 ;struct sk_buff *rep_skb;struct cgroupstats *stats;struct nlattr *na;size_t size;u32 fd;struct file *file;int fput_needed; na = info->attrs[CGROUPSTATS_CMD_ATTR_FD ];if (!na)return -EINVAL ; fd =nla_get_u32 (info->attrs[CGROUPSTATS_CMD_ATTR_FD ]);
kernel/taskstats.c line 408
Quoted 10 lines
kernel/taskstats.c renamed from kernel/taskstats.c.old +1
-1file =fget_light (fd, &fput_needed);if (file) { size =nla_total_size (sizeof (struct cgroupstats )); rc =prepare_reply (info,CGROUPSTATS_CMD_NEW , &rep_skb, size);if (rc <0 ) - goto err; +return rc;
We miss a fput_light() here
kernel/taskstats.c line 417
Quoted 9 lines
kernel/taskstats.c renamed from kernel/taskstats.c.old +3
-0na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS ,sizeof (struct cgroupstats )); stats =nla_data (na);memset (stats,0 ,sizeof (*stats)); rc =cgroupstats_build (stats, file->f_dentry); + +fput_light (file, fput_needed); +
I don't understand this movement, it makes code reading a bit odd too. rc is the result, but we check the result after fput_light?
Quoted 15 lines
kernel/taskstats.c renamed from kernel/taskstats.c.old +2
-5if (rc <0 ) goto err; -fput_light (file, fput_needed);return send_reply (rep_skb, info->snd_pid); +err: +nlmsg_free (rep_skb); } -err: -if (file) -fput_light (file, fput_needed); -nlmsg_free (rep_skb);return rc; }
Signature · 4 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL
PATCH 1/1 kernel/taskstats.c: fix bogus nlmsg_free()
Quoted 16 lines · Balbir Singh
Quoted 14 lines · Adrian Bunk
We'd better not
nlmsg_freeon a pointer containing an undefined value (and without having anything allocated)...Spotted by the Coverity checker.
Signed-off-by Adrian Bunk <[email protected]>---
kernel/taskstats.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)kernel/taskstats.c renamed from kernel/taskstats.c.old +0
-0...
Quoted 6 lines
kernel/taskstats.c
Quoted 4 lines
kernel/taskstats.c renamed from kernel/taskstats.c.old +1
-1if (rc <0 ) - goto err; +return rc;We miss a
fput_light()here
Sorry, my fault.
Quoted 5 lines
Quoted 5 lines
kernel/taskstats.c renamed from kernel/taskstats.c.old +0
-0na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS ,sizeof (struct cgroupstats )); stats =nla_data (na);memset (stats,0 ,sizeof (*stats));
Quoted 8 lines
kernel/taskstats.c
Quoted 4 lines
kernel/taskstats.c renamed from kernel/taskstats.c.old +3
-0rc =cgroupstats_build (stats, file->f_dentry); + +fput_light (file, fput_needed); +I don't understand this movement, it makes code reading a bit odd too. rc is the result, but we check the result after
fput_light?
...
I considered it more odd to read
rc = cgroupstats_build(stats, file->f_dentry);
if (rc < 0)
goto err;
fput_light(file, fput_needed);
return send_reply(rep_skb, info->snd_pid);
err:
fput_light(file, fput_needed);
nlmsg_free(rep_skb);But that's just personal taste.
Anyway, duplicating the same fput_light() call two or three times isn't nice.
Originally I had the bigger patch below and considered it too big for only this fix, but now I think it might be appropriate.
If you ignore whitespace when diff'ing, then all it does is:
<-- snip -->
@@ -398,7 +398,9 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
fd = nla_get_u32(info->attrs[CGROUPSTATS_CMD_ATTR_FD]); file = fget_light(fd, &fput_needed);
- if (file) {
+ if (!file)
+ return 0;
+
size = nla_total_size(sizeof(struct cgroupstats));
rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,
@@ -412,17 +414,15 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)
memset(stats, 0, sizeof(*stats));
rc = cgroupstats_build(stats, file->f_dentry);
- if (rc < 0)
+ if (rc < 0) {
+ nlmsg_free(rep_skb);
goto err;
-
- fput_light(file, fput_needed);
- return send_reply(rep_skb, info->snd_pid);
}
+ rc = send_reply(rep_skb, info->snd_pid);
+
err:
- if (file)
fput_light(file, fput_needed);
- nlmsg_free(rep_skb);
return rc;
}
<-- snip -->
Is this patch OK for you?
cu
Adrian
<-- snip -->
We'd better not nlmsg_free on a pointer containing an undefined value (and without having anything allocated).
Spotted by the Coverity checker.
---
kernel/taskstats.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
eedd297ac36b5d92fc38b937677ba40dc6df1cd0
kernel/taskstats.c +18 -18
@@ -398,31 +398,31 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) fd =nla_get_u32 (info->attrs[CGROUPSTATS_CMD_ATTR_FD ]); file =fget_light (fd, &fput_needed); -if (file) { - size =nla_total_size (sizeof (struct cgroupstats )); +if (!file) +return 0 ; - rc =prepare_reply (info,CGROUPSTATS_CMD_NEW , &rep_skb, - size); -if (rc <0 ) - goto err; + size =nla_total_size (sizeof (struct cgroupstats )); - na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS , -sizeof (struct cgroupstats )); - stats =nla_data (na); -memset (stats,0 ,sizeof (*stats)); + rc =prepare_reply (info,CGROUPSTATS_CMD_NEW , &rep_skb, + size); +if (rc <0 ) + goto err; - rc =cgroupstats_build (stats, file->f_dentry); -if (rc <0 ) - goto err; + na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS , +sizeof (struct cgroupstats )); + stats =nla_data (na); +memset (stats,0 ,sizeof (*stats)); -fput_light (file, fput_needed); -return send_reply (rep_skb, info->snd_pid); + rc =cgroupstats_build (stats, file->f_dentry); +if (rc <0 ) { +nlmsg_free (rep_skb); + goto err; } + rc =send_reply (rep_skb, info->snd_pid); + err: -if (file) -fput_light (file, fput_needed); -nlmsg_free (rep_skb); +fput_light (file, fput_needed);return rc; }
Quoted 13 lines · Adrian Bunk
I considered it more odd to read
rc = cgroupstats_build(stats, file->f_dentry); if (rc < 0) goto err; fput_light(file, fput_needed); return send_reply(rep_skb, info->snd_pid); err: fput_light(file, fput_needed); nlmsg_free(rep_skb);
I agree, but sometimes the alternative can be worse to read and understand
Quoted 117 lines
But that's just personal taste.
Anyway, duplicating the same
fput_light()call two or three times isn't nice.Originally I had the bigger patch below and considered it too big for only this fix, but now I think it might be appropriate.
If you ignore whitespace when diff'ing, then all it does is:
<-- snip -->
kernel/taskstats.c +7
-7@@ -398,7 +398,9 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) fd =nla_get_u32 (info->attrs[CGROUPSTATS_CMD_ATTR_FD ]); file =fget_light (fd, &fput_needed); -if (file) { +if (!file) +return 0 ; + size =nla_total_size (sizeof (struct cgroupstats )); rc = prepare_reply(info, CGROUPSTATS_CMD_NEW, &rep_skb,@@ -412,17 +414,15 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info)memset (stats,0 ,sizeof (*stats)); rc =cgroupstats_build (stats, file->f_dentry); -if (rc <0 ) +if (rc <0 ) { +nlmsg_free (rep_skb); goto err; - -fput_light (file, fput_needed); -return send_reply (rep_skb, info->snd_pid); } + rc =send_reply (rep_skb, info->snd_pid); + err: -if (file)fput_light (file, fput_needed); -nlmsg_free (rep_skb);return rc; }<-- snip -->
Is this patch OK for you?
cu
Adrian<-- snip -->
We'd better not
nlmsg_freeon a pointer containing an undefined value (and without having anything allocated).Spotted by the Coverity checker.
Signed-off-by Adrian Bunk <[email protected]>---
kernel/taskstats.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-)
eedd297ac36b5d92fc38b937677ba40dc6df1cd0kernel/taskstats.c +15
-15@@ -398,31 +398,31 @@ static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) fd =nla_get_u32 (info->attrs[CGROUPSTATS_CMD_ATTR_FD ]); file =fget_light (fd, &fput_needed); -if (file) { - size =nla_total_size (sizeof (struct cgroupstats )); +if (!file) +return 0 ; - rc =prepare_reply (info,CGROUPSTATS_CMD_NEW , &rep_skb, - size); -if (rc <0 ) - goto err; + size =nla_total_size (sizeof (struct cgroupstats )); - na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS , -sizeof (struct cgroupstats )); - stats =nla_data (na); -memset (stats,0 ,sizeof (*stats)); + rc =prepare_reply (info,CGROUPSTATS_CMD_NEW , &rep_skb, + size); +if (rc <0 ) + goto err; - rc =cgroupstats_build (stats, file->f_dentry); -if (rc <0 ) - goto err; + na =nla_reserve (rep_skb,CGROUPSTATS_TYPE_CGROUP_STATS , +sizeof (struct cgroupstats )); + stats =nla_data (na); +memset (stats,0 ,sizeof (*stats)); -fput_light (file, fput_needed); -return send_reply (rep_skb, info->snd_pid); + rc =cgroupstats_build (stats, file->f_dentry); +if (rc <0 ) { +nlmsg_free (rep_skb); + goto err; }
kernel/taskstats.c static int cgroupstats_user_cmd(struct sk_buff *skb, struct genl_info *info) · line 428
Quoted 10 lines
kernel/taskstats.c +3
-3+ rc =send_reply (rep_skb, info->snd_pid); + err: -if (file) -fput_light (file, fput_needed); -nlmsg_free (rep_skb); +fput_light (file, fput_needed);return rc; }
Looks good to me!
Yet to be tested, I'll try and test it soon.
Signature · 4 lines
Warm Regards, Balbir Singh Linux Technology Center IBM, ISTL