Bug 486428

Summary: ioctl(I2C_RDWR) incorrectly checks padding bytes
Product: [Developer tools] valgrind Reporter: alex
Component: generalAssignee: Julian Seward <jseward>
Status: REPORTED ---    
Severity: normal CC: pjfloyd
Priority: NOR    
Version First Reported In: unspecified   
Target Milestone: ---   
Platform: Other   
OS: Linux   
Latest Commit: Version Fixed/Implemented In:
Sentry Crash Report:

Description alex 2024-05-02 04:02:50 UTC
SUMMARY

This mostly looks like a duplicate of 479842, but I'm suggesting a slightly different patch below.

ioctl(I2C_RDWR) complains on 64 bit machines about uninitialized padding bytes.

STEPS TO REPRODUCE
1. Send an I2C_RDWR ioctl after setting `addr`, `flags`, `len`, and `buf` but not any padding bytes.

OBSERVED RESULT

```
==31112== Syscall param ioctl(I2C_RDWR).msgs points to uninitialised byte(s)
==31112==    at 0x49690E4: ioctl (ioctl.c:36)
==31112==    by 0x108FB: test_register_address_space_size (hw_test.c:187)
==31112==    by 0x10BBB: run_tests (hw_test.c:323)
==31112==    by 0x10C67: i2c_test (main.c:33)
==31112==    by 0x10CA7: main (main.c:44)
==31112==  Address 0x7d9562ce is on thread 1's stack
==31112==  in frame #1, created by test_register_address_space_size (hw_test.c:165)
```

EXPECTED RESULT

No error message.

SOFTWARE/OS VERSIONS
Raspbian 12

ADDITIONAL INFORMATION

I would suggest the following patch to fix this issue. I haven't contributed to Valgrind before, and I am not familiar with how such contributions work. I apologize if I missed anything (if so please let me know and I will fix it).

```
diff --git a/coregrind/m_syswrap/syswrap-linux.c b/coregrind/m_syswrap/syswrap-linux.c
index 45413fdd9..cdf2d152f 100644
--- a/coregrind/m_syswrap/syswrap-linux.c
+++ b/coregrind/m_syswrap/syswrap-linux.c
@@ -8574,11 +8574,14 @@ PRE(sys_ioctl)
           PRE_MEM_READ("ioctl(I2C_RDWR)", (Addr)vkui, sizeof(struct vki_i2c_rdwr_ioctl_data));
           for (i=0; i < vkui->nmsgs; i++) {
               struct vki_i2c_msg *msg = vkui->msgs + i;
-              PRE_MEM_READ("ioctl(I2C_RDWR).msgs", (Addr)msg, sizeof(struct vki_i2c_msg));
-              if (msg->flags & VKI_I2C_M_RD) 
-                  PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
+              PRE_MEM_READ("ioctl(I2C_RDWR).msgs[].addr", (Addr)&msg->addr, sizeof(msg->addr));
+              PRE_MEM_READ("ioctl(I2C_RDWR).msgs[].flags", (Addr)&msg->flags, sizeof(msg->flags));
+              PRE_MEM_READ("ioctl(I2C_RDWR).msgs[].len", (Addr)&msg->len, sizeof(msg->len));
+              PRE_MEM_READ("ioctl(I2C_RDWR).msgs[].buf", (Addr)&msg->buf, sizeof(msg->buf));
+              if (msg->flags & VKI_I2C_M_RD)
+                  PRE_MEM_WRITE("ioctl(I2C_RDWR).msgs[].buf[]", (Addr)msg->buf, msg->len);
               else
-                  PRE_MEM_READ("ioctl(I2C_RDWR).msgs.buf", (Addr)msg->buf, msg->len);
+                  PRE_MEM_READ("ioctl(I2C_RDWR).msgs[].buf[]", (Addr)msg->buf, msg->len);
           }
       }
       break;
```