All of lore.kernel.org
 help / color / mirror / Atom feed
* [bug report] chardev: code cleanup for __register_chrdev_region()
@ 2019-04-04 19:08 Dan Carpenter
  2019-04-04 23:13 ` cgxu519
  0 siblings, 1 reply; 4+ messages in thread
From: Dan Carpenter @ 2019-04-04 19:08 UTC (permalink / raw)
  To: cgxu519; +Cc: linux-fsdevel

Hello Chengguang Xu,

The patch 4b0be5726032: "chardev: code cleanup for
__register_chrdev_region()" from Feb 15, 2019, leads to the following
static checker warning:

	fs/char_dev.c:167 __register_chrdev_region()
	error: passing non negative 511 to ERR_PTR

fs/char_dev.c
    96  static struct char_device_struct *
    97  __register_chrdev_region(unsigned int major, unsigned int baseminor,
    98                             int minorct, const char *name)
    99  {
   100          struct char_device_struct *cd, *curr, *prev = NULL;
   101          int ret = -EBUSY;
   102          int i;
   103  
   104          if (major >= CHRDEV_MAJOR_MAX) {
   105                  pr_err("CHRDEV \"%s\" major requested (%u) is greater than the maximum (%u)\n",
   106                         name, major, CHRDEV_MAJOR_MAX-1);
   107                  return ERR_PTR(-EINVAL);
   108          }
   109  
   110          if (minorct > MINORMASK + 1 - baseminor) {
   111                  pr_err("CHRDEV \"%s\" minor range requested (%u-%u) is out of range of maximum range (%u-%u) for a single major\n",
   112                          name, baseminor, baseminor + minorct - 1, 0, MINORMASK);
   113                  return ERR_PTR(-EINVAL);
   114          }
   115  
   116          cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
   117          if (cd == NULL)
   118                  return ERR_PTR(-ENOMEM);
   119  
   120          mutex_lock(&chrdevs_lock);
   121  
   122          if (major == 0) {
   123                  ret = find_dynamic_major();
   124                  if (ret < 0) {
   125                          pr_err("CHRDEV \"%s\" dynamic allocation region is full\n",
   126                                 name);
   127                          goto out;
   128                  }
   129                  major = ret;
                        ^^^^^^^^^^^
"ret" is a major here.

   130          }
   131  
   132          i = major_to_index(major);
   133          for (curr = chrdevs[i]; curr; prev = curr, curr = curr->next) {
   134                  if (curr->major < major)
   135                          continue;
   136  
   137                  if (curr->major > major)
   138                          break;
   139  
   140                  if (curr->baseminor + curr->minorct <= baseminor)
   141                          continue;
   142  
   143                  if (curr->baseminor >= baseminor + minorct)
   144                          break;
   145  
   146                  goto out;

I don't completely understand how this loop works, but I guess we should
set "ret = -EBUSY;" before the goto out.

   147          }
   148  
   149          cd->major = major;
   150          cd->baseminor = baseminor;
   151          cd->minorct = minorct;
   152          strlcpy(cd->name, name, sizeof(cd->name));
   153  
   154          if (!prev) {
   155                  cd->next = curr;
   156                  chrdevs[i] = cd;
   157          } else {
   158                  cd->next = prev->next;
   159                  prev->next = cd;
   160          }
   161  
   162          mutex_unlock(&chrdevs_lock);
   163          return cd;
   164  out:
   165          mutex_unlock(&chrdevs_lock);
   166          kfree(cd);
   167          return ERR_PTR(ret);
                               ^^^
Otherwise it leads to an Oops in the caller.

   168  }

regards,
dan carpenter

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [bug report] chardev: code cleanup for __register_chrdev_region()
  2019-04-04 19:08 [bug report] chardev: code cleanup for __register_chrdev_region() Dan Carpenter
@ 2019-04-04 23:13 ` cgxu519
  2019-04-05  4:57   ` Dan Carpenter
  0 siblings, 1 reply; 4+ messages in thread
From: cgxu519 @ 2019-04-04 23:13 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-fsdevel

On 4/5/19 3:08 AM, Dan Carpenter wrote:
> Hello Chengguang Xu,
>
> The patch 4b0be5726032: "chardev: code cleanup for
> __register_chrdev_region()" from Feb 15, 2019, leads to the following
> static checker warning:
>
> 	fs/char_dev.c:167 __register_chrdev_region()
> 	error: passing non negative 511 to ERR_PTR

Hi Dan,

Thanks for your report,  I would like to know how did you trigger this?
IIUC, in the case of allocating dynamic major will not fail from minor
overlap check.

Thanks,
Chengguang.

>
> fs/char_dev.c
>      96  static struct char_device_struct *
>      97  __register_chrdev_region(unsigned int major, unsigned int baseminor,
>      98                             int minorct, const char *name)
>      99  {
>     100          struct char_device_struct *cd, *curr, *prev = NULL;
>     101          int ret = -EBUSY;
>     102          int i;
>     103
>     104          if (major >= CHRDEV_MAJOR_MAX) {
>     105                  pr_err("CHRDEV \"%s\" major requested (%u) is greater than the maximum (%u)\n",
>     106                         name, major, CHRDEV_MAJOR_MAX-1);
>     107                  return ERR_PTR(-EINVAL);
>     108          }
>     109
>     110          if (minorct > MINORMASK + 1 - baseminor) {
>     111                  pr_err("CHRDEV \"%s\" minor range requested (%u-%u) is out of range of maximum range (%u-%u) for a single major\n",
>     112                          name, baseminor, baseminor + minorct - 1, 0, MINORMASK);
>     113                  return ERR_PTR(-EINVAL);
>     114          }
>     115
>     116          cd = kzalloc(sizeof(struct char_device_struct), GFP_KERNEL);
>     117          if (cd == NULL)
>     118                  return ERR_PTR(-ENOMEM);
>     119
>     120          mutex_lock(&chrdevs_lock);
>     121
>     122          if (major == 0) {
>     123                  ret = find_dynamic_major();
>     124                  if (ret < 0) {
>     125                          pr_err("CHRDEV \"%s\" dynamic allocation region is full\n",
>     126                                 name);
>     127                          goto out;
>     128                  }
>     129                  major = ret;
>                          ^^^^^^^^^^^
> "ret" is a major here.
>
>     130          }
>     131
>     132          i = major_to_index(major);
>     133          for (curr = chrdevs[i]; curr; prev = curr, curr = curr->next) {
>     134                  if (curr->major < major)
>     135                          continue;
>     136
>     137                  if (curr->major > major)
>     138                          break;
>     139
>     140                  if (curr->baseminor + curr->minorct <= baseminor)
>     141                          continue;
>     142
>     143                  if (curr->baseminor >= baseminor + minorct)
>     144                          break;
>     145
>     146                  goto out;
>
> I don't completely understand how this loop works, but I guess we should
> set "ret = -EBUSY;" before the goto out.
>
>     147          }
>     148
>     149          cd->major = major;
>     150          cd->baseminor = baseminor;
>     151          cd->minorct = minorct;
>     152          strlcpy(cd->name, name, sizeof(cd->name));
>     153
>     154          if (!prev) {
>     155                  cd->next = curr;
>     156                  chrdevs[i] = cd;
>     157          } else {
>     158                  cd->next = prev->next;
>     159                  prev->next = cd;
>     160          }
>     161
>     162          mutex_unlock(&chrdevs_lock);
>     163          return cd;
>     164  out:
>     165          mutex_unlock(&chrdevs_lock);
>     166          kfree(cd);
>     167          return ERR_PTR(ret);
>                                 ^^^
> Otherwise it leads to an Oops in the caller.
>
>     168  }
>
> regards,
> dan carpenter


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [bug report] chardev: code cleanup for __register_chrdev_region()
  2019-04-04 23:13 ` cgxu519
