Problem

Enviroment

  • linux version: 4.19.98
    • No SMAP
    • No KPTI

Features

This challenge provide simple device (it has only one function: mod_ioctl). And the function is like following:

struct request_t
{
    unsigned int size;
    char __padding0[4];
    void *data;
};

uint64_6 mod_ioctl(struct file *a1, unsigned int cmd, unsigned __int64 arg) {
  struct request_t req;

  if (copy_from_user(&req, arg, 0x10LL)) return -14LL;
  if (req.size > 0x80) return -22LL;
  mutex_lock(&_mutex);
  if (cmd == 0xC12ED002) {  // cmd == 0xC12ED002: delete_note
    if (!note) {
      goto ERROR;
    }
    kfree(note);
    note = 0LL;
  } else if (cmd == 0xC12ED001) {  // cmd == 0xC12ED001: alloc_new_note
    if (note) kfree(note);
    size = req.size;
    note = (char *)_kmalloc(req.size, 0x6080C0LL);
    if (!note) goto ERROR;
  } else if (cmd == 0xC12ED003) {  // cmd == 0xC12ED003: write_note
    if (!note || req.size > size || copy_from_user(note, req.data, req.size))
      goto ERROR;
    note[req.size] = 0;  // off-by-one if req.size==size
  } else if (cmd != 0xC12ED004 || !note || req.size > size ||
             copy_to_user(req.data, note,
                          req.size)) {  // cmd ==  0xC12ED004: read_note
    goto ERROR;
  }
  mutex_unlock(&_mutex);
  return 0LL;

ERROR:
  mutex_unlock(&_mutex);
  return -22;
}

Vulnerability

The vulnerability is obvious. The off-by-one in write_note.