[Patch]Add a function kernel_string2 for copy non-0-terminated string with fixed length from kernel space at given address.

Cai Fei caifei@cn.fujitsu.com
Fri Oct 12 00:42:00 GMT 2007


Hi,

Systemtap offered a function kernel_string for copy 0-terminated string 
from
kernel space at given address. But in the kernel space, strings do not 
always
end with a 0 but defined with a length. In that case, the function 
kernel_string
may get a string whose length is longer than expected.

I encountered the problem when print the string of argument "fname" in 
kernel
function nfsd_rename.

So I added a function kernel_string2 for copy non-0-terminated string with
fixed length from kernel space at given address. Also, the man paged is 
updated.

Here is the patch:

diff -Nur systemtap-20071006.orig/stapfuncs.5.in systemtap-20071006/stapfuncs.5.in
--- systemtap-20071006.orig/stapfuncs.5.in	2007-10-11 15:44:53.000000000 +0900
+++ systemtap-20071006/stapfuncs.5.in	2007-10-12 08:50:52.000000000 +0900
@@ -73,6 +73,12 @@
 kernel_string:string (addr:long)
 Copy a 0-terminated string from kernel space at given address.
 .TP
+kernel_string2:string (addr:long, n:long)
+Similar with kernel_string, except that not more than n bytes are copied.
+Thus, if there are null bytes among the first n bytes, it is same as
+kernel_string(addr). If not, n bytes will be copied and a null byte will
+be padded to the end.
+.TP
 kernel_long:long (addr:long)
 Copy a long from kernel space at given address.
 .TP
diff -Nur systemtap-20071006.orig/tapset/conversions.stp systemtap-20071006/tapset/conversions.stp
--- systemtap-20071006.orig/tapset/conversions.stp	2007-10-11 15:44:53.000000000 +0900
+++ systemtap-20071006/tapset/conversions.stp	2007-10-12 08:51:16.000000000 +0900
@@ -18,6 +18,19 @@
   }
 %}
 
