This is the mail archive of the
systemtap@sourceware.org
mailing list for the systemtap project.
[Patch]Add a function kernel_string2 for copy non-0-terminated string with fixed length from kernel space at given address.
- From: Cai Fei <caifei at cn dot fujitsu dot com>
- To: systemtap at sourceware dot org
- Date: Fri, 12 Oct 2007 09:41:20 +0900
- Subject: [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)