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]

Re: [PATCH RFC] Fix failure of signing modules on XFS


On 04/03/2015 03:12 AM, qiaonuohan wrote:
> When using a server, whose filesystem is XFS, to compile scripts, the
> following messages are printed and fail to sign modules.
> 
> <cut>
> Server: No matching machine owner key (MOK) available on the server to sign the
>  module.
> Server: The server has no machine owner key (MOK) in common with this
> system. Use the following command to import a server MOK into this
> system, then reboot:
> 
> 	mokutil --import signing_key.x509
> <cut>
> 
> The matching MOK does exist, but the server fails to find it. The detail
> is the server searches keys and check whether they are regular files by
> dirent.d_type, but XFS dirent.d_type is not supported. This patch uses
> S_ISREG to do the check.
> 
> Signed-off-by: qiaonuohan <qiaonuohan@cn.fujitsu.com>
> ---
>  stap-serverd.cxx | 7 +++++--
>  1 file changed, 5 insertions(+), 2 deletions(-)
> 
> diff --git a/stap-serverd.cxx b/stap-serverd.cxx
> index 40b3c39..ad70e8a 100644
> --- a/stap-serverd.cxx
> +++ b/stap-serverd.cxx
> @@ -368,15 +368,18 @@ mok_dir_valid_p (string mok_fingerprint, bool verbose)
>    bool priv_found = false;
>    bool cert_found = false;
>    struct dirent *direntp;
> +  struct stat tmpstat;
>    while ((direntp = readdir (dirp)) != NULL)
>      {
> -      if (! priv_found && direntp->d_type == DT_REG
> +      //XFS dirent.d_type is not supported, using S_ISREG instead
> +      stat((mok_dir + "/" + direntp->d_name).c_str (), &tmpstat);
> +      if (! priv_found && S_ISREG(tmpstat.st_mode)
>  	  && strcmp (direntp->d_name, MOK_PRIVATE_CERT_NAME) == 0)
>          {
>  	  priv_found = true;
>  	  continue;
>  	}
> -      if (! cert_found && direntp->d_type == DT_REG
> +      if (! cert_found && S_ISREG(tmpstat.st_mode)
>  	  && strcmp (direntp->d_name, MOK_PUBLIC_CERT_NAME) == 0)
>          {
>  	  cert_found = true;

Thanks for the problem report and the patch. I see what is going on
here, and the readdir(3) man page clearly states that:

====
Currently,  only  some  filesystems (among them: Btrfs, ext2, ext3, and
ext4) have full support for returning the file  type  in  d_type.   All
applications must properly handle a return of DT_UNKNOWN.
====

But, I'd like to avoid the stat() syscall when possible. So, I tweaked
your patch a bit. The following compiles, but I haven't tried it.

Let me know if it works for you and I'll check it in.

====
diff --git a/stap-serverd.cxx b/stap-serverd.cxx
index 40b3c39..98611c9 100644
--- a/stap-serverd.cxx
+++ b/stap-serverd.cxx
@@ -370,13 +370,28 @@ mok_dir_valid_p (string mok_fingerprint, bool verbose)
   struct dirent *direntp;
   while ((direntp = readdir (dirp)) != NULL)
     {
-      if (! priv_found && direntp->d_type == DT_REG
+      bool reg_file = false;
+
+      if (direntp->d_type == DT_REG)
+	reg_file = true;
+      else if (direntp->d_type == DT_UNKNOWN)
+        {
+	  struct stat tmpstat;
+
+	  // If the filesystem doesn't support d_type, we'll have to
+	  // call stat().
+	  stat((mok_dir + "/" + direntp->d_name).c_str (), &tmpstat);
+	  if (S_ISREG(tmpstat.st_mode))
+	      reg_file = true;
+        }
+
+      if (! priv_found && reg_file
 	  && strcmp (direntp->d_name, MOK_PRIVATE_CERT_NAME) == 0)
         {
 	  priv_found = true;
 	  continue;
 	}
-      if (! cert_found && direntp->d_type == DT_REG
+      if (! cert_found && reg_file
 	  && strcmp (direntp->d_name, MOK_PUBLIC_CERT_NAME) == 0)
         {
 	  cert_found = true;
====

-- 
David Smith
dsmith@redhat.com
Red Hat
http://www.redhat.com
256.217.0141 (direct)
256.837.0057 (fax)


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