Sie sind nicht angemeldet.

Lieber Besucher, herzlich willkommen bei: VDR Portal. Falls dies Ihr erster Besuch auf dieser Seite ist, lesen Sie sich bitte die Hilfe durch. Dort wird Ihnen die Bedienung dieser Seite näher erläutert. Darüber hinaus sollten Sie sich registrieren, um alle Funktionen dieser Seite nutzen zu können. Benutzen Sie das Registrierungsformular, um sich zu registrieren oder informieren Sie sich ausführlich über den Registrierungsvorgang. Falls Sie sich bereits zu einem früheren Zeitpunkt registriert haben, können Sie sich hier anmelden.

1

Sonntag, 20. Juni 2010, 01:32

RemoveFileOrDir in tools.c

Hello,
First of all, excuse me for posting in English, but I've not seen nothing related to patches in international forums. Feel free to reply in German.

In tools.c, when removing a file that is a symlink, the buffer size allocated for the target file path is twice the size of the link path. Under certain circumstances the supposition this is enough is wrong.

In countries like mine (allow me to omit which one it is...) there are many TV stations which have serious problems with the quality of the EPG they provide. In particular, they don't seem to understand the difference between the "short description" and "description" fields and are prone to fill the first one with the second one. If you are recording a series episode you may end with a filename which contains as much of the description as possible. When you change the name of the recording for a more reasonable one, the problem is served.

I think that a call to stat, should be done instead. This patch is for an old vdr, but I think with minor changes it still applies:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
--- VDR-ori/tools.c     2010-06-20 00:37:37.000000000 +0200
+++ VDR-bui/tools.c     2010-06-20 01:01:18.000000000 +0200
@@ -374,22 +374,29 @@
                     char *buffer;
                     asprintf(&buffer, "%s/%s", FileName, e->d_name);
                     if (FollowSymlinks) {
-                       int size = strlen(buffer) * 2; // should be large enough
-                       char *l = MALLOC(char, size);
-                       int n = readlink(buffer, l, size);
-                       if (n < 0) {
-                          if (errno != EINVAL)
-                             LOG_ERROR_STR(buffer);
+                       struct stat st2;
+                       if (stat(buffer, &st2) == 0) {
+                          int size = st2.st_size + 1;
+                          char *l = MALLOC(char, size);
+                          int n = readlink(buffer, l, st2.st_size);
+                          if (n < 0) {
+                              if (errno != EINVAL)
+                                  LOG_ERROR_STR(buffer);
+                              }
+                          else if (n < size) {
+                              l[n] = 0;
+                              dsyslog("removing %s", l);
+                              if (remove(l) < 0)
+                                  LOG_ERROR_STR(l);
+                              }
+                          else
+                              esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);
+                          free(l);
                           }
-                       else if (n < size) {
-                          l[n] = 0;
-                          dsyslog("removing %s", l);
-                          if (remove(l) < 0)
-                             LOG_ERROR_STR(l);
+                       else if (errno != ENOENT) {
+                          LOG_ERROR_STR(FileName);
+                          return false;
                           }
-                       else
-                          esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);
-                       free(l);
                        }
                     dsyslog("removing %s", buffer);
                     if (remove(buffer) < 0)

2

Samstag, 26. Juni 2010, 14:52

I agree that this is a bug, though it does not apply to vanilla VDR, since VDR itself cannot rename a recording, and the symlink always has the same name as the recording itself. Unless you have very different path lengths to your recording directories.

However, IMHO this patch misses a test whether the stated file actually IS an symbolic link. If the name refers to a real file, a filename buffer of the size of the file will be allocated, which may be several gigabytes. Just add a test to S_ISLNK(st2.st_mode).


Cheers,

Udo

3

Sonntag, 27. Juni 2010, 14:42

You're right Udo, I didn't realize the condition of buffer being a symlink was not tested before calling readlink . I'm glad I posted this here before using it... ;-).

Thanks,
atinar

4

Sonntag, 29. August 2010, 16:59

Please test the following patch, which also includes Udo's suggestion (I hope I've put it at the right place ;-):

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
--- tools.c     2010/02/28 13:31:46     2.7
+++ tools.c     2010/08/29 14:50:28
@@ -367,22 +367,31 @@
                  if (strcmp(e->d_name, ".") && strcmp(e->d_name, "..")) {
                     cString buffer = AddDirectory(FileName, e->d_name);
                     if (FollowSymlinks) {
-                       int size = strlen(buffer) * 2; // should be large enough
-                       char *l = MALLOC(char, size);
-                       int n = readlink(buffer, l, size);
-                       if (n < 0) {
-                          if (errno != EINVAL)
-                             LOG_ERROR_STR(*buffer);
+                       struct stat st2;
+                       if (stat(buffer, &st2) == 0) {
+                          if (S_ISLNK(st2.st_mode)) {
+                             int size = st2.st_size + 1;
+                             char *l = MALLOC(char, size);
+                             int n = readlink(buffer, l, st2.st_size);
+                             if (n < 0) {
+                                if (errno != EINVAL)
+                                   LOG_ERROR_STR(*buffer);
+                                }
+                             else if (n < size) {
+                                l[n] = 0;
+                                dsyslog("removing %s", l);
+                                if (remove(l) < 0)
+                                   LOG_ERROR_STR(l);
+                                }
+                             else
+                                esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);
+                             free(l);
+                             }
                           }
-                       else if (n < size) {
-                          l[n] = 0;
-                          dsyslog("removing %s", l);
-                          if (remove(l) < 0)
-                             LOG_ERROR_STR(l);
+                       else if (errno != ENOENT) {
+                          LOG_ERROR_STR(FileName);
+                          return false;
                           }
-                       else
-                          esyslog("ERROR: symlink name length (%d) exceeded anticipated buffer size (%d)", n, size);
-                       free(l);
                        }
                     dsyslog("removing %s", *buffer);
                     if (remove(buffer) < 0)


BTW: I would need your real name and email address if you want to be mentioned in VDR's CONTRIBUTORS file.

Klaus
Gib CI+/HD+ keine Chance! Lasst diese Pest am ausgestreckten Arm verhungern!
Wer für sowas bezahlt macht sich zum Totengräber von Projekten wie VDR!
Die Wahrheit ueber HD Plus
CI-Plus -- Das trojanische Pferd im Wohnzimmer
Mach mit beim VDR User Counter!

Immortal Romance Spielautomat