This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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


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)



Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]