0
// userspace
uint8_t value = 5;
write (fd, (const char *)&value, 1);

// kernel driver
static ssize_t sysfs_store(struct kobject *kobj, struct kobj_attribute *attr, const char *buf, size_t count)
{
    u8 val;
    sscanf(buf, "%hhu" , &val);
    // val should be 5 here but bizarrely its 255
    pr_info("sysfs_store %s %hhu", attr->attr.name, val); 
    ...
}

I checked that buf contains the value 5, so the issue is in driver only with sscanf. please help!

ruke
  • 55
  • 5
  • What is `sscanf` returning? If not 1, it's not setting `val` at all. – Steve Summit Feb 18 '22 at 19:11
  • You realize that 5 is not the same as `'5'`, right? – Steve Summit Feb 18 '22 at 19:12
  • You're writing a "binary" 5, a byte with the value `0x05`. But `sscanf` wants *text*, that is, ASCII digits `'0'` - `'9'`, i.e. `0x30` - `0x39`. – Steve Summit Feb 18 '22 at 19:13
  • its 5. I basically want two values 0 or 1 btw. – ruke Feb 18 '22 at 19:15
  • So replace `sscanf(buf, "%hhu" , &val);` with `val = *buf;`. – Steve Summit Feb 18 '22 at 19:15
  • Thanks a ton @SteveSummit. I was scratching my head with this sscanf. Btw is it safe to directly read from user space buf, or should I copy the buf to kernel first and then derefernce. – ruke Feb 18 '22 at 19:22
  • Not sure, it's been a while since I've done that sort of thing. I suspect you should have a "copy from user" step in there somewhere. – Steve Summit Feb 18 '22 at 19:24
  • Method `.store` of `struct kobj_attribute` type works with **kernel buffer**. You may find out that by looking into the [method's signature](https://elixir.bootlin.com/linux/v5.16.10/source/include/linux/kobject.h#L166): there is no `__user` specifier before `buf` – Tsyvarev Feb 18 '22 at 23:42

0 Answers0