+function kernel_string2:string (addr:long, n:long) %{ /* pure */
+  char *destination = THIS->__retvalue;
+  long len = THIS->n + 1;
+  len = (len > MAXSTRINGLEN) ? MAXSTRINGLEN : len;
+  deref_string (destination, THIS->addr, len);
+  if (0) {
+deref_fault: /* branched to from deref_string() */
+    snprintf (CONTEXT->error_buffer, sizeof(CONTEXT->error_buffer),
+        "kernel string copy fault at 0x%p", (void *) (uintptr_t) THIS->addr);
+    CONTEXT->last_error = CONTEXT->error_buffer;
+  }
+%}
+
 function kernel_long:long (addr:long) %{ /* pure */
   THIS->__retvalue = kread((long *) (intptr_t) THIS->addr);
   if (0) {
diff -Nur systemtap-20071006.orig/tapset/nfsd.stp systemtap-20071006/tapset/nfsd.stp
--- systemtap-20071006.orig/tapset/nfsd.stp	2007-10-11 15:44:53.000000000 +0900
+++ systemtap-20071006/tapset/nfsd.stp	2007-10-12 08:53:39.000000000 +0900
@@ -209,8 +209,8 @@
         version = 2
 	fh = __get_fh($argp,1)
 
-	filename = kernel_string($argp->name)
 	filelen = $argp->len
+	filename = kernel_string2($argp->name, filelen)
 
 	name = "nfsd.proc2.lookup"
 	argstr = sprintf("%s",filename)
@@ -233,8 +233,8 @@
         version = 3
 	fh = __get_fh($argp,1)
 
-	filename = kernel_string($argp->name)
 	filelen = $argp->len
+	filename = kernel_string2($argp->name, filelen)
 
 	name = "nfsd.proc3.lookup"
 	argstr = sprintf("%s",filename)
@@ -511,8 +511,8 @@
         version = 2
 	fh = __get_fh($argp,8)
 
-	filename  = kernel_string($argp->name) 
 	filelen = $argp->len
+	filename  = kernel_string2($argp->name, filelen) 
 
 	name = "nfsd.proc2.create"
 	argstr = sprintf("%s",filename)
@@ -534,8 +534,8 @@
         version = 3
 	fh = __get_fh($argp,9)
 
-	filename  = kernel_string($argp->name) 
 	filelen = $argp->len
+	filename  = kernel_string2($argp->name, filelen) 
 	
 	name = "nfsd.proc3.create"
 	argstr = sprintf("%s",filename)
@@ -576,8 +576,8 @@
         version = 2
 	fh = __get_fh($argp,10)
 
-	filename  = kernel_string($argp->name) 
 	filelen = $argp->len
+	filename  = kernel_string2($argp->name, filelen) 
 
 	name = "nfsd.proc2.remove"
 	argstr = sprintf("%s",filename)
@@ -599,8 +599,8 @@
         version = 3
 	fh = __get_fh($argp,11)
 
-	filename  = kernel_string($argp->name) 
 	filelen = $argp->len
+	filename  = kernel_string2($argp->name, filelen) 
 	
 	name = "nfsd.proc3.remove"
 	argstr = sprintf("%s",filename)
@@ -643,10 +643,10 @@
 	fh = __get_fh($argp,12)
 	tfh = __get_fh($argp,13)
 
-	filename  = kernel_string($argp->fname) 
 	filelen = $argp->flen
-	tname = kernel_string($argp->tname)
+	filename  = kernel_string2($argp->fname, filelen) 
 	tlen = $argp->tlen
+	tname = kernel_string2($argp->tname, tlen)
 
 	name = "nfsd.proc2.rename"
 	argstr = sprintf("%s,%s",filename,tname)
@@ -669,10 +669,10 @@
 	fh = __get_fh($argp,14)
 	tfh = __get_fh($argp,15)
 
-	filename  = kernel_string($argp->fname) 
 	filelen = $argp->flen
-	tname = kernel_string($argp->tname)
+	filename  = kernel_string2($argp->fname, filelen) 
 	tlen = $argp->tlen
+	tname = kernel_string2($argp->tname, tlen)
 
 	name = "nfsd.proc3.rename"
 	argstr = sprintf("%s,%s",filename,tname)
@@ -915,8 +915,8 @@
 {
 	fh = __svc_fh($fhp)
 
-	filename = kernel_string($name)
 	filelen = $len
+	filename = kernel_string2($name, filelen)
 
 	name = "nfsd.lookup"
 	argstr = sprintf("%s",filename)
@@ -947,8 +947,8 @@
 {
 	fh = __svc_fh($fhp)
 
-	filename = kernel_string($fname)
 	filelen = $flen
+	filename = kernel_string2($fname, filelen)
 	type = $type
 	iap_valid = $iap->ia_valid
 	iap_mode = $iap->ia_mode
@@ -987,8 +987,8 @@
 {
 	fh = __svc_fh($fhp)
 
-	filename = kernel_string($fname)
 	filelen = $flen
+	filename = kernel_string2($fname, filelen)
 	iap_valid = $iap->ia_valid
 	iap_mode = $iap->ia_mode
 	truncp = $truncp
@@ -1022,8 +1022,8 @@
 {
 	fh = __svc_fh($fhp)
 
-	filename = kernel_string($fname)
 	filelen = $flen
+	filename = kernel_string2($fname, filelen)
 	type = $type
 
 	name = "nfsd.unlink"
@@ -1056,10 +1056,10 @@
 	fh = __svc_fh($ffhp)
 	tfh = __svc_fh($tfhp)
 
-	filename  = kernel_string($fname) 
 	filelen = $flen
-	tname = kernel_string($tname)
+	filename  = kernel_string2($fname, filelen) 
 	tlen = $tlen
+	tname = kernel_string2($tname, tlen)
 
 	name = "nfsd.rename"
 	argstr = sprintf("%s,%s",filename,tname)
diff -Nur systemtap-20071006.orig/tapset/nfs_proc.stp systemtap-20071006/tapset/nfs_proc.stp
--- systemtap-20071006.orig/tapset/nfs_proc.stp	2007-10-11 14:43:21.000000000 +0900
+++ systemtap-20071006/tapset/nfs_proc.stp	2007-10-11 16:46:39.000000000 +0900
@@ -227,8 +227,8 @@
         prot   = __i2n_ip_proto($dir,1)
         version =2
 
-	filename = kernel_string($name->name)
-        name_len = $name->len
+	name_len = $name->len
+	filename = kernel_string2($name->name, name_len)
 
         name = "nfs.proc2.lookup"
         argstr = sprintf("%s",filename) 
@@ -250,8 +250,8 @@
         prot   = __i2n_ip_proto($dir,1)
         version =3
 
-	filename = kernel_string($name->name)
-        name_len = $name->len
+	name_len = $name->len
+	filename = kernel_string2($name->name, name_len)
 
         name = "nfs.proc3.lookup"
         argstr = sprintf("%s",filename) 
@@ -274,8 +274,8 @@
         prot   = __i2n_ip_proto($dir,1)
         version =4
 
-	filename = kernel_string($name->name)
-        name_len = $name->len
+	name_len = $name->len
+	filename = kernel_string2($name->name, name_len)
         bitmask0 = __nfsv4_bitmask($dir,0)
         bitmask1 = __nfsv4_bitmask($dir,1)
 
@@ -1339,8 +1339,8 @@
 	version =2
 
 	fh = __getfh_inode($dir)
-	filename = kernel_string($dentry->d_name->name)
 	filelen = $dentry->d_name->len
+	filename = kernel_string2($dentry->d_name->name, filelen)
 	mode = $sattr->ia_mode
 
 	name = "nfs.proc2.create"
@@ -1363,8 +1363,8 @@
 	version =3
 
 	fh = __getfh_inode($dir)
-	filename = kernel_string($dentry->d_name->name)
 	filelen = $dentry->d_name->len
+	filename = kernel_string2($dentry->d_name->name, filelen)
 	flag = $flags
 	mode = $sattr->ia_mode
 
@@ -1388,8 +1388,8 @@
 	version =4
 
 	fh = __getfh_inode($dir)
-	filename = kernel_string($dentry->d_name->name)
 	filelen = $dentry->d_name->len
+	filename = kernel_string2($dentry->d_name->name, filelen)
 	flag = $flags
 	mode = $sattr->ia_mode
 
@@ -1435,8 +1435,8 @@
 	version =2
 
 	fh = __getfh_inode($dir)
-	filename = kernel_string($name->name)
 	filelen = $name->len
+	filename = kernel_string2($name->name, filelen)
 
 	name = "nfs.proc2.remove"
 	argstr = sprintf("%s",filename)
@@ -1458,8 +1458,8 @@
 	version =3
 
 	fh = __getfh_inode($dir)
-	filename = kernel_string($name->name)
 	filelen = $name->len
+	filename = kernel_string2($name->name, filelen)
 
 	name = "nfs.proc3.remove"
 	argstr = sprintf("%s",filename)
@@ -1481,8 +1481,8 @@
 	version =4
 
 	fh = __getfh_inode($dir)
-	filename = kernel_string($name->name)
 	filelen = $name->len
+	filename = kernel_string2($name->name, filelen)
 
 	name = "nfs.proc4.remove"
 	argstr = sprintf("%s",filename)
@@ -1529,11 +1529,11 @@
 	version =2
 
 	old_fh = __getfh_inode($old_dir)
-	old_name = kernel_string($old_name->name)
 	old_filelen = $old_name->len
+	old_name = kernel_string2($old_name->name, old_filelen)
 	new_fh = __getfh_inode($new_dir)
-	new_name = kernel_string($new_name->name)
 	new_filelen = $new_name->len
+	new_name = kernel_string2($new_name->name, new_filelen)
 
 	name = "nfs.proc2.rename"
 	argstr = sprintf("%s,%s",old_name,new_name)
@@ -1555,11 +1555,11 @@
 	version =3
 
 	old_fh = __getfh_inode($old_dir)
-	old_name = kernel_string($old_name->name)
 	old_filelen = $old_name->len
+	old_name = kernel_string2($old_name->name, old_filelen)
 	new_fh = __getfh_inode($new_dir)
-	new_name = kernel_string($new_name->name)
 	new_filelen = $new_name->len
+	new_name = kernel_string2($new_name->name, new_filelen)
 
 	name = "nfs.proc3.rename"
 	argstr = sprintf("%s,%s",old_name,new_name)
@@ -1581,11 +1581,11 @@
 	version =4
 
 	old_fh = __getfh_inode($old_dir)
-	old_name = kernel_string($old_name->name)
 	old_filelen = $old_name->len
+	old_name = kernel_string2($old_name->name, old_filelen)
 	new_fh = __getfh_inode($new_dir)
-	new_name = kernel_string($new_name->name)
 	new_filelen = $new_name->len
+	new_name = kernel_string2($new_name->name, new_filelen)
 
 	name = "nfs.proc4.rename"
 	argstr = sprintf("%s,%s",old_name,new_name)




More information about the Systemtap mailing list