diff --git a/drivers/staging/hilog/hilog.c b/drivers/staging/hilog/hilog.c index 178dcb6dd5b1b4553226ac6e3e0223db90dee53d..15b5cd545384334f4c81a67a7c6c568bc53596c6 100644 --- a/drivers/staging/hilog/hilog.c +++ b/drivers/staging/hilog/hilog.c @@ -85,24 +85,28 @@ static inline unsigned char *hilog_buffer_head(void) return hilog_dev.buffer + hilog_dev.hdr_off; } -static void hilog_buffer_inc(size_t sz) +static int hilog_buffer_inc(size_t sz) { if (hilog_dev.size + sz <= HILOG_BUFFER) { hilog_dev.size += sz; hilog_dev.wr_off += sz; hilog_dev.wr_off %= HILOG_BUFFER; hilog_dev.count++; + return 0; } + return -1; } -static void hilog_buffer_dec(size_t sz) +static int hilog_buffer_dec(size_t sz) { if (hilog_dev.size >= sz) { hilog_dev.size -= sz; hilog_dev.hdr_off += sz; hilog_dev.hdr_off %= HILOG_BUFFER; hilog_dev.count--; + return 0; } + return -1; } static int hilog_read_ring_buff(unsigned char __user *buffer, size_t buf_len) @@ -172,7 +176,11 @@ static ssize_t hilog_read(struct file *file, goto out; } - hilog_buffer_dec(sizeof(header)); + if (hilog_buffer_dec(sizeof(header))) { + retval = -EINVAL; + goto out; + } + retval = copy_to_user((unsigned char *)user_buf, (unsigned char *)&header, min(count, sizeof(header))); @@ -190,7 +198,11 @@ static ssize_t hilog_read(struct file *file, goto out; } - hilog_buffer_dec(header.len); + if (hilog_buffer_dec(header.len)) { + retval = -EINVAL; + goto out; + } + retval = header.len + sizeof(header); out: if (retval == -ENOMEM) { @@ -288,7 +300,8 @@ static void hilog_cover_old_log(size_t buf_len) drop_log_lines++; is_this_time_full = true; is_last_time_full = true; - hilog_buffer_dec(sizeof(header) + header.len); + if (hilog_buffer_dec(sizeof(header) + header.len)) + return; } if (is_last_time_full && !is_this_time_full) { /* so we can only print one log if hilog ring buffer is full in a short time */ @@ -315,7 +328,11 @@ int hilog_write_internal(const char __user *buffer, size_t buf_len) retval = -ENODATA; goto out; } - hilog_buffer_inc(sizeof(header)); + + if (hilog_buffer_inc(sizeof(header))) { + retval = -EINVAL; + goto out; + } retval = hilog_write_ring_buffer((unsigned char *)(buffer), header.len); if (retval) { @@ -323,7 +340,10 @@ int hilog_write_internal(const char __user *buffer, size_t buf_len) goto out; } - hilog_buffer_inc(header.len); + if (hilog_buffer_inc(header.len)) { + retval = -EINVAL; + goto out; + } retval = header.len;