@ 2019-04-05  4:57   ` Dan Carpenter
  2019-04-05 11:32     ` cgxu519
  0 siblings, 1 reply; 4+ messages in thread
From: Dan Carpenter @ 2019-04-05  4:57 UTC (permalink / raw)
  To: cgxu519; +Cc: linux-fsdevel

On Fri, Apr 05, 2019 at 07:13:00AM +0800, cgxu519 wrote:
> On 4/5/19 3:08 AM, Dan Carpenter wrote:
> > Hello Chengguang Xu,
> > 
> > The patch 4b0be5726032: "chardev: code cleanup for
> > __register_chrdev_region()" from Feb 15, 2019, leads to the following
> > static checker warning:
> > 
> > 	fs/char_dev.c:167 __register_chrdev_region()
> > 	error: passing non negative 511 to ERR_PTR
> 
> Hi Dan,
> 
> Thanks for your report,  I would like to know how did you trigger this?

This a Smatch warning but you probably need to have the cross function
DB built to see it.

> IIUC, in the case of allocating dynamic major will not fail from minor
> overlap check.

Fine, but it's harmless to set "ret = -EBUSY;" before the goto out just
to silence the warning.  It would make the code more easy to understand
as well.

regards,
dan carpenter


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [bug report] chardev: code cleanup for __register_chrdev_region()
  2019-04-05  4:57   ` Dan Carpenter
@ 2019-04-05 11:32     ` cgxu519
  0 siblings, 0 replies; 4+ messages in thread
From: cgxu519 @ 2019-04-05 11:32 UTC (permalink / raw)
  To: Dan Carpenter; +Cc: linux-fsdevel

On 4/5/19 12:57 PM, Dan Carpenter wrote:
> On Fri, Apr 05, 2019 at 07:13:00AM +0800, cgxu519 wrote:
>> On 4/5/19 3:08 AM, Dan Carpenter wrote:
>>> Hello Chengguang Xu,
>>>
>>> The patch 4b0be5726032: "chardev: code cleanup for
>>> __register_chrdev_region()" from Feb 15, 2019, leads to the following
>>> static checker warning:
>>>
>>> 	fs/char_dev.c:167 __register_chrdev_region()
>>> 	error: passing non negative 511 to ERR_PTR
>> Hi Dan,
>>
>> Thanks for your report,  I would like to know how did you trigger this?
> This a Smatch warning but you probably need to have the cross function
> DB built to see it.
>
>> IIUC, in the case of allocating dynamic major will not fail from minor
>> overlap check.
> Fine, but it's harmless to set "ret = -EBUSY;" before the goto out just
> to silence the warning.  It would make the code more easy to understand
> as well.
Yes, that's better. I'll send v3 version.


Thanks,
Chengguang.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-04-05 11:32 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-04-04 19:08 [bug report] chardev: code cleanup for __register_chrdev_region() Dan Carpenter
2019-04-04 23:13 ` cgxu519
2019-04-05  4:57   ` Dan Carpenter
2019-04-05 11:32     ` cgxu519

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.