> > > On 7 Mar 2018, at 07:53, Frediano Ziglio <fziglio@xxxxxxxxxx> wrote: > > > >>> > >>> On 3 Mar 2018, at 10:36, Frediano Ziglio <fziglio@xxxxxxxxxx> wrote: > >>> > >>>>> > >>>>> On 28 Feb 2018, at 13:53, Lukáš Hrázký <lhrazky@xxxxxxxxxx> wrote: > >>>>> > >>>>> Log error messages from the server to syslog (not aborting the agent). > >>>>> Limits the messages to 1023 bytes, error messages from the server are > >>>>> not expected to be longer. In the unlikely case the message is longer, > >>>>> log the first 1023 bytes and throw an exception (because we don't read > >>>>> out the rest of the message, causing desynchronization between the > >>>>> server and the streaming agent). > >>>>> > >>>>> Signed-off-by: Lukáš Hrázký <lhrazky@xxxxxxxxxx> > >>>>> --- > >>>>> src/spice-streaming-agent.cpp | 26 +++++++++++++++++++++++--- > >>>>> 1 file changed, 23 insertions(+), 3 deletions(-) > >>>>> > >>>>> diff --git a/src/spice-streaming-agent.cpp > >>>>> b/src/spice-streaming-agent.cpp > >>>>> index ee57920..954d1b3 100644 > >>>>> --- a/src/spice-streaming-agent.cpp > >>>>> +++ b/src/spice-streaming-agent.cpp > >>>>> @@ -137,10 +137,30 @@ static void handle_stream_capabilities(uint32_t > >>>>> len) > >>>>> } > >>>>> } > >>>>> > >>>>> -static void handle_stream_error(uint32_t len) > >>>>> +static void handle_stream_error(size_t len) > >>>>> { > >>>>> - // TODO read message and use it > >>>>> - throw std::runtime_error("got an error message from server"); > >>>>> + if (len < sizeof(StreamMsgNotifyError)) { > >>>>> + throw std::runtime_error("Received NotifyError message size " > >>>>> + > >>>>> std::to_string(len) + > >>>>> + " is too small (smaller than " + > >>>>> + > >>>>> std::to_string(sizeof(StreamMsgNotifyError)) > >>>>> + ")"); > >>>>> + } > >>>>> + > >>>>> + struct : StreamMsgNotifyError { > >>>> > >>>> :-O > >>>> > >>>> I had t read that twice to make sure that was actually what was written… > >>>> Barf. > >>>> > >>>> > >>>>> + uint8_t msg[1024]; > >>>> > >>>> Hard-coded magic value. There should be a constant for it in > >>>> stream-device.h. > >>>> Please add it. > >>>> > >>> > >>> Currently the protocol does not define a limit, this is a guest limit but > >>> probably a safe and reasonable limit for the protocol can be decided. > >> > >> Problem with this approach is that the guest cannot read anything past any > >> error message that is too large for it. One could > >> - define a protocol limit (the simplest) > >> - skip the extra bytes > >> - allocate a modest amount for the common case, and dynamically allocate > >> otherwise > >> - use dynamic storage in all cases > >> > >> I don’t care either way, but killing the agent if the server sends an > >> error > >> that is too large opens a denial of service window. > >> > > > > Yes, can be done (I'd suggest skipping the rest). > > Currently errors are fatal. > > > >>> > >>>>> + } msg; > >>>> > >>>> So I was aggravated very recently regarding padding (having to > >>>> initialize > >>>> it…), but this patch gets nary a peep and the series is acked and merged > >>>> right away? > >>>> > >>> > >>> Perhaps you lost the mails saying that the protocol structure don't and > >>> won't have internal padding. > >> > >> Only on x86. It has padding on any ABI with a natural 64-bit alignment. > >> > >> I don’t have an Itanium handy, but computing the offsetof(msg.msg) and > >> offsetof(msg.StreamNotifyError::msg) on a Raspberry Pi using > >> -mstructure-size-boundary=64 yields: > >> > >> offsetof msg.msg=8 > >> offsetof msg.StreamNotifyError::msg=4 > >> > > > > Some compiler flag are used to break the ABI > > I used the compiler flag only to illustrate that relying on the absence of > padding was not portable. > > Did you really miss that my point was: “not portable” and not “hey, let’s use > mysterious flags for the sake of it"? > Yes, also assuming uint8_t is not strictly portable. Currently there's no real ABI that breaks either thing. > > and should be used in specific cases like some optimized code or writing a > > language library > > if the language for some reason requires a different ABI, you won't > > be able to call libc function safely if you use such options and as > > you want to break the ABI you'll get an ABI breakage. > > Is a lecture on ABI breaking flags entirely necessary here? > > I used one to prove that the code is ABI-dependent, therefore not portable. > > > > > My suggestion on overriding the field was not intended. > > > >> > >>>> When you inherit, the derived members are aligned, and there is > >>>> potential > >>>> padding. However, the code as merged relies on msg.msg being identical > >>>> to > >>>> msg.StreamMsgNotifyError::msg. In other words, this code implicitly > >>>> relies > >>>> on the lack of any padding. Add for example a ‘char c’ or ‘bool b’ after > >>>> error_code in StreamMsgNotifyError, and suddenly, > >>> > >>> Adding bool or char to StreamMsgNotifyError or a internal padding is > >>> a bug writing protocol (as already discussed) and also being an ABI now > >>> we can't change it so there isn't and there won't be any such field. > >> > >> I was using that as an illustration of the problem. > >> > >>> > >>>> msg.StreamMsgNotifyError::msg is at offset 5 while msg.msg is at offset > >>>> 8 > >>>> on > >>>> my machine, and all your messages will “mysteriously” be off by three > >>>> bytes. > >>>> > >>> > >>> Yes, if you don't know how to write a protocol structure, ignore the ABI > >>> and ignore the notes on the protocol file describing it you have this > >>> problem. > >> > >> Why not just use the “packed” attribute? > >> > > > > Already replied. > > I remember only one response from you, which was "Try to see why ip protocol > take into account alignment.” (2018-02-22). That left me to guess what you > meant, since there was no link or explanation. I’m also puzzled by this > response, since I’m pretty sure the IP protocol was invented long before the > “packed” attribute. > No, there are another reply on this ML, don't remember the email. > If you imply that packed is generally not used in network protocol, I believe > this is false, or at least that the Linux kernel did not get the memo. For > instance: > > /* common bits */ > struct ceph_x_ticket_blob { > __u8 struct_v; > __le64 secret_id; > __le32 blob_len; > char blob[]; > } __attribute__ ((packed)); > > Now, that structure definition I understand quite well. It’s packed, and it > specifies that the data is little endian. > > So would you please be kind enough to elaborate why you believe there should > be no packed attribute in the SPICE protocol, or refer me to the message > where there is such an explanation (I obviously missed it, and I searched)? > > > > > > >>> > >>>> Please fix it. > >>>> > >>> > >>> Fix what ? > >> > >> The non-portable, hard to read code that was introduced by this patch. > >> > >> For example, use the original msg field, not the derived object’s msg > >> field. > >> If you do that, gcc warns about an out-of-bounds access because the size > >> is > >> 0, so you may need to go through an intermediate pointer. > >> > > > > Yes, override was not intended. > > Unnamed structure are quite common, really used daily but a name won't > > surely hurt. > > Anonymous structs are a relatively frequent way of doing things in C, yes. > But not in C++. > > And here, it’s not just anonymous, it’s an anonymous derived struct. > Honestly, that’s the first time I see that. Can you show me another example? > As I said not against adding a name if is more readable for you. Do you have any suggestion? > > > > >>> > >>>>> + > >>>>> + size_t len_to_read = std::min(len, sizeof(msg) - 1); > >>>>> + > >>>>> + read_all(&msg, len_to_read); > >>>>> + msg.msg[len_to_read - sizeof(StreamMsgNotifyError)] = '\0'; > >>>>> + > >>>>> + syslog(LOG_ERR, "Received NotifyError message from the server: %d > >>>>> - > >>>>> %s\n", > >>>>> + msg.error_code, msg.msg); > >>>>> + > >>>>> + if (len_to_read < len) { > >>>>> + throw std::runtime_error("Received NotifyError message size " > >>>>> + > >>>>> std::to_string(len) + > >>>>> + " is too big (bigger than " + > >>>>> std::to_string(sizeof(msg)) + ")"); > >>>>> + } > >>>>> } > >>>>> > >>>>> static void read_command_from_device(void) > >>> > > Frediano _______________________________________________ Spice-devel mailing list Spice-devel@xxxxxxxxxxxxxxxxxxxxx https://lists.freedesktop.org/mailman/listinfo/spice-devel