<div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, Aug 31, 2022 at 3:27 AM Rob Landley <<a href="mailto:rob@landley.net">rob@landley.net</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">On 8/30/22 10:31, Weizhao Ouyang wrote:<br>
> When getfattx reading overlayfs merged dirs, listxattr will got<br>
> different keys_len with zero size and determined size, then it will<br>
> stuck in this while scope. Update the keys_len after the second<br>
> listxattr to fix it.<br>
<br>
Do you have a test case I can use to reproduce this? (I've never used xattrs<br>
together with overlayfs before.)<br>
<br>
Also, I believe Elliott has a different implementation of getfattr in android<br>
(for some sort of C++ library reasons, I'd have to check my notes), so he'll<br>
probably want the test case there too?<br></blockquote><div><br></div><div>no, i sent you this implementation :-)</div><div><br></div><div>i think you're thinking of modprobe, which is parallelized and used as a library inside init directly?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
> Signed-off-by: Weizhao Ouyang <<a href="mailto:o451686892@gmail.com" target="_blank">o451686892@gmail.com</a>><br>
> ---<br>
> toys/pending/getfattr.c | 19 +++++++++++++------<br>
> 1 file changed, 13 insertions(+), 6 deletions(-)<br>
> <br>
> diff --git a/toys/pending/getfattr.c b/toys/pending/getfattr.c<br>
> index bf2c04c8..aa2c3958 100644<br>
> --- a/toys/pending/getfattr.c<br>
> +++ b/toys/pending/getfattr.c<br>
> @@ -43,15 +43,22 @@ static void do_getfattr(char *file)<br>
> }<br>
> <br>
> // Collect the keys.<br>
> - while ((keys_len = lister(file, NULL, 0))) {<br>
> - if (keys_len == -1) perror_msg("listxattr failed");<br>
> - keys = xmalloc(keys_len);<br>
> - if (lister(file, keys, keys_len) == keys_len) break;<br>
> + keys_len = lister(file, NULL, 0);<br>
> + if (keys_len < 0)<br>
> + perror_exit("listxattr failed");<br>
> + else if (keys_len == 0)<br>
> + return;<br>
> +<br>
> + keys = xmalloc(keys_len);<br>
> + keys_len = lister(file, keys, keys_len);<br>
> + if (keys_len < 0) {<br>
> free(keys);<br>
> + perror_exit("listxattr failed");<br>
> + } else if (keys_len == 0) {<br>
> + free(keys);<br>
> + return;<br>
> }<br>
> <br>
> - if (keys_len == 0) return;<br>
> -<br>
> // Sort the keys.<br>
> for (key = keys, key_count = 0; key-keys < keys_len; key += strlen(key)+1)<br>
> key_count++;<br>
<br>
Ok, in THEORY the reason for the original loop is that the size could change out<br>
from under us if the filesystem is modified while we're reading it. You're<br>
saying it loops endlessly, because "listxattr will got different keys_len with<br>
zero size and determined size".<br>
<br>
Your new unrolled version just _sets_ keys_len to whatever the second one<br>
returns. So on overlayfs, listxattr(file, NULL, 0) and listattr(file, keys, len)<br>
return different values for the same file.<br>
<br>
This sounds like a bug in overlayfs you're working around, but if we have to do<br>
that to work with deployed reality fine. The problem is, if the new keys_len is<br>
LONGER than the previous one, then we didn't malloc() enough space for it, and<br>
"sort the keys" below will fall off the end of the buffer.<br></blockquote><div><br></div><div><a class="gmail_plusreply" id="plusReplyChip-0" href="mailto:dvander@google.com" tabindex="-1">+David Anderson</a> --- are you aware of this behavior? (sounds like a bug to me too, but you know more about fs stuff than i do...)<br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
I'd really like a test case so I can see this in action...<br>
<br>
Thanks,<br>
<br>
Rob<br>
_______________________________________________<br>
Toybox mailing list<br>
<a href="mailto:Toybox@lists.landley.net" target="_blank">Toybox@lists.landley.net</a><br>
<a href="http://lists.landley.net/listinfo.cgi/toybox-landley.net" rel="noreferrer" target="_blank">http://lists.landley.net/listinfo.cgi/toybox-landley.net</a><br>
</blockquote></div></div>