Scripts are wonderful

The past couple of weeks have been quite eventful with some interesting scripts being written and tested out. So, lets talk about them.

There are some cases where the values returned by memory allocation functions like kmalloc, kzalloc, kcalloc, kmem_cache_alloc, kmem_cache_zalloc, kmem_cache_alloc_node, kmalloc_node and kzalloc_node are type casted, which is unnecessary. On sending a coccinelle semantic patch making the change, I realised from the feedback that not only these functions, but most void * values need not be type casted.
Here is a part of the initial script:

@@
type T;
@@

– (T *)
(\(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|
kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(…))

I started working on making the script more generic. But there were many cases where the void * has to be casted to make it useful. These are listed with examples to make them clear, but this may not be comprehensive:

1. Arithmetic operations. eg: sch->padded = (char *) sch – (char *) p; [Code]

2. Structure dereference. eg: n = ((struct rt6_info *)v)->dst.rt6_next; [Code]

3. Indirection operation. eg: *((u8 *) ptr++) = type; [Code]

4. Array dereference. eg: key = (struct sadb_key*) ext_hdrs[SADB_EXT_KEY_ENCRYPT-1]; [Code]

5. Cases where the type cast is __user, __ioremap, __force etc. which are not data types but macros. eg:  memcpy(to, (__force void*)from, n); [Code]

6. Casting of NULL before dereferencing. eg: dinfo->count = cpu_to_le32(sizeof(((struct aac_get_config_status_resp *)NULL)->data));[Code]

7. Use of sizeof on the casted value. eg: target_host->max_cmd_len = sizeof ((struct srp_cmd *) (void *) 0L)->cdb;[Code]

Taking into consideration these cases, I decided to handle only a assignment case initially. Here, is the patch.

@r@
void* e;
identifier a;
type T;
position p;
@@

a = (T@p *)e

@script:python@
t << r.T;
pc << r.p;
@@
if “__” in t: //To deal with cases like __user
cocci.include_match(False)

@remove_cast@
expression e;
identifier a;
type T;
position r.p;
@@

a =
-(T@p *)
e

Now, I am working on extending the patch to generic cases like when arguments are passes to a function with typecasting etc. being careful not to generate false positives.

And yeah for those following the blog, some more devm_ patches have got into the kernel and more will be following. I’ll be updating the list below soon. Many more interesting scripts and the complete version will be updated soon.. so keep learning and have fun 🙂

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s