New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
udev: readd format length parameter #6651
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would also be great to update udev-test.pl
.
src/udev/udev-event.c
Outdated
num = (int) strtoul(from, &tail, 10); | ||
if (num > 0) { | ||
log_debug("format length='%i'", num); | ||
from = strjoina("%", tail); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is it safe to call strjoina
inside this loop?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
stack allocation is never permissible in loops. strjoina() does stack allocation, hence no, it's not safe.
src/udev/udev-event.c
Outdated
if (num > 0) { | ||
log_debug("format length='%i'", num); | ||
from = strjoina("%", tail); | ||
l = num+1; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What happens to dest
if num+1
is greater than size
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
num+1 > size should be handeled by the backend function.
The function strpcpy (src/basic/strxcpyx.c) that is called from subst_format_var will only copy up to the length of the source string:
size_t strpcpy(char **dest, size_t size, const char *src) {
[...]
len = strlen(src);
if (len >= size) {
if (size > 1)
*dest = mempcpy(*dest, src, size-1);
size = 0;
} else {
if (len > 0) {
*dest = mempcpy(*dest, src, len);
size -= len;
}
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems that the length of src
might be greater than the length of dst
in this case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In other words, l
shows how many bytes can be written to dst
. If l
is increased and strlen(src)
is greater than the previous value of l
, then dst
might be overflowed.
legacy udev had an udev rule parameter "format length" that could determine the lenght of a string taken from sysfs attributes. This seems to have become lost during the transition to systemd-udev. Adding it back helps for backward compatibility and more userfriendly symlink names.
I've changed @@ -289,7 +289,7 @@ EOF
not_exp_name => "not" ,
rules => <<EOF
SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="-special-*", SYMLINK+="not"
-SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", SYMLINK+="%c-%n"
+SUBSYSTEMS=="scsi", PROGRAM=="/bin/echo -n special-device", RESULT=="special-*", SYMLINK+="%14c-%n"
EOF . I got the following:
. By the way, judging by a0ee5a0, it seems that |
Thanks for the investigation, I wasn't aware that the format length feature has been explicitely removed. Waiting for feedback about the reason before continuing. Concerning the dst overflow, shouldn't this rather be fixed in the strpcpy function, instead of taking care of this via the calling function? |
I'm not sure what
Only the caller knows that |
I see, thanks for elaboration. |
You're welcome. Actually, this PR has helped me to find #6664 and I'm a bit worried that bugs of that kind seem to be quite common in |
@kaysievers can you give some background about the reason for a0ee5a0 ? |
I don't remember any specific reasons about this one, just that we removed a whole bunch of magic string mangling; we did not want udev provide shell-like features. People asked for more of them, and we thought they should use a shell, if they need to do more complicated things. |
I think we should have less string mangling support in udev rules, not more. hence, let's not add this, I see little point in restoring something that was removed 8 years ago and nobody noticed or missed so far. Closing. I hope this makes sense. |
legacy udev had an udev rule parameter "format length" that could determine the
lenght of a string taken from sysfs attributes.
This seems to have become lost during the transition to systemd-udev.
Adding it back helps for backward compatibility and more userfriendly symlink names.