IAudioPolicyService: Add attribute tags sanitization

When audio_attributes_t was read from the binder parcel,
the string tags field was copied without checking that
it contained a '\0'.

This could lead to read past the end when tags were used.

This patch always adds a '\0' at the end of the buffer when
deserializing.

Bug: 68953950
Test: manual playback/record
Test: send binder payload without \0 in tags attribute, check that only
      AUDIO_ATTRIBUTES_TAGS_MAX_SIZE - 1 char are printed.
Change-Id: I285258cbf7cfaf26b191d1f31b3b1e2d724c4934
Merged-In: I285258cbf7cfaf26b191d1f31b3b1e2d724c4934
Signed-off-by: Kevin Rocard <krocard@google.com>
(cherry picked from commit ab4d9f873ae433d75fbd7bd9af0aa4f7c3bcd92c)
diff --git a/include/media/IAudioPolicyService.h b/include/media/IAudioPolicyService.h
index 0e9e3bc..de6e5ce 100644
--- a/include/media/IAudioPolicyService.h
+++ b/include/media/IAudioPolicyService.h
@@ -181,6 +181,8 @@
                                     const Parcel& data,
                                     Parcel* reply,
                                     uint32_t flags = 0);
+private:
+    void sanetizeAudioAttributes(audio_attributes_t* attr);
 };
 
 // ----------------------------------------------------------------------------
diff --git a/media/libmedia/IAudioPolicyService.cpp b/media/libmedia/IAudioPolicyService.cpp
index 6405d6d..294b8f6 100644
--- a/media/libmedia/IAudioPolicyService.cpp
+++ b/media/libmedia/IAudioPolicyService.cpp
@@ -893,6 +893,7 @@
             bool hasAttributes = data.readInt32() != 0;
             if (hasAttributes) {
                 data.read(&attr, sizeof(audio_attributes_t));
+                sanetizeAudioAttributes(&attr);
             }
             audio_session_t session = (audio_session_t)data.readInt32();
             audio_stream_type_t stream = AUDIO_STREAM_DEFAULT;
@@ -960,6 +961,7 @@
             CHECK_INTERFACE(IAudioPolicyService, data, reply);
             audio_attributes_t attr;
             data.read(&attr, sizeof(audio_attributes_t));
+            sanetizeAudioAttributes(&attr);
             audio_session_t session = (audio_session_t)data.readInt32();
             pid_t pid = (pid_t)data.readInt32();
             uid_t uid = (uid_t)data.readInt32();
@@ -1332,6 +1334,7 @@
             data.read(&source, sizeof(struct audio_port_config));
             audio_attributes_t attributes;
             data.read(&attributes, sizeof(audio_attributes_t));
+            sanetizeAudioAttributes(&attributes);
             audio_io_handle_t handle = {};
             status_t status = startAudioSource(&source, &attributes, &handle);
             reply->writeInt32(status);
@@ -1371,6 +1374,15 @@
     }
 }
 
+void BnAudioPolicyService::sanetizeAudioAttributes(audio_attributes_t* attr)
+{
+    const size_t tagsMaxSize = AUDIO_ATTRIBUTES_TAGS_MAX_SIZE;
+    if (strnlen(attr->tags, tagsMaxSize) >= tagsMaxSize) {
+        android_errorWriteLog(0x534e4554, "68953950"); // SafetyNet logging
+    }
+    attr->tags[tagsMaxSize - 1] = '\0';
+}
+
 // ----------------------------------------------------------------------------
 
 } // namespace android