Code Monkey home page Code Monkey logo

Comments (3)

bas-t avatar bas-t commented on August 17, 2024

I'm on dvb-c, can't reproduce this.
If you can produce a patch that addresses this issue, please do so by doing a PR

from dvbloopback.

HSchill avatar HSchill commented on August 17, 2024

Trying to fix the root cause is a quite big challenge, but to ensure that parg always is big enough for a linear copy is quite easy.
(and we also get rid of a memory in the kernel the "tvp = (struct dtv_property *) kmalloc(tvps->num *"
there is no free for that kmalloc ...)

Here is a simple patch that I am using and it seems to work pretty well,

@@ -127,6 +127,7 @@ static int dvblb_usercopy(struct file *file,
        void    *mbuf = NULL;
        void    *parg = NULL;
        int     err  = -EINVAL;
+       int     msize = 0;
        struct  dtv_properties *tvps = NULL;
        struct  dtv_property *tvp = NULL;

@@ -142,14 +143,27 @@ static int dvblb_usercopy(struct file *file,
        case _IOC_READ: /* some v4l ioctls are marked wrong ... */
        case _IOC_WRITE:
        case (_IOC_WRITE | _IOC_READ):
-               if (_IOC_SIZE(cmd) <= sizeof(sbuf)) {
-                       parg = sbuf;
-               } else {
-                       /* too big to allocate from stack */
-                       mbuf = kmalloc(_IOC_SIZE(cmd),GFP_KERNEL);
-                       if (NULL == mbuf)
-                               return -ENOMEM;
-                       parg = mbuf;
+
+               /*
+                * Since most part of the code assume that "parg" is a contious pice of
+                * memory when FE_SET_PROPERTY / FE_GET_PROPERTY is used
+                * It doesn't work with tvps->props attached as a pointer
+                * it will be over written and recalculated as an offset to parg (tvps)
+                * This is not a nice fix but it works  /H.Schillstrom
+                */
+               msize = _IOC_SIZE(cmd);
+
+               if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) {                                                                                                                                                                      
+                       tvps = (struct dtv_properties __user *)arg;                                                                                                                                                                              
+                       msize += tvps->num * sizeof(struct dtv_property);                                                                                                                                                                        
+               }                                                                                                                                                                                                                                
+               if (msize < sizeof(sbuf))                                                                                                                                                                                                        
+                   parg = sbuf;                                                                                                                                                                                                                 
+               else {                                                                                                                                                                                                                           
+                   mbuf = kmalloc(msize,  GFP_KERNEL);                                                                                                                                                                                          
+                   if (NULL == mbuf)                                                                                                                                                                                                            
+                       return -ENOMEM;                                                                                                                                                                                                          
+                   parg = mbuf;                                                                                                                                                                                                                 
                }                                                                                                                                                                                                                                

                err = -EFAULT;                                                                                                                                                                                                                   
@@ -157,12 +171,9 @@ static int dvblb_usercopy(struct file *file,                                                                                                                                                                                
                        goto out;                                                                                                                                                                                                                
                if ((cmd == FE_SET_PROPERTY) || (cmd == FE_GET_PROPERTY)) {                                                                                                                                                                      
                    tvps = (struct dtv_properties __user *)arg;                                                                                                                                                                                  
-                   tvp = (struct dtv_property *) kmalloc(tvps->num *                                                                                                                                                                            
-                       sizeof(struct dtv_property), GFP_KERNEL);                                                                                                                                                                                
-                   if (!tvp){                                                                                                                                                                                                                   
-                       err = -ENOMEM;                                                                                                                                                                                                           
-                       goto out;                                                                                                                                                                                                                
-                   }                                                                                                                                                                                                                            
+                                                                                                                                                                                                                                                
+                   tvp = (struct dtv_property *) (parg + _IOC_SIZE(cmd));                                                                                                                                                                       
+                                                                                                                                                                                                                                                
                    if (copy_from_user(tvp, tvps->props,                                                                                                                                                                                         
                        (tvps->num) * sizeof(struct dtv_property))) {                                                                                                                                                                            
                        err = -EFAULT;                                                                                                                                                                                                           


from dvbloopback.

bas-t avatar bas-t commented on August 17, 2024

Nevertheless, can you please do a PR?

from dvbloopback.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.